Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index 15ce0f2..320af25 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -253,6 +253,7 @@
 !Edrivers/usb/core/urb.c
 !Edrivers/usb/core/message.c
 !Edrivers/usb/core/file.c
+!Edrivers/usb/core/driver.c
 !Edrivers/usb/core/usb.c
 !Edrivers/usb/core/hub.c
     </chapter>
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 933fae7..f4b8dc4 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -27,6 +27,7 @@
 2.2  Powersave
 2.3  Userspace
 2.4  Ondemand
+2.5  Conservative
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -110,9 +111,64 @@
 
 The CPUfreq govenor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
-switch the frequency very fast.
+switch the frequency very quickly.  There are a number of sysfs file
+accessible parameters:
+
+sampling_rate: measured in uS (10^-6 seconds), this is how often you
+want the kernel to look at the CPU usage and to make decisions on
+what to do about the frequency.  Typically this is set to values of
+around '10000' or more.
+
+show_sampling_rate_(min|max): the minimum and maximum sampling rates
+available that you may set 'sampling_rate' to.
+
+up_threshold: defines what the average CPU usaged between the samplings
+of 'sampling_rate' needs to be for the kernel to make a decision on
+whether it should increase the frequency.  For example when it is set
+to its default value of '80' it means that between the checking
+intervals the CPU needs to be on average more than 80% in use to then
+decide that the CPU frequency needs to be increased.  
+
+sampling_down_factor: this parameter controls the rate that the CPU
+makes a decision on when to decrease the frequency.  When set to its
+default value of '5' it means that at 1/5 the sampling_rate the kernel
+makes a decision to lower the frequency.  Five "lower rate" decisions
+have to be made in a row before the CPU frequency is actually lower.
+If set to '1' then the frequency decreases as quickly as it increases,
+if set to '2' it decreases at half the rate of the increase.
+
+ignore_nice_load: this parameter takes a value of '0' or '1', when set
+to '0' (its default) then all processes are counted towards towards the
+'cpu utilisation' value.   When set to '1' then processes that are
+run with a 'nice' value will not count (and thus be ignored) in the
+overal usage calculation.  This is useful if you are running a CPU
+intensive calculation on your laptop that you do not care how long it
+takes to complete as you can 'nice' it and prevent it from taking part
+in the deciding process of whether to increase your CPU frequency.
 
 
+2.5 Conservative
+----------------
+
+The CPUfreq governor "conservative", much like the "ondemand"
+governor, sets the CPU depending on the current usage.  It differs in
+behaviour in that it gracefully increases and decreases the CPU speed
+rather than jumping to max speed the moment there is any load on the
+CPU.  This behaviour more suitable in a battery powered environment.
+The governor is tweaked in the same manner as the "ondemand" governor
+through sysfs with the addition of:
+
+freq_step: this describes what percentage steps the cpu freq should be
+increased and decreased smoothly by.  By default the cpu frequency will
+increase in 5% chunks of your maximum cpu frequency.  You can change this
+value to anywhere between 0 and 100 where '0' will effectively lock your
+CPU at a speed regardless of its load whilst '100' will, in theory, make
+it behave identically to the "ondemand" governor.
+
+down_threshold: same as the 'up_threshold' found for the "ondemand"
+governor but for the opposite direction.  For example when set to its
+default value of '20' it means that if the CPU usage needs to be below
+20% between samples to have the frequency decreased.
 
 3. The Governor Interface in the CPUfreq Core
 =============================================
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 5dffcfe..61a56b1 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -633,6 +633,14 @@
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 			Format: <irq>
 
+	combined_mode=	[HW] control which driver uses IDE ports in combined
+			mode: legacy IDE driver, libata, or both
+			(in the libata case, libata.atapi_enabled=1 may be
+			useful as well).  Note that using the ide or libata
+			options may affect your device naming (e.g. by
+			changing hdc to sdb).
+			Format: combined (default), ide, or libata
+
 	inttest=	[IA64]
 
 	io7=		[HW] IO7 for Marvel based alpha systems
diff --git a/Documentation/networking/gianfar.txt b/Documentation/networking/gianfar.txt
new file mode 100644
index 0000000..ad474ea
--- /dev/null
+++ b/Documentation/networking/gianfar.txt
@@ -0,0 +1,72 @@
+The Gianfar Ethernet Driver
+Sysfs File description
+
+Author: Andy Fleming <afleming@freescale.com>
+Updated: 2005-07-28
+
+SYSFS
+
+Several of the features of the gianfar driver are controlled
+through sysfs files.  These are:
+
+bd_stash:
+To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
+bd_stash, echo 'off' or '0' to disable
+
+rx_stash_len:
+To stash the first n bytes of the packet in L2, echo the number
+of bytes to buf_stash_len.  echo 0 to disable.
+
+WARNING: You could really screw these up if you set them too low or high!
+fifo_threshold:
+To change the number of bytes the controller needs in the
+fifo before it starts transmission, echo the number of bytes to 
+fifo_thresh.  Range should be 0-511.
+
+fifo_starve:
+When the FIFO has less than this many bytes during a transmit, it
+enters starve mode, and increases the priority of TX memory
+transactions.  To change, echo the number of bytes to
+fifo_starve.  Range should be 0-511.
+
+fifo_starve_off:
+Once in starve mode, the FIFO remains there until it has this
+many bytes.  To change, echo the number of bytes to
+fifo_starve_off.  Range should be 0-511.
+
+CHECKSUM OFFLOADING
+
+The eTSEC controller (first included in parts from late 2005 like
+the 8548) has the ability to perform TCP, UDP, and IP checksums
+in hardware.  The Linux kernel only offloads the TCP and UDP
+checksums (and always performs the pseudo header checksums), so
+the driver only supports checksumming for TCP/IP and UDP/IP
+packets.  Use ethtool to enable or disable this feature for RX
+and TX.
+
+VLAN
+
+In order to use VLAN, please consult Linux documentation on
+configuring VLANs.  The gianfar driver supports hardware insertion and
+extraction of VLAN headers, but not filtering.  Filtering will be
+done by the kernel.
+
+MULTICASTING
+
+The gianfar driver supports using the group hash table on the
+TSEC (and the extended hash table on the eTSEC) for multicast
+filtering.  On the eTSEC, the exact-match MAC registers are used
+before the hash tables.  See Linux documentation on how to join
+multicast groups.
+
+PADDING
+
+The gianfar driver supports padding received frames with 2 bytes
+to align the IP header to a 16-byte boundary, when supported by
+hardware.
+
+ETHTOOL
+
+The gianfar driver supports the use of ethtool for many
+configuration options.  You must run ethtool only on currently
+open interfaces.  See ethtool documentation for details.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ebc09a1..2b7cf19 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -46,6 +46,29 @@
 	for the hash secret) for IP fragments.
 	Default: 600
 
+ipfrag_max_dist - INTEGER
+	ipfrag_max_dist is a non-negative integer value which defines the 
+	maximum "disorder" which is allowed among fragments which share a 
+	common IP source address. Note that reordering of packets is 
+	not unusual, but if a large number of fragments arrive from a source 
+	IP address while a particular fragment queue remains incomplete, it 
+	probably indicates that one or more fragments belonging to that queue 
+	have been lost. When ipfrag_max_dist is positive, an additional check 
+	is done on fragments before they are added to a reassembly queue - if 
+	ipfrag_max_dist (or more) fragments have arrived from a particular IP 
+	address between additions to any IP fragment queue using that source 
+	address, it's presumed that one or more fragments in the queue are 
+	lost. The existing fragment queue will be dropped, and a new one 
+	started. An ipfrag_max_dist value of zero disables this check.
+
+	Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
+	result in unnecessarily dropping fragment queues when normal
+	reordering of packets occurs, which could lead to poor application 
+	performance. Using a very large value, e.g. 50000, increases the 
+	likelihood of incorrectly reassembling IP fragments that originate 
+	from different IP datagrams, which could result in data corruption.
+	Default: 64
+
 INET peer storage:
 
 inet_peer_threshold - INTEGER
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid
index 5331d91..09f6300 100644
--- a/Documentation/scsi/ChangeLog.megaraid
+++ b/Documentation/scsi/ChangeLog.megaraid
@@ -1,3 +1,38 @@
+Release Date	: Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
+Older Version	: 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
+
+1.	Sorted out PCI IDs to remove megaraid support overlaps.
+	Based on the patch from Daniel, sorted out PCI IDs along with
+	charactor node name change from 'megadev' to 'megadev_legacy' to avoid
+	conflict.
+	---
+	Hopefully we'll be getting the build restriction zapped much sooner, 
+	but we should also be thinking about totally removing the hardware 
+	support overlap in the megaraid drivers.
+
+	This patch pencils in a date of Feb 06 for this, and performs some 
+	printk abuse in hope that existing legacy users might pick up on what's
+	going on.
+
+	Signed-off-by: Daniel Drake <dsd@gentoo.org>
+	---
+
+2.	Fixed a issue: megaraid always fails to reset handler.
+	---
+	I found that the megaraid driver always fails to reset the
+	adapter with the following message:
+		megaraid: resetting the host...
+		megaraid mbox: reset sequence completed successfully
+		megaraid: fast sync command timed out
+		megaraid: reservation reset failed
+	when the "Cluster mode" of the adapter BIOS is enabled.
+	So, whenever the reset occurs, the adapter goes to
+	offline and just become unavailable.
+
+	Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
+	---
+
 Release Date	: Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
 Older Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 3209b37e..8bbae3e 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -150,7 +150,8 @@
 LLD                   mid level                    LLD
 ===-------------------=========--------------------===------
 scsi_host_alloc()  -->
-scsi_add_host()  --------+
+scsi_add_host()  ---->
+scsi_scan_host()  -------+
                          |
                     slave_alloc()
                     slave_configure() -->  scsi_adjust_queue_depth()
@@ -196,7 +197,7 @@
 
 
 The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_add_host() function causes a scan for SCSI devices
+HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
 attached to the HBA's SCSI transport. On newer SCSI transports the HBA
 may become aware of a new SCSI device _after_ the scan has completed.
 An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -372,7 +373,7 @@
 Summary:
    scsi_activate_tcq - turn on tag command queueing
    scsi_add_device - creates new scsi device (lu) instance
-   scsi_add_host - perform sysfs registration and SCSI bus scan.
+   scsi_add_host - perform sysfs registration and set up transport class
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_assign_lock - replace default host_lock with given lock
    scsi_bios_ptable - return copy of block device's partition table
@@ -386,6 +387,7 @@
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
+   scsi_scan_host - scan SCSI bus
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
@@ -425,10 +427,10 @@
  *      Might block: yes
  *
  *      Notes: This call is usually performed internally during a scsi
- *      bus scan when an HBA is added (i.e. scsi_add_host()). So it
+ *      bus scan when an HBA is added (i.e. scsi_scan_host()). So it
  *      should only be called if the HBA becomes aware of a new scsi
- *      device (lu) after scsi_add_host() has completed. If successful
- *      this call we lead to slave_alloc() and slave_configure() callbacks
+ *      device (lu) after scsi_scan_host() has completed. If successful
+ *      this call can lead to slave_alloc() and slave_configure() callbacks
  *      into the LLD.
  *
  *      Defined in: drivers/scsi/scsi_scan.c
@@ -439,7 +441,7 @@
 
 
 /**
- * scsi_add_host - perform sysfs registration and SCSI bus scan.
+ * scsi_add_host - perform sysfs registration and set up transport class
  * @shost:   pointer to scsi host instance
  * @dev:     pointer to struct device of type scsi class
  *
@@ -448,7 +450,11 @@
  *      Might block: no
  *
  *      Notes: Only required in "hotplug initialization model" after a
- *      successful call to scsi_host_alloc().
+ *      successful call to scsi_host_alloc().  This function does not
+ *	scan the bus; this can be done by calling scsi_scan_host() or
+ *	in some other transport-specific way.  The LLD must set up
+ *	the transport template before calling this function and may only
+ *	access the transport class data after this function has been called.
  *
  *      Defined in: drivers/scsi/hosts.c
  **/
@@ -559,7 +565,7 @@
  *      area for the LLD's exclusive use.
  *      Both associated refcounting objects have their refcount set to 1.
  *      Full registration (in sysfs) and a bus scan are performed later when
- *      scsi_add_host() is called.
+ *      scsi_add_host() and scsi_scan_host() are called.
  *
  *      Defined in: drivers/scsi/hosts.c .
  **/
@@ -699,6 +705,19 @@
 
 
 /**
+ * scsi_scan_host - scan SCSI bus
+ * @shost: a pointer to a scsi host instance
+ *
+ *	Might block: yes
+ *
+ *	Notes: Should be called after scsi_add_host()
+ *
+ *	Defined in: drivers/scsi/scsi_scan.c
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+
+
+/**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
  *                      to adjust the queue depth on the device.
diff --git a/MAINTAINERS b/MAINTAINERS
index 79f0efa..b524ca3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2638,6 +2638,12 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB ISP116X DRIVER
+P:	Olav Kongas
+M:	ok@artecdesign.ee
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB KAWASAKI LSI DRIVER
 P:	Oliver Neukum
 M:	oliver@neukum.name
@@ -2649,7 +2655,7 @@
 P:	Matthew Dharm
 M:	mdharm-usb@one-eyed-alien.net
 L:	linux-usb-users@lists.sourceforge.net
-L:	linux-usb-devel@lists.sourceforge.net
+L:	usb-storage@lists.one-eyed-alien.net
 S:	Maintained
 W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
 
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 07892f4..277498a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -43,6 +43,7 @@
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -393,6 +394,25 @@
 	&mst_flash_device[1],
 };
 
+static int mainstone_ohci_init(struct device *dev)
+{
+	/* setup Port1 GPIO pin. */
+	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
+	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+
+	/* Set the Power Control Polarity Low and Power Sense
+	   Polarity Low to active low. */
+	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= mainstone_ohci_init,
+};
+
 static void __init mainstone_init(void)
 {
 	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@@ -424,6 +444,7 @@
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
+	pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index c722a9a..b41b1ef 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,6 +21,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -194,6 +195,11 @@
 	.resource       = pxa27x_ohci_resources,
 };
 
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+	ohci_device.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
 	&ohci_device,
 };
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 04a4053..2b62dee 100644
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -177,9 +177,10 @@
  */
 static int nforce2_set_fsb(unsigned int fsb)
 {
-	u32 pll, temp = 0;
+	u32 temp = 0;
 	unsigned int tfsb;
 	int diff;
+	int pll = 0;
 
 	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
 		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 68a1fc8..0fbbd4c 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -45,7 +45,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.50.4"
+#define VERSION "version 1.60.0"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -216,10 +216,10 @@
 
 	do {
 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-                if (i++ > 100) {
-                        printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
-                        return 1;
-                }
+		if (i++ > 100) {
+			printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+			return 1;
+		}
 	} while (query_current_values_with_pending_wait(data));
 
 	if (savefid != data->currfid) {
@@ -336,7 +336,7 @@
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, 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",
@@ -359,9 +359,11 @@
 	    : vcoreqfid - vcocurrfid;
 
 	while (vcofiddiff > 2) {
+		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
+
 		if (reqfid > data->currfid) {
 			if (data->currfid > LO_FID_TABLE_TOP) {
-				if (write_new_fid(data, data->currfid + 2)) {
+				if (write_new_fid(data, data->currfid + fid_interval)) {
 					return 1;
 				}
 			} else {
@@ -371,7 +373,7 @@
 				}
 			}
 		} else {
-			if (write_new_fid(data, data->currfid - 2))
+			if (write_new_fid(data, data->currfid - fid_interval))
 				return 1;
 		}
 
@@ -464,7 +466,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
 	if (smp_processor_id() != cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
 		goto out;
 	}
 
@@ -474,7 +476,7 @@
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 	if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 	    ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
-	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
+	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
 		printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
 		goto out;
 	}
@@ -517,22 +519,24 @@
 			printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
 			return -ENODEV;
 		}
-		if ((pst[j].fid > MAX_FID)
-		    || (pst[j].fid & 1)
-		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
+		if (pst[j].fid > MAX_FID) {
+			printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
+			return -ENODEV;
+		}
+		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 		}
 		if (pst[j].fid < lastfid)
 			lastfid = pst[j].fid;
 	}
 	if (lastfid & 1) {
-		printk(KERN_ERR PFX "lastfid invalid\n");
+		printk(KERN_ERR BFX "lastfid invalid\n");
 		return -EINVAL;
 	}
 	if (lastfid > LO_FID_TABLE_TOP)
-		printk(KERN_INFO PFX  "first fid not from lo freq table\n");
+		printk(KERN_INFO BFX  "first fid not from lo freq table\n");
 
 	return 0;
 }
@@ -631,7 +635,7 @@
 
 		dprintk("table vers: 0x%x\n", psb->tableversion);
 		if (psb->tableversion != PSB_VERSION_1_4) {
-			printk(KERN_INFO BFX "PSB table is not v1.4\n");
+			printk(KERN_ERR BFX "PSB table is not v1.4\n");
 			return -ENODEV;
 		}
 
@@ -689,7 +693,7 @@
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * www.amd.com
 	 */
-	printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+	printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
 	return -ENODEV;
 }
 
@@ -912,7 +916,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 	}
 
@@ -982,6 +986,9 @@
 	cpumask_t oldmask = CPU_MASK_ALL;
 	int rc, i;
 
+	if (!cpu_online(pol->cpu))
+		return -ENODEV;
+
 	if (!check_supported_cpu(pol->cpu))
 		return -ENODEV;
 
@@ -1021,7 +1028,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 	}
 
@@ -1162,10 +1169,9 @@
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
-
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index b1e85bb..d0de37d 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -42,7 +42,7 @@
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM_K8			0
 #define CPUID_XMOD			0x000f0000	/* extended model */
-#define CPUID_XMOD_REV_F		0x00040000
+#define CPUID_XMOD_REV_G		0x00060000
 #define CPUID_USE_XFAM_XMOD		0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000
 #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
@@ -86,13 +86,14 @@
  *   low fid table
  * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
  *   in the low fid table
- * - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid
+ * - the parts can only step at <= 200 MHz intervals, odd fid values are
+ *   supported in revision G and later revisions.
  * - lowest frequency must be >= interprocessor hypertransport link speed
  *   (only applies to MP systems obviously)
  */
 
 /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP     6	/* fid values marking the boundary    */
+#define LO_FID_TABLE_TOP     7	/* fid values marking the boundary    */
 #define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
 
 #define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
@@ -106,7 +107,7 @@
 #define MIN_FREQ 800	/* Min and max freqs, per spec */
 #define MAX_FREQ 5000
 
-#define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
+#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
 #define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
 
 #define VID_OFF 0x3f
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index 5b7d18a..b425cd3 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -40,6 +40,7 @@
  */
 static unsigned int speedstep_processor = 0;
 
+static u32 pmbase;
 
 /*
  *   There are only two frequency states for each processor. Values
@@ -56,6 +57,33 @@
 
 
 /**
+ * speedstep_find_register - read the PMBASE address
+ *
+ * Returns: -ENODEV if no register could be found
+ */
+static int speedstep_find_register (void)
+{
+	if (!speedstep_chipset_dev)
+		return -ENODEV;
+
+	/* get PMBASE */
+	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
+	if (!(pmbase & 0x01)) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	pmbase &= 0xFFFFFFFE;
+	if (!pmbase) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	dprintk("pmbase is 0x%x\n", pmbase);
+	return 0;
+}
+
+/**
  * speedstep_set_state - set the SpeedStep state
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
  *
@@ -63,27 +91,13 @@
  */
 static void speedstep_set_state (unsigned int state)
 {
-	u32 pmbase;
 	u8 pm2_blk;
 	u8 value;
 	unsigned long flags;
 
-	if (!speedstep_chipset_dev || (state > 0x1))
+	if (state > 0x1)
 		return;
 
-	/* get PMBASE */
-	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
-	if (!(pmbase & 0x01)) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
-	}
-
-	pmbase &= 0xFFFFFFFE;
-	if (!pmbase) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
-	}
-
 	/* Disable IRQs */
 	local_irq_save(flags);
 
@@ -315,10 +329,11 @@
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
 
-	/* detect low and high frequency */
+	/* detect low and high frequency and transition latency */
 	result = speedstep_get_freqs(speedstep_processor,
 				     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				     &policy->cpuinfo.transition_latency,
 				     &speedstep_set_state);
 	set_cpus_allowed(current, cpus_allowed);
 	if (result)
@@ -335,7 +350,6 @@
 
 	/* cpuinfo and default policy values */
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	policy->cur = speed;
 
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -400,6 +414,9 @@
 		return -EINVAL;
 	}
 
+	if (speedstep_find_register())
+		return -ENODEV;
+
 	return cpufreq_register_driver(&speedstep_driver);
 }
 
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index d368b3f..7c47005 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -320,11 +320,13 @@
 unsigned int speedstep_get_freqs(unsigned int processor,
 				  unsigned int *low_speed,
 				  unsigned int *high_speed,
+				  unsigned int *transition_latency,
 				  void (*set_state) (unsigned int state))
 {
 	unsigned int prev_speed;
 	unsigned int ret = 0;
 	unsigned long flags;
+	struct timeval tv1, tv2;
 
 	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
 		return -EINVAL;
@@ -337,7 +339,7 @@
 		return -EIO;
 
 	dprintk("previous speed is %u\n", prev_speed);
-	
+
 	local_irq_save(flags);
 
 	/* switch to low state */
@@ -350,8 +352,17 @@
 
 	dprintk("low speed is %u\n", *low_speed);
 
+	/* start latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv1);
+
 	/* switch to high state */
 	set_state(SPEEDSTEP_HIGH);
+
+	/* end latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv2);
+
 	*high_speed = speedstep_get_processor_frequency(processor);
 	if (!*high_speed) {
 		ret = -EIO;
@@ -369,6 +380,25 @@
 	if (*high_speed != prev_speed)
 		set_state(SPEEDSTEP_LOW);
 
+	if (transition_latency) {
+		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
+			tv2.tv_usec - tv1.tv_usec;
+		dprintk("transition latency is %u uSec\n", *transition_latency);
+
+		/* convert uSec to nSec and add 20% for safety reasons */
+		*transition_latency *= 1200;
+
+		/* check if the latency measurement is too high or too low
+		 * and set it to a safe value (500uSec) in that case
+		 */
+		if (*transition_latency > 10000000 || *transition_latency < 50000) {
+			printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
+					"range (%u nSec), falling back to a safe one of %u nSec.\n",
+					*transition_latency, 500000);
+			*transition_latency = 500000;
+		}
+	}
+
  out:
 	local_irq_restore(flags);
 	return (ret);
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
index 261a2c9..6a727fd 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
@@ -44,4 +44,5 @@
 extern unsigned int speedstep_get_freqs(unsigned int processor,
 	  unsigned int *low_speed,
 	  unsigned int *high_speed,
+	  unsigned int *transition_latency,
 	  void (*set_state) (unsigned int state));
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 2718fb6..28cc5d5 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -269,6 +269,7 @@
 		result = speedstep_get_freqs(speedstep_processor,
 				&speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				NULL,
 				&speedstep_set_state);
 
 		if (result) {
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index e792131..6d91b27 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <asm/semaphore.h>
 #include <linux/seq_file.h>
+#include <linux/cpufreq.h>
 
 /*
  *	Get CPU information for use by the procfs.
@@ -86,8 +87,11 @@
 		seq_printf(m, "stepping\t: unknown\n");
 
 	if ( cpu_has(c, X86_FEATURE_TSC) ) {
+		unsigned int freq = cpufreq_quick_get(n);
+		if (!freq)
+			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-			cpu_khz / 1000, (cpu_khz % 1000));
+			freq / 1000, (freq % 1000));
 	}
 
 	/* Cache size */
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 5add0bc..088e5dd 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/initrd.h>
 #include <linux/platform.h>
 #include <linux/pm.h>
+#include <linux/cpufreq.h>
 
 #include <asm/ia32.h>
 #include <asm/machvec.h>
@@ -517,6 +518,7 @@
 	char family[32], features[128], *cp, sep;
 	struct cpuinfo_ia64 *c = v;
 	unsigned long mask;
+	unsigned int proc_freq;
 	int i;
 
 	mask = c->features;
@@ -549,6 +551,10 @@
 		sprintf(cp, " 0x%lx", mask);
 	}
 
+	proc_freq = cpufreq_quick_get(cpunum);
+	if (!proc_freq)
+		proc_freq = c->proc_freq / 1000;
+
 	seq_printf(m,
 		   "processor  : %d\n"
 		   "vendor     : %s\n"
@@ -565,7 +571,7 @@
 		   "BogoMIPS   : %lu.%02lu\n",
 		   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
 		   features, c->ppn, c->number,
-		   c->proc_freq / 1000000, c->proc_freq % 1000000,
+		   proc_freq / 1000, proc_freq % 1000,
 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 #ifdef CONFIG_SMP
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 330cf84..60353f5 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -420,7 +420,7 @@
 		goto out;
 	pos = merge_64(a4, a5);
 	ret = rw_verify_area(READ, file, &pos, count);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = -EINVAL;
 	if (!file->f_op || !(read = file->f_op->read))
@@ -455,7 +455,7 @@
 		goto out;
 	pos = merge_64(a4, a5);
 	ret = rw_verify_area(WRITE, file, &pos, count);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = -EINVAL;
 	if (!file->f_op || !(write = file->f_op->write))
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 750e01d..64c4534 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -42,6 +42,7 @@
 #include <linux/edd.h>
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
+#include <linux/cpufreq.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -1256,8 +1257,11 @@
 		seq_printf(m, "stepping\t: unknown\n");
 	
 	if (cpu_has(c,X86_FEATURE_TSC)) {
+		unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+		if (!freq)
+			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-			     cpu_khz / 1000, (cpu_khz % 1000));
+			     freq / 1000, (freq % 1000));
 	}
 
 	/* Cache size */
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 99c9ca6..d4beb9a 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -239,7 +239,7 @@
 	q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 	q->backing_dev_info.state = 0;
 	q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
-	blk_queue_max_sectors(q, MAX_SECTORS);
+	blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
 	blk_queue_hardsect_size(q, 512);
 	blk_queue_dma_alignment(q, 511);
 	blk_queue_congestion_threshold(q);
@@ -555,7 +555,12 @@
 		printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
 	}
 
-	q->max_sectors = q->max_hw_sectors = max_sectors;
+	if (BLK_DEF_MAX_SECTORS > max_sectors)
+		q->max_hw_sectors = q->max_sectors = max_sectors;
+ 	else {
+		q->max_sectors = BLK_DEF_MAX_SECTORS;
+		q->max_hw_sectors = max_sectors;
+	}
 }
 
 EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -657,8 +662,8 @@
 void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
 {
 	/* zero is "infinity" */
-	t->max_sectors = t->max_hw_sectors =
-		min_not_zero(t->max_sectors,b->max_sectors);
+	t->max_sectors = min_not_zero(t->max_sectors,b->max_sectors);
+	t->max_hw_sectors = min_not_zero(t->max_hw_sectors,b->max_hw_sectors);
 
 	t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
 	t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
@@ -1293,9 +1298,15 @@
 static int ll_back_merge_fn(request_queue_t *q, struct request *req, 
 			    struct bio *bio)
 {
+	unsigned short max_sectors;
 	int len;
 
-	if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+	if (unlikely(blk_pc_request(req)))
+		max_sectors = q->max_hw_sectors;
+	else
+		max_sectors = q->max_sectors;
+
+	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
 		req->flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -1325,9 +1336,16 @@
 static int ll_front_merge_fn(request_queue_t *q, struct request *req, 
 			     struct bio *bio)
 {
+	unsigned short max_sectors;
 	int len;
 
-	if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+	if (unlikely(blk_pc_request(req)))
+		max_sectors = q->max_hw_sectors;
+	else
+		max_sectors = q->max_sectors;
+
+
+	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
 		req->flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -2144,7 +2162,7 @@
 	struct bio *bio;
 	int reading;
 
-	if (len > (q->max_sectors << 9))
+	if (len > (q->max_hw_sectors << 9))
 		return -EINVAL;
 	if (!len || !ubuf)
 		return -EINVAL;
@@ -2259,7 +2277,7 @@
 {
 	struct bio *bio;
 
-	if (len > (q->max_sectors << 9))
+	if (len > (q->max_hw_sectors << 9))
 		return -EINVAL;
 	if (!len || !kbuf)
 		return -EINVAL;
@@ -2306,6 +2324,8 @@
 	generic_unplug_device(q);
 }
 
+EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
+
 /**
  * blk_execute_rq - insert a request into queue for execution
  * @q:		queue to insert the request in
@@ -2444,7 +2464,7 @@
 /*
  * queue lock must be held
  */
-static void __blk_put_request(request_queue_t *q, struct request *req)
+void __blk_put_request(request_queue_t *q, struct request *req)
 {
 	struct request_list *rl = req->rl;
 
@@ -2473,6 +2493,8 @@
 	}
 }
 
+EXPORT_SYMBOL_GPL(__blk_put_request);
+
 void blk_put_request(struct request *req)
 {
 	unsigned long flags;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 6e7db2e..1d8852f 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -233,7 +233,7 @@
 	if (verify_command(file, cmd))
 		return -EPERM;
 
-	if (hdr->dxfer_len > (q->max_sectors << 9))
+	if (hdr->dxfer_len > (q->max_hw_sectors << 9))
 		return -EIO;
 
 	if (hdr->dxfer_len)
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 7b1cd93..c4b9d2a 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -358,7 +358,8 @@
 	  This driver supports certain USB attached storage devices
 	  such as flash keys.
 
-	  Warning: Enabling this cripples the usb-storage driver.
+	  If you enable this driver, it is recommended to avoid conflicts
+	  with usb-storage by enabling USB_LIBUSUAL.
 
 	  If unsure, say N.
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index bfb23d5..10740a0 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -9,7 +9,6 @@
  *
  * TODO (sorted by decreasing priority)
  *  -- Kill first_open (Al Viro fixed the block layer now)
- *  -- Do resets with usb_device_reset (needs a thread context, use khubd)
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@@ -29,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
@@ -107,16 +107,6 @@
  */
 
 /*
- * Definitions which have to be scattered once we understand the layout better.
- */
-
-/* Transport (despite PR in the name) */
-#define US_PR_BULK	0x50		/* bulk only */
-
-/* Protocol */
-#define US_SC_SCSI	0x06		/* Transparent */
-
-/*
  * This many LUNs per USB device.
  * Every one of them takes a host, see UB_MAX_HOSTS.
  */
@@ -125,7 +115,7 @@
 /*
  */
 
-#define UB_MINORS_PER_MAJOR	8
+#define UB_PARTS_PER_LUN      8
 
 #define UB_MAX_CDB_SIZE      16		/* Corresponds to Bulk */
 
@@ -245,6 +235,13 @@
 	void *back;
 };
 
+struct ub_request {
+	struct request *rq;
+	unsigned int current_try;
+	unsigned int nsg;		/* sgv[nsg] */
+	struct scatterlist sgv[UB_MAX_REQ_SG];
+};
+
 /*
  */
 struct ub_capacity {
@@ -340,6 +337,8 @@
 	int readonly;
 	int first_open;			/* Kludge. See ub_bd_open. */
 
+	struct ub_request urq;
+
 	/* Use Ingo's mempool if or when we have more than one command. */
 	/*
 	 * Currently we never need more than one command for the whole device.
@@ -360,6 +359,7 @@
 	atomic_t poison;		/* The USB device is disconnected */
 	int openc;			/* protected by ub_lock! */
 					/* kref is too implicit for our taste */
+	int reset;			/* Reset is running */
 	unsigned int tagcnt;
 	char name[12];
 	struct usb_device *dev;
@@ -387,6 +387,9 @@
 	struct bulk_cs_wrap work_bcs;
 	struct usb_ctrlrequest work_cr;
 
+	struct work_struct reset_work;
+	wait_queue_head_t reset_wait;
+
 	int sg_stat[6];
 	struct ub_scsi_trace tr;
 };
@@ -395,12 +398,14 @@
  */
 static void ub_cleanup(struct ub_dev *sc);
 static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
 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_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
 static void ub_scsi_action(unsigned long _dev);
@@ -415,6 +420,8 @@
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
+static void ub_reset_enter(struct ub_dev *sc);
+static void ub_reset_task(void *arg);
 static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
 static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_capacity *ret);
@@ -422,13 +429,18 @@
 
 /*
  */
+#ifdef CONFIG_USB_LIBUSUAL
+
+#define ub_usb_ids  storage_usb_ids
+#else
+
 static struct usb_device_id ub_usb_ids[] = {
-	// { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) },	/* SDDR-31 */
 	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
 	{ }
 };
 
 MODULE_DEVICE_TABLE(usb, ub_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /*
  * Find me a way to identify "next free minor" for add_disk(),
@@ -522,6 +534,9 @@
 	spin_lock_irqsave(&sc->lock, flags);
 
 	cnt += sprintf(page + cnt,
+	    "poison %d reset %d\n",
+	    atomic_read(&sc->poison), sc->reset);
+	cnt += sprintf(page + cnt,
 	    "qlen %d qmax %d\n",
 	    sc->cmd_queue.qlen, sc->cmd_queue.qmax);
 	cnt += sprintf(page + cnt,
@@ -770,7 +785,8 @@
 {
 	struct ub_dev *sc = lun->udev;
 	struct ub_scsi_cmd *cmd;
-	int rc;
+	struct ub_request *urq;
+	int n_elem;
 
 	if (atomic_read(&sc->poison) || lun->changed) {
 		blkdev_dequeue_request(rq);
@@ -778,66 +794,71 @@
 		return 0;
 	}
 
+	if (lun->urq.rq != NULL)
+		return -1;
 	if ((cmd = ub_get_cmd(lun)) == 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, lun, cmd, rq);
-	} else {
-		rc = ub_cmd_build_block(sc, lun, cmd, rq);
-	}
-	if (rc != 0) {
-		ub_put_cmd(lun, cmd);
-		ub_end_rq(rq, 0);
-		return 0;
-	}
-	cmd->state = UB_CMDST_INIT;
-	cmd->lun = lun;
-	cmd->done = ub_rw_cmd_done;
-	cmd->back = rq;
 
-	cmd->tag = sc->tagcnt++;
-	if (ub_submit_scsi(sc, cmd) != 0) {
-		ub_put_cmd(lun, cmd);
-		ub_end_rq(rq, 0);
-		return 0;
-	}
-
-	return 0;
-}
-
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
-{
-	int ub_dir;
-	int n_elem;
-	unsigned int block, nblks;
-
-	if (rq_data_dir(rq) == WRITE)
-		ub_dir = UB_DIR_WRITE;
-	else
-		ub_dir = UB_DIR_READ;
-	cmd->dir = ub_dir;
+	urq = &lun->urq;
+	memset(urq, 0, sizeof(struct ub_request));
+	urq->rq = rq;
 
 	/*
 	 * get scatterlist from block layer
 	 */
-	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-	if (n_elem <= 0) {
+	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
+	if (n_elem < 0) {
 		printk(KERN_INFO "%s: failed request map (%d)\n",
-		    sc->name, n_elem); /* P3 */
-		return -1;		/* request with no s/g entries? */
+		    lun->name, n_elem); /* P3 */
+		goto drop;
 	}
 	if (n_elem > UB_MAX_REQ_SG) {	/* Paranoia */
 		printk(KERN_WARNING "%s: request with %d segments\n",
-		    sc->name, n_elem);
-		return -1;
+		    lun->name, n_elem);
+		goto drop;
 	}
-	cmd->nsg = n_elem;
+	urq->nsg = n_elem;
 	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
+	if (blk_pc_request(rq)) {
+		ub_cmd_build_packet(sc, lun, cmd, urq);
+	} else {
+		ub_cmd_build_block(sc, lun, cmd, urq);
+	}
+	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;
+	cmd->done = ub_rw_cmd_done;
+	cmd->back = urq;
+
+	cmd->tag = sc->tagcnt++;
+	if (ub_submit_scsi(sc, cmd) != 0)
+		goto drop;
+
+	return 0;
+
+drop:
+	ub_put_cmd(lun, cmd);
+	ub_end_rq(rq, 0);
+	return 0;
+}
+
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
+{
+	struct request *rq = urq->rq;
+	unsigned int block, nblks;
+
+	if (rq_data_dir(rq) == WRITE)
+		cmd->dir = UB_DIR_WRITE;
+	else
+		cmd->dir = UB_DIR_READ;
+
+	cmd->nsg = urq->nsg;
+	memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
+
 	/*
 	 * build the command
 	 *
@@ -847,7 +868,7 @@
 	block = rq->sector >> lun->capacity.bshift;
 	nblks = rq->nr_sectors >> lun->capacity.bshift;
 
-	cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
+	cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
 	/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
 	cmd->cdb[2] = block >> 24;
 	cmd->cdb[3] = block >> 16;
@@ -858,14 +879,12 @@
 	cmd->cdb_len = 10;
 
 	cmd->len = rq->nr_sectors * 512;
-
-	return 0;
 }
 
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
 {
-	int n_elem;
+	struct request *rq = urq->rq;
 
 	if (rq->data_len == 0) {
 		cmd->dir = UB_DIR_NONE;
@@ -874,40 +893,26 @@
 			cmd->dir = UB_DIR_WRITE;
 		else
 			cmd->dir = UB_DIR_READ;
-
 	}
 
-	/*
-	 * get scatterlist from block layer
-	 */
-	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-	if (n_elem < 0) {
-		printk(KERN_INFO "%s: failed request map (%d)\n",
-		    sc->name, n_elem); /* P3 */
-		return -1;
-	}
-	if (n_elem > UB_MAX_REQ_SG) {	/* Paranoia */
-		printk(KERN_WARNING "%s: request with %d segments\n",
-		    sc->name, n_elem);
-		return -1;
-	}
-	cmd->nsg = n_elem;
-	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+	cmd->nsg = urq->nsg;
+	memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
 
 	memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
 	cmd->cdb_len = rq->cmd_len;
 
 	cmd->len = rq->data_len;
-
-	return 0;
 }
 
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
-	struct request *rq = cmd->back;
 	struct ub_lun *lun = cmd->lun;
+	struct ub_request *urq = cmd->back;
+	struct request *rq;
 	int uptodate;
 
+	rq = urq->rq;
+
 	if (cmd->error == 0) {
 		uptodate = 1;
 
@@ -928,9 +933,16 @@
 				rq->errors = SAM_STAT_CHECK_CONDITION;
 			else
 				rq->errors = DID_ERROR << 16;
+		} else {
+			if (cmd->error == -EIO) {
+				if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
+					return;
+			}
 		}
 	}
 
+	urq->rq = NULL;
+
 	ub_put_cmd(lun, cmd);
 	ub_end_rq(rq, uptodate);
 	blk_start_queue(lun->disk->queue);
@@ -938,13 +950,45 @@
 
 static void ub_end_rq(struct request *rq, int uptodate)
 {
-	int rc;
-
-	rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
-	// assert(rc == 0);
+	end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
 	end_that_request_last(rq);
 }
 
+static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd)
+{
+
+	if (atomic_read(&sc->poison))
+		return -ENXIO;
+
+	ub_reset_enter(sc);
+
+	if (urq->current_try >= 3)
+		return -EIO;
+	urq->current_try++;
+	/* P3 */ printk("%s: dir %c len/act %d/%d "
+	    "[sense %x %02x %02x] retry %d\n",
+	    sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
+	    cmd->key, cmd->asc, cmd->ascq, urq->current_try);
+
+	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	ub_cmd_build_block(sc, lun, cmd, urq);
+
+	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;
+	cmd->done = ub_rw_cmd_done;
+	cmd->back = urq;
+
+	cmd->tag = sc->tagcnt++;
+
+#if 0 /* Wasteful */
+	return ub_submit_scsi(sc, cmd);
+#else
+	ub_cmdq_add(sc, cmd);
+	return 0;
+#endif
+}
+
 /*
  * Submit a regular SCSI operation (not an auto-sense).
  *
@@ -1075,7 +1119,7 @@
 	struct ub_scsi_cmd *cmd;
 	int rc;
 
-	while ((cmd = ub_cmdq_peek(sc)) != NULL) {
+	while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
 		if (cmd->state == UB_CMDST_DONE) {
 			ub_cmdq_pop(sc);
 			(*cmd->done)(sc, cmd);
@@ -1098,11 +1142,12 @@
 {
 	struct urb *urb = &sc->work_urb;
 	struct bulk_cs_wrap *bcs;
+	int len;
 	int rc;
 
 	if (atomic_read(&sc->poison)) {
-		/* A little too simplistic, I feel... */
-		goto Bad_End;
+		ub_state_done(sc, cmd, -ENODEV);
+		return;
 	}
 
 	if (cmd->state == UB_CMDST_CLEAR) {
@@ -1110,7 +1155,6 @@
 			/*
 			 * STALL while clearning STALL.
 			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
@@ -1129,11 +1173,6 @@
 
 	} else if (cmd->state == UB_CMDST_CLR2STS) {
 		if (urb->status == -EPIPE) {
-			/*
-			 * STALL while clearning STALL.
-			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
-			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
 			goto Bad_End;
@@ -1151,11 +1190,6 @@
 
 	} else if (cmd->state == UB_CMDST_CLRRS) {
 		if (urb->status == -EPIPE) {
-			/*
-			 * STALL while clearning STALL.
-			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
-			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
 			goto Bad_End;
@@ -1172,7 +1206,12 @@
 		ub_state_stat_counted(sc, cmd);
 
 	} else if (cmd->state == UB_CMDST_CMD) {
-		if (urb->status == -EPIPE) {
+		switch (urb->status) {
+		case 0:
+			break;
+		case -EOVERFLOW:
+			goto Bad_End;
+		case -EPIPE:
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
@@ -1182,17 +1221,20 @@
 				 * This is typically ENOMEM or some other such shit.
 				 * Retrying is pointless. Just do Bad End on it...
 				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 			cmd->state = UB_CMDST_CLEAR;
 			ub_cmdtr_state(sc, cmd);
 			return;
-		}
-		if (urb->status != 0) {
+		case -ESHUTDOWN:	/* unplug */
+		case -EILSEQ:		/* unplug timeout on uhci */
+			ub_state_done(sc, cmd, -ENODEV);
+			return;
+		default:
 			goto Bad_End;
 		}
 		if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
-			/* XXX Must do reset here to unconfuse the device */
 			goto Bad_End;
 		}
 
@@ -1211,11 +1253,8 @@
 				printk(KERN_NOTICE "%s: "
 				    "unable to submit clear (%d)\n",
 				    sc->name, rc);
-				/*
-				 * This is typically ENOMEM or some other such shit.
-				 * Retrying is pointless. Just do Bad End on it...
-				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 			cmd->state = UB_CMDST_CLR2STS;
 			ub_cmdtr_state(sc, cmd);
@@ -1224,14 +1263,50 @@
 		if (urb->status == -EOVERFLOW) {
 			/*
 			 * A babble? Failure, but we must transfer CSW now.
-			 * XXX This is going to end in perpetual babble. Reset.
 			 */
 			cmd->error = -EOVERFLOW;	/* A cheap trick... */
 			ub_state_stat(sc, cmd);
 			return;
 		}
-		if (urb->status != 0)
-			goto Bad_End;
+
+		if (cmd->dir == UB_DIR_WRITE) {
+			/*
+			 * Do not continue writes in case of a failure.
+			 * Doing so would cause sectors to be mixed up,
+			 * which is worse than sectors lost.
+			 *
+			 * We must try to read the CSW, or many devices
+			 * get confused.
+			 */
+			len = urb->actual_length;
+			if (urb->status != 0 ||
+			    len != cmd->sgv[cmd->current_sg].length) {
+				cmd->act_len += len;
+				ub_cmdtr_act_len(sc, cmd);
+
+				cmd->error = -EIO;
+				ub_state_stat(sc, cmd);
+				return;
+			}
+
+		} else {
+			/*
+			 * If an error occurs on read, we record it, and
+			 * continue to fetch data in order to avoid bubble.
+			 *
+			 * As a small shortcut, we stop if we detect that
+			 * a CSW mixed into data.
+			 */
+			if (urb->status != 0)
+				cmd->error = -EIO;
+
+			len = urb->actual_length;
+			if (urb->status != 0 ||
+			    len != cmd->sgv[cmd->current_sg].length) {
+				if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN)
+					goto Bad_End;
+			}
+		}
 
 		cmd->act_len += urb->actual_length;
 		ub_cmdtr_act_len(sc, cmd);
@@ -1249,11 +1324,8 @@
 				printk(KERN_NOTICE "%s: "
 				    "unable to submit clear (%d)\n",
 				    sc->name, rc);
-				/*
-				 * This is typically ENOMEM or some other such shit.
-				 * Retrying is pointless. Just do Bad End on it...
-				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 
 			/*
@@ -1266,14 +1338,8 @@
 			ub_cmdtr_state(sc, cmd);
 			return;
 		}
-		if (urb->status == -EOVERFLOW) {
-			/*
-			 * XXX We are screwed here. Retrying is pointless,
-			 * because the pipelined data will not get in until
-			 * we read with a big enough buffer. We must reset XXX.
-			 */
-			goto Bad_End;
-		}
+
+		/* Catch everything, including -EOVERFLOW and other nasties. */
 		if (urb->status != 0)
 			goto Bad_End;
 
@@ -1319,15 +1385,15 @@
 			return;
 		}
 
-		rc = le32_to_cpu(bcs->Residue);
-		if (rc != cmd->len - cmd->act_len) {
+		len = le32_to_cpu(bcs->Residue);
+		if (len != cmd->len - cmd->act_len) {
 			/*
 			 * It is all right to transfer less, the caller has
 			 * to check. But it's not all right if the device
 			 * counts disagree with our counts.
 			 */
 			/* P3 */ printk("%s: resid %d len %d act %d\n",
-			    sc->name, rc, cmd->len, cmd->act_len);
+			    sc->name, len, cmd->len, cmd->act_len);
 			goto Bad_End;
 		}
 
@@ -1338,13 +1404,13 @@
 			ub_state_sense(sc, cmd);
 			return;
 		case US_BULK_STAT_PHASE:
-			/* XXX We must reset the transport here */
 			/* P3 */ printk("%s: status PHASE\n", sc->name);
 			goto Bad_End;
 		default:
 			printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
 			    sc->name, bcs->Status);
-			goto Bad_End;
+			ub_state_done(sc, cmd, -EINVAL);
+			return;
 		}
 
 		/* Not zeroing error to preserve a babble indicator */
@@ -1364,7 +1430,8 @@
 		printk(KERN_WARNING "%s: "
 		    "wrong command state %d\n",
 		    sc->name, cmd->state);
-		goto Bad_End;
+		ub_state_done(sc, cmd, -EINVAL);
+		return;
 	}
 	return;
 
@@ -1612,6 +1679,93 @@
 }
 
 /*
+ * Reset management
+ */
+
+static void ub_reset_enter(struct ub_dev *sc)
+{
+
+	if (sc->reset) {
+		/* This happens often on multi-LUN devices. */
+		return;
+	}
+	sc->reset = 1;
+
+#if 0 /* Not needed because the disconnect waits for us. */
+	unsigned long flags;
+	spin_lock_irqsave(&ub_lock, flags);
+	sc->openc++;
+	spin_unlock_irqrestore(&ub_lock, flags);
+#endif
+
+#if 0 /* We let them stop themselves. */
+	struct list_head *p;
+	struct ub_lun *lun;
+	list_for_each(p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		blk_stop_queue(lun->disk->queue);
+	}
+#endif
+
+	schedule_work(&sc->reset_work);
+}
+
+static void ub_reset_task(void *arg)
+{
+	struct ub_dev *sc = arg;
+	unsigned long flags;
+	struct list_head *p;
+	struct ub_lun *lun;
+	int lkr, rc;
+
+	if (!sc->reset) {
+		printk(KERN_WARNING "%s: Running reset unrequested\n",
+		    sc->name);
+		return;
+	}
+
+	if (atomic_read(&sc->poison)) {
+		printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
+		    sc->name); /* P3 This floods. Remove soon. XXX */
+	} else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
+		printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
+		    sc->name); /* P3 This floods. Remove soon. XXX */
+	} else {
+		if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
+			printk(KERN_NOTICE
+			    "%s: usb_lock_device_for_reset failed (%d)\n",
+			    sc->name, lkr);
+		} else {
+			rc = usb_reset_device(sc->dev);
+			if (rc < 0) {
+				printk(KERN_NOTICE "%s: "
+				    "usb_lock_device_for_reset failed (%d)\n",
+				    sc->name, rc);
+			}
+
+			if (lkr)
+				usb_unlock_device(sc->dev);
+		}
+	}
+
+	/*
+	 * In theory, no commands can be running while reset is active,
+	 * so nobody can ask for another reset, and so we do not need any
+	 * queues of resets or anything. We do need a spinlock though,
+	 * to interact with block layer.
+	 */
+	spin_lock_irqsave(&sc->lock, flags);
+	sc->reset = 0;
+	tasklet_schedule(&sc->tasklet);
+	list_for_each(p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		blk_start_queue(lun->disk->queue);
+	}
+	wake_up(&sc->reset_wait);
+	spin_unlock_irqrestore(&sc->lock, flags);
+}
+
+/*
  * This is called from a process context.
  */
 static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
@@ -2146,7 +2300,7 @@
 	if (ep_in == NULL || ep_out == NULL) {
 		printk(KERN_NOTICE "%s: failed endpoint check\n",
 		    sc->name);
-		return -EIO;
+		return -ENODEV;
 	}
 
 	/* Calculate and store the pipe values */
@@ -2172,6 +2326,9 @@
 	int rc;
 	int i;
 
+	if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
+		return -ENXIO;
+
 	rc = -ENOMEM;
 	if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
 		goto err_core;
@@ -2181,6 +2338,8 @@
 	usb_init_urb(&sc->work_urb);
 	tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
 	atomic_set(&sc->poison, 0);
+	INIT_WORK(&sc->reset_work, ub_reset_task, sc);
+	init_waitqueue_head(&sc->reset_wait);
 
 	init_timer(&sc->work_timer);
 	sc->work_timer.data = (unsigned long) sc;
@@ -2201,7 +2360,8 @@
 
 	/* XXX Verify that we can handle the device (from descriptors) */
 
-	ub_get_pipes(sc, sc->dev, intf);
+	if (ub_get_pipes(sc, sc->dev, intf) != 0)
+		goto err_dev_desc;
 
 	if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
 		goto err_diag;
@@ -2272,6 +2432,7 @@
 
 	/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
 err_diag:
+err_dev_desc:
 	usb_set_intfdata(intf, NULL);
 	// usb_put_intf(sc->intf);
 	usb_put_dev(sc->dev);
@@ -2309,14 +2470,14 @@
 	ub_revalidate(sc, lun);
 
 	rc = -ENOMEM;
-	if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
+	if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
 		goto err_diskalloc;
 
 	lun->disk = disk;
 	sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
 	sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
 	disk->major = UB_MAJOR;
-	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
+	disk->first_minor = lun->id * UB_PARTS_PER_LUN;
 	disk->fops = &ub_bd_fops;
 	disk->private_data = lun;
 	disk->driverfs_dev = &sc->intf->dev;
@@ -2380,6 +2541,11 @@
 	atomic_set(&sc->poison, 1);
 
 	/*
+	 * Wait for reset to end, if any.
+	 */
+	wait_event(sc->reset_wait, !sc->reset);
+
+	/*
 	 * Blow away queued commands.
 	 *
 	 * Actually, this never works, because before we get here
@@ -2392,7 +2558,7 @@
 	{
 		struct ub_scsi_cmd *cmd;
 		int cnt = 0;
-		while ((cmd = ub_cmdq_pop(sc)) != NULL) {
+		while ((cmd = ub_cmdq_peek(sc)) != NULL) {
 			cmd->error = -ENOTCONN;
 			cmd->state = UB_CMDST_DONE;
 			ub_cmdtr_state(sc, cmd);
@@ -2461,7 +2627,6 @@
 }
 
 static struct usb_driver ub_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ub",
 	.probe =	ub_probe,
 	.disconnect =	ub_disconnect,
@@ -2479,6 +2644,7 @@
 	if ((rc = usb_register(&ub_driver)) != 0)
 		goto err_register;
 
+	usb_usual_set_present(USB_US_TYPE_UB);
 	return 0;
 
 err_register:
@@ -2494,6 +2660,7 @@
 
 	devfs_remove(DEVFS_NAME);
 	unregister_blkdev(UB_MAJOR, DRV_NAME);
+	usb_usual_clear_present(USB_US_TYPE_UB);
 }
 
 module_init(ub_init);
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 8e7fb35..3e7a067 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -275,7 +275,6 @@
 }
 
 static struct usb_driver bcm203x_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bcm203x",
 	.probe		= bcm203x_probe,
 	.disconnect	= bcm203x_disconnect,
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 067e278..8947c88 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -768,7 +768,6 @@
 }
 
 static struct usb_driver bfusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bfusb",
 	.probe		= bfusb_probe,
 	.disconnect	= bfusb_disconnect,
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 3947963..9446960 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -619,7 +619,6 @@
 }
 
 static struct usb_driver bpa10x_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bpa10x",
 	.probe		= bpa10x_probe,
 	.disconnect	= bpa10x_disconnect,
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 057cb2b..92382e8 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -1044,7 +1044,6 @@
 }
 
 static struct usb_driver hci_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "hci_usb",
 	.probe		= hci_usb_probe,
 	.disconnect	= hci_usb_disconnect,
diff --git a/drivers/char/ip2/i2pack.h b/drivers/char/ip2/i2pack.h
index e9b87a7..00342a6 100644
--- a/drivers/char/ip2/i2pack.h
+++ b/drivers/char/ip2/i2pack.h
@@ -358,7 +358,7 @@
 #define MB_OUT_STRIPPED    0x40  // Board has read all output from fifo 
 #define MB_FATAL_ERROR     0x20  // Board has encountered a fatal error
 
-#pragma pack(4)                  // Reset padding to command-line default
+#pragma pack()                  // Reset padding to command-line default
 
 #endif      // I2PACK_H
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7999da2..bdfdfd2 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1554,10 +1554,8 @@
 
 EXPORT_SYMBOL(secure_tcp_sequence_number);
 
-
-
-/* Generate secure starting point for ephemeral TCP port search */
-u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+/* Generate secure starting point for ephemeral IPV4 transport port search */
+u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
 {
 	struct keydata *keyptr = get_keyptr();
 	u32 hash[4];
@@ -1575,7 +1573,7 @@
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
+u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
 {
 	struct keydata *keyptr = get_keyptr();
 	u32 hash[12];
@@ -1586,7 +1584,7 @@
 
 	return twothirdsMD4Transform(daddr, hash);
 }
-EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
+EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
 #endif
 
 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 092e9b1..1533f56 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -151,7 +151,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver usb_pcwd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		DRIVER_NAME,
 	.probe =	usb_pcwd_probe,
 	.disconnect =	usb_pcwd_disconnect,
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 815902c..a9163d0 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -823,6 +823,30 @@
 
 
 /** 
+ * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
+ * @cpu: CPU number
+ *
+ * This is the last known freq, without actually getting it from the driver.
+ * Return value will be same as what is shown in scaling_cur_freq in sysfs.
+ */
+unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	unsigned int ret = 0;
+
+	if (policy) {
+		down(&policy->lock);
+		ret = policy->cur;
+		up(&policy->lock);
+		cpufreq_cpu_put(policy);
+	}
+
+	return (ret);
+}
+EXPORT_SYMBOL(cpufreq_quick_get);
+
+
+/** 
  * cpufreq_get - get the current CPU frequency (in kHz)
  * @cpu: CPU number
  *
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 2ed5c43..39543a2 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -93,7 +93,7 @@
 {
 	return	kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait +
-		( !dbs_tuners_ins.ignore_nice ? 
+		( dbs_tuners_ins.ignore_nice ?
 		  kstat_cpu(cpu).cpustat.nice :
 		  0);
 }
@@ -127,7 +127,7 @@
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
 show_one(down_threshold, down_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
@@ -207,7 +207,7 @@
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 		const char *buf, size_t count)
 {
 	unsigned int input;
@@ -272,7 +272,7 @@
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
 define_one_rw(down_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 define_one_rw(freq_step);
 
 static struct attribute * dbs_attributes[] = {
@@ -282,7 +282,7 @@
 	&sampling_down_factor.attr,
 	&up_threshold.attr,
 	&down_threshold.attr,
-	&ignore_nice.attr,
+	&ignore_nice_load.attr,
 	&freq_step.attr,
 	NULL
 };
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 1774111..e69fd8d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -89,7 +89,7 @@
 {
 	return	kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait +
-		( !dbs_tuners_ins.ignore_nice ? 
+		( dbs_tuners_ins.ignore_nice ?
 		  kstat_cpu(cpu).cpustat.nice :
 		  0);
 }
@@ -122,7 +122,7 @@
 show_one(sampling_rate, sampling_rate);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
 		const char *buf, size_t count)
@@ -182,7 +182,7 @@
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 		const char *buf, size_t count)
 {
 	unsigned int input;
@@ -223,7 +223,7 @@
 define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 
 static struct attribute * dbs_attributes[] = {
 	&sampling_rate_max.attr,
@@ -231,7 +231,7 @@
 	&sampling_rate.attr,
 	&sampling_down_factor.attr,
 	&up_threshold.attr,
-	&ignore_nice.attr,
+	&ignore_nice_load.attr,
 	NULL
 };
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 475d98f..780009c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -47,6 +47,8 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 
+#include <net/dst.h>
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index ef3ee03..ed0c2ea 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -43,6 +43,8 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 
+#include <net/dst.h>
+
 #include "ipoib.h"
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 64b4a30..bc2fce6 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -235,7 +235,6 @@
 MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
 
 struct usb_driver iforce_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"iforce",
 	.probe =	iforce_usb_probe,
 	.disconnect =	iforce_usb_disconnect,
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index f8457ef..ca5b4a3 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1715,7 +1715,6 @@
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-	.owner = THIS_MODULE,
 	.name  = "hfc_usb",
 	.id_table = hfcusb_idtab,
 	.probe = hfc_usb_probe,
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 8e192a3..99cb0f3 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -180,7 +180,6 @@
 MODULE_DEVICE_TABLE (usb, st5481_ids);
 
 static struct usb_driver st5481_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"st5481_usb",
 	.probe =	probe_st5481,
 	.disconnect =	disconnect_st5481,
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index a6d3baa..a6f2dc6 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -638,7 +638,7 @@
 static void check_for_valid_limits(struct io_restrictions *rs)
 {
 	if (!rs->max_sectors)
-		rs->max_sectors = MAX_SECTORS;
+		rs->max_sectors = SAFE_MAX_SECTORS;
 	if (!rs->max_phys_segments)
 		rs->max_phys_segments = MAX_PHYS_SEGMENTS;
 	if (!rs->max_hw_segments)
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 0a78ba3..a6c91db 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -544,7 +544,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver flexcop_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "b2c2_flexcop_usb",
 	.probe		= flexcop_usb_probe,
 	.disconnect = flexcop_usb_disconnect,
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 336fc28..b996fb5 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -986,7 +986,6 @@
 MODULE_DEVICE_TABLE(usb, cinergyt2_table);
 
 static struct usb_driver cinergyt2_driver = {
-	.owner	= THIS_MODULE,
 	.name	= "cinergyT2",
 	.probe	= cinergyt2_probe,
 	.disconnect	= cinergyt2_disconnect,
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index 8c7beff..ce44aa6 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -144,7 +144,6 @@
 };
 
 static struct usb_driver a800_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_a800",
 	.probe		= a800_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 3fe383f..d05fab01 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -241,7 +241,6 @@
 };
 
 static struct usb_driver cxusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index aa271a2..52ac3e5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -373,7 +373,6 @@
 };
 
 static struct usb_driver dibusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dibusb_mb",
 	.probe		= dibusb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 6a0912e..55802fb 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -82,7 +82,6 @@
 };
 
 static struct usb_driver dibusb_mc_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dibusb_mc",
 	.probe		= dibusb_mc_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index f98e306..450417a 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -233,7 +233,6 @@
 };
 
 static struct usb_driver digitv_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_digitv",
 	.probe		= digitv_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index b595476..6e2bac8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -198,7 +198,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver dtt200u_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dtt200u",
 	.probe		= dtt200u_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 1841a66..fac48fc 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -202,7 +202,6 @@
 };
 
 static struct usb_driver nova_t_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_nova_t_usb2",
 	.probe		= nova_t_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 6fd6765..14f1911 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -128,7 +128,6 @@
 };
 
 static struct usb_driver umt_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_umt_010",
 	.probe		= umt_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index de13c04..afa00fd 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -256,7 +256,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb-usb-vp702x",
 	.probe 		= vp702x_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 75765e3..3835235 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -253,7 +253,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp7045_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_vp7045",
 	.probe		= vp7045_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
index 9774e94..1439cb7 100644
--- a/drivers/media/video/cpia_usb.c
+++ b/drivers/media/video/cpia_usb.c
@@ -582,7 +582,6 @@
 
 
 static struct usb_driver cpia_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "cpia",
 	.probe		= cpia_probe,
 	.disconnect	= cpia_disconnect,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 06d7687..3a56120 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1884,7 +1884,6 @@
 }
 
 static struct usb_driver em28xx_usb_driver = {
-	.owner = THIS_MODULE,
 	.name = "em28xx",
 	.probe = em28xx_usb_probe,
 	.disconnect = em28xx_usb_disconnect,
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 4262a22..5378360 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -313,13 +313,13 @@
 		u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
 		if (ioc->bus_type == FC)
 			mpt_fc_log_info(ioc, log_info);
-		else if (ioc->bus_type == SCSI)
+		else if (ioc->bus_type == SPI)
 			mpt_sp_log_info(ioc, log_info);
 		else if (ioc->bus_type == SAS)
 			mpt_sas_log_info(ioc, log_info);
 	}
 	if (ioc_stat & MPI_IOCSTATUS_MASK) {
-		if (ioc->bus_type == SCSI &&
+		if (ioc->bus_type == SPI &&
 		    cb_idx != mpt_stm_index &&
 		    cb_idx != mpt_lan_index)
 			mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
@@ -1376,7 +1376,7 @@
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
 		ioc->prod_name = "LSI53C1030";
-		ioc->bus_type = SCSI;
+		ioc->bus_type = SPI;
 		/* 1030 Chip Fix. Disable Split transactions
 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
 		 */
@@ -1389,7 +1389,7 @@
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
 		ioc->prod_name = "LSI53C1035";
-		ioc->bus_type = SCSI;
+		ioc->bus_type = SPI;
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
 		ioc->prod_name = "LSISAS1064";
@@ -3042,7 +3042,7 @@
 	/* Clear the internal flash bad bit - autoincrementing register,
 	 * so must do two writes.
 	 */
-	if (ioc->bus_type == SCSI) {
+	if (ioc->bus_type == SPI) {
 		/*
 		 * 1030 and 1035 H/W errata, workaround to access
 		 * the ClearFlashBadSignatureBit
@@ -3152,7 +3152,7 @@
 	int cnt,cntdn;
 
 	dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
-	if (ioc->bus_type == SCSI) {
+	if (ioc->bus_type == SPI) {
 		/* Always issue a Msg Unit Reset first. This will clear some
 		 * SCSI bus hang conditions.
 		 */
@@ -3580,7 +3580,7 @@
 	dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
 		ioc->name, numSGE, num_sge, num_chain));
 
-	if (ioc->bus_type == SCSI)
+	if (ioc->bus_type == SPI)
 		num_chain *= MPT_SCSI_CAN_QUEUE;
 	else
 		num_chain *= MPT_FC_CAN_QUEUE;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index bac8eb4..6c48d1f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.03.04"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.04"
+#define MPT_LINUX_VERSION_COMMON	"3.03.05"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.05"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -321,7 +321,7 @@
  *	Dynamic Multi-Pathing specific stuff...
  */
 
-/* VirtDevice negoFlags field */
+/* VirtTarget negoFlags field */
 #define MPT_TARGET_NO_NEGO_WIDE		0x01
 #define MPT_TARGET_NO_NEGO_SYNC		0x02
 #define MPT_TARGET_NO_NEGO_QAS		0x04
@@ -330,8 +330,7 @@
 /*
  *	VirtDevice - FC LUN device or SCSI target device
  */
-typedef struct _VirtDevice {
-	struct scsi_device	*device;
+typedef struct _VirtTarget {
 	u8			 tflags;
 	u8			 ioc_id;
 	u8			 target_id;
@@ -342,21 +341,18 @@
 	u8			 negoFlags;	/* bit field, see above */
 	u8			 raidVolume;	/* set, if RAID Volume */
 	u8			 type;		/* byte 0 of Inquiry data */
-	u8			 cflags;	/* controller flags */
-	u8			 rsvd1raid;
-	u16			 fc_phys_lun;
-	u16			 fc_xlat_lun;
 	u32			 num_luns;
 	u32			 luns[8];		/* Max LUNs is 256 */
-	u8			 pad[4];
 	u8			 inq_data[8];
-		/* IEEE Registered Extended Identifier
-		   obtained via INQUIRY VPD page 0x83 */
-		/* NOTE: Do not separate uniq_prepad and uniq_data
-		   as they are treateed as a single entity in the code */
-	u8			 uniq_prepad[8];
-	u8			 uniq_data[20];
-	u8			 pad2[4];
+} VirtTarget;
+
+typedef struct _VirtDevice {
+	VirtTarget	 	*vtarget;
+	u8			 ioc_id;
+	u8			 bus_id;
+	u8			 target_id;
+	u8			 configured_lun;
+	u32			 lun;
 } VirtDevice;
 
 /*
@@ -903,7 +899,7 @@
 
 typedef enum {
 	FC,
-	SCSI,
+	SPI,
 	SAS
 } BUS_TYPE;
 
@@ -912,7 +908,7 @@
 	int			  port;
 	u32			  pad0;
 	struct scsi_cmnd	**ScsiLookup;
-	VirtDevice		**Targets;
+	VirtTarget		**Targets;
 	MPT_LOCAL_REPLY		 *pLocal;		/* used for internal commands */
 	struct timer_list	  timer;
 		/* Pool of memory for holding SCpnts before doing
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 602138f..959d2c5 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1245,7 +1245,7 @@
 	MPT_ADAPTER		*ioc;
 	struct Scsi_Host	*sh;
 	MPT_SCSI_HOST		*hd;
-	VirtDevice		*vdev;
+	VirtTarget		*vdev;
 	char			*pmem;
 	int			*pdata;
 	IOCPage2_t		*pIoc2;
@@ -1822,7 +1822,7 @@
 	case MPI_FUNCTION_SCSI_IO_REQUEST:
 		if (ioc->sh) {
 			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
-			VirtDevice	*pTarget = NULL;
+			VirtTarget	*pTarget = NULL;
 			MPT_SCSI_HOST	*hd = NULL;
 			int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
 			int scsidir = 0;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index a628be9..ba61e18 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -84,13 +84,16 @@
 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptfc_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptfc",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT FC Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptscsih_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -167,13 +170,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptfc_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptfc_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -198,7 +203,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptfc_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -266,7 +272,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -284,14 +290,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -330,13 +336,13 @@
 	if(error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	scsi_scan_host(sh);
 	return 0;
 
-mptfc_probe_failed:
+out_mptfc_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index e0a8bb8..17e9757e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -228,31 +228,35 @@
  * implement ->target_alloc.
  */
 static int
-mptsas_slave_alloc(struct scsi_device *device)
+mptsas_slave_alloc(struct scsi_device *sdev)
 {
-	struct Scsi_Host	*host = device->host;
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
 	struct sas_rphy		*rphy;
 	struct mptsas_portinfo	*p;
+	VirtTarget		*vtarget;
 	VirtDevice		*vdev;
-	uint			target = device->id;
+	struct scsi_target 	*starget;
 	int i;
 
-	if ((vdev = hd->Targets[target]) != NULL)
-		goto out;
-
 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
 	if (!vdev) {
 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
 				hd->ioc->name, sizeof(VirtDevice));
 		return -ENOMEM;
 	}
-
 	memset(vdev, 0, sizeof(VirtDevice));
-	vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
 	vdev->ioc_id = hd->ioc->id;
+	sdev->hostdata = vdev;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdev->vtarget = vtarget;
+	if (vtarget->num_luns == 0) {
+		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+		hd->Targets[sdev->id] = vtarget;
+	}
 
-	rphy = dev_to_rphy(device->sdev_target->dev.parent);
+	rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
 	list_for_each_entry(p, &hd->ioc->sas_topology, list) {
 		for (i = 0; i < p->num_phys; i++) {
 			if (p->phy_info[i].attached.sas_address ==
@@ -260,7 +264,7 @@
 				vdev->target_id =
 					p->phy_info[i].attached.target;
 				vdev->bus_id = p->phy_info[i].attached.bus;
-				hd->Targets[device->id] = vdev;
+				vdev->lun = sdev->lun;
 				goto out;
 			}
 		}
@@ -271,19 +275,24 @@
 	return -ENODEV;
 
  out:
-	vdev->num_luns++;
-	device->hostdata = vdev;
+	vtarget->ioc_id = vdev->ioc_id;
+	vtarget->target_id = vdev->target_id;
+	vtarget->bus_id = vdev->bus_id;
+	vtarget->num_luns++;
 	return 0;
 }
 
 static struct scsi_host_template mptsas_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptsas",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT SPI Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptsas_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -986,7 +995,6 @@
 		goto out_free_port_info;
 
 	list_add_tail(&port_info->list, &ioc->sas_topology);
-
 	for (i = 0; i < port_info->num_phys; i++) {
 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1133,13 +1141,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptsas_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptsas_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -1163,7 +1173,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptsas_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -1237,7 +1248,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -1255,14 +1266,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vtarget @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -1308,14 +1319,14 @@
 	if (error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	mptsas_scan_sas_topology(ioc);
 
 	return 0;
 
-mptsas_probe_failed:
+out_mptsas_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index b7b9846..93a16fa 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -150,28 +150,29 @@
 int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
-static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
-static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
-static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
+static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
+static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
 static void	mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
-static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
+static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
-static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
+static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
+static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 
 static struct work_struct   mptscsih_persistTask;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
 static void	mptscsih_domainValidation(void *hd);
-static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 static void	mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
 static int	mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
 static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
 static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
 static void	mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
+static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 #endif
 
 void 		mptscsih_remove(struct pci_dev *);
@@ -627,7 +628,7 @@
 		dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
 			"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
 			"resid=%d bufflen=%d xfer_cnt=%d\n",
-			ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+			ioc->id, sc->device->id, sc->device->lun,
 			status, scsi_state, scsi_status, sc->resid,
 			sc->request_bufflen, xfer_cnt));
 
@@ -641,7 +642,7 @@
 		    pScsiReply->ResponseInfo) {
 			printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
 			"FCP_ResponseInfo=%08xh\n",
-			ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+			ioc->id, sc->device->id, sc->device->lun,
 			le32_to_cpu(pScsiReply->ResponseInfo));
 		}
 
@@ -677,8 +678,8 @@
 			sc->result = DID_RESET << 16;
 
 			/* GEM Workaround. */
-			if (ioc->bus_type == SCSI)
-				mptscsih_no_negotiate(hd, sc->device->id);
+			if (ioc->bus_type == SPI)
+				mptscsih_no_negotiate(hd, sc);
 			break;
 
 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
@@ -892,16 +893,15 @@
  *		when a lun is disable by mid-layer.
  *		Do NOT access the referenced scsi_cmnd structure or
  *		members. Will cause either a paging or NULL ptr error.
- *	@hd: Pointer to a SCSI HOST structure
- *	@target: target id
- *	@lun: lun
+ *      @hd: Pointer to a SCSI HOST structure
+ *	@vdevice: per device private data
  *
  *	Returns: None.
  *
  *	Called from slave_destroy.
  */
 static void
-mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
+mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
 	SCSIIORequest_t	*mf = NULL;
 	int		 ii;
@@ -909,7 +909,7 @@
 	struct scsi_cmnd *sc;
 
 	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
-			target, lun, max));
+			vdevice->target_id, vdevice->lun, max));
 
 	for (ii=0; ii < max; ii++) {
 		if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -919,7 +919,7 @@
 			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
 					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
 
-			if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
+			if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
 				continue;
 
 			/* Cleanup
@@ -993,8 +993,10 @@
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct Scsi_Host 	*host = ioc->sh;
 	MPT_SCSI_HOST		*hd;
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 	int 		 	count;
 	unsigned long	 	flags;
+#endif	
 	int sz1;
 
 	if(!host) {
@@ -1075,11 +1077,6 @@
 
 	hd = (MPT_SCSI_HOST *)host->hostdata;
 
-	/* Flush the cache of this adapter
-	 */
-	if(hd != NULL)
-		mptscsih_synchronize_cache(hd, 0);
-
 }
 
 #ifdef CONFIG_PM
@@ -1286,7 +1283,7 @@
 	MPT_SCSI_HOST		*hd;
 	MPT_FRAME_HDR		*mf;
 	SCSIIORequest_t		*pScsiReq;
-	VirtDevice		*pTarget = SCpnt->device->hostdata;
+	VirtDevice		*vdev = SCpnt->device->hostdata;
 	int	 lun;
 	u32	 datalen;
 	u32	 scsictl;
@@ -1341,8 +1338,8 @@
 	/* Default to untagged. Once a target structure has been allocated,
 	 * use the Inquiry data to determine if device supports tagged.
 	 */
-	if (pTarget
-	    && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+	if (vdev
+	    && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
 	    && (SCpnt->device->tagged_supported)) {
 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
 	} else {
@@ -1351,8 +1348,8 @@
 
 	/* Use the above information to set up the message frame
 	 */
-	pScsiReq->TargetID = (u8) pTarget->target_id;
-	pScsiReq->Bus = pTarget->bus_id;
+	pScsiReq->TargetID = (u8) vdev->target_id;
+	pScsiReq->Bus = vdev->bus_id;
 	pScsiReq->ChainOffset = 0;
 	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
 	pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1403,8 +1400,8 @@
 	SCpnt->host_scribble = NULL;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-	if (hd->ioc->bus_type == SCSI) {
-		int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
+	if (hd->ioc->bus_type == SPI) {
+		int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
 		int issueCmd = 1;
 
 		if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1437,7 +1434,7 @@
 			/* Set the DV flags.
 			 */
 			if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
-				mptscsih_set_dvflags(hd, pScsiReq);
+				mptscsih_set_dvflags(hd, SCpnt);
 
 			if (!issueCmd)
 				goto fail;
@@ -1741,6 +1738,7 @@
 	u32		 ctx2abort;
 	int		 scpnt_idx;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1790,8 +1788,9 @@
 
 	hd->abortSCpnt = SCpnt;
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-		SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
+		vdev->bus_id, vdev->target_id, vdev->lun,
 		ctx2abort, 2 /* 2 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
@@ -1822,6 +1821,7 @@
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1839,8 +1839,9 @@
 	       hd->ioc->name, SCpnt);
 	scsi_print_command(SCpnt);
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-		SCpnt->device->channel, SCpnt->device->id,
+		vdev->bus_id, vdev->target_id,
 		0, 0, 5 /* 5 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1871,6 +1872,7 @@
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1888,8 +1890,9 @@
 	if (hd->timeouts < -1)
 		hd->timeouts++;
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-		SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
+		vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -2151,23 +2154,36 @@
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	OS entry point to allow host driver to alloc memory
- *	for each scsi device. Called once per device the bus scan.
+ *	for each scsi target. Called once per device the bus scan.
  *	Return non-zero if allocation fails.
- *	Init memory once per id (not LUN).
  */
 int
-mptscsih_slave_alloc(struct scsi_device *device)
+mptscsih_target_alloc(struct scsi_target *starget)
 {
-	struct Scsi_Host	*host = device->host;
+	VirtTarget		*vtarget;
+
+	vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
+	if (!vtarget)
+		return -ENOMEM;
+	memset(vtarget, 0, sizeof(VirtTarget));
+	starget->hostdata = vtarget;
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	OS entry point to allow host driver to alloc memory
+ *	for each scsi device. Called once per device the bus scan.
+ *	Return non-zero if allocation fails.
+ */
+int
+mptscsih_slave_alloc(struct scsi_device *sdev)
+{
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
+	VirtTarget		*vtarget;
 	VirtDevice		*vdev;
-	uint			target = device->id;
-
-	if (hd == NULL)
-		return -ENODEV;
-
-	if ((vdev = hd->Targets[target]) != NULL)
-		goto out;
+	struct scsi_target 	*starget;
 
 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
 	if (!vdev) {
@@ -2177,25 +2193,33 @@
 	}
 
 	memset(vdev, 0, sizeof(VirtDevice));
-	vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
 	vdev->ioc_id = hd->ioc->id;
-	vdev->target_id = device->id;
-	vdev->bus_id = device->channel;
-	vdev->raidVolume = 0;
-	hd->Targets[device->id] = vdev;
-	if (hd->ioc->bus_type == SCSI) {
-		if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
-			vdev->raidVolume = 1;
-			ddvtprintk((KERN_INFO
-			    "RAID Volume @ id %d\n", device->id));
-		}
-	} else {
-		vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-	}
+	vdev->target_id = sdev->id;
+	vdev->bus_id = sdev->channel;
+	vdev->lun = sdev->lun;
+	sdev->hostdata = vdev;
 
- out:
-	vdev->num_luns++;
-	device->hostdata = vdev;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdev->vtarget = vtarget;
+
+	if (vtarget->num_luns == 0) {
+		hd->Targets[sdev->id] = vtarget;
+		vtarget->ioc_id = hd->ioc->id;
+		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+		vtarget->target_id = sdev->id;
+		vtarget->bus_id = sdev->channel;
+		if (hd->ioc->bus_type == SPI) {
+			if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
+				vtarget->raidVolume = 1;
+				ddvtprintk((KERN_INFO
+				    "RAID Volume @ id %d\n", sdev->id));
+			}
+		} else {
+			vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+		}
+	}
+	vtarget->num_luns++;
 	return 0;
 }
 
@@ -2204,40 +2228,52 @@
  *	Called if no device present or device being unloaded
  */
 void
-mptscsih_slave_destroy(struct scsi_device *device)
+mptscsih_target_destroy(struct scsi_target *starget)
 {
-	struct Scsi_Host	*host = device->host;
+	if (starget->hostdata)
+		kfree(starget->hostdata);
+	starget->hostdata = NULL;
+}
+
+/*
+ *	OS entry point to allow for host driver to free allocated memory
+ *	Called if no device present or device being unloaded
+ */
+void
+mptscsih_slave_destroy(struct scsi_device *sdev)
+{
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
-	VirtDevice		*vdev;
-	uint			target = device->id;
-	uint			lun = device->lun;
+	VirtTarget		*vtarget;
+	VirtDevice		*vdevice;
+	struct scsi_target 	*starget;
 
-	if (hd == NULL)
-		return;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdevice = sdev->hostdata;
 
-	mptscsih_search_running_cmds(hd, target, lun);
-
-	vdev = hd->Targets[target];
-	vdev->luns[0] &= ~(1 << lun);
-	if (--vdev->num_luns)
-		return;
-
-	kfree(hd->Targets[target]);
-	hd->Targets[target] = NULL;
-
-	if (hd->ioc->bus_type == SCSI) {
-		if (mptscsih_is_phys_disk(hd->ioc, target)) {
-			hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
-		} else {
-			hd->ioc->spi_data.dvStatus[target] =
-				MPT_SCSICFG_NEGOTIATE;
-
-			if (!hd->negoNvram) {
-				hd->ioc->spi_data.dvStatus[target] |=
-					MPT_SCSICFG_DV_NOT_DONE;
+	mptscsih_search_running_cmds(hd, vdevice);
+	vtarget->luns[0] &= ~(1 << vdevice->lun);
+	vtarget->num_luns--;
+	if (vtarget->num_luns == 0) {
+		mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
+		if (hd->ioc->bus_type == SPI) {
+			if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
+				hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
+			} else {
+				hd->ioc->spi_data.dvStatus[vtarget->target_id] =
+					MPT_SCSICFG_NEGOTIATE;
+				if (!hd->negoNvram) {
+					hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
+						MPT_SCSICFG_DV_NOT_DONE;
+				}
 			}
 		}
+		hd->Targets[sdev->id] = NULL;
 	}
+	mptscsih_synchronize_cache(hd, vdevice);
+	kfree(vdevice);
+	sdev->hostdata = NULL;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2251,22 +2287,21 @@
 int
 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
-	VirtDevice *pTarget;
-	int	max_depth;
-	int	tagged;
+	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+	VirtTarget 		*vtarget;
+	struct scsi_target 	*starget;
+	int			max_depth;
+	int			tagged;
 
-	if (hd == NULL)
-		return 0;
-	if (!(pTarget = hd->Targets[sdev->id]))
-		return 0;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
 
-	if (hd->ioc->bus_type == SCSI) {
-		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
-			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+	if (hd->ioc->bus_type == SPI) {
+		if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+			if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
 				max_depth = 1;
-			else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
-			         (pTarget->minSyncFactor <= MPT_ULTRA160 ))
+			else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
+			         (vtarget->minSyncFactor <= MPT_ULTRA160 ))
 				max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
 			else
 				max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
@@ -2295,64 +2330,58 @@
  *	Return non-zero if fails.
  */
 int
-mptscsih_slave_configure(struct scsi_device *device)
+mptscsih_slave_configure(struct scsi_device *sdev)
 {
-	struct Scsi_Host	*sh = device->host;
-	VirtDevice		*pTarget;
+	struct Scsi_Host	*sh = sdev->host;
+	VirtTarget		*vtarget;
+	VirtDevice		*vdevice;
+	struct scsi_target 	*starget;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sh->hostdata;
+	int			indexed_lun, lun_index;
 
-	if ((hd == NULL) || (hd->Targets == NULL)) {
-		return 0;
-	}
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdevice = sdev->hostdata;
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"device @ %p, id=%d, LUN=%d, channel=%d\n",
-		hd->ioc->name, device, device->id, device->lun, device->channel));
-	dsprintk((MYIOC_s_INFO_FMT
-		"sdtr %d wdtr %d ppr %d inq length=%d\n",
-		hd->ioc->name, device->sdtr, device->wdtr,
-		device->ppr, device->inquiry_len));
+		hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
+	if (hd->ioc->bus_type == SPI)
+		dsprintk((MYIOC_s_INFO_FMT
+		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
+		    hd->ioc->name, sdev->sdtr, sdev->wdtr,
+		    sdev->ppr, sdev->inquiry_len));
 
-	if (device->id > sh->max_id) {
+	if (sdev->id > sh->max_id) {
 		/* error case, should never happen */
-		scsi_adjust_queue_depth(device, 0, 1);
+		scsi_adjust_queue_depth(sdev, 0, 1);
 		goto slave_configure_exit;
 	}
 
-	pTarget = hd->Targets[device->id];
-
-	if (pTarget == NULL) {
-		/* Driver doesn't know about this device.
-		 * Kernel may generate a "Dummy Lun 0" which
-		 * may become a real Lun if a
-		 * "scsi add-single-device" command is executed
-		 * while the driver is active (hot-plug a
-		 * device).  LSI Raid controllers need
-		 * queue_depth set to DEV_HIGH for this reason.
-		 */
-		scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-			MPT_SCSI_CMD_PER_DEV_HIGH);
-		goto slave_configure_exit;
-	}
-
-	mptscsih_initTarget(hd, device->channel, device->id, device->lun,
-		device->inquiry, device->inquiry_len );
-	mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
+	vdevice->configured_lun=1;
+	lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
+	indexed_lun = (vdevice->lun % 32);
+	vtarget->luns[lun_index] |= (1 << indexed_lun);
+	mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
+	    sdev->inquiry_len );
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"Queue depth=%d, tflags=%x\n",
-		hd->ioc->name, device->queue_depth, pTarget->tflags));
+		hd->ioc->name, sdev->queue_depth, vtarget->tflags));
 
-	dsprintk((MYIOC_s_INFO_FMT
-		"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
-		hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
+	if (hd->ioc->bus_type == SPI)
+		dsprintk((MYIOC_s_INFO_FMT
+		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+		    hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
+		    vtarget->minSyncFactor));
 
 slave_configure_exit:
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"tagged %d, simple %d, ordered %d\n",
-		hd->ioc->name,device->tagged_supported, device->simple_tags,
-		device->ordered_tags));
+		hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
+		sdev->ordered_tags));
 
 	return 0;
 }
@@ -2370,16 +2399,14 @@
 static void
 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
-	VirtDevice	*target;
+	VirtDevice	*vdev;
 	SCSIIORequest_t	*pReq;
 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
-	int		 index;
 
 	/* Get target structure
 	 */
 	pReq = (SCSIIORequest_t *) mf;
-	index = (int) pReq->TargetID;
-	target = hd->Targets[index];
+	vdev = sc->device->hostdata;
 
 	if (sense_count) {
 		u8 *sense_data;
@@ -2393,7 +2420,7 @@
 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
 		 */
 		if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
-			if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
+			if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
 				int idx;
 				MPT_ADAPTER *ioc = hd->ioc;
 
@@ -2403,7 +2430,7 @@
 
 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-					(pReq->Bus << 8) || pReq->TargetID;
+					(sc->device->channel << 8) || sc->device->id;
 
 				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
@@ -2503,9 +2530,9 @@
 		/* 2. Chain Buffer initialization
 		 */
 
-		/* 4. Renegotiate to all devices, if SCSI
+		/* 4. Renegotiate to all devices, if SPI
 		 */
-		if (ioc->bus_type == SCSI) {
+		if (ioc->bus_type == SPI) {
 			dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
 			mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
 		}
@@ -2534,7 +2561,7 @@
 
 		/* 7. Set flag to force DV and re-read IOC Page 3
 		 */
-		if (ioc->bus_type == SCSI) {
+		if (ioc->bus_type == SPI) {
 			ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
 			ddvtprintk(("Set reload IOC Pg3 Flag\n"));
 		}
@@ -2576,7 +2603,7 @@
 		break;
 	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
 	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
-		if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+		if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
 			hd->soft_resets++;
 		break;
 	case MPI_EVENT_LOGOUT:				/* 09 */
@@ -2597,11 +2624,11 @@
 
 	case MPI_EVENT_INTEGRATED_RAID:			/* 0B */
 	{
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 		pMpiEventDataRaid_t pRaidEventData =
 		    (pMpiEventDataRaid_t) pEvReply->Data;
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 		/* Domain Validation Needed */
-		if (ioc->bus_type == SCSI &&
+		if (ioc->bus_type == SPI &&
 		    pRaidEventData->ReasonCode ==
 		    MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
 			mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
@@ -2632,8 +2659,7 @@
 /*
  *	mptscsih_initTarget - Target, LUN alloc/free functionality.
  *	@hd: Pointer to MPT_SCSI_HOST structure
- *	@bus_id: Bus number (?)
- *	@target_id: SCSI target id
+ *	@vtarget: per target private data
  *	@lun: SCSI LUN id
  *	@data: Pointer to data
  *	@dlen: Number of INQUIRY bytes
@@ -2646,15 +2672,14 @@
  *
  */
 static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
 {
-	int		indexed_lun, lun_index;
-	VirtDevice	*vdev;
 	SpiCfgData	*pSpi;
 	char		data_56;
+	int		inq_len;
 
 	dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
-			hd->ioc->name, bus_id, target_id, lun, hd));
+		hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
 
 	/*
 	 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
@@ -2674,75 +2699,68 @@
 	if (data[0] & 0xe0)
 		return;
 
-	if ((vdev = hd->Targets[target_id]) == NULL) {
+	if (vtarget == NULL)
 		return;
-	}
 
-	lun_index = (lun >> 5);  /* 32 luns per lun_index */
-	indexed_lun = (lun % 32);
-	vdev->luns[lun_index] |= (1 << indexed_lun);
+	if (data)
+		vtarget->type = data[0];
 
-	if (hd->ioc->bus_type == SCSI) {
-		if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
-			/* Treat all Processors as SAF-TE if
-			 * command line option is set */
-			vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-			mptscsih_writeIOCPage4(hd, target_id, bus_id);
-		}else if ((data[0] == TYPE_PROCESSOR) &&
-			!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
-			if ( dlen > 49 ) {
-				vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-				if ( data[44] == 'S' &&
-				     data[45] == 'A' &&
-				     data[46] == 'F' &&
-				     data[47] == '-' &&
-				     data[48] == 'T' &&
-				     data[49] == 'E' ) {
-					vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-					mptscsih_writeIOCPage4(hd, target_id, bus_id);
-				}
+	if (hd->ioc->bus_type != SPI)
+		return;
+
+	if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+		/* Treat all Processors as SAF-TE if
+		 * command line option is set */
+		vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+		mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
+	}else if ((data[0] == TYPE_PROCESSOR) &&
+		!(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+		if ( dlen > 49 ) {
+			vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+			if ( data[44] == 'S' &&
+			     data[45] == 'A' &&
+			     data[46] == 'F' &&
+			     data[47] == '-' &&
+			     data[48] == 'T' &&
+			     data[49] == 'E' ) {
+				vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+				mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
 			}
 		}
-		if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
-			if ( dlen > 8 ) {
-				memcpy (vdev->inq_data, data, 8);
-			} else {
-				memcpy (vdev->inq_data, data, dlen);
-			}
+	}
+	if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+		inq_len = dlen < 8 ? dlen : 8;
+		memcpy (vtarget->inq_data, data, inq_len);
+		/* If have not done DV, set the DV flag.
+		 */
+		pSpi = &hd->ioc->spi_data;
+		if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
+			if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
+				pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
+		}
+		vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
 
-			/* If have not done DV, set the DV flag.
+		data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
+		if (dlen > 56) {
+			if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+			/* Update the target capabilities
 			 */
-			pSpi = &hd->ioc->spi_data;
-			if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
-				if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
-					pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
+				data_56 = data[56];
+				vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
 			}
-
-			vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-
-
-			data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
-			if (dlen > 56) {
-				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-				/* Update the target capabilities
-				 */
-					data_56 = data[56];
-					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-				}
-			}
-			mptscsih_setTargetNegoParms(hd, vdev, data_56);
-		} else {
-			/* Initial Inquiry may not request enough data bytes to
-			 * obtain byte 57.  DV will; if target doesn't return
-			 * at least 57 bytes, data[56] will be zero. */
-			if (dlen > 56) {
-				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-				/* Update the target capabilities
-				 */
-					data_56 = data[56];
-					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-					mptscsih_setTargetNegoParms(hd, vdev, data_56);
-				}
+		}
+		mptscsih_setTargetNegoParms(hd, vtarget, data_56);
+	} else {
+		/* Initial Inquiry may not request enough data bytes to
+		 * obtain byte 57.  DV will; if target doesn't return
+		 * at least 57 bytes, data[56] will be zero. */
+		if (dlen > 56) {
+			if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+			/* Update the target capabilities
+			 */
+				data_56 = data[56];
+				vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
+				mptscsih_setTargetNegoParms(hd, vtarget, data_56);
 			}
 		}
 	}
@@ -2755,12 +2773,12 @@
  *
  */
 static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
+mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
 {
 	SpiCfgData *pspi_data = &hd->ioc->spi_data;
 	int  id = (int) target->target_id;
 	int  nvram;
-	VirtDevice	*vdev;
+	VirtTarget	*vtarget;
 	int ii;
 	u8 width = MPT_NARROW;
 	u8 factor = MPT_ASYNC;
@@ -2905,9 +2923,9 @@
 
 			ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
 			for (ii = 0; ii < id; ii++) {
-				if ( (vdev = hd->Targets[ii]) ) {
-					vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-					mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
+				if ( (vtarget = hd->Targets[ii]) ) {
+					vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
 				}
 			}
 		}
@@ -2926,105 +2944,17 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
- * Else set the NEED_DV flag after Read Capacity Issued (disks)
- * or Mode Sense (cdroms).
- *
- * Tapes, initTarget will set this flag on completion of Inquiry command.
- * Called only if DV_NOT_DONE flag is set
- */
-static void
-mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
-{
-	MPT_ADAPTER	*ioc = hd->ioc;
-	u8 cmd;
-	SpiCfgData	*pSpi;
-
-	ddvtprintk((MYIOC_s_NOTE_FMT
-		" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
-		hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
-
-	if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
-		return;
-
-	cmd = pReq->CDB[0];
-
-	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
-		pSpi = &ioc->spi_data;
-		if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
-			/* Set NEED_DV for all hidden disks
-			 */
-			Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-			int		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-
-			while (numPDisk) {
-				pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
-				ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
-				pPDisk++;
-				numPDisk--;
-			}
-		}
-		pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
-		ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
-	}
-}
-
-/* mptscsih_raid_set_dv_flags()
- *
- * New or replaced disk. Set DV flag and schedule DV.
- */
-static void
-mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
-{
-	MPT_ADAPTER	*ioc = hd->ioc;
-	SpiCfgData	*pSpi = &ioc->spi_data;
-	Ioc3PhysDisk_t	*pPDisk;
-	int		 numPDisk;
-
-	if (hd->negoNvram != 0)
-		return;
-
-	ddvtprintk(("DV requested for phys disk id %d\n", id));
-	if (ioc->raid_data.pIocPg3) {
-		pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-		while (numPDisk) {
-			if (id == pPDisk->PhysDiskNum) {
-				pSpi->dvStatus[pPDisk->PhysDiskID] =
-				    (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
-				pSpi->forceDv = MPT_SCSICFG_NEED_DV;
-				ddvtprintk(("NEED_DV set for phys disk id %d\n",
-				    pPDisk->PhysDiskID));
-				break;
-			}
-			pPDisk++;
-			numPDisk--;
-		}
-
-		if (numPDisk == 0) {
-			/* The physical disk that needs DV was not found
-			 * in the stored IOC Page 3. The driver must reload
-			 * this page. DV routine will set the NEED_DV flag for
-			 * all phys disks that have DV_NOT_DONE set.
-			 */
-			pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
-			ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
-		}
-	}
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * If no Target, bus reset on 1st I/O. Set the flag to
  * prevent any future negotiations to this device.
  */
 static void
-mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
+mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
 {
+	VirtDevice	*vdev;
 
-	if ((hd->Targets) && (hd->Targets[target_id] == NULL))
-		hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
-
+	if ((vdev = sc->device->hostdata) != NULL)
+		hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
 	return;
 }
 
@@ -3100,7 +3030,7 @@
 	MPT_ADAPTER		*ioc = hd->ioc;
 	Config_t		*pReq;
 	SCSIDevicePage1_t	*pData;
-	VirtDevice		*pTarget=NULL;
+	VirtTarget		*vtarget=NULL;
 	MPT_FRAME_HDR		*mf;
 	dma_addr_t		 dataDma;
 	u16			 req_idx;
@@ -3180,11 +3110,11 @@
 		/* If id is not a raid volume, get the updated
 		 * transmission settings from the target structure.
 		 */
-		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-			width = pTarget->maxWidth;
-			factor = pTarget->minSyncFactor;
-			offset = pTarget->maxOffset;
-			negoFlags = pTarget->negoFlags;
+		if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
+			width = vtarget->maxWidth;
+			factor = vtarget->minSyncFactor;
+			offset = vtarget->maxOffset;
+			negoFlags = vtarget->negoFlags;
 		}
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
@@ -3904,36 +3834,104 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
- *	@hd: Pointer to MPT_SCSI_HOST structure
- *	@portnum: IOC port number
+ *	mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
+ *	@hd: Pointer to a SCSI HOST structure
+ *	@vtarget: per device private data
  *
  *	Uses the ISR, but with special processing.
  *	MUST be single-threaded.
  *
- *	Return: 0 on completion
  */
-static int
-mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
+static void
+mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
 {
 	MPT_ADAPTER		*ioc= hd->ioc;
-	VirtDevice		*pTarget;
-	SCSIDevicePage1_t	*pcfg1Data = NULL;
-	INTERNAL_CMD		 iocmd;
+	SCSIDevicePage1_t	*pcfg1Data;
 	CONFIGPARMS		 cfg;
-	dma_addr_t		 cfg1_dma_addr = -1;
-	ConfigPageHeader_t	 header1;
-	int			 bus = 0;
-	int			 id = 0;
-	int			 lun;
-	int			 indexed_lun, lun_index;
-	int			 hostId = ioc->pfacts[portnum].PortSCSIID;
-	int			 max_id;
-	int			 requested, configuration, data;
-	int			 doConfig = 0;
+	dma_addr_t		 cfg1_dma_addr;
+	ConfigPageHeader_t	 header;
+	int			 id;
+	int			 requested, configuration, data,i;
 	u8			 flags, factor;
 
-	max_id = ioc->sh->max_id - 1;
+	if (ioc->bus_type != SPI)
+		return;
+
+	if (!ioc->spi_data.sdp1length)
+		return;
+
+	pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+		 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
+
+	if (pcfg1Data == NULL)
+		return;
+
+	header.PageVersion = ioc->spi_data.sdp1version;
+	header.PageLength = ioc->spi_data.sdp1length;
+	header.PageNumber = 1;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	cfg.cfghdr.hdr = &header;
+	cfg.physAddr = cfg1_dma_addr;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	cfg.dir = 1;
+	cfg.timeout = 0;
+
+	if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
+		for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+			id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
+			flags = hd->ioc->spi_data.noQas;
+			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+				data = hd->ioc->spi_data.nvram[id];
+				if (data & MPT_NVRAM_WIDE_DISABLE)
+					flags |= MPT_TARGET_NO_NEGO_WIDE;
+				factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+				if ((factor == 0) || (factor == MPT_ASYNC))
+					flags |= MPT_TARGET_NO_NEGO_SYNC;
+			}
+			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+				&configuration, flags);
+			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+				"offset=0 negoFlags=%x request=%x config=%x\n",
+				id, flags, requested, configuration));
+			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
+			pcfg1Data->Reserved = 0;
+			pcfg1Data->Configuration = cpu_to_le32(configuration);
+			cfg.pageAddr = (vtarget->bus_id<<8) | id;
+			mpt_config(hd->ioc, &cfg);
+		}
+	} else {
+		flags = vtarget->negoFlags;
+		mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+				&configuration, flags);
+		dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+			"offset=0 negoFlags=%x request=%x config=%x\n",
+			vtarget->target_id, flags, requested, configuration));
+		pcfg1Data->RequestedParameters = cpu_to_le32(requested);
+		pcfg1Data->Reserved = 0;
+		pcfg1Data->Configuration = cpu_to_le32(configuration);
+		cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
+		mpt_config(hd->ioc, &cfg);
+	}
+
+	if (pcfg1Data)
+		pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
+ *	@hd: Pointer to a SCSI HOST structure
+ *	@vtarget: per device private data
+ *	@lun: lun
+ *
+ *	Uses the ISR, but with special processing.
+ *	MUST be single-threaded.
+ *
+ */
+static void
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
+{
+	INTERNAL_CMD		 iocmd;
 
 	/* Following parameters will not change
 	 * in this routine.
@@ -3945,108 +3943,30 @@
 	iocmd.data_dma = -1;
 	iocmd.size = 0;
 	iocmd.rsvd = iocmd.rsvd2 = 0;
+	iocmd.bus = vdevice->bus_id;
+	iocmd.id = vdevice->target_id;
+	iocmd.lun = (u8)vdevice->lun;
 
-	/* No SCSI hosts
-	 */
-	if (hd->Targets == NULL)
+	if ((vdevice->vtarget->type & TYPE_DISK) &&
+	    (vdevice->configured_lun))
+		mptscsih_do_cmd(hd, &iocmd);
+}
+
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+{
+	int i;
+
+	if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
 		return 0;
 
-	/* Skip the host
-	 */
-	if (id == hostId)
-		id++;
-
-	/* Write SDP1 for all SCSI devices
-	 * Alloc memory and set up config buffer
-	 */
-	if (ioc->bus_type == SCSI) {
-		if (ioc->spi_data.sdp1length > 0) {
-			pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
-					 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
-
-			if (pcfg1Data != NULL) {
-				doConfig = 1;
-				header1.PageVersion = ioc->spi_data.sdp1version;
-				header1.PageLength = ioc->spi_data.sdp1length;
-				header1.PageNumber = 1;
-				header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-				cfg.cfghdr.hdr = &header1;
-				cfg.physAddr = cfg1_dma_addr;
-				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-				cfg.dir = 1;
-				cfg.timeout = 0;
-			}
-		}
-	}
-
-	/* loop through all devices on this port
-	 */
-	while (bus < MPT_MAX_BUS) {
-		iocmd.bus = bus;
-		iocmd.id = id;
-		pTarget = hd->Targets[(int)id];
-
-		if (doConfig) {
-
-			/* Set the negotiation flags */
-			if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-				flags = pTarget->negoFlags;
-			} else {
-				flags = hd->ioc->spi_data.noQas;
-				if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-					data = hd->ioc->spi_data.nvram[id];
-
-					if (data & MPT_NVRAM_WIDE_DISABLE)
-						flags |= MPT_TARGET_NO_NEGO_WIDE;
-
-					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
-					if ((factor == 0) || (factor == MPT_ASYNC))
-						flags |= MPT_TARGET_NO_NEGO_SYNC;
-				}
-			}
-
-			/* Force to async, narrow */
-			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
-					&configuration, flags);
-			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
-				"offset=0 negoFlags=%x request=%x config=%x\n",
-				id, flags, requested, configuration));
-			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
-			pcfg1Data->Reserved = 0;
-			pcfg1Data->Configuration = cpu_to_le32(configuration);
-			cfg.pageAddr = (bus<<8) | id;
-			mpt_config(hd->ioc, &cfg);
-		}
-
-		/* If target Ptr NULL or if this target is NOT a disk, skip.
-		 */
-		if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
-			for (lun=0; lun <= MPT_LAST_LUN; lun++) {
-				/* If LUN present, issue the command
-				 */
-				lun_index = (lun >> 5);  /* 32 luns per lun_index */
-				indexed_lun = (lun % 32);
-				if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
-					iocmd.lun = lun;
-					(void) mptscsih_do_cmd(hd, &iocmd);
-				}
-			}
-		}
-
-		/* get next relevant device */
-		id++;
-
-		if (id == hostId)
-			id++;
-
-		if (id > max_id) {
-			id = 0;
-			bus++;
-		}
-	}
-
-	if (pcfg1Data) {
-		pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+		if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+			return 1;
 	}
 
 	return 0;
@@ -4101,8 +4021,8 @@
 
 			msleep(250);
 
-			/* DV only to SCSI adapters */
-			if (ioc->bus_type != SCSI)
+			/* DV only to SPI adapters */
+			if (ioc->bus_type != SPI)
 				continue;
 
 			/* Make sure everything looks ok */
@@ -4205,32 +4125,12 @@
 	return;
 }
 
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int
-mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
-{
-	int i;
-
-	if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
-		return 0;
-
-	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
-		if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
-			return 1;
-	}
-
-	return 0;
-}
-
 /* Write SDP1 if no QAS has been enabled
  */
 static void
 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
 {
-	VirtDevice *pTarget;
+	VirtTarget *vtarget;
 	int ii;
 
 	if (hd->Targets == NULL)
@@ -4243,11 +4143,11 @@
 		if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
 			continue;
 
-		pTarget = hd->Targets[ii];
+		vtarget = hd->Targets[ii];
 
-		if ((pTarget != NULL) && (!pTarget->raidVolume)) {
-			if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
-				pTarget->negoFlags |= hd->ioc->spi_data.noQas;
+		if ((vtarget != NULL) && (!vtarget->raidVolume)) {
+			if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
+				vtarget->negoFlags |= hd->ioc->spi_data.noQas;
 				dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
 				mptscsih_writeSDP1(hd, 0, ii, 0);
 			}
@@ -4287,7 +4187,7 @@
 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 {
 	MPT_ADAPTER		*ioc = hd->ioc;
-	VirtDevice		*pTarget;
+	VirtTarget		*vtarget;
 	SCSIDevicePage1_t	*pcfg1Data;
 	SCSIDevicePage0_t	*pcfg0Data;
 	u8			*pbuf1;
@@ -4358,12 +4258,12 @@
 	iocmd.physDiskNum = -1;
 	iocmd.rsvd = iocmd.rsvd2 = 0;
 
-	pTarget = hd->Targets[id];
+	vtarget = hd->Targets[id];
 
 	/* Use tagged commands if possible.
 	 */
-	if (pTarget) {
-		if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+	if (vtarget) {
+		if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
 			iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
 		else {
 			if (hd->ioc->facts.FWVersion.Word < 0x01000600)
@@ -4579,7 +4479,7 @@
 		/* Reset the size for disks
 		 */
 		inq0 = (*pbuf1) & 0x1F;
-		if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
+		if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
 			sz = 0x40;
 			iocmd.size = sz;
 		}
@@ -4589,8 +4489,7 @@
 		 */
 		if (inq0 == TYPE_PROCESSOR) {
 			mptscsih_initTarget(hd,
-				bus,
-				id,
+				vtarget,
 				lun,
 				pbuf1,
 				sz);
@@ -4604,22 +4503,22 @@
 			goto target_done;
 
 		if (sz == 0x40) {
-			if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
-				&& (pTarget->minSyncFactor > 0x09)) {
+			if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
+				&& (vtarget->minSyncFactor > 0x09)) {
 				if ((pbuf1[56] & 0x04) == 0)
 					;
 				else if ((pbuf1[56] & 0x01) == 1) {
-					pTarget->minSyncFactor =
+					vtarget->minSyncFactor =
 					    nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
 				} else {
-					pTarget->minSyncFactor =
+					vtarget->minSyncFactor =
 					    nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
 				}
 
-				dv.max.factor = pTarget->minSyncFactor;
+				dv.max.factor = vtarget->minSyncFactor;
 
 				if ((pbuf1[56] & 0x02) == 0) {
-					pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
 					hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
 					ddvprintk((MYIOC_s_NOTE_FMT
 					    "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
@@ -4702,8 +4601,7 @@
 						    "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
 						hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
 						mptscsih_initTarget(hd,
-							bus,
-							id,
+							vtarget,
 							lun,
 							pbuf1,
 							sz);
@@ -5204,7 +5102,7 @@
 static void
 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 {
-	VirtDevice		*pTarget;
+	VirtTarget		*vtarget;
 	SCSIDevicePage0_t	*pPage0;
 	SCSIDevicePage1_t	*pPage1;
 	int			val = 0, data, configuration;
@@ -5224,11 +5122,11 @@
 		 * already throttled back.
 		 */
 		negoFlags = hd->ioc->spi_data.noQas;
-		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
-			width = pTarget->maxWidth;
-			offset = pTarget->maxOffset;
-			factor = pTarget->minSyncFactor;
-			negoFlags |= pTarget->negoFlags;
+		if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
+			width = vtarget->maxWidth;
+			offset = vtarget->maxOffset;
+			factor = vtarget->minSyncFactor;
+			negoFlags |= vtarget->negoFlags;
 		} else {
 			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
 				data = hd->ioc->spi_data.nvram[id];
@@ -5430,11 +5328,11 @@
 		 * or overwrite nvram (phys disks only).
 		 */
 
-		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
-			pTarget->maxWidth = dv->now.width;
-			pTarget->maxOffset = dv->now.offset;
-			pTarget->minSyncFactor = dv->now.factor;
-			pTarget->negoFlags = dv->now.flags;
+		if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
+			vtarget->maxWidth = dv->now.width;
+			vtarget->maxOffset = dv->now.offset;
+			vtarget->minSyncFactor = dv->now.factor;
+			vtarget->negoFlags = dv->now.flags;
 		} else {
 			/* Preserv all flags, use
 			 * read-modify-write algorithm
@@ -5588,6 +5486,94 @@
 		break;
 	}
 }
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
+ * Else set the NEED_DV flag after Read Capacity Issued (disks)
+ * or Mode Sense (cdroms).
+ *
+ * Tapes, initTarget will set this flag on completion of Inquiry command.
+ * Called only if DV_NOT_DONE flag is set
+ */
+static void
+mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
+{
+	MPT_ADAPTER	*ioc = hd->ioc;
+	u8 cmd;
+	SpiCfgData	*pSpi;
+
+	ddvtprintk((MYIOC_s_NOTE_FMT
+		" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+		hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
+
+	if ((sc->device->lun != 0) || (hd->negoNvram != 0))
+		return;
+
+	cmd = sc->cmnd[0];
+
+	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
+		pSpi = &ioc->spi_data;
+		if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
+			/* Set NEED_DV for all hidden disks
+			 */
+			Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+			int		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+
+			while (numPDisk) {
+				pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
+				ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+				pPDisk++;
+				numPDisk--;
+			}
+		}
+		pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
+		ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
+	}
+}
+
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+	MPT_ADAPTER	*ioc = hd->ioc;
+	SpiCfgData	*pSpi = &ioc->spi_data;
+	Ioc3PhysDisk_t	*pPDisk;
+	int		 numPDisk;
+
+	if (hd->negoNvram != 0)
+		return;
+
+	ddvtprintk(("DV requested for phys disk id %d\n", id));
+	if (ioc->raid_data.pIocPg3) {
+		pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+		while (numPDisk) {
+			if (id == pPDisk->PhysDiskNum) {
+				pSpi->dvStatus[pPDisk->PhysDiskID] =
+				    (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+				pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+				ddvtprintk(("NEED_DV set for phys disk id %d\n",
+				    pPDisk->PhysDiskID));
+				break;
+			}
+			pPDisk++;
+			numPDisk--;
+		}
+
+		if (numPDisk == 0) {
+			/* The physical disk that needs DV was not found
+			 * in the stored IOC Page 3. The driver must reload
+			 * this page. DV routine will set the NEED_DV flag for
+			 * all phys disks that have DV_NOT_DONE set.
+			 */
+			pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+			ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+		}
+	}
+}
 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
 
 EXPORT_SYMBOL(mptscsih_remove);
@@ -5599,7 +5585,9 @@
 EXPORT_SYMBOL(mptscsih_proc_info);
 EXPORT_SYMBOL(mptscsih_info);
 EXPORT_SYMBOL(mptscsih_qcmd);
+EXPORT_SYMBOL(mptscsih_target_alloc);
 EXPORT_SYMBOL(mptscsih_slave_alloc);
+EXPORT_SYMBOL(mptscsih_target_destroy);
 EXPORT_SYMBOL(mptscsih_slave_destroy);
 EXPORT_SYMBOL(mptscsih_slave_configure);
 EXPORT_SYMBOL(mptscsih_abort);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 971fda4..d3cba12 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -91,7 +91,9 @@
 extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
 extern const char * mptscsih_info(struct Scsi_Host *SChost);
 extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
+extern int mptscsih_target_alloc(struct scsi_target *starget);
 extern int mptscsih_slave_alloc(struct scsi_device *device);
+extern void mptscsih_target_destroy(struct scsi_target *starget);
 extern void mptscsih_slave_destroy(struct scsi_device *device);
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 5c0e307..ce332a6 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -103,13 +103,16 @@
 static int	mptspiInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptspi_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptspi",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT SPI Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptscsih_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -177,13 +180,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptspi_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptspi_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -208,7 +213,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptspi_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -286,7 +292,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -304,14 +310,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -385,13 +391,13 @@
 	if(error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	scsi_scan_host(sh);
 	return 0;
 
-mptspi_probe_failed:
+out_mptspi_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 30bee11..d2102a2 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -586,16 +586,16 @@
 	dma_addr_t tx_bufs_dma;
 	signed char phys[4];		/* MII device addresses. */
 	char twistie, twist_row, twist_col;	/* Twister tune state. */
-	unsigned int default_port:4;	/* Last dev->if_port value. */
+	unsigned int default_port : 4;	/* Last dev->if_port value. */
+	unsigned int have_thread : 1;
 	spinlock_t lock;
 	spinlock_t rx_lock;
 	chip_t chipset;
-	pid_t thr_pid;
-	wait_queue_head_t thr_wait;
-	struct completion thr_exited;
 	u32 rx_config;
 	struct rtl_extra_stats xstats;
-	int time_to_die;
+
+	struct work_struct thread;
+
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
@@ -620,7 +620,7 @@
 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 val);
-static void rtl8139_start_thread(struct net_device *dev);
+static void rtl8139_start_thread(struct rtl8139_private *tp);
 static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -637,6 +637,7 @@
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
+static void rtl8139_thread (void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1007,8 +1008,7 @@
 		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
 	spin_lock_init (&tp->lock);
 	spin_lock_init (&tp->rx_lock);
-	init_waitqueue_head (&tp->thr_wait);
-	init_completion (&tp->thr_exited);
+	INIT_WORK(&tp->thread, rtl8139_thread, dev);
 	tp->mii.dev = dev;
 	tp->mii.mdio_read = mdio_read;
 	tp->mii.mdio_write = mdio_write;
@@ -1345,7 +1345,7 @@
 			dev->irq, RTL_R8 (MediaStatus),
 			tp->mii.full_duplex ? "full" : "half");
 
-	rtl8139_start_thread(dev);
+	rtl8139_start_thread(tp);
 
 	return 0;
 }
@@ -1594,55 +1594,43 @@
 		 RTL_R8 (Config1));
 }
 
-static int rtl8139_thread (void *data)
+static void rtl8139_thread (void *_data)
 {
-	struct net_device *dev = data;
+	struct net_device *dev = _data;
 	struct rtl8139_private *tp = netdev_priv(dev);
-	unsigned long timeout;
+	unsigned long thr_delay;
 
-	daemonize("%s", dev->name);
-	allow_signal(SIGTERM);
-
-	while (1) {
-		timeout = next_tick;
-		do {
-			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
-			/* make swsusp happy with our thread */
-			try_to_freeze();
-		} while (!signal_pending (current) && (timeout > 0));
-
-		if (signal_pending (current)) {
-			flush_signals(current);
-		}
-
-		if (tp->time_to_die)
-			break;
-
-		if (rtnl_lock_interruptible ())
-			break;
+	if (rtnl_shlock_nowait() == 0) {
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
+
+		thr_delay = next_tick;
+	} else {
+		/* unlikely race.  mitigate with fast poll. */
+		thr_delay = HZ / 2;
 	}
 
-	complete_and_exit (&tp->thr_exited, 0);
+	schedule_delayed_work(&tp->thread, thr_delay);
 }
 
-static void rtl8139_start_thread(struct net_device *dev)
+static void rtl8139_start_thread(struct rtl8139_private *tp)
 {
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	tp->thr_pid = -1;
 	tp->twistie = 0;
-	tp->time_to_die = 0;
 	if (tp->chipset == CH_8139_K)
 		tp->twistie = 1;
 	else if (tp->drv_flags & HAS_LNK_CHNG)
 		return;
 
-	tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES);
-	if (tp->thr_pid < 0) {
-		printk (KERN_WARNING "%s: unable to start kernel thread\n",
-			dev->name);
+	tp->have_thread = 1;
+
+	schedule_delayed_work(&tp->thread, next_tick);
+}
+
+static void rtl8139_stop_thread(struct rtl8139_private *tp)
+{
+	if (tp->have_thread) {
+		cancel_rearming_delayed_work(&tp->thread);
+		tp->have_thread = 0;
 	}
 }
 
@@ -2224,22 +2212,12 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	int ret = 0;
 	unsigned long flags;
 
 	netif_stop_queue (dev);
 
-	if (tp->thr_pid >= 0) {
-		tp->time_to_die = 1;
-		wmb();
-		ret = kill_proc (tp->thr_pid, SIGTERM, 1);
-		if (ret) {
-			printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
-			return ret;
-		}
-		wait_for_completion (&tp->thr_exited);
-	}
-	
+	rtl8139_stop_thread(tp);
+
 	if (netif_msg_ifdown(tp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ebd7313..e2fa29b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1901,6 +1901,8 @@
 
 	  If in doubt, say N.
 
+source "drivers/net/ixp2000/Kconfig"
+
 config MYRI_SBUS
 	tristate "MyriCOM Gigabit Ethernet support"
 	depends on SBUS
@@ -2008,7 +2010,18 @@
 
 	  It does not support the link failover and network management 
 	  features that "portable" vendor supplied sk98lin driver does.
-	
+
+
+config SKY2
+	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL
+	select CRC32
+	---help---
+	  This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called sky2.  This is recommended.
+
 config SK98LIN
 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
 	depends on PCI
@@ -2120,7 +2133,7 @@
 
 config SPIDER_NET
 	tristate "Spider Gigabit Ethernet driver"
-	depends on PCI && PPC_BPA
+	depends on PCI && PPC_CELL
 	help
 	  This driver supports the Gigabit Ethernet chips present on the
 	  Cell Processor-Based Blades from IBM.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4cffd34..b74a7cb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,10 @@
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
+gianfar_driver-objs := gianfar.o \
+		gianfar_ethtool.o \
+		gianfar_mii.o \
+		gianfar_sysfs.o
 
 #
 # link order important here
@@ -59,6 +62,7 @@
 obj-$(CONFIG_SPIDER_NET) += spidernet.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
+obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
@@ -202,6 +206,7 @@
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index cf50384..5cdae2b 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -4,5 +4,5 @@
 
 obj-$(CONFIG_BONDING) += bonding.o
 
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
 
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index d2f34d5..f3f5825 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -18,38 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Based on discussion on mailing list, changed locking scheme
- *	  to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *	  of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *	  hidden bugs and solves system hangs that occurred due to the fact
- *	  that holding lock_irqsave doesn't prevent softirqs from running.
- *	  This also increases total throughput since interrupts are not
- *	  blocked on each transmitted packets or monitor timeout.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fix long fail over time when releasing last slave of an active
- *	  aggregator - send LACPDU on unbind of slave to tell partner this
- *	  port is no longer aggregatable.
- *
- * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *	- Send LACPDU as highest priority packet to further fix the above
- *	  problem on very high Tx traffic load where packets may get dropped
- *	  by the slave.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 //#define BONDING_DEBUG 1
@@ -1198,10 +1166,10 @@
 			// detect loopback situation
 			if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
 				// INFO_RECEIVED_LOOPBACK_FRAMES
-				printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
-						port->slave->dev->name);
-				printk(KERN_ERR "Check the configuration to verify that all Adapters "
-						"are connected to 802.3ad compliant switch ports\n");
+				printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
+				       "adapter (%s). Check the configuration to verify that all "
+				       "Adapters are connected to 802.3ad compliant switch ports\n",
+				       port->slave->dev->master->name, port->slave->dev->name);
 				__release_rx_machine_lock(port);
 				return;
 			}
@@ -1378,8 +1346,9 @@
 			}
 		}
 		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-			printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
 			       "related to aggregator %d but was not on its port list\n",
+			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name,
 			       port->aggregator->aggregator_identifier);
 		}
@@ -1450,7 +1419,8 @@
 
 			dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
 		} else {
-			printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
+			printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
+			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name);
 		}
 	}
@@ -1582,8 +1552,9 @@
 
 		// check if any partner replys
 		if (best_aggregator->is_individual) {
-			printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
-					"for any adapters in the bond\n");
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
+			       "the link partner for any adapters in the bond\n",
+			       best_aggregator->slave->dev->master->name);
 		}
 
 		// check if there are more than one aggregator
@@ -1915,7 +1886,8 @@
 	struct aggregator *aggregator;
 
 	if (bond == NULL) {
-		printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
+		printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
+		       slave->dev->master->name, slave->dev->name);
 		return -1;
 	}
 
@@ -1990,7 +1962,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
+		       "unbind an uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2021,7 +1995,8 @@
 				dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
 
 				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-					printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
+					printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+					       aggregator->slave->dev->master->name);
 					// select new active aggregator
 					 select_new_active_agg = 1;
 				}
@@ -2051,15 +2026,17 @@
 					ad_agg_selection_logic(__get_first_agg(port));
 				}
 			} else {
-				printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
-				       "and could not find a new aggregator for its ports\n");
+				printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
+				       "and could not find a new aggregator for its ports\n",
+				       slave->dev->master->name);
 			}
 		} else { // in case that the only port related to this aggregator is the one we want to remove
 			select_new_active_agg = aggregator->is_active;
 			// clear the aggregator
 			ad_clear_agg(aggregator);
 			if (select_new_active_agg) {
-				printk(KERN_INFO "Removing an active aggregator\n");
+				printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+				       slave->dev->master->name);
 				// select new active aggregator
 				ad_agg_selection_logic(__get_first_agg(port));
 			}
@@ -2085,7 +2062,8 @@
 					// clear the aggregator
 					ad_clear_agg(temp_aggregator);
 					if (select_new_active_agg) {
-						printk(KERN_INFO "Removing an active aggregator\n");
+						printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+						       slave->dev->master->name);
 						// select new active aggregator
 						ad_agg_selection_logic(__get_first_agg(port));
 					}
@@ -2131,7 +2109,8 @@
 		// select the active aggregator for the bond
 		if ((port = __get_first_port(bond))) {
 			if (!port->slave) {
-				printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+				printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
+				       "uninitialized\n", bond->dev->name);
 				goto re_arm;
 			}
 
@@ -2143,7 +2122,8 @@
 	// for each port run the state machines
 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
+			       "port\n", bond->dev->name);
 			goto re_arm;
 		}
 
@@ -2184,7 +2164,8 @@
 		port = &(SLAVE_AD_INFO(slave).port);
 
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
+			       "uninitialized\n", slave->dev->name, slave->dev->master->name);
 			return;
 		}
 
@@ -2230,8 +2211,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
-		       slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
+		       "changed for uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2257,8 +2239,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
-		       slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
+		       "for uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2285,8 +2268,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
-			slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
+		       "uninitialized port on %s\n",
+			slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2363,7 +2347,8 @@
 	}
 
 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-		printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
+		printk(KERN_DEBUG DRV_NAME ": %s: Error: "
+		       "bond_3ad_get_active_agg_info failed\n", dev->name);
 		goto out;
 	}
 
@@ -2372,7 +2357,9 @@
 
 	if (slaves_in_agg == 0) {
 		/*the aggregator is empty*/
-		printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
+		printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
+		       "aggregator is empty\n",
+		       dev->name);
 		goto out;
 	}
 
@@ -2390,7 +2377,8 @@
 	}
 
 	if (slave_agg_no >= 0) {
-		printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+		printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
+		       "for aggregator ID %d\n", dev->name, agg_id);
 		goto out;
 	}
 
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 673a30a..5ee2cef 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -18,19 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 #ifndef __BOND_3AD_H__
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f8fce39..854ddfb 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -18,25 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed signed/unsigned calculation errors that caused load sharing
- *	  to collapse to one slave under very heavy UDP Tx stress.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *	- Add support for setting bond's MAC address with special
- *	  handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed: Cannot remove and re-enslave the original active slave.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Add capability to tag self generated packets in ALB/TLB modes.
  */
 
 //#define BONDING_DEBUG 1
@@ -198,20 +179,21 @@
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+	struct tlb_client_info *new_hashtbl;
 	int i;
 
 	spin_lock_init(&(bond_info->tx_hashtbl_lock));
 
-	_lock_tx_hashtbl(bond);
-
-	bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
-	if (!bond_info->tx_hashtbl) {
+	new_hashtbl = kmalloc(size, GFP_KERNEL);
+	if (!new_hashtbl) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: Failed to allocate TLB hash table\n",
+		       ": %s: Error: Failed to allocate TLB hash table\n",
 		       bond->dev->name);
-		_unlock_tx_hashtbl(bond);
 		return -1;
 	}
+	_lock_tx_hashtbl(bond);
+
+	bond_info->tx_hashtbl = new_hashtbl;
 
 	memset(bond_info->tx_hashtbl, 0, size);
 
@@ -513,7 +495,8 @@
 				 client_info->mac_dst);
 		if (!skb) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: failed to create an ARP packet\n");
+			       ": %s: Error: failed to create an ARP packet\n",
+			       client_info->slave->dev->master->name);
 			continue;
 		}
 
@@ -523,7 +506,8 @@
 			skb = vlan_put_tag(skb, client_info->vlan_id);
 			if (!skb) {
 				printk(KERN_ERR DRV_NAME
-				       ": Error: failed to insert VLAN tag\n");
+				       ": %s: Error: failed to insert VLAN tag\n",
+				       client_info->slave->dev->master->name);
 				continue;
 			}
 		}
@@ -606,8 +590,9 @@
 
 		if (!client_info->slave) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: found a client with no channel in "
-			       "the client's hash table\n");
+			       ": %s: Error: found a client with no channel in "
+			       "the client's hash table\n",
+			       bond->dev->name);
 			continue;
 		}
 		/*update all clients using this src_ip, that are not assigned
@@ -797,21 +782,22 @@
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
+	struct rlb_client_info	*new_hashtbl;
 	int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
 	int i;
 
 	spin_lock_init(&(bond_info->rx_hashtbl_lock));
 
-	_lock_rx_hashtbl(bond);
-
-	bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
-	if (!bond_info->rx_hashtbl) {
+	new_hashtbl = kmalloc(size, GFP_KERNEL);
+	if (!new_hashtbl) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: Failed to allocate RLB hash table\n",
+		       ": %s: Error: Failed to allocate RLB hash table\n",
 		       bond->dev->name);
-		_unlock_rx_hashtbl(bond);
 		return -1;
 	}
+	_lock_rx_hashtbl(bond);
+
+	bond_info->rx_hashtbl = new_hashtbl;
 
 	bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
@@ -927,7 +913,8 @@
 			skb = vlan_put_tag(skb, vlan->vlan_id);
 			if (!skb) {
 				printk(KERN_ERR DRV_NAME
-				       ": Error: failed to insert VLAN tag\n");
+				       ": %s: Error: failed to insert VLAN tag\n",
+				       bond->dev->name);
 				continue;
 			}
 		}
@@ -956,11 +943,11 @@
 	s_addr.sa_family = dev->type;
 	if (dev_set_mac_address(dev, &s_addr)) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: dev_set_mac_address of dev %s failed! ALB "
+		       ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
 		       "mode requires that the base driver support setting "
 		       "the hw address also when the network device's "
 		       "interface is open\n",
-		       dev->name);
+		       dev->master->name, dev->name);
 		return -EOPNOTSUPP;
 	}
 	return 0;
@@ -1153,16 +1140,16 @@
 				       bond->alb_info.rlb_enabled);
 
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: the hw address of slave %s is in use by "
+		       ": %s: Warning: the hw address of slave %s is in use by "
 		       "the bond; giving it the hw address of %s\n",
-		       slave->dev->name, free_mac_slave->dev->name);
+		       bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
 
 	} else if (has_bond_addr) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: the hw address of slave %s is in use by the "
+		       ": %s: Error: the hw address of slave %s is in use by the "
 		       "bond; couldn't find a slave with a free hw address to "
 		       "give it (this should not have happened)\n",
-		       slave->dev->name);
+		       bond->dev->name, slave->dev->name);
 		return -EFAULT;
 	}
 
@@ -1250,6 +1237,8 @@
 			tlb_deinitialize(bond);
 			return res;
 		}
+	} else {
+		bond->alb_info.rlb_enabled = 0;
 	}
 
 	return 0;
@@ -1409,7 +1398,7 @@
 		read_lock(&bond->curr_slave_lock);
 
 		bond_for_each_slave(bond, slave, i) {
-			alb_send_learning_packets(slave,slave->dev->dev_addr);
+			alb_send_learning_packets(slave, slave->dev->dev_addr);
 		}
 
 		read_unlock(&bond->curr_slave_lock);
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e4091cd..28f2a2f 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -18,15 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *	- Add support for setting bond's MAC address with special
- *	  handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 #ifndef __BOND_ALB_H__
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 94cec3c..2582d98 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -29,466 +29,6 @@
  *	b: if a hw mac address already is there, eth0's hw mac address
  *	   will then be set from bond0.
  *
- * v0.1 - first working version.
- * v0.2 - changed stats to be calculated by summing slaves stats.
- *
- * Changes:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fix leaks on failure at bond_init
- *
- * 2000/09/30 - Willy Tarreau <willy at meta-x.org>
- *     - added trivial code to release a slave device.
- *     - fixed security bug (CAP_NET_ADMIN not checked)
- *     - implemented MII link monitoring to disable dead links :
- *       All MII capable slaves are checked every <miimon> milliseconds
- *       (100 ms seems good). This value can be changed by passing it to
- *       insmod. A value of zero disables the monitoring (default).
- *     - fixed an infinite loop in bond_xmit_roundrobin() when there's no
- *       good slave.
- *     - made the code hopefully SMP safe
- *
- * 2000/10/03 - Willy Tarreau <willy at meta-x.org>
- *     - optimized slave lists based on relevant suggestions from Thomas Davis
- *     - implemented active-backup method to obtain HA with two switches:
- *       stay as long as possible on the same active interface, while we
- *       also monitor the backup one (MII link status) because we want to know
- *       if we are able to switch at any time. ( pass "mode=1" to insmod )
- *     - lots of stress testings because we need it to be more robust than the
- *       wires ! :->
- *
- * 2000/10/09 - Willy Tarreau <willy at meta-x.org>
- *     - added up and down delays after link state change.
- *     - optimized the slaves chaining so that when we run forward, we never
- *       repass through the bond itself, but we can find it by searching
- *       backwards. Renders the deletion more difficult, but accelerates the
- *       scan.
- *     - smarter enslaving and releasing.
- *     - finer and more robust SMP locking
- *
- * 2000/10/17 - Willy Tarreau <willy at meta-x.org>
- *     - fixed two potential SMP race conditions
- *
- * 2000/10/18 - Willy Tarreau <willy at meta-x.org>
- *     - small fixes to the monitoring FSM in case of zero delays
- * 2000/11/01 - Willy Tarreau <willy at meta-x.org>
- *     - fixed first slave not automatically used in trunk mode.
- * 2000/11/10 : spelling of "EtherChannel" corrected.
- * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl().
- * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait().
- *
- * 2001/1/3 - Chad N. Tindel <ctindel at ieee dot org>
- *     - The bonding driver now simulates MII status monitoring, just like
- *       a normal network device.  It will show that the link is down iff
- *       every slave in the bond shows that their links are down.  If at least
- *       one slave is up, the bond's MII status will appear as up.
- *
- * 2001/2/7 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Applications can now query the bond from user space to get
- *       information which may be useful.  They do this by calling
- *       the BOND_INFO_QUERY ioctl.  Once the app knows how many slaves
- *       are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to
- *       get slave specific information (# link failures, etc).  See
- *       <linux/if_bonding.h> for more details.  The structs of interest
- *       are ifbond and ifslave.
- *
- * 2001/4/5 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Ported to 2.4 Kernel
- *
- * 2001/5/2 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - When a device is detached from a bond, the slave device is no longer
- *       left thinking that is has a master.
- *
- * 2001/5/16 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - memset did not appropriately initialized the bond rw_locks. Used
- *       rwlock_init to initialize to unlocked state to prevent deadlock when
- *       first attempting a lock
- *     - Called SET_MODULE_OWNER for bond device
- *
- * 2001/5/17 - Tim Anderson <tsa at mvista.com>
- *     - 2 paths for releasing for slave release; 1 through ioctl
- *       and 2) through close. Both paths need to release the same way.
- *     - the free slave in bond release is changing slave status before
- *       the free. The netdev_set_master() is intended to change slave state
- *       so it should not be done as part of the release process.
- *     - Simple rule for slave state at release: only the active in A/B and
- *       only one in the trunked case.
- *
- * 2001/6/01 - Tim Anderson <tsa at mvista.com>
- *     - Now call dev_close when releasing a slave so it doesn't screw up
- *       out routing table.
- *
- * 2001/6/01 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Added /proc support for getting bond and slave information.
- *       Information is in /proc/net/<bond device>/info.
- *     - Changed the locking when calling bond_close to prevent deadlock.
- *
- * 2001/8/05 - Janice Girouard <girouard at us.ibm.com>
- *     - correct problem where refcnt of slave is not incremented in bond_ioctl
- *       so the system hangs when halting.
- *     - correct locking problem when unable to malloc in bond_enslave.
- *     - adding bond_xmit_xor logic.
- *     - adding multiple bond device support.
- *
- * 2001/8/13 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - correct locking problem with rtnl_exlock_nowait
- *
- * 2001/8/23 - Janice Girouard <girouard at us.ibm.com>
- *     - bzero initial dev_bonds, to correct oops
- *     - convert SIOCDEVPRIVATE to new MII ioctl calls
- *
- * 2001/9/13 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Add the BOND_CHANGE_ACTIVE ioctl implementation
- *
- * 2001/9/14 - Mark Huth <mhuth at mvista dot com>
- *     - Change MII_LINK_READY to not check for end of auto-negotiation,
- *       but only for an up link.
- *
- * 2001/9/20 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Add the device field to bonding_t.  Previously the net_device
- *       corresponding to a bond wasn't available from the bonding_t
- *       structure.
- *
- * 2001/9/25 - Janice Girouard <girouard at us.ibm.com>
- *     - add arp_monitor for active backup mode
- *
- * 2001/10/23 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Various memory leak fixes
- *
- * 2001/11/5 - Mark Huth <mark dot huth at mvista dot com>
- *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
- *       certain hotswap conditions.
- *       Note:  this same change may be required in bond_arp_monitor ???
- *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
- *     - Handle hot swap ethernet interface deregistration events to remove
- *       kernel oops following hot swap of enslaved interface
- *
- * 2002/1/2 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Restore original slave flags at release time.
- *
- * 2002/02/18 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - bond_release(): calling kfree on our_slave after call to
- *       bond_restore_slave_flags, not before
- *     - bond_enslave(): saving slave flags into original_flags before
- *       call to netdev_set_master, so the IFF_SLAVE flag doesn't end
- *       up in original_flags
- *
- * 2002/04/05 - Mark Smith <mark.smith at comdev dot cc> and
- *              Steve Mead <steve.mead at comdev dot cc>
- *     - Port Gleb Natapov's multicast support patchs from 2.4.12
- *       to 2.4.18 adding support for multicast.
- *
- * 2002/06/10 - Tony Cureington <tony.cureington * hp_com>
- *     - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link;
- *       actually changed function to use MIIPHY, then MIIREG, and finally
- *       ETHTOOL to determine the link status
- *     - fixed bad ifr_data pointer assignments in bond_ioctl
- *     - corrected mode 1 being reported as active-backup in bond_get_info;
- *       also added text to distinguish type of load balancing (rr or xor)
- *     - change arp_ip_target module param from "1-12s" (array of 12 ptrs)
- *       to "s" (a single ptr)
- *
- * 2002/08/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Removed acquisition of xmit_lock in set_multicast_list; caused
- *       deadlock on SMP (lock is held by caller).
- *     - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link().
- *
- * 2002/09/18 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Fixed up bond_check_dev_link() (and callers): removed some magic
- *	 numbers, banished local MII_ defines, wrapped ioctl calls to
- *	 prevent EFAULT errors
- *
- * 2002/9/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - make sure the ip target matches the arp_target before saving the
- *	 hw address.
- *
- * 2002/9/30 - Dan Eisner <eisner at 2robots dot com>
- *     - make sure my_ip is set before taking down the link, since
- *	 not all switches respond if the source ip is not set.
- *
- * 2002/10/8 - Janice Girouard <girouard at us dot ibm dot com>
- *     - read in the local ip address when enslaving a device
- *     - add primary support
- *     - make sure 2*arp_interval has passed when a new device
- *       is brought on-line before taking it down.
- *
- * 2002/09/11 - Philippe De Muyter <phdm at macqel dot be>
- *     - Added bond_xmit_broadcast logic.
- *     - Added bond_mode() support function.
- *
- * 2002/10/26 - Laurent Deniel <laurent.deniel at free.fr>
- *     - allow to register multicast addresses only on active slave
- *       (useful in active-backup mode)
- *     - add multicast module parameter
- *     - fix deletion of multicast groups after unloading module
- *
- * 2002/11/06 - Kameshwara Rayaprolu <kameshwara.rao * wipro_com>
- *     - Changes to prevent panic from closing the device twice; if we close
- *       the device in bond_release, we must set the original_flags to down
- *       so it won't be closed again by the network layer.
- *
- * 2002/11/07 - Tony Cureington <tony.cureington * hp_com>
- *     - Fix arp_target_hw_addr memory leak
- *     - Created activebackup_arp_monitor function to handle arp monitoring
- *       in active backup mode - the bond_arp_monitor had several problems...
- *       such as allowing slaves to tx arps sequentially without any delay
- *       for a response
- *     - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
- *       this function to just handle arp monitoring in load-balancing mode;
- *       it is a lot more compact now
- *     - Changes to ensure one and only one slave transmits in active-backup
- *       mode
- *     - Robustesize parameters; warn users about bad combinations of
- *       parameters; also if miimon is specified and a network driver does
- *       not support MII or ETHTOOL, inform the user of this
- *     - Changes to support link_failure_count when in arp monitoring mode
- *     - Fix up/down delay reported in /proc
- *     - Added version; log version; make version available from "modinfo -d"
- *     - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH)
- *	 failed, the ETHTOOL ioctl never got a chance
- *
- * 2002/11/16 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix multicast handling in activebackup_arp_monitor
- *     - remove one unnecessary and confusing curr_active_slave == slave test
- *	 in activebackup_arp_monitor
- *
- *  2002/11/17 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix bond_slave_info_query when slave_id = num_slaves
- *
- *  2002/11/19 - Janice Girouard <girouard at us dot ibm dot com>
- *     - correct ifr_data reference.  Update ifr_data reference
- *       to mii_ioctl_data struct values to avoid confusion.
- *
- *  2002/11/22 - Bert Barbe <bert.barbe at oracle dot com>
- *      - Add support for multiple arp_ip_target
- *
- *  2002/12/13 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Changed to allow text strings for mode and multicast, e.g.,
- *	  insmod bonding mode=active-backup.  The numbers still work.
- *	  One change: an invalid choice will cause module load failure,
- *	  rather than the previous behavior of just picking one.
- *	- Minor cleanups; got rid of dup ctype stuff, atoi function
- *
- * 2003/02/07 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Added use_carrier module parameter that causes miimon to
- *	  use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
- *	- Minor cleanups; consolidated ioctl calls to one function.
- *
- * 2003/02/07 - Tony Cureington <tony.cureington * hp_com>
- *	- Fix bond_mii_monitor() logic error that could result in
- *	  bonding round-robin mode ignoring links after failover/recovery
- *
- * 2003/03/17 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
- *	  Shmulik dot Hen at intel.com.
- *	- Based on discussion on mailing list, changed use of
- *	  update_slave_cnt(), created wrapper functions for adding/removing
- *	  slaves, changed bond_xmit_xor() to check slave_cnt instead of
- *	  checking slave and slave->dev (which only worked by accident).
- *	- Misc code cleanup: get arp_send() prototype from header file,
- *	  add max_bonds to bonding.txt.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Make sure only bond_attach_slave() and bond_detach_slave() can
- *	  manipulate the slave list, including slave_cnt, even when in
- *	  bond_release_all().
- *	- Fixed hang in bond_release() with traffic running:
- *	  netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed hang in bond_enslave() with traffic running:
- *	  netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
- *	- Added support for getting slave's speed and duplex via ethtool.
- *	  Needed for 802.3ad and other future modes.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Enable support of modes that need to use the unique mac address of
- *	  each slave.
- *	  * bond_enslave(): Moved setting the slave's mac address, and
- *	    openning it, from the application to the driver. This breaks
- *	    backward comaptibility with old versions of ifenslave that open
- *	     the slave before enalsving it !!!.
- *	  * bond_release(): The driver also takes care of closing the slave
- *	    and restoring its original mac address.
- *	- Removed the code that restores all base driver's flags.
- *	  Flags are automatically restored once all undo stages are done
- *	  properly.
- *	- Block possibility of enslaving before the master is up. This
- *	  prevents putting the system in an unstable state.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *		Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
- *	- Added ABI version control to restore compatibility between
- *	  new/old ifenslave and new/old bonding.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed bug in bond_release_all(): save old value of curr_active_slave
- *	  before setting it to NULL.
- *	- Changed driver versioning scheme to include version number instead
- *	  of release date (that is already in another field). There are 3
- *	  fields X.Y.Z where:
- *		X - Major version - big behavior changes
- *		Y - Minor version - addition of features
- *		Z - Extra version - minor changes and bug fixes
- *	  The current version is 1.0.0 as a base line.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *	- Code beautification and style changes (mainly in comments).
- *	  new version - 1.0.1
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Based on discussion on mailing list, changed locking scheme
- *	  to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *	  of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *	  hidden bugs and solves system hangs that occurred due to the fact
- *	  that holding lock_irqsave doesn't prevent softirqs from running.
- *	  This also increases total throughput since interrupts are not
- *	  blocked on each transmitted packets or monitor timeout.
- *	  new version - 2.0.0
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for Transmit load balancing mode.
- *	- Concentrate all assignments of curr_active_slave to a single point
- *	  so specific modes can take actions when the primary adapter is
- *	  changed.
- *	- Take the updelay parameter into consideration during bond_enslave
- *	  since some adapters loose their link during setting the device.
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *	  new version - 2.1.0
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *	- Added support for Adaptive load balancing mode which is
- *	  equivalent to Transmit load balancing + Receive load balancing.
- *	  new version - 2.2.0
- *
- * 2003/05/15 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Applied fix to activebackup_arp_monitor posted to bonding-devel
- *	  by Tony Cureington <tony.cureington * hp_com>.  Fixes ARP
- *	  monitor endless failover bug.  Version to 2.2.10
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed bug in ABI version control - Don't commit to a specific
- *	  ABI version if receiving unsupported ioctl commands.
- *
- * 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Fix ifenslave -c causing bond to loose existing routes;
- *	  added bond_set_mac_address() that doesn't require the
- *	  bond to be down.
- *	- In conjunction with fix for ifenslave -c, in
- *	  bond_change_active(), changing to the already active slave
- *	  is no longer an error (it successfully does nothing).
- *
- * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
- * 	- Fixed bond_change_active() for ALB/TLB modes.
- *	  Version to 2.2.14.
- *
- * 2003/07/29 - Amir Noam <amir.noam at intel dot com>
- * 	- Fixed ARP monitoring bug.
- *	  Version to 2.2.15.
- *
- * 2003/07/31 - Willy Tarreau <willy at ods dot org>
- * 	- Fixed kernel panic when using ARP monitoring without
- *	  setting bond's IP address.
- *	  Version to 2.2.16.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- * 	- Back port from 2.6: use alloc_netdev(); fix /proc handling;
- *	  made stats a part of bond struct so no need to allocate
- *	  and free it separately; use standard list operations instead
- *	  of pre-allocated array of bonds.
- *	  Version to 2.3.0.
- *
- * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
- *	       Amir Noam <amir.noam at intel dot com> and
- *	       Shmulik Hen <shmulik.hen at intel dot com>
- *	- Propagating master's settings: Distinguish between modes that
- *	  use a primary slave from those that don't, and propagate settings
- *	  accordingly; Consolidate change_active opeartions and add
- *	  reselect_active and find_best opeartions; Decouple promiscuous
- *	  handling from the multicast mode setting; Add support for changing
- *	  HW address and MTU with proper unwind; Consolidate procfs code,
- *	  add CHANGENAME handler; Enhance netdev notification handling.
- *	  Version to 2.4.0.
- *
- * 2003/09/15 - Stephen Hemminger <shemminger at osdl dot org>,
- *	       Amir Noam <amir.noam at intel dot com>
- *	- Convert /proc to seq_file interface.
- *	  Change /proc/net/bondX/info to /proc/net/bonding/bondX.
- *	  Set version to 2.4.1.
- *
- * 2003/11/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fix /proc creation/destruction.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Massive cleanup - Set version to 2.5.0
- *	  Code changes:
- *	  o Consolidate format of prints and debug prints.
- *	  o Remove bonding_t/slave_t typedefs and consolidate all casts.
- *	  o Remove dead code and unnecessary checks.
- *	  o Consolidate starting/stopping timers.
- *	  o Consolidate handling of primary module param throughout the code.
- *	  o Removed multicast module param support - all settings are done
- *	    according to mode.
- *	  o Slave list iteration - bond is no longer part of the list,
- *	    added cyclic list iteration macros.
- *	  o Consolidate error handling in all xmit functions.
- *	  Style changes:
- *	  o Consolidate function naming and declarations.
- *	  o Consolidate function params and local variables names.
- *	  o Consolidate return values.
- *	  o Consolidate curly braces.
- *	  o Consolidate conditionals format.
- *	  o Change struct member names and types.
- *	  o Chomp trailing spaces, remove empty lines, fix indentations.
- *	  o Re-organize code according to context.
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed: Cannot remove and re-enslave the original active slave.
- *	- Fixed: Releasing the original active slave causes mac address
- *		 duplication.
- *	- Add support for slaves that use ethtool_ops.
- *	  Set version to 2.5.3.
- *
- * 2004/01/05 - Amir Noam <amir.noam at intel dot com>
- *	- Save bonding parameters per bond instead of using the global values.
- *	  Set version to 2.5.4.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Enhance VLAN support:
- *	  * Add support for VLAN hardware acceleration capable slaves.
- *	  * Add capability to tag self generated packets in ALB/TLB modes.
- *	  Set version to 2.6.0.
- * 2004/10/29 - Mitch Williams <mitch.a.williams at intel dot com>
- *      - Fixed bug when unloading module while using 802.3ad.  If
- *        spinlock debugging is turned on, this causes a stack dump.
- *        Solution is to move call to dev_remove_pack outside of the
- *        spinlock.
- *        Set version to 2.6.1.
- * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com>
- * 	- Support for generating gratuitous ARPs in active-backup mode.
- * 	  Includes support for VLAN tagging all bonding-generated ARPs
- * 	  as needed.  Set version to 2.6.2.
- * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov>
- *	- alternate hashing policy support for mode 2
- *	  * Added kernel parameter "xmit_hash_policy" to allow the selection
- *	    of different hashing policies for mode 2.  The original mode 2
- *	    policy is the default, now found in xmit_hash_policy_layer2().
- *	  * Added xmit_hash_policy_layer34()
- *	- Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
- *	  Set version to 2.6.3.
- * 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com>
- *	- Removed backwards compatibility for old ifenslaves.  Version 2.6.4.
  */
 
 //#define BONDING_DEBUG 1
@@ -557,6 +97,7 @@
 static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
+struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -565,17 +106,24 @@
 module_param(updelay, int, 0);
 MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
 module_param(downdelay, int, 0);
-MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
+MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
+			    "in milliseconds");
 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_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
+			      "0 for off, 1 for on (default)");
 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_DESC(mode, "Mode of operation : 0 for balance-rr, "
+		       "1 for active-backup, 2 for balance-xor, "
+		       "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
+		       "6 for balance-alb");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
+			    "(slow/fast)");
 module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
+				   ", 1 for layer 3+4");
 module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
 module_param_array(arp_ip_target, charp, NULL, 0);
@@ -586,30 +134,27 @@
 static const char *version =
 	DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-static LIST_HEAD(bond_dev_list);
+LIST_HEAD(bond_dev_list);
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *bond_proc_dir = NULL;
 #endif
 
+extern struct rw_semaphore bonding_rwsem;
 static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
 static int arp_ip_count	= 0;
 static int bond_mode	= BOND_MODE_ROUNDROBIN;
 static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
 static int lacp_fast	= 0;
 
-struct bond_parm_tbl {
-	char *modename;
-	int mode;
-};
 
-static struct bond_parm_tbl bond_lacp_tbl[] = {
+struct bond_parm_tbl bond_lacp_tbl[] = {
 {	"slow",		AD_LACP_SLOW},
 {	"fast",		AD_LACP_FAST},
 {	NULL,		-1},
 };
 
-static struct bond_parm_tbl bond_mode_tbl[] = {
+struct bond_parm_tbl bond_mode_tbl[] = {
 {	"balance-rr",		BOND_MODE_ROUNDROBIN},
 {	"active-backup",	BOND_MODE_ACTIVEBACKUP},
 {	"balance-xor",		BOND_MODE_XOR},
@@ -620,7 +165,7 @@
 {	NULL,			-1},
 };
 
-static struct bond_parm_tbl xmit_hashtype_tbl[] = {
+struct bond_parm_tbl xmit_hashtype_tbl[] = {
 {	"layer2",		BOND_XMIT_POLICY_LAYER2},
 {	"layer3+4",		BOND_XMIT_POLICY_LAYER34},
 {	NULL,			-1},
@@ -628,12 +173,11 @@
 
 /*-------------------------- Forward declarations ---------------------------*/
 
-static inline void bond_set_mode_ops(struct bonding *bond, int mode);
 static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
-static const char *bond_mode_name(int mode)
+const char *bond_mode_name(int mode)
 {
 	switch (mode) {
 	case BOND_MODE_ROUNDROBIN :
@@ -910,7 +454,7 @@
 	res = bond_add_vlan(bond, vid);
 	if (res) {
 		printk(KERN_ERR DRV_NAME
-		       ": %s: Failed to add vlan id %d\n",
+		       ": %s: Error: Failed to add vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -944,7 +488,7 @@
 	res = bond_del_vlan(bond, vid);
 	if (res) {
 		printk(KERN_ERR DRV_NAME
-		       ": %s: Failed to remove vlan id %d\n",
+		       ": %s: Error: Failed to remove vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -1449,7 +993,7 @@
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 {
 	struct slave *old_active = bond->curr_active_slave;
 
@@ -1523,7 +1067,7 @@
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_select_active_slave(struct bonding *bond)
+void bond_select_active_slave(struct bonding *bond)
 {
 	struct slave *best_slave;
 
@@ -1591,7 +1135,7 @@
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	dprintk("bond_dev=%p\n", bond_dev);
 	dprintk("slave_dev=%p\n", slave_dev);
@@ -1631,7 +1175,7 @@
 }
 
 /* enslave device <slave> to bond device <master> */
-static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *new_slave = NULL;
@@ -1644,8 +1188,8 @@
 	if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
 		slave_dev->do_ioctl == NULL) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning : no link monitoring support for %s\n",
-		       slave_dev->name);
+		       ": %s: Warning: no link monitoring support for %s\n",
+		       bond_dev->name, slave_dev->name);
 	}
 
 	/* bond must be initialized by bond_open() before enslaving */
@@ -1666,17 +1210,17 @@
 		dprintk("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
 		if (!list_empty(&bond->vlan_list)) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: cannot enslave VLAN "
+			       ": %s: Error: cannot enslave VLAN "
 			       "challenged slave %s on VLAN enabled "
-			       "bond %s\n", slave_dev->name,
+			       "bond %s\n", bond_dev->name, slave_dev->name,
 			       bond_dev->name);
 			return -EPERM;
 		} else {
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: enslaved VLAN challenged "
+			       ": %s: Warning: enslaved VLAN challenged "
 			       "slave %s. Adding VLANs will be blocked as "
 			       "long as %s is part of bond %s\n",
-			       slave_dev->name, slave_dev->name,
+			       bond_dev->name, slave_dev->name, slave_dev->name,
 			       bond_dev->name);
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		}
@@ -1706,12 +1250,11 @@
 
 	if (slave_dev->set_mac_address == NULL) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: The slave device you specified does "
-		       "not support setting the MAC address.\n");
-		printk(KERN_ERR
-		       "Your kernel likely does not support slave devices.\n");
-
-		res = -EOPNOTSUPP;
+			": %s: Error: The slave device you specified does "
+			"not support setting the MAC address. "
+			"Your kernel likely does not support slave "
+			"devices.\n", bond_dev->name);
+  		res = -EOPNOTSUPP;
 		goto err_undo_flags;
 	}
 
@@ -1827,21 +1370,21 @@
 			 * the messages for netif_carrier.
 			 */
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: MII and ETHTOOL support not "
+			       ": %s: Warning: MII and ETHTOOL support not "
 			       "available for interface %s, and "
 			       "arp_interval/arp_ip_target module parameters "
 			       "not specified, thus bonding will not detect "
 			       "link failures! see bonding.txt for details.\n",
-			       slave_dev->name);
+			       bond_dev->name, slave_dev->name);
 		} else if (link_reporting == -1) {
 			/* unable get link status using mii/ethtool */
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: can't get link status from "
+			       ": %s: Warning: can't get link status from "
 			       "interface %s; the network driver associated "
 			       "with this interface does not support MII or "
 			       "ETHTOOL link status reporting, thus miimon "
 			       "has no effect on this interface.\n",
-			       slave_dev->name);
+			       bond_dev->name, slave_dev->name);
 		}
 	}
 
@@ -1868,15 +1411,15 @@
 	if (bond_update_speed_duplex(new_slave) &&
 	    (new_slave->link != BOND_LINK_DOWN)) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: failed to get speed and duplex from %s, "
+		       ": %s: Warning: failed to get speed and duplex from %s, "
 		       "assumed to be 100Mb/sec and Full.\n",
-		       new_slave->dev->name);
+		       bond_dev->name, new_slave->dev->name);
 
 		if (bond->params.mode == BOND_MODE_8023AD) {
-			printk(KERN_WARNING
-			       "Operation of 802.3ad mode requires ETHTOOL "
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
 			       "support in base driver for proper aggregator "
-			       "selection.\n");
+			       "selection.\n", bond_dev->name);
 		}
 	}
 
@@ -1958,6 +1501,10 @@
 
 	write_unlock_bh(&bond->lock);
 
+	res = bond_create_slave_symlinks(bond_dev, slave_dev);
+	if (res)
+		goto err_unset_master;
+
 	printk(KERN_INFO DRV_NAME
 	       ": %s: enslaving %s as a%s interface with a%s link.\n",
 	       bond_dev->name, slave_dev->name,
@@ -1999,7 +1546,7 @@
  *   for Bonded connections:
  *     The first up interface should be left on and all others downed.
  */
-static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2010,7 +1557,7 @@
 	if (!(slave_dev->flags & IFF_SLAVE) ||
 	    (slave_dev->master != bond_dev)) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: cannot release %s.\n",
+		       ": %s: Error: cannot release %s.\n",
 		       bond_dev->name, slave_dev->name);
 		return -EINVAL;
 	}
@@ -2031,11 +1578,12 @@
 				 ETH_ALEN);
 	if (!mac_addr_differ && (bond->slave_cnt > 1)) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: the permanent HWaddr of %s "
+		       ": %s: Warning: the permanent HWaddr of %s "
 		       "- %02X:%02X:%02X:%02X:%02X:%02X - is "
 		       "still in use by %s. Set the HWaddr of "
 		       "%s to a different address to avoid "
 		       "conflicts.\n",
+		       bond_dev->name,
 		       slave_dev->name,
 		       slave->perm_hwaddr[0],
 		       slave->perm_hwaddr[1],
@@ -2111,24 +1659,28 @@
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		} else {
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: clearing HW address of %s while it "
+			       ": %s: Warning: clearing HW address of %s while it "
 			       "still has VLANs.\n",
-			       bond_dev->name);
+			       bond_dev->name, bond_dev->name);
 			printk(KERN_WARNING DRV_NAME
-			       ": When re-adding slaves, make sure the bond's "
-			       "HW address matches its VLANs'.\n");
+			       ": %s: When re-adding slaves, make sure the bond's "
+			       "HW address matches its VLANs'.\n",
+			       bond_dev->name);
 		}
 	} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
 		   !bond_has_challenged_slaves(bond)) {
 		printk(KERN_INFO DRV_NAME
-		       ": last VLAN challenged slave %s "
+		       ": %s: last VLAN challenged slave %s "
 		       "left bond %s. VLAN blocking is removed\n",
-		       slave_dev->name, bond_dev->name);
+		       bond_dev->name, slave_dev->name, bond_dev->name);
 		bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
 	}
 
 	write_unlock_bh(&bond->lock);
 
+	/* must do this from outside any spinlocks */
+	bond_destroy_slave_symlinks(bond_dev, slave_dev);
+
 	bond_del_vlans_from_slave(bond, slave_dev);
 
 	/* If the mode USES_PRIMARY, then we should only remove its
@@ -2220,6 +1772,7 @@
 		 */
 		write_unlock_bh(&bond->lock);
 
+		bond_destroy_slave_symlinks(bond_dev, slave_dev);
 		bond_del_vlans_from_slave(bond, slave_dev);
 
 		/* If the mode USES_PRIMARY, then we should only remove its
@@ -2274,12 +1827,13 @@
 		bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 	} else {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: clearing HW address of %s while it "
+		       ": %s: Warning: clearing HW address of %s while it "
 		       "still has VLANs.\n",
-		       bond_dev->name);
+		       bond_dev->name, bond_dev->name);
 		printk(KERN_WARNING DRV_NAME
-		       ": When re-adding slaves, make sure the bond's "
-		       "HW address matches its VLANs'.\n");
+		       ": %s: When re-adding slaves, make sure the bond's "
+		       "HW address matches its VLANs'.\n",
+		       bond_dev->name);
 	}
 
 	printk(KERN_INFO DRV_NAME
@@ -2397,7 +1951,7 @@
 /*-------------------------------- Monitoring -------------------------------*/
 
 /* this function is called regularly to monitor each slave's link. */
-static void bond_mii_monitor(struct net_device *bond_dev)
+void bond_mii_monitor(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2596,8 +2150,11 @@
 			break;
 		default:
 			/* Should not happen */
-			printk(KERN_ERR "bonding: Error: %s  Illegal value (link=%d)\n",
-			       slave->dev->name, slave->link);
+			printk(KERN_ERR DRV_NAME
+			       ": %s: Error: %s Illegal value (link=%d)\n",
+			       bond_dev->name,
+			       slave->dev->name,
+			       slave->link);
 			goto out;
 		} /* end of switch (slave->link) */
 
@@ -2721,7 +2278,9 @@
 	struct flowi fl;
 	struct rtable *rt;
 
-	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
+	for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		if (!targets[i])
+			continue;
 		dprintk("basa: target %x\n", targets[i]);
 		if (list_empty(&bond->vlan_list)) {
 			dprintk("basa: empty vlan: arp_send\n");
@@ -2825,7 +2384,7 @@
  * arp is transmitted to generate traffic. see activebackup_arp_monitor for
  * arp monitoring in active backup mode.
  */
-static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2963,7 +2522,7 @@
  * may have received.
  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
  */
-static void bond_activebackup_arp_mon(struct net_device *bond_dev)
+void bond_activebackup_arp_mon(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave;
@@ -3249,6 +2808,8 @@
 {
 	struct bonding *bond = seq->private;
 	struct slave *curr;
+	int i;
+	u32 target;
 
 	read_lock(&bond->curr_slave_lock);
 	curr = bond->curr_active_slave;
@@ -3257,10 +2818,17 @@
 	seq_printf(seq, "Bonding Mode: %s\n",
 		   bond_mode_name(bond->params.mode));
 
+	if (bond->params.mode == BOND_MODE_XOR ||
+		bond->params.mode == BOND_MODE_8023AD) {
+		seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
+			xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+			bond->params.xmit_policy);
+	}
+
 	if (USES_PRIMARY(bond->params.mode)) {
 		seq_printf(seq, "Primary Slave: %s\n",
-			   (bond->params.primary[0]) ?
-			   	bond->params.primary : "None");
+			   (bond->primary_slave) ?
+			   bond->primary_slave->dev->name : "None");
 
 		seq_printf(seq, "Currently Active Slave: %s\n",
 			   (curr) ? curr->dev->name : "None");
@@ -3273,6 +2841,27 @@
 	seq_printf(seq, "Down Delay (ms): %d\n",
 		   bond->params.downdelay * bond->params.miimon);
 
+
+	/* ARP information */
+	if(bond->params.arp_interval > 0) {
+		int printed=0;
+		seq_printf(seq, "ARP Polling Interval (ms): %d\n",
+				bond->params.arp_interval);
+
+		seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
+
+		for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
+			if (!bond->params.arp_targets[i])
+				continue;
+			if (printed)
+				seq_printf(seq, ",");
+			target = ntohl(bond->params.arp_targets[i]);
+			seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
+			printed = 1;
+		}
+		seq_printf(seq, "\n");
+	}
+
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
 
@@ -3478,7 +3067,10 @@
 	bond_remove_proc_entry(bond);
 	bond_create_proc_entry(bond);
 #endif
-
+	down_write(&(bonding_rwsem));
+        bond_destroy_sysfs_entry(bond);
+        bond_create_sysfs_entry(bond);
+	up_write(&(bonding_rwsem));
 	return NOTIFY_DONE;
 }
 
@@ -3955,6 +3547,7 @@
 		return -EPERM;
 	}
 
+	down_write(&(bonding_rwsem));
 	slave_dev = dev_get_by_name(ifr->ifr_slave);
 
 	dprintk("slave_dev=%p: \n", slave_dev);
@@ -3987,6 +3580,7 @@
 		dev_put(slave_dev);
 	}
 
+	up_write(&(bonding_rwsem));
 	return res;
 }
 
@@ -4071,6 +3665,7 @@
 	bond_for_each_slave(bond, slave, i) {
 		dprintk("s %p s->p %p c_m %p\n", slave,
 			slave->prev, slave->dev->change_mtu);
+
 		res = dev_set_mtu(slave->dev, new_mtu);
 
 		if (res) {
@@ -4397,8 +3992,9 @@
 				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 				if (!skb2) {
 					printk(KERN_ERR DRV_NAME
-					       ": Error: bond_xmit_broadcast(): "
-					       "skb_clone() failed\n");
+					       ": %s: Error: bond_xmit_broadcast(): "
+					       "skb_clone() failed\n",
+					       bond_dev->name);
 					continue;
 				}
 
@@ -4431,7 +4027,7 @@
 /*
  * set bond mode specific net device operations
  */
-static inline void bond_set_mode_ops(struct bonding *bond, int mode)
+void bond_set_mode_ops(struct bonding *bond, int mode)
 {
 	struct net_device *bond_dev = bond->dev;
 
@@ -4467,7 +4063,8 @@
 	default:
 		/* Should never happen, mode already checked */
 		printk(KERN_ERR DRV_NAME
-		       ": Error: Unknown bonding mode %d\n",
+		       ": %s: Error: Unknown bonding mode %d\n",
+		       bond_dev->name,
 		       mode);
 		break;
 	}
@@ -4491,7 +4088,7 @@
  * Does not allocate but creates a /proc entry.
  * Allowed to fail.
  */
-static int __init bond_init(struct net_device *bond_dev, struct bond_params *params)
+static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 {
 	struct bonding *bond = bond_dev->priv;
 
@@ -4565,7 +4162,7 @@
 /* De-initialize device specific data.
  * Caller must hold rtnl_lock.
  */
-static inline void bond_deinit(struct net_device *bond_dev)
+void bond_deinit(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 
@@ -4601,7 +4198,7 @@
  * Convert string input module parms.  Accept either the
  * number of the mode or its string name.
  */
-static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
 {
 	int i;
 
@@ -4670,7 +4267,7 @@
 	if (max_bonds < 1 || max_bonds > INT_MAX) {
 		printk(KERN_WARNING DRV_NAME
 		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
-		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
 		       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
 		max_bonds = BOND_DEFAULT_MAX_BONDS;
 	}
@@ -4881,81 +4478,96 @@
 	return 0;
 }
 
+/* Create a new bond based on the specified name and bonding parameters.
+ * Caller must NOT hold rtnl_lock; we need to release it here before we
+ * set up our sysfs entries.
+ */
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
+{
+	struct net_device *bond_dev;
+	int res;
+
+	rtnl_lock();
+	bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
+	if (!bond_dev) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: eek! can't alloc netdev!\n",
+		       name);
+		res = -ENOMEM;
+		goto out_rtnl;
+	}
+
+	/* bond_init() must be called after dev_alloc_name() (for the
+	 * /proc files), but before register_netdevice(), because we
+	 * need to set function pointers.
+	 */
+
+	res = bond_init(bond_dev, params);
+	if (res < 0) {
+		goto out_netdev;
+	}
+
+	SET_MODULE_OWNER(bond_dev);
+
+	res = register_netdevice(bond_dev);
+	if (res < 0) {
+		goto out_bond;
+	}
+	if (newbond)
+		*newbond = bond_dev->priv;
+
+	rtnl_unlock(); /* allows sysfs registration of net device */
+	res = bond_create_sysfs_entry(bond_dev->priv);
+	goto done;
+out_bond:
+	bond_deinit(bond_dev);
+out_netdev:
+	free_netdev(bond_dev);
+out_rtnl:
+	rtnl_unlock();
+done:
+	return res;
+}
+
 static int __init bonding_init(void)
 {
-	struct bond_params params;
 	int i;
 	int res;
+	char new_bond_name[8];  /* Enough room for 999 bonds at init. */
 
 	printk(KERN_INFO "%s", version);
 
-	res = bond_check_params(&params);
+	res = bond_check_params(&bonding_defaults);
 	if (res) {
-		return res;
+		goto out;
 	}
 
-	rtnl_lock();
-
 #ifdef CONFIG_PROC_FS
 	bond_create_proc_dir();
 #endif
-
 	for (i = 0; i < max_bonds; i++) {
-		struct net_device *bond_dev;
-
-		bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
-		if (!bond_dev) {
-			res = -ENOMEM;
-			goto out_err;
-		}
-
-		res = dev_alloc_name(bond_dev, "bond%d");
-		if (res < 0) {
-			free_netdev(bond_dev);
-			goto out_err;
-		}
-
-		/* bond_init() must be called after dev_alloc_name() (for the
-		 * /proc files), but before register_netdevice(), because we
-		 * need to set function pointers.
-		 */
-		res = bond_init(bond_dev, &params);
-		if (res < 0) {
-			free_netdev(bond_dev);
-			goto out_err;
-		}
-
-		SET_MODULE_OWNER(bond_dev);
-
-		res = register_netdevice(bond_dev);
-		if (res < 0) {
-			bond_deinit(bond_dev);
-			free_netdev(bond_dev);
-			goto out_err;
-		}
+		sprintf(new_bond_name, "bond%d",i);
+		res = bond_create(new_bond_name,&bonding_defaults, NULL);
+		if (res)
+			goto err;
 	}
 
-	rtnl_unlock();
+	res = bond_create_sysfs();
+	if (res)
+		goto err;
+
 	register_netdevice_notifier(&bond_netdev_notifier);
 	register_inetaddr_notifier(&bond_inetaddr_notifier);
 
-	return 0;
-
-out_err:
-	/*
-	 * rtnl_unlock() will run netdev_run_todo(), putting the
-	 * thus-far-registered bonding devices into a state which
-	 * unregigister_netdevice() will accept
-	 */
-	rtnl_unlock();
+	goto out;
+err:
 	rtnl_lock();
-
-	/* free and unregister all bonds that were successfully added */
 	bond_free_all();
-
+	bond_destroy_sysfs();
 	rtnl_unlock();
-
+out:
 	return res;
+
 }
 
 static void __exit bonding_exit(void)
@@ -4965,6 +4577,7 @@
 
 	rtnl_lock();
 	bond_free_all();
+	bond_destroy_sysfs();
 	rtnl_unlock();
 }
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
new file mode 100644
index 0000000..32d13da
--- /dev/null
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -0,0 +1,1358 @@
+
+/*
+ * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You 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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
+#include <linux/rtnetlink.h>
+
+/* #define BONDING_DEBUG 1 */
+#include "bonding.h"
+#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_bond(cd)	((struct bonding *)(to_net_dev(cd)->priv))
+
+/*---------------------------- Declarations -------------------------------*/
+
+
+extern struct list_head bond_dev_list;
+extern struct bond_params bonding_defaults;
+extern struct bond_parm_tbl bond_mode_tbl[];
+extern struct bond_parm_tbl bond_lacp_tbl[];
+extern struct bond_parm_tbl xmit_hashtype_tbl[];
+
+static int expected_refcount = -1;
+static struct class *netdev_class;
+/*--------------------------- Data Structures -----------------------------*/
+
+/* Bonding sysfs lock.  Why can't we just use the subsytem lock?
+ * Because kobject_register tries to acquire the subsystem lock.  If
+ * we already hold the lock (which we would if the user was creating
+ * a new bond through the sysfs interface), we deadlock.
+ * This lock is only needed when deleting a bond - we need to make sure
+ * that we don't collide with an ongoing ioctl.
+ */
+
+struct rw_semaphore bonding_rwsem;
+
+
+
+
+/*------------------------------ Functions --------------------------------*/
+
+/*
+ * "show" function for the bond_masters attribute.
+ * The class parameter is ignored.
+ */
+static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
+{
+	int res = 0;
+	struct bonding *bond;
+
+	down_read(&(bonding_rwsem));
+
+	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+		if (res > (PAGE_SIZE - IFNAMSIZ)) {
+			/* not enough space for another interface name */
+			if ((PAGE_SIZE - res) > 10)
+				res = PAGE_SIZE - 10;
+			res += sprintf(buffer + res, "++more++");
+			break;
+		}
+		res += sprintf(buffer + res, "%s ",
+			       bond->dev->name);
+	}
+	res += sprintf(buffer + res, "\n");
+	res++;
+	up_read(&(bonding_rwsem));
+	return res;
+}
+
+/*
+ * "store" function for the bond_masters attribute.  This is what
+ * creates and deletes entire bonds.
+ *
+ * The class parameter is ignored.
+ *
+ */
+
+static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+{
+	char command[IFNAMSIZ + 1] = {0, };
+	char *ifname;
+	int res = count;
+	struct bonding *bond;
+	struct bonding *nxt;
+
+	down_write(&(bonding_rwsem));
+	sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+	ifname = command + 1;
+	if ((strlen(command) <= 1) ||
+	    !dev_valid_name(ifname))
+		goto err_no_cmd;
+
+	if (command[0] == '+') {
+
+		/* Check to see if the bond already exists. */
+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+			if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+				printk(KERN_ERR DRV_NAME
+					": cannot add bond %s; it already exists\n",
+					ifname);
+				res = -EPERM;
+				goto out;
+			}
+
+		printk(KERN_INFO DRV_NAME
+			": %s is being created...\n", ifname);
+		if (bond_create(ifname, &bonding_defaults, &bond)) {
+			printk(KERN_INFO DRV_NAME
+			": %s interface already exists. Bond creation failed.\n",
+			ifname);
+			res = -EPERM;
+		}
+		goto out;
+	}
+
+	if (command[0] == '-') {
+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+			if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+				rtnl_lock();
+				/* check the ref count on the bond's kobject.
+				 * If it's > expected, then there's a file open,
+				 * and we have to fail.
+				 */
+				if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
+							> expected_refcount){
+					rtnl_unlock();
+					printk(KERN_INFO DRV_NAME
+						": Unable remove bond %s due to open references.\n",
+						ifname);
+					res = -EPERM;
+					goto out;
+				}
+				printk(KERN_INFO DRV_NAME
+					": %s is being deleted...\n",
+					bond->dev->name);
+				unregister_netdevice(bond->dev);
+				bond_deinit(bond->dev);
+		        	bond_destroy_sysfs_entry(bond);
+				rtnl_unlock();
+				goto out;
+			}
+
+		printk(KERN_ERR DRV_NAME
+			": unable to delete non-existent bond %s\n", ifname);
+		res = -ENODEV;
+		goto out;
+	}
+
+err_no_cmd:
+	printk(KERN_ERR DRV_NAME
+		": no command found in bonding_masters. Use +ifname or -ifname.\n");
+	res = -EPERM;
+
+	/* Always return either count or an error.  If you return 0, you'll
+	 * get called forever, which is bad.
+	 */
+out:
+	up_write(&(bonding_rwsem));
+	return res;
+}
+/* class attribute for bond_masters file.  This ends up in /sys/class/net */
+static CLASS_ATTR(bonding_masters,  S_IWUSR | S_IRUGO,
+		  bonding_show_bonds, bonding_store_bonds);
+
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+	char linkname[IFNAMSIZ+7];
+	int ret = 0;
+
+	/* first, create a link from the slave back to the master */
+	ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
+				"master");
+	if (ret)
+		return ret;
+	/* next, create a link from the master to the slave */
+	sprintf(linkname,"slave_%s",slave->name);
+	ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
+				linkname);
+	return ret;
+
+}
+
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+	char linkname[IFNAMSIZ+7];
+
+	sysfs_remove_link(&(slave->class_dev.kobj), "master");
+	sprintf(linkname,"slave_%s",slave->name);
+	sysfs_remove_link(&(master->class_dev.kobj), linkname);
+}
+
+
+/*
+ * Show the slaves in the current bond.
+ */
+static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
+{
+	struct slave *slave;
+	int i, res = 0;
+	struct bonding *bond = to_bond(cd);
+
+	read_lock_bh(&bond->lock);
+	bond_for_each_slave(bond, slave, i) {
+		if (res > (PAGE_SIZE - IFNAMSIZ)) {
+			/* not enough space for another interface name */
+			if ((PAGE_SIZE - res) > 10)
+				res = PAGE_SIZE - 10;
+			res += sprintf(buf + res, "++more++");
+			break;
+		}
+		res += sprintf(buf + res, "%s ", slave->dev->name);
+	}
+	read_unlock_bh(&bond->lock);
+	res += sprintf(buf + res, "\n");
+	res++;
+	return res;
+}
+
+/*
+ * Set the slaves in the current bond.  The bond interface must be
+ * up for this to succeed.
+ * This function is largely the same flow as bonding_update_bonds().
+ */
+static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
+{
+	char command[IFNAMSIZ + 1] = { 0, };
+	char *ifname;
+	int i, res, found, ret = count;
+	struct slave *slave;
+	struct net_device *dev = 0;
+	struct bonding *bond = to_bond(cd);
+
+	/* Quick sanity check -- is the bond interface up? */
+	if (!(bond->dev->flags & IFF_UP)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update slaves because interface is down.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	/* Note:  We can't hold bond->lock here, as bond_create grabs it. */
+
+	sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+	ifname = command + 1;
+	if ((strlen(command) <= 1) ||
+	    !dev_valid_name(ifname))
+		goto err_no_cmd;
+
+	if (command[0] == '+') {
+
+		/* Got a slave name in ifname.  Is it already in the list? */
+		found = 0;
+		read_lock_bh(&bond->lock);
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+				printk(KERN_ERR DRV_NAME
+				       ": %s: Interface %s is already enslaved!\n",
+				       bond->dev->name, ifname);
+				ret = -EPERM;
+				read_unlock_bh(&bond->lock);
+				goto out;
+			}
+
+		read_unlock_bh(&bond->lock);
+		printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
+		       bond->dev->name, ifname);
+		dev = dev_get_by_name(ifname);
+		if (!dev) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Interface %s does not exist!\n",
+			       bond->dev->name, ifname);
+			ret = -EPERM;
+			goto out;
+		}
+		else
+			dev_put(dev);
+
+		if (dev->flags & IFF_UP) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: Error: Unable to enslave %s "
+			       "because it is already up.\n",
+			       bond->dev->name, dev->name);
+			ret = -EPERM;
+			goto out;
+		}
+		/* If this is the first slave, then we need to set
+		   the master's hardware address to be the same as the
+		   slave's. */
+		if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
+			memcpy(bond->dev->dev_addr, dev->dev_addr,
+			       dev->addr_len);
+		}
+
+		/* Set the slave's MTU to match the bond */
+		if (dev->mtu != bond->dev->mtu) {
+			if (dev->change_mtu) {
+				res = dev->change_mtu(dev,
+						      bond->dev->mtu);
+				if (res) {
+					ret = res;
+					goto out;
+				}
+			} else {
+				dev->mtu = bond->dev->mtu;
+			}
+		}
+		rtnl_lock();
+		res = bond_enslave(bond->dev, dev);
+		rtnl_unlock();
+		if (res) {
+			ret = res;
+		}
+		goto out;
+	}
+
+	if (command[0] == '-') {
+		dev = NULL;
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+				dev = slave->dev;
+				break;
+			}
+		if (dev) {
+			printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
+				bond->dev->name, dev->name);
+			rtnl_lock();
+			res = bond_release(bond->dev, dev);
+			rtnl_unlock();
+			if (res) {
+				ret = res;
+				goto out;
+			}
+			/* set the slave MTU to the default */
+			if (dev->change_mtu) {
+				dev->change_mtu(dev, 1500);
+			} else {
+				dev->mtu = 1500;
+			}
+		}
+		else {
+			printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
+				ifname, bond->dev->name);
+			ret = -ENODEV;
+		}
+		goto out;
+	}
+
+err_no_cmd:
+	printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+	ret = -EPERM;
+
+out:
+	return ret;
+}
+
+static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+
+/*
+ * Show and set the bonding mode.  The bond interface must be down to
+ * change the mode.
+ */
+static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%s %d\n",
+			bond_mode_tbl[bond->params.mode].modename,
+			bond->params.mode) + 1;
+}
+
+static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       ": unable to update mode of %s because interface is up.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+	if (new_value < 0)  {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid mode value %.*s.\n",
+		       bond->dev->name,
+		       (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		bond->params.mode = new_value;
+		bond_set_mode_ops(bond, bond->params.mode);
+		printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
+			bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+
+/*
+ * Show and set the bonding transmit hash method.  The bond interface must be down to
+ * change the xmit hash policy.
+ */
+static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
+{
+	int count;
+	struct bonding *bond = to_bond(cd);
+
+	if ((bond->params.mode != BOND_MODE_XOR) &&
+	    (bond->params.mode != BOND_MODE_8023AD)) {
+		// Not Applicable
+		count = sprintf(buf, "NA\n") + 1;
+	} else {
+		count = sprintf(buf, "%s %d\n",
+			xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+			bond->params.xmit_policy) + 1;
+	}
+
+	return count;
+}
+
+static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       "%s: Interface is up. Unable to update xmit policy.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if ((bond->params.mode != BOND_MODE_XOR) &&
+	    (bond->params.mode != BOND_MODE_8023AD)) {
+		printk(KERN_ERR DRV_NAME
+		       "%s: Transmit hash policy is irrelevant in this mode.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+	if (new_value < 0)  {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
+		       bond->dev->name,
+		       (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		bond->params.xmit_policy = new_value;
+		bond_set_mode_ops(bond, bond->params.mode);
+		printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+			bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+
+/*
+ * Show and set the arp timer interval.  There are two tricky bits
+ * here.  First, if ARP monitoring is activated, then we must disable
+ * MII monitoring.  Second, if the ARP timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
+}
+
+static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no arp_interval value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
+		       bond->dev->name, new_value, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	printk(KERN_INFO DRV_NAME
+	       ": %s: Setting ARP monitoring interval to %d.\n",
+	       bond->dev->name, new_value);
+	bond->params.arp_interval = new_value;
+	if (bond->params.miimon) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: ARP monitoring cannot be used with MII monitoring. "
+		       "%s Disabling MII monitoring.\n",
+		       bond->dev->name, bond->dev->name);
+		bond->params.miimon = 0;
+		/* Kill MII timer, else it brings bond's link down */
+		if (bond->arp_timer.function) {
+			printk(KERN_INFO DRV_NAME
+			": %s: Kill MII timer, else it brings bond's link down...\n",
+		       bond->dev->name);
+			del_timer_sync(&bond->mii_timer);
+		}
+	}
+	if (!bond->params.arp_targets[0]) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: ARP monitoring has been set up, "
+		       "but no ARP targets have been specified.\n",
+		       bond->dev->name);
+	}
+	if (bond->dev->flags & IFF_UP) {
+		/* If the interface is up, we may need to fire off
+		 * the ARP timer.  If the interface is down, the
+		 * timer will get fired off when the open function
+		 * is called.
+		 */
+		if (bond->arp_timer.function) {
+			/* The timer's already set up, so fire it off */
+			mod_timer(&bond->arp_timer, jiffies + 1);
+		} else {
+			/* Set up the timer. */
+			init_timer(&bond->arp_timer);
+			bond->arp_timer.expires = jiffies + 1;
+			bond->arp_timer.data =
+				(unsigned long) bond->dev;
+			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
+				bond->arp_timer.function =
+					(void *)
+					&bond_activebackup_arp_mon;
+			} else {
+				bond->arp_timer.function =
+					(void *)
+					&bond_loadbalance_arp_mon;
+			}
+			add_timer(&bond->arp_timer);
+		}
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+
+/*
+ * Show and set the arp targets.
+ */
+static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
+{
+	int i, res = 0;
+	struct bonding *bond = to_bond(cd);
+
+	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
+		if (bond->params.arp_targets[i])
+			res += sprintf(buf + res, "%u.%u.%u.%u ",
+			       NIPQUAD(bond->params.arp_targets[i]));
+	}
+	if (res)
+		res--;  /* eat the leftover space */
+	res += sprintf(buf + res, "\n");
+	res++;
+	return res;
+}
+
+static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
+{
+	u32 newtarget;
+	int i = 0, done = 0, ret = count;
+	struct bonding *bond = to_bond(cd);
+	u32 *targets;
+
+	targets = bond->params.arp_targets;
+	newtarget = in_aton(buf + 1);
+	/* look for adds */
+	if (buf[0] == '+') {
+		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
+ 			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+		/* look for an empty slot to put the target in, and check for dupes */
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+			if (targets[i] == newtarget) { /* duplicate */
+				printk(KERN_ERR DRV_NAME
+				       ": %s: ARP target %u.%u.%u.%u is already present\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				if (done)
+					targets[i] = 0;
+				ret = -EINVAL;
+				goto out;
+			}
+			if (targets[i] == 0 && !done) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: adding ARP target %d.%d.%d.%d.\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				done = 1;
+				targets[i] = newtarget;
+			}
+		}
+		if (!done) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: ARP target table is full!\n",
+			       bond->dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+	}
+	else if (buf[0] == '-')	{
+		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
+			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+			if (targets[i] == newtarget) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: removing ARP target %d.%d.%d.%d.\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				targets[i] = 0;
+				done = 1;
+			}
+		}
+		if (!done) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
+			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+	else {
+		printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+			bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
+
+/*
+ * Show and set the up and down delays.  These must be multiples of the
+ * MII monitoring value, and are stored internally as the multiplier.
+ * Thus, we must translate to MS for the real world.
+ */
+static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (!(bond->params.miimon)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to set down delay as MII monitoring is disabled\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no down delay value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		if ((new_value % bond->params.miimon) != 0) {
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: down delay (%d) is not a multiple "
+			       "of miimon (%d), delay rounded to %d ms\n",
+			       bond->dev->name, new_value, bond->params.miimon,
+			       (new_value / bond->params.miimon) *
+			       bond->params.miimon);
+		}
+		bond->params.downdelay = new_value / bond->params.miimon;
+		printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
+		       bond->dev->name, bond->params.downdelay * bond->params.miimon);
+
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+
+static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
+
+}
+
+static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (!(bond->params.miimon)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to set up delay as MII monitoring is disabled\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no up delay value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		if ((new_value % bond->params.miimon) != 0) {
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: up delay (%d) is not a multiple "
+			       "of miimon (%d), updelay rounded to %d ms\n",
+			       bond->dev->name, new_value, bond->params.miimon,
+			       (new_value / bond->params.miimon) *
+			       bond->params.miimon);
+		}
+		bond->params.updelay = new_value / bond->params.miimon;
+		printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
+		       bond->dev->name, bond->params.updelay * bond->params.miimon);
+
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+
+/*
+ * Show and set the LACP interval.  Interface must be down, and the mode
+ * must be set to 802.3ad mode.
+ */
+static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%s %d\n",
+		bond_lacp_tbl[bond->params.lacp_fast].modename,
+		bond->params.lacp_fast) + 1;
+}
+
+static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update LACP rate because interface is up.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (bond->params.mode != BOND_MODE_8023AD) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+
+	if ((new_value == 1) || (new_value == 0)) {
+		bond->params.lacp_fast = new_value;
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Setting LACP rate to %s (%d).\n",
+		       bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
+	} else {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid LACP rate value %.*s.\n",
+		     	bond->dev->name, (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+
+/*
+ * Show and set the MII monitor interval.  There are two tricky bits
+ * here.  First, if MII monitoring is activated, then we must disable
+ * ARP monitoring.  Second, if the timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no miimon value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Setting MII monitoring interval to %d.\n",
+		       bond->dev->name, new_value);
+		bond->params.miimon = new_value;
+		if(bond->params.updelay)
+			printk(KERN_INFO DRV_NAME
+			      ": %s: Note: Updating updelay (to %d) "
+			      "since it is a multiple of the miimon value.\n",
+			      bond->dev->name,
+			      bond->params.updelay * bond->params.miimon);
+		if(bond->params.downdelay)
+			printk(KERN_INFO DRV_NAME
+			      ": %s: Note: Updating downdelay (to %d) "
+			      "since it is a multiple of the miimon value.\n",
+			      bond->dev->name,
+			      bond->params.downdelay * bond->params.miimon);
+		if (bond->params.arp_interval) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: MII monitoring cannot be used with "
+			       "ARP monitoring. Disabling ARP monitoring...\n",
+			       bond->dev->name);
+			bond->params.arp_interval = 0;
+			/* Kill ARP timer, else it brings bond's link down */
+			if (bond->mii_timer.function) {
+				printk(KERN_INFO DRV_NAME
+				": %s: Kill ARP timer, else it brings bond's link down...\n",
+			       bond->dev->name);
+				del_timer_sync(&bond->arp_timer);
+			}
+		}
+
+		if (bond->dev->flags & IFF_UP) {
+			/* If the interface is up, we may need to fire off
+			 * the MII timer. If the interface is down, the
+			 * timer will get fired off when the open function
+			 * is called.
+			 */
+			if (bond->mii_timer.function) {
+				/* The timer's already set up, so fire it off */
+				mod_timer(&bond->mii_timer, jiffies + 1);
+			} else {
+				/* Set up the timer. */
+				init_timer(&bond->mii_timer);
+				bond->mii_timer.expires = jiffies + 1;
+				bond->mii_timer.data =
+					(unsigned long) bond->dev;
+				bond->mii_timer.function =
+					(void *) &bond_mii_monitor;
+				add_timer(&bond->mii_timer);
+			}
+		}
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+
+/*
+ * Show and set the primary slave.  The store function is much
+ * simpler than bonding_store_slaves function because it only needs to
+ * handle one interface name.
+ * The bond must be a mode that supports a primary for this be
+ * set.
+ */
+static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->primary_slave)
+		count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+
+static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
+{
+	int i;
+	struct slave *slave;
+	struct bonding *bond = to_bond(cd);
+
+	write_lock_bh(&bond->lock);
+	if (!USES_PRIMARY(bond->params.mode)) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Unable to set primary slave; %s is in mode %d\n",
+		       bond->dev->name, bond->dev->name, bond->params.mode);
+	} else {
+		bond_for_each_slave(bond, slave, i) {
+			if (strnicmp
+			    (slave->dev->name, buf,
+			     strlen(slave->dev->name)) == 0) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: Setting %s as primary slave.\n",
+				       bond->dev->name, slave->dev->name);
+				bond->primary_slave = slave;
+				bond_select_active_slave(bond);
+				goto out;
+			}
+		}
+
+		/* if we got here, then we didn't match the name of any slave */
+
+		if (strlen(buf) == 0 || buf[0] == '\n') {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Setting primary slave to None.\n",
+			       bond->dev->name);
+			bond->primary_slave = 0;
+				bond_select_active_slave(bond);
+		} else {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
+			       bond->dev->name, (int)strlen(buf) - 1, buf);
+		}
+	}
+out:
+	write_unlock_bh(&bond->lock);
+	return count;
+}
+static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+
+/*
+ * Show and set the use_carrier flag.
+ */
+static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
+}
+
+static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no use_carrier value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if ((new_value == 0) || (new_value == 1)) {
+		bond->params.use_carrier = new_value;
+		printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
+		       bond->dev->name, new_value);
+	} else {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Ignoring invalid use_carrier value %d.\n",
+		       bond->dev->name, new_value);
+	}
+out:
+	return count;
+}
+static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+
+
+/*
+ * Show and set currently active_slave.
+ */
+static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
+{
+	struct slave *curr;
+	struct bonding *bond = to_bond(cd);
+	int count;
+
+
+	read_lock(&bond->curr_slave_lock);
+	curr = bond->curr_active_slave;
+	read_unlock(&bond->curr_slave_lock);
+
+	if (USES_PRIMARY(bond->params.mode) && curr)
+		count = sprintf(buf, "%s\n", curr->dev->name) + 1;
+	else
+		count = sprintf(buf, "\n") + 1;
+	return count;
+}
+
+static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
+{
+	int i;
+	struct slave *slave;
+        struct slave *old_active = NULL;
+        struct slave *new_active = NULL;
+	struct bonding *bond = to_bond(cd);
+
+	write_lock_bh(&bond->lock);
+	if (!USES_PRIMARY(bond->params.mode)) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Unable to change active slave; %s is in mode %d\n",
+		       bond->dev->name, bond->dev->name, bond->params.mode);
+	} else {
+		bond_for_each_slave(bond, slave, i) {
+			if (strnicmp
+			    (slave->dev->name, buf,
+			     strlen(slave->dev->name)) == 0) {
+        			old_active = bond->curr_active_slave;
+        			new_active = slave;
+        			if (new_active && (new_active == old_active)) {
+					/* do nothing */
+					printk(KERN_INFO DRV_NAME
+				       	       ": %s: %s is already the current active slave.\n",
+				               bond->dev->name, slave->dev->name);
+					goto out;
+				}
+				else {
+        				if ((new_active) &&
+            				    (old_active) &&
+				            (new_active->link == BOND_LINK_UP) &&
+				            IS_UP(new_active->dev)) {
+						printk(KERN_INFO DRV_NAME
+				       	              ": %s: Setting %s as active slave.\n",
+				                      bond->dev->name, slave->dev->name);
+                				bond_change_active_slave(bond, new_active);
+        				}
+					else {
+						printk(KERN_INFO DRV_NAME
+				       	              ": %s: Could not set %s as active slave; "
+						      "either %s is down or the link is down.\n",
+				                      bond->dev->name, slave->dev->name,
+						      slave->dev->name);
+					}
+					goto out;
+				}
+			}
+		}
+
+		/* if we got here, then we didn't match the name of any slave */
+
+		if (strlen(buf) == 0 || buf[0] == '\n') {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Setting active slave to None.\n",
+			       bond->dev->name);
+			bond->primary_slave = 0;
+				bond_select_active_slave(bond);
+		} else {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
+			       bond->dev->name, (int)strlen(buf) - 1, buf);
+		}
+	}
+out:
+	write_unlock_bh(&bond->lock);
+	return count;
+
+}
+static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+
+
+/*
+ * Show link status of the bond interface.
+ */
+static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
+{
+	struct slave *curr;
+	struct bonding *bond = to_bond(cd);
+
+	read_lock(&bond->curr_slave_lock);
+	curr = bond->curr_active_slave;
+	read_unlock(&bond->curr_slave_lock);
+
+	return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
+}
+static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
+
+
+/*
+ * Show current 802.3ad aggregator ID.
+ */
+static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.aggregator_id) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
+
+
+/*
+ * Show number of active 802.3ad ports.
+ */
+static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0: ad_info.ports) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
+
+
+/*
+ * Show current 802.3ad actor key.
+ */
+static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.actor_key) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner key.
+ */
+static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.partner_key) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner mac.
+ */
+static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
+			count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n",
+				       ad_info.partner_system[0],
+				       ad_info.partner_system[1],
+				       ad_info.partner_system[2],
+				       ad_info.partner_system[3],
+				       ad_info.partner_system[4],
+				       ad_info.partner_system[5]) + 1;
+		}
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
+
+
+
+static struct attribute *per_bond_attrs[] = {
+	&class_device_attr_slaves.attr,
+	&class_device_attr_mode.attr,
+	&class_device_attr_arp_interval.attr,
+	&class_device_attr_arp_ip_target.attr,
+	&class_device_attr_downdelay.attr,
+	&class_device_attr_updelay.attr,
+	&class_device_attr_lacp_rate.attr,
+	&class_device_attr_xmit_hash_policy.attr,
+	&class_device_attr_miimon.attr,
+	&class_device_attr_primary.attr,
+	&class_device_attr_use_carrier.attr,
+	&class_device_attr_active_slave.attr,
+	&class_device_attr_mii_status.attr,
+	&class_device_attr_ad_aggregator.attr,
+	&class_device_attr_ad_num_ports.attr,
+	&class_device_attr_ad_actor_key.attr,
+	&class_device_attr_ad_partner_key.attr,
+	&class_device_attr_ad_partner_mac.attr,
+	NULL,
+};
+
+static struct attribute_group bonding_group = {
+	.name = "bonding",
+	.attrs = per_bond_attrs,
+};
+
+/*
+ * Initialize sysfs.  This sets up the bonding_masters file in
+ * /sys/class/net.
+ */
+int bond_create_sysfs(void)
+{
+	int ret = 0;
+	struct bonding *firstbond;
+
+	init_rwsem(&bonding_rwsem);
+
+	/* get the netdev class pointer */
+	firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
+	if (!firstbond)
+		return -ENODEV;
+
+	netdev_class = firstbond->dev->class_dev.class;
+	if (!netdev_class)
+		return -ENODEV;
+
+	ret = class_create_file(netdev_class, &class_attr_bonding_masters);
+
+	return ret;
+
+}
+
+/*
+ * Remove /sys/class/net/bonding_masters.
+ */
+void bond_destroy_sysfs(void)
+{
+	if (netdev_class)
+		class_remove_file(netdev_class, &class_attr_bonding_masters);
+}
+
+/*
+ * Initialize sysfs for each bond.  This sets up and registers
+ * the 'bondctl' directory for each individual bond under /sys/class/net.
+ */
+int bond_create_sysfs_entry(struct bonding *bond)
+{
+	struct net_device *dev = bond->dev;
+	int err;
+
+	err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
+	if (err) {
+		printk(KERN_EMERG "eek! didn't create group!\n");
+	}
+
+	if (expected_refcount < 1)
+		expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
+
+	return err;
+}
+/*
+ * Remove sysfs entries for each bond.
+ */
+void bond_destroy_sysfs_entry(struct bonding *bond)
+{
+	struct net_device *dev = bond->dev;
+
+	sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
+}
+
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 1433e91..015c7f1 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -10,25 +10,6 @@
  *	This software may be used and distributed according to the terms
  *	of the GNU Public License, incorporated herein by reference.
  *
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *		Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Code beautification and style changes (mainly in comments).
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for Transmit load balancing mode.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
- *
- * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
- *      - added "xmit_policy" kernel parameter for alternate hashing policy
- *	  support for mode 2
  */
 
 #ifndef _LINUX_BONDING_H
@@ -37,11 +18,12 @@
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
 #include <linux/if_bonding.h>
+#include <linux/kobject.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"2.6.5"
-#define DRV_RELDATE	"November 4, 2005"
+#define DRV_VERSION	"3.0.0"
+#define DRV_RELDATE	"November 8, 2005"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -152,6 +134,11 @@
 	u32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
 
+struct bond_parm_tbl {
+	char *modename;
+	int mode;
+};
+
 struct vlan_entry {
 	struct list_head vlan_list;
 	u32 vlan_ip;
@@ -159,7 +146,7 @@
 };
 
 struct slave {
-	struct net_device *dev; /* first - usefull for panic debug */
+	struct net_device *dev; /* first - useful for panic debug */
 	struct slave *next;
 	struct slave *prev;
 	s16    delay;
@@ -185,7 +172,7 @@
  *    beforehand.
  */
 struct bonding {
-	struct   net_device *dev; /* first - usefull for panic debug */
+	struct   net_device *dev; /* first - useful for panic debug */
 	struct   slave *first_slave;
 	struct   slave *curr_active_slave;
 	struct   slave *current_arp_slave;
@@ -255,6 +242,25 @@
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_deinit(struct net_device *bond_dev);
+int bond_create_sysfs(void);
+void bond_destroy_sysfs(void);
+void bond_destroy_sysfs_entry(struct bonding *bond);
+int bond_create_sysfs_entry(struct bonding *bond);
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
+void bond_mii_monitor(struct net_device *bond_dev);
+void bond_loadbalance_arp_mon(struct net_device *bond_dev);
+void bond_activebackup_arp_mon(struct net_device *bond_dev);
+void bond_set_mode_ops(struct bonding *bond, int mode);
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+const char *bond_mode_name(int mode);
+void bond_select_active_slave(struct bonding *bond);
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 
 #endif /* _LINUX_BONDING_H */
 
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 53b41d9..2c5b849 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1332,8 +1332,8 @@
  *
  * This runs with softirqs disabled.
  */
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-		       unsigned int qid, struct net_device *dev)
+static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
+		     unsigned int qid, struct net_device *dev)
 {
 	struct sge *sge = adapter->sge;
 	struct cmdQ *q = &sge->cmdQ[qid];
@@ -1352,9 +1352,10 @@
 			set_bit(dev->if_port, &sge->stopped_tx_queues);
 			sge->stats.cmdQ_full[3]++;
 			spin_unlock(&q->lock);
-			CH_ERR("%s: Tx ring full while queue awake!\n",
-			       adapter->name);
-			return 1;
+			if (!netif_queue_stopped(dev))
+				CH_ERR("%s: Tx ring full while queue awake!\n",
+				       adapter->name);
+			return NETDEV_TX_BUSY;
 		}
 		if (unlikely(credits - count < q->stop_thres)) {
 			sge->stats.cmdQ_full[3]++;
@@ -1389,7 +1390,7 @@
 			writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
 		}
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
@@ -1449,7 +1450,7 @@
 		if (unlikely(skb->len < ETH_HLEN ||
 			     skb->len > dev->mtu + eth_hdr_len(skb->data))) {
 			dev_kfree_skb_any(skb);
-			return NET_XMIT_SUCCESS;
+			return NETDEV_TX_OK;
 		}
 
 		/*
@@ -1467,7 +1468,7 @@
 			skb = skb_realloc_headroom(skb, sizeof(*cpl));
 			dev_kfree_skb_any(orig_skb);
 			if (!skb)
-				return -ENOMEM;
+				return NETDEV_TX_OK;
 		}
 
 		if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
@@ -1475,7 +1476,7 @@
 		    skb->nh.iph->protocol == IPPROTO_UDP)
 			if (unlikely(skb_checksum_help(skb, 0))) {
 				dev_kfree_skb_any(skb);
-				return -ENOMEM;
+				return NETDEV_TX_OK;
 			}
 
 		/* Hmmm, assuming to catch the gratious arp... and we'll use
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 434b255..6d0d24a 100644
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -89,8 +89,6 @@
 int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
 void t1_sge_destroy(struct sge *);
 intr_handler_t t1_select_intr_handler(adapter_t *adapter);
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-		       unsigned int qid, struct net_device *netdev);
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 3f653a9..e02e9ba 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -188,11 +188,13 @@
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
 
-	struct e1000_buffer previous_buffer_info;
 	spinlock_t tx_lock;
 	uint16_t tdh;
 	uint16_t tdt;
 	uint64_t pkt;
+
+	boolean_t last_tx_tso;
+
 };
 
 struct e1000_rx_ring {
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 8eae8ba..c88f1a3 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -562,10 +562,29 @@
                        struct ethtool_drvinfo *drvinfo)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	char firmware_version[32];
+	uint16_t eeprom_data;
 
 	strncpy(drvinfo->driver,  e1000_driver_name, 32);
 	strncpy(drvinfo->version, e1000_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
+	
+	/* EEPROM image version # is reported as firware version # for
+	 * 8257{1|2|3} controllers */
+	e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
+	switch (adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+	case e1000_82573:
+		sprintf(firmware_version, "%d.%d-%d", 
+			(eeprom_data & 0xF000) >> 12,
+			(eeprom_data & 0x0FF0) >> 4,
+			eeprom_data & 0x000F);
+		break;
+	default:
+		sprintf(firmware_version, "n/a");
+	}
+
+	strncpy(drvinfo->fw_version, firmware_version, 32);
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 	drvinfo->n_stats = E1000_STATS_LEN;
 	drvinfo->testinfo_len = E1000_TEST_LEN;
@@ -960,13 +979,21 @@
 		}
 	}
 
-	if(txdr->desc)
+	if(txdr->desc) {
 		pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
-	if(rxdr->desc)
+		txdr->desc = NULL;
+	}
+	if(rxdr->desc) {
 		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
+		rxdr->desc = NULL;
+	}
 
 	kfree(txdr->buffer_info);
+	txdr->buffer_info = NULL;
+
 	kfree(rxdr->buffer_info);
+	rxdr->buffer_info = NULL;
+
 	return;
 }
 
@@ -1301,21 +1328,32 @@
 e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
 	uint32_t rctl;
+	struct e1000_hw *hw = &adapter->hw;
 
-	if(adapter->hw.media_type == e1000_media_type_fiber ||
-	   adapter->hw.media_type == e1000_media_type_internal_serdes) {
-		if(adapter->hw.mac_type == e1000_82545 ||
-		   adapter->hw.mac_type == e1000_82546 ||
-		   adapter->hw.mac_type == e1000_82545_rev_3 ||
-		   adapter->hw.mac_type == e1000_82546_rev_3)
+	if (hw->media_type == e1000_media_type_fiber ||
+	   hw->media_type == e1000_media_type_internal_serdes) {
+		switch (hw->mac_type) {
+		case e1000_82545:
+		case e1000_82546:
+		case e1000_82545_rev_3:
+		case e1000_82546_rev_3:
 			return e1000_set_phy_loopback(adapter);
-		else {
-			rctl = E1000_READ_REG(&adapter->hw, RCTL);
+			break;
+		case e1000_82571:
+		case e1000_82572:
+#define E1000_SERDES_LB_ON 0x410
+			e1000_set_phy_loopback(adapter);
+			E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
+			msec_delay(10);
+			return 0;
+			break;
+		default:
+			rctl = E1000_READ_REG(hw, RCTL);
 			rctl |= E1000_RCTL_LBM_TCVR;
-			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+			E1000_WRITE_REG(hw, RCTL, rctl);
 			return 0;
 		}
-	} else if(adapter->hw.media_type == e1000_media_type_copper)
+	} else if (hw->media_type == e1000_media_type_copper)
 		return e1000_set_phy_loopback(adapter);
 
 	return 7;
@@ -1326,25 +1364,36 @@
 {
 	uint32_t rctl;
 	uint16_t phy_reg;
+	struct e1000_hw *hw = &adapter->hw;
 
 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
 	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 
-	if(adapter->hw.media_type == e1000_media_type_copper ||
-	   ((adapter->hw.media_type == e1000_media_type_fiber ||
-	     adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-	    (adapter->hw.mac_type == e1000_82545 ||
-	     adapter->hw.mac_type == e1000_82546 ||
-	     adapter->hw.mac_type == e1000_82545_rev_3 ||
-	     adapter->hw.mac_type == e1000_82546_rev_3))) {
-		adapter->hw.autoneg = TRUE;
-		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-		if(phy_reg & MII_CR_LOOPBACK) {
-			phy_reg &= ~MII_CR_LOOPBACK;
-			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
-			e1000_phy_reset(&adapter->hw);
+	switch (hw->mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		if (hw->media_type == e1000_media_type_fiber ||
+		   hw->media_type == e1000_media_type_internal_serdes){
+#define E1000_SERDES_LB_OFF 0x400
+			E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
+			msec_delay(10);
+			break;
 		}
+		/* fall thru for Cu adapters */
+	case e1000_82545:
+	case e1000_82546:
+	case e1000_82545_rev_3:
+	case e1000_82546_rev_3:
+	default:
+		hw->autoneg = TRUE;
+		e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
+		if (phy_reg & MII_CR_LOOPBACK) {
+			phy_reg &= ~MII_CR_LOOPBACK;
+			e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
+			e1000_phy_reset(hw);
+		}
+		break;
 	}
 }
 
@@ -1440,9 +1489,11 @@
 e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
 {
 	if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
-	if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback;
+	if((*data = e1000_setup_loopback_test(adapter)))
+		goto err_loopback_setup;
 	*data = e1000_run_loopback_test(adapter);
 	e1000_loopback_cleanup(adapter);
+err_loopback_setup:
 	e1000_free_desc_rings(adapter);
 err_loopback:
 	return *data;
@@ -1671,6 +1722,14 @@
 		msleep_interruptible(data * 1000);
 		del_timer_sync(&adapter->blink_timer);
 	}
+	else if(adapter->hw.mac_type < e1000_82573) {
+		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
+			E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
+			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
+		msleep_interruptible(data * 1000);
+	}
 	else {
 		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
 			E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index a267c52..136fc03 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -563,11 +563,13 @@
             msec_delay(20);
             break;
         case e1000_82573:
-            udelay(10);
-            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-            E1000_WRITE_FLUSH(hw);
+            if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
+                udelay(10);
+                ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+                E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+                E1000_WRITE_FLUSH(hw);
+            }
             /* fall through */
         case e1000_82571:
         case e1000_82572:
@@ -844,19 +846,27 @@
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
-        DEBUGOUT("EEPROM Read Error\n");
-        return -E1000_ERR_EEPROM;
-    }
-
-    if(hw->fc == e1000_fc_default) {
-        if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-            hw->fc = e1000_fc_none;
-        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-                EEPROM_WORD0F_ASM_DIR)
-            hw->fc = e1000_fc_tx_pause;
-        else
+    if (hw->fc == e1000_fc_default) {
+        switch (hw->mac_type) {
+        case e1000_82573:
             hw->fc = e1000_fc_full;
+            break;
+        default:
+            ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
+                                        1, &eeprom_data);
+            if (ret_val) {
+                DEBUGOUT("EEPROM Read Error\n");
+                return -E1000_ERR_EEPROM;
+            }
+            if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+                hw->fc = e1000_fc_none;
+            else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
+                    EEPROM_WORD0F_ASM_DIR)
+                hw->fc = e1000_fc_tx_pause;
+            else
+                hw->fc = e1000_fc_full;
+            break;
+        }
     }
 
     /* We want to save off the original Flow Control configuration just
@@ -2962,13 +2972,22 @@
     if(hw->mac_type > e1000_82543) {
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
          * bit. Then, take it out of reset.
+         * For pre-e1000_82571 hardware, we delay for 10ms between the assert 
+         * and deassert.  For e1000_82571 hardware and later, we instead delay
+         * for 10ms after the deassertion.
          */
         ctrl = E1000_READ_REG(hw, CTRL);
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
         E1000_WRITE_FLUSH(hw);
-        msec_delay(10);
+        
+        if (hw->mac_type < e1000_82571) 
+            msec_delay(10);
+        
         E1000_WRITE_REG(hw, CTRL, ctrl);
         E1000_WRITE_FLUSH(hw);
+        
+        if (hw->mac_type >= e1000_82571)
+            msec_delay(10);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
@@ -5278,11 +5297,15 @@
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
-    case e1000_82571:
     case e1000_82572:
     case e1000_82573:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
+        hw->bus_width = e1000_bus_width_pciex_1;
+        break;
+    case e1000_82571:
+        hw->bus_type = e1000_bus_type_pci_express;
+        hw->bus_speed = e1000_bus_speed_2500;
         hw->bus_width = e1000_bus_width_pciex_4;
         break;
     default:
@@ -6650,6 +6673,12 @@
         break;
     }
 
+    /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
+     * Need to wait for PHY configuration completion before accessing NVM
+     * and PHY. */
+    if (hw->mac_type == e1000_82573)
+        msec_delay(25);
+
     return E1000_SUCCESS;
 }
 
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 76ce128..7caa357 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -123,6 +123,7 @@
     e1000_bus_width_32,
     e1000_bus_width_64,
     e1000_bus_width_pciex_1,
+    e1000_bus_width_pciex_2,
     e1000_bus_width_pciex_4,
     e1000_bus_width_reserved
 } e1000_bus_width;
@@ -149,6 +150,7 @@
     e1000_igp_cable_length_90  = 90,
     e1000_igp_cable_length_100 = 100,
     e1000_igp_cable_length_110 = 110,
+    e1000_igp_cable_length_115 = 115,
     e1000_igp_cable_length_120 = 120,
     e1000_igp_cable_length_130 = 130,
     e1000_igp_cable_length_140 = 140,
@@ -1457,6 +1459,7 @@
 #define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
 #define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
 #define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SECVAL_SHIFT      22
 #define E1000_STM_OPCODE     0xDB00
 #define E1000_HICR_FW_RESET  0xC0
 
@@ -1951,7 +1954,6 @@
 
 #define E1000_MDALIGN          4096
 
-#define E1000_GCR_BEM32                 0x00400000
 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
 /* Function Active and Power State to MNG */
 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index e0ae248..438a931 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -711,6 +711,7 @@
 		break;
 	case e1000_82546:
 	case e1000_82546_rev_3:
+	case e1000_82571:
 		if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
 		   && (adapter->hw.media_type == e1000_media_type_copper)) {
 			e1000_read_eeprom(&adapter->hw,
@@ -1158,7 +1159,6 @@
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
-	memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
 
 	/* round up to nearest 4K */
 
@@ -1813,11 +1813,6 @@
 
 	/* Free all the Tx ring sk_buffs */
 
-	if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-		e1000_unmap_and_free_tx_resource(adapter,
-				&tx_ring->previous_buffer_info);
-	}
-
 	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
 		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1832,6 +1827,7 @@
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
+	tx_ring->last_tx_tso = 0;
 
 	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
 	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
@@ -2437,6 +2433,16 @@
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
+		/* Workaround for Controller erratum --
+		 * descriptor for non-tso packet in a linear SKB that follows a
+		 * tso gets written back prematurely before the data is fully
+		 * DMAd to the controller */
+		if (!skb->data_len && tx_ring->last_tx_tso &&
+				!skb_shinfo(skb)->tso_size) {
+			tx_ring->last_tx_tso = 0;
+			size -= 4;
+		}
+
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
 		if(unlikely(mss && !nr_frags && size == len && size > 8))
@@ -2693,6 +2699,14 @@
 	if(skb->ip_summed == CHECKSUM_HW)
 		count++;
 #endif
+
+#ifdef NETIF_F_TSO
+	/* Controller Erratum workaround */
+	if (!skb->data_len && tx_ring->last_tx_tso &&
+		!skb_shinfo(skb)->tso_size)
+		count++;
+#endif
+
 	count += TXD_USE_COUNT(len, max_txd_pwr);
 
 	if(adapter->pcix_82544)
@@ -2774,9 +2788,10 @@
 		return NETDEV_TX_OK;
 	}
 
-	if (likely(tso))
+	if (likely(tso)) {
+		tx_ring->last_tx_tso = 1;
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
@@ -3227,37 +3242,12 @@
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
 	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-		/* Premature writeback of Tx descriptors clear (free buffers
-		 * and unmap pci_mapping) previous_buffer_info */
-		if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-			e1000_unmap_and_free_tx_resource(adapter,
-					&tx_ring->previous_buffer_info);
-		}
-
 		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
 
-#ifdef NETIF_F_TSO
-			if (!(netdev->features & NETIF_F_TSO)) {
-#endif
-				e1000_unmap_and_free_tx_resource(adapter,
-				                                 buffer_info);
-#ifdef NETIF_F_TSO
-			} else {
-				if (cleaned) {
-					memcpy(&tx_ring->previous_buffer_info,
-					       buffer_info,
-					       sizeof(struct e1000_buffer));
-					memset(buffer_info, 0,
-					       sizeof(struct e1000_buffer));
-				} else {
-					e1000_unmap_and_free_tx_resource(
-					    adapter, buffer_info);
-				}
-			}
-#endif
+			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 
 			tx_desc->buffer_addr = 0;
 			tx_desc->lower.data = 0;
@@ -3318,12 +3308,6 @@
 			netif_stop_queue(netdev);
 		}
 	}
-#ifdef NETIF_F_TSO
-	if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
-	    time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
-		e1000_unmap_and_free_tx_resource(
-		    adapter, &tx_ring->previous_buffer_info);
-#endif
 	return cleaned;
 }
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0f030b7..146f951 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2,7 +2,8 @@
  * drivers/net/gianfar.c
  *
  * Gianfar Ethernet Driver
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
  * Based on 8260_io/fcc_enet.c
  *
  * Author: Andy Fleming
@@ -22,8 +23,6 @@
  *  B-V +1.62
  *
  *  Theory of operation
- *  This driver is designed for the non-CPM ethernet controllers
- *  on the 85xx and 83xx family of integrated processors
  *
  *  The driver is initialized through platform_device.  Structures which
  *  define the configuration needed by the board are defined in a
@@ -110,7 +109,7 @@
 #endif
 
 const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.2";
+const char gfar_driver_version[] = "1.3";
 
 static int gfar_enet_open(struct net_device *dev);
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -139,6 +138,10 @@
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
 static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+void gfar_halt(struct net_device *dev);
+void gfar_start(struct net_device *dev);
+static void gfar_clear_exact_match(struct net_device *dev);
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
 
 extern struct ethtool_ops gfar_ethtool_ops;
 
@@ -146,12 +149,10 @@
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
-int gfar_uses_fcb(struct gfar_private *priv)
+/* Returns 1 if incoming frames use an FCB */
+static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
-	if (priv->vlan_enable || priv->rx_csum_enable)
-		return 1;
-	else
-		return 0;
+	return (priv->vlan_enable || priv->rx_csum_enable);
 }
 
 /* Set up the ethernet device structure, private data,
@@ -320,15 +321,10 @@
 	else
 		priv->padding = 0;
 
-	dev->hard_header_len += priv->padding;
-
 	if (dev->features & NETIF_F_IP_CSUM)
 		dev->hard_header_len += GMAC_FCB_LEN;
 
 	priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
-#ifdef CONFIG_GFAR_BUFSTASH
-	priv->rx_stash_size = STASH_LENGTH;
-#endif
 	priv->tx_ring_size = DEFAULT_TX_RING_SIZE;
 	priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
 
@@ -350,6 +346,9 @@
 		goto register_fail;
 	}
 
+	/* Create all the sysfs files */
+	gfar_init_sysfs(dev);
+
 	/* Print out the device info */
 	printk(KERN_INFO DEVICE_NAME, dev->name);
 	for (idx = 0; idx < 6; idx++)
@@ -357,8 +356,7 @@
 	printk("\n");
 
 	/* Even more device info helps when determining which kernel */
-	/* provided which set of benchmarks.  Since this is global for all */
-	/* devices, we only print it once */
+	/* provided which set of benchmarks. */
 #ifdef CONFIG_GFAR_NAPI
 	printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
 #else
@@ -463,19 +461,9 @@
 	/* Initialize the max receive buffer length */
 	gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
 
-#ifdef CONFIG_GFAR_BUFSTASH
-	/* If we are stashing buffers, we need to set the
-	 * extraction length to the size of the buffer */
-	gfar_write(&priv->regs->attreli, priv->rx_stash_size << 16);
-#endif
-
 	/* Initialize the Minimum Frame Length Register */
 	gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
 
-	/* Setup Attributes so that snooping is on for rx */
-	gfar_write(&priv->regs->attr, ATTR_INIT_SETTINGS);
-	gfar_write(&priv->regs->attreli, ATTRELI_INIT_SETTINGS);
-
 	/* Assign the TBI an address which won't conflict with the PHYs */
 	gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
 }
@@ -577,8 +565,7 @@
 		for (i = 0; i < priv->rx_ring_size; i++) {
 			if (priv->rx_skbuff[i]) {
 				dma_unmap_single(NULL, rxbdp->bufPtr,
-						priv->rx_buffer_size
-						+ RXBUF_ALIGNMENT,
+						priv->rx_buffer_size,
 						DMA_FROM_DEVICE);
 
 				dev_kfree_skb_any(priv->rx_skbuff[i]);
@@ -636,6 +623,7 @@
 	struct gfar *regs = priv->regs;
 	int err = 0;
 	u32 rctrl = 0;
+	u32 attrs = 0;
 
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
@@ -795,18 +783,50 @@
 	if (priv->rx_csum_enable)
 		rctrl |= RCTRL_CHECKSUMMING;
 
-	if (priv->extended_hash)
+	if (priv->extended_hash) {
 		rctrl |= RCTRL_EXTHASH;
 
+		gfar_clear_exact_match(dev);
+		rctrl |= RCTRL_EMEN;
+	}
+
 	if (priv->vlan_enable)
 		rctrl |= RCTRL_VLAN;
 
+	if (priv->padding) {
+		rctrl &= ~RCTRL_PAL_MASK;
+		rctrl |= RCTRL_PADDING(priv->padding);
+	}
+
 	/* Init rctrl based on our settings */
 	gfar_write(&priv->regs->rctrl, rctrl);
 
 	if (dev->features & NETIF_F_IP_CSUM)
 		gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
 
+	/* Set the extraction length and index */
+	attrs = ATTRELI_EL(priv->rx_stash_size) |
+		ATTRELI_EI(priv->rx_stash_index);
+
+	gfar_write(&priv->regs->attreli, attrs);
+
+	/* Start with defaults, and add stashing or locking
+	 * depending on the approprate variables */
+	attrs = ATTR_INIT_SETTINGS;
+
+	if (priv->bd_stash_en)
+		attrs |= ATTR_BDSTASH;
+
+	if (priv->rx_stash_size != 0)
+		attrs |= ATTR_BUFSTASH;
+
+	gfar_write(&priv->regs->attr, attrs);
+
+	gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
+	gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
+	gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+
+	/* Start the controller */
 	gfar_start(dev);
 
 	return 0;
@@ -851,34 +871,32 @@
 	return err;
 }
 
-static struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
+static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
 {
 	struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
 
 	memset(fcb, 0, GMAC_FCB_LEN);
 
-	/* Flag the bd so the controller looks for the FCB */
-	bdp->status |= TXBD_TOE;
-
 	return fcb;
 }
 
 static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
 {
-	int len;
+	u8 flags = 0;
 
 	/* If we're here, it's a IP packet with a TCP or UDP
 	 * payload.  We set it to checksum, using a pseudo-header
 	 * we provide
 	 */
-	fcb->ip = 1;
-	fcb->tup = 1;
-	fcb->ctu = 1;
-	fcb->nph = 1;
+	flags = TXFCB_DEFAULT;
 
-	/* Notify the controller what the protocol is */
-	if (skb->nh.iph->protocol == IPPROTO_UDP)
-		fcb->udp = 1;
+	/* Tell the controller what the protocol is */
+	/* And provide the already calculated phcs */
+	if (skb->nh.iph->protocol == IPPROTO_UDP) {
+		flags |= TXFCB_UDP;
+		fcb->phcs = skb->h.uh->check;
+	} else
+		fcb->phcs = skb->h.th->check;
 
 	/* l3os is the distance between the start of the
 	 * frame (skb->data) and the start of the IP hdr.
@@ -887,17 +905,12 @@
 	fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN);
 	fcb->l4os = (u16)(skb->h.raw - skb->nh.raw);
 
-	len = skb->nh.iph->tot_len - fcb->l4os;
-
-	/* Provide the pseudoheader csum */
-	fcb->phcs = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-			skb->nh.iph->daddr, len,
-			skb->nh.iph->protocol, 0);
+	fcb->flags = flags;
 }
 
-void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
+void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
 {
-	fcb->vln = 1;
+	fcb->flags |= TXFCB_VLN;
 	fcb->vlctl = vlan_tx_tag_get(skb);
 }
 
@@ -908,6 +921,7 @@
 	struct gfar_private *priv = netdev_priv(dev);
 	struct txfcb *fcb = NULL;
 	struct txbd8 *txbdp;
+	u16 status;
 
 	/* Update transmit stats */
 	priv->stats.tx_bytes += skb->len;
@@ -919,19 +933,22 @@
 	txbdp = priv->cur_tx;
 
 	/* Clear all but the WRAP status flags */
-	txbdp->status &= TXBD_WRAP;
+	status = txbdp->status & TXBD_WRAP;
 
 	/* Set up checksumming */
-	if ((dev->features & NETIF_F_IP_CSUM)
-			&& (CHECKSUM_HW == skb->ip_summed)) {
+	if (likely((dev->features & NETIF_F_IP_CSUM)
+			&& (CHECKSUM_HW == skb->ip_summed))) {
 		fcb = gfar_add_fcb(skb, txbdp);
+		status |= TXBD_TOE;
 		gfar_tx_checksum(skb, fcb);
 	}
 
 	if (priv->vlan_enable &&
 			unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
-		if (NULL == fcb)
+		if (unlikely(NULL == fcb)) {
 			fcb = gfar_add_fcb(skb, txbdp);
+			status |= TXBD_TOE;
+		}
 
 		gfar_tx_vlan(skb, fcb);
 	}
@@ -949,14 +966,16 @@
 	    (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size);
 
 	/* Flag the BD as interrupt-causing */
-	txbdp->status |= TXBD_INTERRUPT;
+	status |= TXBD_INTERRUPT;
 
 	/* Flag the BD as ready to go, last in frame, and  */
 	/* in need of CRC */
-	txbdp->status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
+	status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
 
 	dev->trans_start = jiffies;
 
+	txbdp->status = status;
+
 	/* If this was the last BD in the ring, the next one */
 	/* is at the beginning of the ring */
 	if (txbdp->status & TXBD_WRAP)
@@ -1010,21 +1029,7 @@
 /* Changes the mac address if the controller is not running. */
 int gfar_set_mac_address(struct net_device *dev)
 {
-	struct gfar_private *priv = netdev_priv(dev);
-	int i;
-	char tmpbuf[MAC_ADDR_LEN];
-	u32 tempval;
-
-	/* Now copy it into the mac registers backwards, cuz */
-	/* little endian is silly */
-	for (i = 0; i < MAC_ADDR_LEN; i++)
-		tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->dev_addr[i];
-
-	gfar_write(&priv->regs->macstnaddr1, *((u32 *) (tmpbuf)));
-
-	tempval = *((u32 *) (tmpbuf + 4));
-
-	gfar_write(&priv->regs->macstnaddr2, tempval);
+	gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
 
 	return 0;
 }
@@ -1110,7 +1115,7 @@
 	    INCREMENTAL_BUFFER_SIZE;
 
 	/* Only stop and start the controller if it isn't already
-	 * stopped */
+	 * stopped, and we changed something */
 	if ((oldsize != tempsize) && (dev->flags & IFF_UP))
 		stop_gfar(dev);
 
@@ -1220,6 +1225,7 @@
 
 struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 {
+	unsigned int alignamount;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
 	unsigned int timeout = SKB_ALLOC_TIMEOUT;
@@ -1231,18 +1237,18 @@
 	if (NULL == skb)
 		return NULL;
 
+	alignamount = RXBUF_ALIGNMENT -
+		(((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1));
+
 	/* We need the data buffer to be aligned properly.  We will reserve
 	 * as many bytes as needed to align the data properly
 	 */
-	skb_reserve(skb,
-		    RXBUF_ALIGNMENT -
-		    (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1)));
+	skb_reserve(skb, alignamount);
 
 	skb->dev = dev;
 
 	bdp->bufPtr = dma_map_single(NULL, skb->data,
-			priv->rx_buffer_size + RXBUF_ALIGNMENT,
-			DMA_FROM_DEVICE);
+			priv->rx_buffer_size, DMA_FROM_DEVICE);
 
 	bdp->length = 0;
 
@@ -1350,7 +1356,7 @@
 	/* If valid headers were found, and valid sums
 	 * were verified, then we tell the kernel that no
 	 * checksumming is necessary.  Otherwise, it is */
-	if (fcb->cip && !fcb->eip && fcb->ctu && !fcb->etu)
+	if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	else
 		skb->ip_summed = CHECKSUM_NONE;
@@ -1401,7 +1407,7 @@
 		skb->protocol = eth_type_trans(skb, dev);
 
 		/* Send the packet up the stack */
-		if (unlikely(priv->vlgrp && fcb->vln))
+		if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
 			ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
 		else
 			ret = RECEIVE(skb);
@@ -1620,6 +1626,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 	if (phydev->link) {
 		u32 tempval = gfar_read(&regs->maccfg2);
+		u32 ecntrl = gfar_read(&regs->ecntrl);
 
 		/* Now we make sure that we can be in full duplex mode.
 		 * If not, we operate in half-duplex mode. */
@@ -1644,6 +1651,13 @@
 			case 10:
 				tempval =
 				    ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
+
+				/* Reduced mode distinguishes
+				 * between 10 and 100 */
+				if (phydev->speed == SPEED_100)
+					ecntrl |= ECNTRL_R100;
+				else
+					ecntrl &= ~(ECNTRL_R100);
 				break;
 			default:
 				if (netif_msg_link(priv))
@@ -1657,6 +1671,7 @@
 		}
 
 		gfar_write(&regs->maccfg2, tempval);
+		gfar_write(&regs->ecntrl, ecntrl);
 
 		if (!priv->oldlink) {
 			new_state = 1;
@@ -1721,6 +1736,9 @@
 		gfar_write(&regs->gaddr6, 0xffffffff);
 		gfar_write(&regs->gaddr7, 0xffffffff);
 	} else {
+		int em_num;
+		int idx;
+
 		/* zero out the hash */
 		gfar_write(&regs->igaddr0, 0x0);
 		gfar_write(&regs->igaddr1, 0x0);
@@ -1739,18 +1757,47 @@
 		gfar_write(&regs->gaddr6, 0x0);
 		gfar_write(&regs->gaddr7, 0x0);
 
+		/* If we have extended hash tables, we need to
+		 * clear the exact match registers to prepare for
+		 * setting them */
+		if (priv->extended_hash) {
+			em_num = GFAR_EM_NUM + 1;
+			gfar_clear_exact_match(dev);
+			idx = 1;
+		} else {
+			idx = 0;
+			em_num = 0;
+		}
+
 		if(dev->mc_count == 0)
 			return;
 
 		/* Parse the list, and set the appropriate bits */
 		for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
-			gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
+			if (idx < em_num) {
+				gfar_set_mac_for_addr(dev, idx,
+						mc_ptr->dmi_addr);
+				idx++;
+			} else
+				gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
 		}
 	}
 
 	return;
 }
 
+
+/* Clears each of the exact match registers to zero, so they
+ * don't interfere with normal reception */
+static void gfar_clear_exact_match(struct net_device *dev)
+{
+	int idx;
+	u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0};
+
+	for(idx = 1;idx < GFAR_EM_NUM + 1;idx++)
+		gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr);
+}
+
 /* Set the appropriate hash bit for the given addr */
 /* The algorithm works like so:
  * 1) Take the Destination Address (ie the multicast address), and
@@ -1781,6 +1828,32 @@
 	return;
 }
 
+
+/* There are multiple MAC Address register pairs on some controllers
+ * This function sets the numth pair to a given address
+ */
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	int idx;
+	char tmpbuf[MAC_ADDR_LEN];
+	u32 tempval;
+	u32 *macptr = &priv->regs->macstnaddr1;
+
+	macptr += num*2;
+
+	/* Now copy it into the mac registers backwards, cuz */
+	/* little endian is silly */
+	for (idx = 0; idx < MAC_ADDR_LEN; idx++)
+		tmpbuf[MAC_ADDR_LEN - 1 - idx] = addr[idx];
+
+	gfar_write(macptr, *((u32 *) (tmpbuf)));
+
+	tempval = *((u32 *) (tmpbuf + 4));
+
+	gfar_write(macptr+1, tempval);
+}
+
 /* GFAR error interrupt handler */
 static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
 {
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 5065ba8..94a91da 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -90,12 +90,26 @@
 #define GFAR_RX_MAX_RING_SIZE   256
 #define GFAR_TX_MAX_RING_SIZE   256
 
+#define GFAR_MAX_FIFO_THRESHOLD 511
+#define GFAR_MAX_FIFO_STARVE	511
+#define GFAR_MAX_FIFO_STARVE_OFF 511
+
 #define DEFAULT_RX_BUFFER_SIZE  1536
 #define TX_RING_MOD_MASK(size) (size-1)
 #define RX_RING_MOD_MASK(size) (size-1)
 #define JUMBO_BUFFER_SIZE 9728
 #define JUMBO_FRAME_SIZE 9600
 
+#define DEFAULT_FIFO_TX_THR 0x100
+#define DEFAULT_FIFO_TX_STARVE 0x40
+#define DEFAULT_FIFO_TX_STARVE_OFF 0x80
+#define DEFAULT_BD_STASH 1
+#define DEFAULT_STASH_LENGTH	64
+#define DEFAULT_STASH_INDEX	0
+
+/* The number of Exact Match registers */
+#define GFAR_EM_NUM	15
+
 /* Latency of interface clock in nanoseconds */
 /* Interface clock latency , in this case, means the
  * time described by a value of 1 in the interrupt
@@ -112,11 +126,11 @@
 
 #define DEFAULT_TX_COALESCE 1
 #define DEFAULT_TXCOUNT	16
-#define DEFAULT_TXTIME	400
+#define DEFAULT_TXTIME	4
 
 #define DEFAULT_RX_COALESCE 1
 #define DEFAULT_RXCOUNT	16
-#define DEFAULT_RXTIME	400
+#define DEFAULT_RXTIME	4
 
 #define TBIPA_VALUE		0x1f
 #define MIIMCFG_INIT_VALUE	0x00000007
@@ -147,6 +161,7 @@
 
 #define ECNTRL_INIT_SETTINGS	0x00001000
 #define ECNTRL_TBI_MODE         0x00000020
+#define ECNTRL_R100		0x00000008
 
 #define MRBLR_INIT_SETTINGS	DEFAULT_RX_BUFFER_SIZE
 
@@ -181,10 +196,12 @@
 #define RCTRL_PRSDEP_MASK	0x000000c0
 #define RCTRL_PRSDEP_INIT	0x000000c0
 #define RCTRL_PROM		0x00000008
+#define RCTRL_EMEN		0x00000002
 #define RCTRL_CHECKSUMMING	(RCTRL_IPCSEN \
 		| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
 #define RCTRL_EXTHASH		(RCTRL_GHTX)
 #define RCTRL_VLAN		(RCTRL_PRSDEP_INIT)
+#define RCTRL_PADDING(x)	((x << 16) & RCTRL_PAL_MASK)
 
 
 #define RSTAT_CLEAR_RHALT       0x00800000
@@ -251,28 +268,26 @@
 		IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
 		| IMASK_PERR)
 
+/* Fifo management */
+#define FIFO_TX_THR_MASK	0x01ff
+#define FIFO_TX_STARVE_MASK	0x01ff
+#define FIFO_TX_STARVE_OFF_MASK	0x01ff
 
 /* Attribute fields */
 
 /* This enables rx snooping for buffers and descriptors */
-#ifdef CONFIG_GFAR_BDSTASH
 #define ATTR_BDSTASH		0x00000800
-#else
-#define ATTR_BDSTASH		0x00000000
-#endif
 
-#ifdef CONFIG_GFAR_BUFSTASH
 #define ATTR_BUFSTASH		0x00004000
-#define STASH_LENGTH		64
-#else
-#define ATTR_BUFSTASH		0x00000000
-#endif
 
 #define ATTR_SNOOPING		0x000000c0
-#define ATTR_INIT_SETTINGS      (ATTR_SNOOPING \
-		| ATTR_BDSTASH | ATTR_BUFSTASH)
+#define ATTR_INIT_SETTINGS      ATTR_SNOOPING
 
 #define ATTRELI_INIT_SETTINGS   0x0
+#define ATTRELI_EL_MASK		0x3fff0000
+#define ATTRELI_EL(x) (x << 16)
+#define ATTRELI_EI_MASK		0x00003fff
+#define ATTRELI_EI(x) (x)
 
 
 /* TxBD status field bits */
@@ -328,6 +343,7 @@
 #define RXFCB_CTU		0x0400
 #define RXFCB_EIP		0x0200
 #define RXFCB_ETU		0x0100
+#define RXFCB_CSUM_MASK		0x0f00
 #define RXFCB_PERR_MASK		0x000c
 #define RXFCB_PERR_BADL3	0x0008
 
@@ -339,14 +355,7 @@
 };
 
 struct txfcb {
-	u8	vln:1,
-		ip:1,
-		ip6:1,
-		tup:1,
-		udp:1,
-		cip:1,
-		ctu:1,
-		nph:1;
+	u8	flags;
 	u8	reserved;
 	u8	l4os;	/* Level 4 Header Offset */
 	u8	l3os; 	/* Level 3 Header Offset */
@@ -362,14 +371,7 @@
 };
 
 struct rxfcb {
-	u16	vln:1,
-		ip:1,
-		ip6:1,
-		tup:1,
-		cip:1,
-		ctu:1,
-		eip:1,
-		etu:1;
+	u16	flags;
 	u8	rq;	/* Receive Queue index */
 	u8	pro;	/* Layer 4 Protocol */
 	u16	reserved;
@@ -688,12 +690,17 @@
 	spinlock_t lock;
 	unsigned int rx_buffer_size;
 	unsigned int rx_stash_size;
+	unsigned int rx_stash_index;
 	unsigned int tx_ring_size;
 	unsigned int rx_ring_size;
+	unsigned int fifo_threshold;
+	unsigned int fifo_starve;
+	unsigned int fifo_starve_off;
 
 	unsigned char vlan_enable:1,
 		rx_csum_enable:1,
-		extended_hash:1;
+		extended_hash:1,
+		bd_stash_en:1;
 	unsigned short padding;
 	struct vlan_group *vlgrp;
 	/* Info structure initialized by board setup code */
@@ -731,6 +738,6 @@
 extern void gfar_halt(struct net_device *dev);
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
-void gfar_setup_stashing(struct net_device *dev);
+void gfar_init_sysfs(struct net_device *dev);
 
 #endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index cfa3cd7..765e810 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -125,7 +125,7 @@
 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	
+
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
 		memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
 	else
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index e85eb21..d527cf2 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -24,6 +24,7 @@
 #define MII_READ_COMMAND       0x00000001
 
 #define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+		| SUPPORTED_10baseT_Full \
 		| SUPPORTED_100baseT_Half \
 		| SUPPORTED_100baseT_Full \
 		| SUPPORTED_Autoneg \
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
new file mode 100644
index 0000000..10d34cb
--- /dev/null
+++ b/drivers/net/gianfar_sysfs.c
@@ -0,0 +1,311 @@
+/*
+ * drivers/net/gianfar_sysfs.c
+ *
+ * Gianfar Ethernet Driver
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
+ * Based on 8260_io/fcc_enet.c
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-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.
+ *
+ * Sysfs file creation and management
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include "gianfar.h"
+
+#define GFAR_ATTR(_name) \
+static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
+static ssize_t gfar_set_##_name(struct class_device *cdev, \
+		const char *buf, size_t count); \
+static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
+
+#define GFAR_CREATE_FILE(_dev, _name) \
+	class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
+
+GFAR_ATTR(bd_stash);
+GFAR_ATTR(rx_stash_size);
+GFAR_ATTR(rx_stash_index);
+GFAR_ATTR(fifo_threshold);
+GFAR_ATTR(fifo_starve);
+GFAR_ATTR(fifo_starve_off);
+
+#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
+
+static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
+}
+
+static ssize_t gfar_set_bd_stash(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	int new_setting = 0;
+	u32 temp;
+	unsigned long flags;
+
+	/* Find out the new setting */
+	if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
+		new_setting = 1;
+	else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
+		new_setting = 0;
+	else
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* Set the new stashing value */
+	priv->bd_stash_en = new_setting;
+
+	temp = gfar_read(&priv->regs->attr);
+	
+	if (new_setting)
+		temp |= ATTR_BDSTASH;
+	else
+		temp &= ~(ATTR_BDSTASH);
+
+	gfar_write(&priv->regs->attr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->rx_stash_size);
+}
+
+static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int length = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (length > priv->rx_buffer_size)
+		return count;
+
+	if (length == priv->rx_stash_size)
+		return count;
+
+	priv->rx_stash_size = length;
+
+	temp = gfar_read(&priv->regs->attreli);
+	temp &= ~ATTRELI_EL_MASK;
+	temp |= ATTRELI_EL(length);
+	gfar_write(&priv->regs->attreli, temp);
+
+	/* Turn stashing on/off as appropriate */
+	temp = gfar_read(&priv->regs->attr);
+
+	if (length)
+		temp |= ATTR_BUFSTASH;
+	else
+		temp &= ~(ATTR_BUFSTASH);
+
+	gfar_write(&priv->regs->attr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+
+/* Stashing will only be enabled when rx_stash_size != 0 */
+static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->rx_stash_index);
+}
+
+static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned short index = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (index > priv->rx_stash_size)
+		return count;
+
+	if (index == priv->rx_stash_index)
+		return count;
+
+	priv->rx_stash_index = index;
+
+	temp = gfar_read(&priv->regs->attreli);
+	temp &= ~ATTRELI_EI_MASK;
+	temp |= ATTRELI_EI(index);
+	gfar_write(&priv->regs->attreli, flags);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_threshold);
+}
+
+static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int length = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (length > GFAR_MAX_FIFO_THRESHOLD)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_threshold = length;
+
+	temp = gfar_read(&priv->regs->fifo_tx_thr);
+	temp &= ~FIFO_TX_THR_MASK;
+	temp |= length;
+	gfar_write(&priv->regs->fifo_tx_thr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_starve);
+}
+
+
+static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int num = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (num > GFAR_MAX_FIFO_STARVE)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_starve = num;
+
+	temp = gfar_read(&priv->regs->fifo_tx_starve);
+	temp &= ~FIFO_TX_STARVE_MASK;
+	temp |= num;
+	gfar_write(&priv->regs->fifo_tx_starve, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_starve_off);
+}
+
+static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int num = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (num > GFAR_MAX_FIFO_STARVE_OFF)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_starve_off = num;
+
+	temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
+	temp &= ~FIFO_TX_STARVE_OFF_MASK;
+	temp |= num;
+	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+void gfar_init_sysfs(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+
+	/* Initialize the default values */
+	priv->rx_stash_size = DEFAULT_STASH_LENGTH;
+	priv->rx_stash_index = DEFAULT_STASH_INDEX;
+	priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
+	priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
+	priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
+	priv->bd_stash_en = DEFAULT_BD_STASH;
+
+	/* Create our sysfs files */
+	GFAR_CREATE_FILE(dev, bd_stash);
+	GFAR_CREATE_FILE(dev, rx_stash_size);
+	GFAR_CREATE_FILE(dev, rx_stash_index);
+	GFAR_CREATE_FILE(dev, fifo_threshold);
+	GFAR_CREATE_FILE(dev, fifo_starve);
+	GFAR_CREATE_FILE(dev, fifo_starve_off);
+
+}
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index c22c051..fa176ff 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1539,7 +1539,6 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "irda-usb",
 	.probe		= irda_usb_probe,
 	.disconnect	= irda_usb_disconnect,
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 3961a75..31867e4 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -1152,7 +1152,6 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "stir4200",
 	.probe		= stir_probe,
 	.disconnect	= stir_disconnect,
diff --git a/drivers/net/ixp2000/Kconfig b/drivers/net/ixp2000/Kconfig
new file mode 100644
index 0000000..2fec241
--- /dev/null
+++ b/drivers/net/ixp2000/Kconfig
@@ -0,0 +1,6 @@
+config ENP2611_MSF_NET
+	tristate "Radisys ENP2611 MSF network interface support"
+	depends on ARCH_ENP2611
+	help
+	  This is a driver for the MSF network interface unit in
+	  the IXP2400 on the Radisys ENP2611 platform.
diff --git a/drivers/net/ixp2000/Makefile b/drivers/net/ixp2000/Makefile
new file mode 100644
index 0000000..fd38351
--- /dev/null
+++ b/drivers/net/ixp2000/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ENP2611_MSF_NET) += enp2611_mod.o
+
+enp2611_mod-objs := caleb.o enp2611.o ixp2400-msf.o ixpdev.o pm3386.o
diff --git a/drivers/net/ixp2000/caleb.c b/drivers/net/ixp2000/caleb.c
new file mode 100644
index 0000000..3595e10
--- /dev/null
+++ b/drivers/net/ixp2000/caleb.c
@@ -0,0 +1,137 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/module.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "caleb.h"
+
+#define CALEB_IDLO		0x00
+#define CALEB_IDHI		0x01
+#define CALEB_RID		0x02
+#define CALEB_RESET		0x03
+#define CALEB_INTREN0		0x04
+#define CALEB_INTREN1		0x05
+#define CALEB_INTRSTAT0		0x06
+#define CALEB_INTRSTAT1		0x07
+#define CALEB_PORTEN		0x08
+#define CALEB_BURST		0x09
+#define CALEB_PORTPAUS		0x0A
+#define CALEB_PORTPAUSD		0x0B
+#define CALEB_PHY0RX		0x10
+#define CALEB_PHY1RX		0x11
+#define CALEB_PHY0TX		0x12
+#define CALEB_PHY1TX		0x13
+#define CALEB_IXPRX_HI_CNTR	0x15
+#define CALEB_PHY0RX_HI_CNTR	0x16
+#define CALEB_PHY1RX_HI_CNTR	0x17
+#define CALEB_IXPRX_CNTR	0x18
+#define CALEB_PHY0RX_CNTR	0x19
+#define CALEB_PHY1RX_CNTR	0x1A
+#define CALEB_IXPTX_CNTR	0x1B
+#define CALEB_PHY0TX_CNTR	0x1C
+#define CALEB_PHY1TX_CNTR	0x1D
+#define CALEB_DEBUG0		0x1E
+#define CALEB_DEBUG1		0x1F
+
+
+static u8 caleb_reg_read(int reg)
+{
+	u8 value;
+
+	value = *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg));
+
+//	printk(KERN_INFO "caleb_reg_read(%d) = %.2x\n", reg, value);
+
+	return value;
+}
+
+static void caleb_reg_write(int reg, u8 value)
+{
+	u8 dummy;
+
+//	printk(KERN_INFO "caleb_reg_write(%d, %.2x)\n", reg, value);
+
+	*((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg)) = value;
+
+	dummy = *((volatile u8 *)ENP2611_CALEB_VIRT_BASE);
+	__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+
+void caleb_reset(void)
+{
+	/*
+	 * Perform a chip reset.
+	 */
+	caleb_reg_write(CALEB_RESET, 0x02);
+	udelay(1);
+
+	/*
+	 * Enable all interrupt sources.  This is needed to get
+	 * meaningful results out of the status bits (register 6
+	 * and 7.)
+	 */
+	caleb_reg_write(CALEB_INTREN0, 0xff);
+	caleb_reg_write(CALEB_INTREN1, 0x07);
+
+	/*
+	 * Set RX and TX FIFO thresholds to 1.5kb.
+	 */
+	caleb_reg_write(CALEB_PHY0RX, 0x11);
+	caleb_reg_write(CALEB_PHY1RX, 0x11);
+	caleb_reg_write(CALEB_PHY0TX, 0x11);
+	caleb_reg_write(CALEB_PHY1TX, 0x11);
+
+	/*
+	 * Program SPI-3 burst size.
+	 */
+	caleb_reg_write(CALEB_BURST, 0);	// 64-byte RBUF mpackets
+//	caleb_reg_write(CALEB_BURST, 1);	// 128-byte RBUF mpackets
+//	caleb_reg_write(CALEB_BURST, 2);	// 256-byte RBUF mpackets
+}
+
+void caleb_enable_rx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp |= 1 << port;
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_rx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp &= ~(1 << port);
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_enable_tx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp |= 1 << (port + 4);
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_tx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp &= ~(1 << (port + 4));
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
diff --git a/drivers/net/ixp2000/caleb.h b/drivers/net/ixp2000/caleb.h
new file mode 100644
index 0000000..e93a1ef
--- /dev/null
+++ b/drivers/net/ixp2000/caleb.h
@@ -0,0 +1,22 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __CALEB_H
+#define __CALEB_H
+
+void caleb_reset(void);
+void caleb_enable_rx(int port);
+void caleb_disable_rx(int port);
+void caleb_enable_tx(int port);
+void caleb_disable_tx(int port);
+
+
+#endif
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c
new file mode 100644
index 0000000..d82651a
--- /dev/null
+++ b/drivers/net/ixp2000/enp2611.c
@@ -0,0 +1,245 @@
+/*
+ * IXP2400 MSF network device driver for the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixpdev.h"
+#include "caleb.h"
+#include "ixp2400-msf.h"
+#include "pm3386.h"
+
+/***********************************************************************
+ * The Radisys ENP2611 is a PCI form factor board with three SFP GBIC
+ * slots, connected via two PMC/Sierra 3386s and an SPI-3 bridge FPGA
+ * to the IXP2400.
+ *
+ *                +-------------+
+ * SFP GBIC #0 ---+             |       +---------+
+ *                |  PM3386 #0  +-------+         |
+ * SFP GBIC #1 ---+             |       | "Caleb" |         +---------+
+ *                +-------------+       |         |         |         |
+ *                                      | SPI-3   +---------+ IXP2400 |
+ *                +-------------+       | bridge  |         |         |
+ * SFP GBIC #2 ---+             |       | FPGA    |         +---------+
+ *                |  PM3386 #1  +-------+         |
+ *                |             |       +---------+
+ *                +-------------+
+ *              ^                   ^                  ^
+ *              | 1.25Gbaud         | 104MHz           | 104MHz
+ *              | SERDES ea.        | SPI-3 ea.        | SPI-3
+ *
+ ***********************************************************************/
+static struct ixp2400_msf_parameters enp2611_msf_parameters =
+{
+	.rx_mode =		IXP2400_RX_MODE_UTOPIA_POS |
+				IXP2400_RX_MODE_1x32 |
+				IXP2400_RX_MODE_MPHY |
+				IXP2400_RX_MODE_MPHY_32 |
+				IXP2400_RX_MODE_MPHY_POLLED_STATUS |
+				IXP2400_RX_MODE_MPHY_LEVEL3 |
+				IXP2400_RX_MODE_RBUF_SIZE_64,
+
+	.rxclk01_multiplier =	IXP2400_PLL_MULTIPLIER_16,
+
+	.rx_poll_ports =	3,
+
+	.rx_channel_mode = {
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE
+	},
+
+	.tx_mode =		IXP2400_TX_MODE_UTOPIA_POS |
+				IXP2400_TX_MODE_1x32 |
+				IXP2400_TX_MODE_MPHY |
+				IXP2400_TX_MODE_MPHY_32 |
+				IXP2400_TX_MODE_MPHY_POLLED_STATUS |
+				IXP2400_TX_MODE_MPHY_LEVEL3 |
+				IXP2400_TX_MODE_TBUF_SIZE_64,
+
+	.txclk01_multiplier =	IXP2400_PLL_MULTIPLIER_16,
+
+	.tx_poll_ports =	3,
+
+	.tx_channel_mode = {
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE
+	}
+};
+
+struct enp2611_ixpdev_priv
+{
+	struct ixpdev_priv		ixpdev_priv;
+	struct net_device_stats		stats;
+};
+
+static struct net_device *nds[3];
+static struct timer_list link_check_timer;
+
+static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
+{
+	struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
+
+	pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
+
+	return &(ip->stats);
+}
+
+/* @@@ Poll the SFP moddef0 line too.  */
+/* @@@ Try to use the pm3386 DOOL interrupt as well.  */
+static void enp2611_check_link_status(unsigned long __dummy)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		struct net_device *dev;
+		int status;
+
+		dev = nds[i];
+
+		status = pm3386_is_link_up(i);
+		if (status && !netif_carrier_ok(dev)) {
+			/* @@@ Should report autonegotiation status.  */
+			printk(KERN_INFO "%s: NIC Link is Up\n", dev->name);
+
+			pm3386_enable_tx(i);
+			caleb_enable_tx(i);
+			netif_carrier_on(dev);
+		} else if (!status && netif_carrier_ok(dev)) {
+			printk(KERN_INFO "%s: NIC Link is Down\n", dev->name);
+
+			netif_carrier_off(dev);
+			caleb_disable_tx(i);
+			pm3386_disable_tx(i);
+		}
+	}
+
+	link_check_timer.expires = jiffies + HZ / 10;
+	add_timer(&link_check_timer);
+}
+
+static void enp2611_set_port_admin_status(int port, int up)
+{
+	if (up) {
+		caleb_enable_rx(port);
+
+		pm3386_set_carrier(port, 1);
+		pm3386_enable_rx(port);
+	} else {
+		caleb_disable_tx(port);
+		pm3386_disable_tx(port);
+		/* @@@ Flush out pending packets.  */
+		pm3386_set_carrier(port, 0);
+
+		pm3386_disable_rx(port);
+		caleb_disable_rx(port);
+	}
+}
+
+static int __init enp2611_init_module(void)
+{ 
+	int i;
+
+	if (!machine_is_enp2611())
+		return -ENODEV;
+
+	caleb_reset();
+	pm3386_reset();
+
+	for (i = 0; i < 3; i++) {
+		nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
+		if (nds[i] == NULL) {
+			while (--i >= 0)
+				free_netdev(nds[i]);
+			return -ENOMEM;
+		}
+
+		SET_MODULE_OWNER(nds[i]);
+		nds[i]->get_stats = enp2611_get_stats;
+		pm3386_init_port(i);
+		pm3386_get_mac(i, nds[i]->dev_addr);
+	}
+
+	ixp2400_msf_init(&enp2611_msf_parameters);
+
+	if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) {
+		for (i = 0; i < 3; i++)
+			free_netdev(nds[i]);
+		return -EINVAL;
+	}
+
+	init_timer(&link_check_timer);
+	link_check_timer.function = enp2611_check_link_status;
+	link_check_timer.expires = jiffies;
+	add_timer(&link_check_timer);
+
+	return 0;
+}
+
+static void __exit enp2611_cleanup_module(void)
+{
+	int i;
+
+	del_timer_sync(&link_check_timer);
+
+	ixpdev_deinit();
+	for (i = 0; i < 3; i++)
+		free_netdev(nds[i]);
+}
+
+module_init(enp2611_init_module);
+module_exit(enp2611_cleanup_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/ixp2400-msf.c b/drivers/net/ixp2000/ixp2400-msf.c
new file mode 100644
index 0000000..48a3a89
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400-msf.c
@@ -0,0 +1,213 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/arch/ixp2000-regs.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+#include "ixp2400-msf.h"
+
+/*
+ * This is the Intel recommended PLL init procedure as described on
+ * page 340 of the IXP2400/IXP2800 Programmer's Reference Manual.
+ */
+static void ixp2400_pll_init(struct ixp2400_msf_parameters *mp)
+{
+	int rx_dual_clock;
+	int tx_dual_clock;
+	u32 value;
+
+	/*
+	 * If the RX mode is not 1x32, we have to enable both RX PLLs
+	 * (#0 and #1.)  The same thing for the TX direction.
+	 */
+	rx_dual_clock = !!(mp->rx_mode & IXP2400_RX_MODE_WIDTH_MASK);
+	tx_dual_clock = !!(mp->tx_mode & IXP2400_TX_MODE_WIDTH_MASK);
+
+	/*
+	 * Read initial value.
+	 */
+	value = ixp2000_reg_read(IXP2000_MSF_CLK_CNTRL);
+
+	/*
+	 * Put PLLs in powerdown and bypass mode.
+	 */
+	value |= 0x0000f0f0;
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Set single or dual clock mode bits.
+	 */
+	value &= ~0x03000000;
+	value |= (rx_dual_clock << 24) | (tx_dual_clock << 25);
+
+	/*
+	 * Set multipliers.
+	 */
+	value &= ~0x00ff0000;
+	value |= mp->rxclk01_multiplier << 16;
+	value |= mp->rxclk23_multiplier << 18;
+	value |= mp->txclk01_multiplier << 20;
+	value |= mp->txclk23_multiplier << 22;
+
+	/*
+	 * And write value.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Disable PLL bypass mode.
+	 */
+	value &= ~(0x00005000 | rx_dual_clock << 13 | tx_dual_clock << 15);
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Turn on PLLs.
+	 */
+	value &= ~(0x00000050 | rx_dual_clock << 5 | tx_dual_clock << 7);
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Wait for PLLs to lock.  There are lock status bits, but IXP2400
+	 * erratum #65 says that these lock bits should not be relied upon
+	 * as they might not accurately reflect the true state of the PLLs.
+	 */
+	udelay(100);
+}
+
+/*
+ * Needed according to p480 of Programmer's Reference Manual.
+ */
+static void ixp2400_msf_free_rbuf_entries(struct ixp2400_msf_parameters *mp)
+{
+	int size_bits;
+	int i;
+
+	/*
+	 * Work around IXP2400 erratum #69 (silent RBUF-to-DRAM transfer
+	 * corruption) in the Intel-recommended way: do not add the RBUF
+	 * elements susceptible to corruption to the freelist.
+	 */
+	size_bits = mp->rx_mode & IXP2400_RX_MODE_RBUF_SIZE_MASK;
+	if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_64) {
+		for (i = 1; i < 128; i++) {
+			if (i == 9 || i == 18 || i == 27)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	} else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_128) {
+		for (i = 1; i < 64; i++) {
+			if (i == 4 || i == 9 || i == 13)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	} else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_256) {
+		for (i = 1; i < 32; i++) {
+			if (i == 2 || i == 4 || i == 6)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	}
+}
+
+static u32 ixp2400_msf_valid_channels(u32 reg)
+{
+	u32 channels;
+
+	channels = 0;
+	switch (reg & IXP2400_RX_MODE_WIDTH_MASK) {
+	case IXP2400_RX_MODE_1x32:
+		channels = 0x1;
+		if (reg & IXP2400_RX_MODE_MPHY &&
+		    !(reg & IXP2400_RX_MODE_MPHY_32))
+			channels = 0xf;
+		break;
+
+	case IXP2400_RX_MODE_2x16:
+		channels = 0x5;
+		break;
+
+	case IXP2400_RX_MODE_4x8:
+		channels = 0xf;
+		break;
+
+	case IXP2400_RX_MODE_1x16_2x8:
+		channels = 0xd;
+		break;
+	}
+
+	return channels;
+}
+
+static void ixp2400_msf_enable_rx(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+
+	value = ixp2000_reg_read(IXP2000_MSF_RX_CONTROL) & 0x0fffffff;
+	value |= ixp2400_msf_valid_channels(mp->rx_mode) << 28;
+	ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, value);
+}
+
+static void ixp2400_msf_enable_tx(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+
+	value = ixp2000_reg_read(IXP2000_MSF_TX_CONTROL) & 0x0fffffff;
+	value |= ixp2400_msf_valid_channels(mp->tx_mode) << 28;
+	ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, value);
+}
+
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+	int i;
+
+	/*
+	 * Init the RX/TX PLLs based on the passed parameter block.
+	 */
+	ixp2400_pll_init(mp);
+
+	/*
+	 * Reset MSF.  Bit 7 in IXP_RESET_0 resets the MSF.
+	 */
+	value = ixp2000_reg_read(IXP2000_RESET0);
+	ixp2000_reg_write(IXP2000_RESET0, value | 0x80);
+	ixp2000_reg_write(IXP2000_RESET0, value & ~0x80);
+
+	/*
+	 * Initialise the RX section.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_RX_MPHY_POLL_LIMIT, mp->rx_poll_ports - 1);
+	ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, mp->rx_mode);
+	for (i = 0; i < 4; i++) {
+		ixp2000_reg_write(IXP2000_MSF_RX_UP_CONTROL_0 + i,
+						mp->rx_channel_mode[i]);
+	}
+	ixp2400_msf_free_rbuf_entries(mp);
+	ixp2400_msf_enable_rx(mp);
+
+	/*
+	 * Initialise the TX section.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_TX_MPHY_POLL_LIMIT, mp->tx_poll_ports - 1);
+	ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, mp->tx_mode);
+	for (i = 0; i < 4; i++) {
+		ixp2000_reg_write(IXP2000_MSF_TX_UP_CONTROL_0 + i,
+						mp->tx_channel_mode[i]);
+	}
+	ixp2400_msf_enable_tx(mp);
+}
diff --git a/drivers/net/ixp2000/ixp2400-msf.h b/drivers/net/ixp2000/ixp2400-msf.h
new file mode 100644
index 0000000..3ac1af2
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400-msf.h
@@ -0,0 +1,115 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#ifndef __IXP2400_MSF_H
+#define __IXP2400_MSF_H
+
+struct ixp2400_msf_parameters
+{
+	u32				rx_mode;
+	unsigned			rxclk01_multiplier:2;
+	unsigned			rxclk23_multiplier:2;
+	unsigned			rx_poll_ports:6;
+	u32				rx_channel_mode[4];
+
+	u32				tx_mode;
+	unsigned			txclk01_multiplier:2;
+	unsigned			txclk23_multiplier:2;
+	unsigned			tx_poll_ports:6;
+	u32				tx_channel_mode[4];
+};
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp);
+
+#define IXP2400_PLL_MULTIPLIER_48		0x00
+#define IXP2400_PLL_MULTIPLIER_24		0x01
+#define IXP2400_PLL_MULTIPLIER_16		0x02
+#define IXP2400_PLL_MULTIPLIER_12		0x03
+
+#define IXP2400_RX_MODE_CSIX			0x00400000
+#define IXP2400_RX_MODE_UTOPIA_POS		0x00000000
+#define IXP2400_RX_MODE_WIDTH_MASK		0x00300000
+#define IXP2400_RX_MODE_1x16_2x8		0x00300000
+#define IXP2400_RX_MODE_4x8			0x00200000
+#define IXP2400_RX_MODE_2x16			0x00100000
+#define IXP2400_RX_MODE_1x32			0x00000000
+#define IXP2400_RX_MODE_MPHY			0x00080000
+#define IXP2400_RX_MODE_SPHY			0x00000000
+#define IXP2400_RX_MODE_MPHY_32			0x00040000
+#define IXP2400_RX_MODE_MPHY_4			0x00000000
+#define IXP2400_RX_MODE_MPHY_POLLED_STATUS	0x00020000
+#define IXP2400_RX_MODE_MPHY_DIRECT_STATUS	0x00000000
+#define IXP2400_RX_MODE_CBUS_FULL_DUPLEX	0x00010000
+#define IXP2400_RX_MODE_CBUS_SIMPLEX		0x00000000
+#define IXP2400_RX_MODE_MPHY_LEVEL2		0x00004000
+#define IXP2400_RX_MODE_MPHY_LEVEL3		0x00000000
+#define IXP2400_RX_MODE_CBUS_8BIT		0x00002000
+#define IXP2400_RX_MODE_CBUS_4BIT		0x00000000
+#define IXP2400_RX_MODE_CSIX_SINGLE_FREELIST	0x00000200
+#define IXP2400_RX_MODE_CSIX_SPLIT_FREELISTS	0x00000000
+#define IXP2400_RX_MODE_RBUF_SIZE_MASK		0x0000000c
+#define IXP2400_RX_MODE_RBUF_SIZE_256		0x00000008
+#define IXP2400_RX_MODE_RBUF_SIZE_128		0x00000004
+#define IXP2400_RX_MODE_RBUF_SIZE_64		0x00000000
+
+#define IXP2400_PORT_RX_MODE_SLAVE		0x00000040
+#define IXP2400_PORT_RX_MODE_MASTER		0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY_L3		0x00000020
+#define IXP2400_PORT_RX_MODE_POS_PHY_L2		0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY		0x00000010
+#define IXP2400_PORT_RX_MODE_UTOPIA		0x00000000
+#define IXP2400_PORT_RX_MODE_EVEN_PARITY	0x0000000c
+#define IXP2400_PORT_RX_MODE_ODD_PARITY		0x00000008
+#define IXP2400_PORT_RX_MODE_NO_PARITY		0x00000000
+#define IXP2400_PORT_RX_MODE_UTOPIA_BIG_CELLS	0x00000002
+#define IXP2400_PORT_RX_MODE_UTOPIA_NORMAL_CELLS	0x00000000
+#define IXP2400_PORT_RX_MODE_2_CYCLE_DECODE	0x00000001
+#define IXP2400_PORT_RX_MODE_1_CYCLE_DECODE	0x00000000
+
+#define IXP2400_TX_MODE_CSIX			0x00400000
+#define IXP2400_TX_MODE_UTOPIA_POS		0x00000000
+#define IXP2400_TX_MODE_WIDTH_MASK		0x00300000
+#define IXP2400_TX_MODE_1x16_2x8		0x00300000
+#define IXP2400_TX_MODE_4x8			0x00200000
+#define IXP2400_TX_MODE_2x16			0x00100000
+#define IXP2400_TX_MODE_1x32			0x00000000
+#define IXP2400_TX_MODE_MPHY			0x00080000
+#define IXP2400_TX_MODE_SPHY			0x00000000
+#define IXP2400_TX_MODE_MPHY_32			0x00040000
+#define IXP2400_TX_MODE_MPHY_4			0x00000000
+#define IXP2400_TX_MODE_MPHY_POLLED_STATUS	0x00020000
+#define IXP2400_TX_MODE_MPHY_DIRECT_STATUS	0x00000000
+#define IXP2400_TX_MODE_CBUS_FULL_DUPLEX	0x00010000
+#define IXP2400_TX_MODE_CBUS_SIMPLEX		0x00000000
+#define IXP2400_TX_MODE_MPHY_LEVEL2		0x00004000
+#define IXP2400_TX_MODE_MPHY_LEVEL3		0x00000000
+#define IXP2400_TX_MODE_CBUS_8BIT		0x00002000
+#define IXP2400_TX_MODE_CBUS_4BIT		0x00000000
+#define IXP2400_TX_MODE_TBUF_SIZE_MASK		0x0000000c
+#define IXP2400_TX_MODE_TBUF_SIZE_256		0x00000008
+#define IXP2400_TX_MODE_TBUF_SIZE_128		0x00000004
+#define IXP2400_TX_MODE_TBUF_SIZE_64		0x00000000
+
+#define IXP2400_PORT_TX_MODE_SLAVE		0x00000040
+#define IXP2400_PORT_TX_MODE_MASTER		0x00000000
+#define IXP2400_PORT_TX_MODE_POS_PHY		0x00000010
+#define IXP2400_PORT_TX_MODE_UTOPIA		0x00000000
+#define IXP2400_PORT_TX_MODE_EVEN_PARITY	0x0000000c
+#define IXP2400_PORT_TX_MODE_ODD_PARITY		0x00000008
+#define IXP2400_PORT_TX_MODE_NO_PARITY		0x00000000
+#define IXP2400_PORT_TX_MODE_UTOPIA_BIG_CELLS	0x00000002
+#define IXP2400_PORT_TX_MODE_2_CYCLE_DECODE	0x00000001
+#define IXP2400_PORT_TX_MODE_1_CYCLE_DECODE	0x00000000
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixp2400_rx.uc b/drivers/net/ixp2000/ixp2400_rx.uc
new file mode 100644
index 0000000..42a73e3
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_rx.uc
@@ -0,0 +1,408 @@
+/*
+ * RX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one full element list is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4.  (This
+ *   is not an exhaustive list.)
+ * - The RBUF uses 64-byte mpackets.
+ * - RX descriptors reside in SRAM, and have the following format:
+ *	struct rx_desc
+ *	{
+ *	// to uengine
+ *		u32	buf_phys_addr;
+ *		u32	buf_length;
+ *
+ *	// from uengine
+ *		u32	channel;
+ *		u32	pkt_length;
+ *	};
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 0 is rx_pending.
+ * - Scratch ring 1 is rx_done, and has status condition 'full'.
+ * - The host triggers rx_done flush and rx_pending refill on seeing INTA.
+ * - This code is run on all eight threads of the microengine it runs on.
+ *
+ * Local memory is used for per-channel RX state.
+ */
+
+#define RX_THREAD_FREELIST_0		0x0030
+#define RBUF_ELEMENT_DONE		0x0044
+
+#define CHANNEL_FLAGS			*l$index0[0]
+#define CHANNEL_FLAG_RECEIVING		1
+#define PACKET_LENGTH			*l$index0[1]
+#define PACKET_CHECKSUM			*l$index0[2]
+#define BUFFER_HANDLE			*l$index0[3]
+#define BUFFER_START			*l$index0[4]
+#define BUFFER_LENGTH			*l$index0[5]
+
+#define CHANNEL_STATE_SIZE		24	// in bytes
+#define CHANNEL_STATE_SHIFT		5	// ceil(log2(state size))
+
+
+	.sig volatile sig1
+	.sig volatile sig2
+	.sig volatile sig3
+
+	.sig mpacket_arrived
+	.reg add_to_rx_freelist
+	.reg read $rsw0, $rsw1
+	.xfer_order $rsw0 $rsw1
+
+	.reg zero
+
+	/*
+	 * Initialise add_to_rx_freelist.
+	 */
+	.begin
+		.reg temp
+		.reg temp2
+
+		immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]
+		immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]
+
+		local_csr_rd[ACTIVE_CTX_STS]
+		immed[temp, 0]
+		alu[temp2, temp, and, 0x1f]
+		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]
+		alu[temp2, temp, and, 0x80]
+		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]
+	.end
+
+	immed[zero, 0]
+
+	/*
+	 * Skip context 0 initialisation?
+	 */
+	.begin
+		br!=ctx[0, mpacket_receive_loop#]
+	.end
+
+	/*
+	 * Initialise local memory.
+	 */
+	.begin
+		.reg addr
+		.reg temp
+
+		immed[temp, 0]
+	init_local_mem_loop#:
+		alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]
+		local_csr_wr[ACTIVE_LM_ADDR_0, addr]
+		nop
+		nop
+		nop
+
+		immed[CHANNEL_FLAGS, 0]
+
+		alu[temp, temp, +, 1]
+		alu[--, temp, and, 0x20]
+		beq[init_local_mem_loop#]
+	.end
+
+	/*
+	 * Initialise signal pipeline.
+	 */
+	.begin
+		local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+		.set_sig sig1
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+		.set_sig sig2
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+		.set_sig sig3
+	.end
+
+mpacket_receive_loop#:
+	/*
+	 * Synchronise and wait for mpacket.
+	 */
+	.begin
+		ctx_arb[sig1]
+		local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+
+		msf[fast_wr, --, add_to_rx_freelist, 0]
+		.set_sig mpacket_arrived
+		ctx_arb[mpacket_arrived]
+		.set $rsw0 $rsw1
+	.end
+
+	/*
+	 * We halt if we see {inbparerr,parerr,null,soperror}.
+	 */
+	.begin
+		alu_shf[--, 0x1b, and, $rsw0, >>8]
+		bne[abort_rswerr#]
+	.end
+
+	/*
+	 * Point local memory pointer to this channel's state area.
+	 */
+	.begin
+		.reg chanaddr
+
+		alu[chanaddr, $rsw0, and, 0x1f]
+		alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]
+		local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]
+		nop
+		nop
+		nop
+	.end
+
+	/*
+	 * Check whether we received a SOP mpacket while we were already
+	 * working on a packet, or a non-SOP mpacket while there was no
+	 * packet pending.  (SOP == RECEIVING -> abort)  If everything's
+	 * okay, update the RECEIVING flag to reflect our new state.
+	 */
+	.begin
+		.reg temp
+		.reg eop
+
+		#if CHANNEL_FLAG_RECEIVING != 1
+		#error CHANNEL_FLAG_RECEIVING is not 1
+		#endif
+
+		alu_shf[temp, 1, and, $rsw0, >>15]
+		alu[temp, temp, xor, CHANNEL_FLAGS]
+		alu[--, temp, and, CHANNEL_FLAG_RECEIVING]
+		beq[abort_proterr#]
+
+		alu_shf[eop, 1, and, $rsw0, >>14]
+		alu[CHANNEL_FLAGS, temp, xor, eop]
+	.end
+
+	/*
+	 * Copy the mpacket into the right spot, and in case of EOP,
+	 * write back the descriptor and pass the packet on.
+	 */
+	.begin
+		.reg buffer_offset
+		.reg _packet_length
+		.reg _packet_checksum
+		.reg _buffer_handle
+		.reg _buffer_start
+		.reg _buffer_length
+
+		/*
+		 * Determine buffer_offset, _packet_length and
+		 * _packet_checksum.
+		 */
+		.begin
+			.reg temp
+
+			alu[--, 1, and, $rsw0, >>15]
+			beq[not_sop#]
+
+			immed[PACKET_LENGTH, 0]
+			immed[PACKET_CHECKSUM, 0]
+
+		not_sop#:
+			alu[buffer_offset, --, b, PACKET_LENGTH]
+			alu_shf[temp, 0xff, and, $rsw0, >>16]
+			alu[_packet_length, buffer_offset, +, temp]
+			alu[PACKET_LENGTH, --, b, _packet_length]
+
+			immed[temp, 0xffff]
+			alu[temp, $rsw1, and, temp]
+			alu[_packet_checksum, PACKET_CHECKSUM, +, temp]
+			alu[PACKET_CHECKSUM, --, b, _packet_checksum]
+		.end
+
+		/*
+		 * Allocate buffer in case of SOP.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>15]
+			beq[skip_buffer_alloc#]
+
+			.begin
+				.sig zzz
+				.reg read $stemp $stemp2
+				.xfer_order $stemp $stemp2
+
+			rx_nobufs#:
+				scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]
+				alu[_buffer_handle, --, b, $stemp]
+				beq[rx_nobufs#]
+
+				sram[read, $stemp, _buffer_handle, 0, 2],
+								ctx_swap[zzz]
+				alu[_buffer_start, --, b, $stemp]
+				alu[_buffer_length, --, b, $stemp2]
+			.end
+
+		skip_buffer_alloc#:
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig2]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+		.end
+
+		/*
+		 * Synchronise buffer state.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>15]
+			beq[copy_from_local_mem#]
+
+			alu[BUFFER_HANDLE, --, b, _buffer_handle]
+			alu[BUFFER_START, --, b, _buffer_start]
+			alu[BUFFER_LENGTH, --, b, _buffer_length]
+			br[sync_state_done#]
+
+		copy_from_local_mem#:
+			alu[_buffer_handle, --, b, BUFFER_HANDLE]
+			alu[_buffer_start, --, b, BUFFER_START]
+			alu[_buffer_length, --, b, BUFFER_LENGTH]
+
+		sync_state_done#:
+		.end
+
+#if 0
+		/*
+		 * Debug buffer state management.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>14]
+			beq[no_poison#]
+			immed[BUFFER_HANDLE, 0xdead]
+			immed[BUFFER_START, 0xdead]
+			immed[BUFFER_LENGTH, 0xdead]
+		no_poison#:
+
+			immed[temp, 0xdead]
+			alu[--, _buffer_handle, -, temp]
+			beq[state_corrupted#]
+			alu[--, _buffer_start, -, temp]
+			beq[state_corrupted#]
+			alu[--, _buffer_length, -, temp]
+			beq[state_corrupted#]
+		.end
+#endif
+
+		/*
+		 * Check buffer length.
+		 */
+		.begin
+			alu[--, _buffer_length, -, _packet_length]
+			blo[buffer_overflow#]
+		.end
+
+		/*
+		 * Copy the mpacket and give back the RBUF element.
+		 */
+		.begin
+			.reg element
+			.reg xfer_size
+			.reg temp
+			.sig copy_sig
+
+			alu_shf[element, 0x7f, and, $rsw0, >>24]
+			alu_shf[xfer_size, 0xff, and, $rsw0, >>16]
+
+			alu[xfer_size, xfer_size, -, 1]
+			alu_shf[xfer_size, 0x10, or, xfer_size, >>3]
+			alu_shf[temp, 0x10, or, xfer_size, <<21]
+			alu_shf[temp, temp, or, element, <<11]
+			alu_shf[--, temp, or, 1, <<18]
+
+			dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],
+						indirect_ref, sig_done[copy_sig]
+			ctx_arb[copy_sig]
+
+			alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]
+			msf[fast_wr, --, temp, 0]
+		.end
+
+		/*
+		 * If EOP, write back the packet descriptor.
+		 */
+		.begin
+			.reg write $stemp $stemp2
+			.xfer_order $stemp $stemp2
+			.sig zzz
+
+			alu_shf[--, 1, and, $rsw0, >>14]
+			beq[no_writeback#]
+
+			alu[$stemp, $rsw0, and, 0x1f]
+			alu[$stemp2, --, b, _packet_length]
+			sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]
+
+		no_writeback#:
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig3]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+		.end
+
+		/*
+		 * If EOP, put the buffer back onto the scratch ring.
+		 */
+		.begin
+			.reg write $stemp
+			.sig zzz
+
+			br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]
+
+			alu_shf[--, 1, and, $rsw0, >>14]
+			beq[mpacket_receive_loop#]
+
+			alu[--, 1, and, $rsw0, >>10]
+			bne[rxerr#]
+
+			alu[$stemp, --, b, _buffer_handle]
+			scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]
+			cap[fast_wr, 0, XSCALE_INT_A]
+			br[mpacket_receive_loop#]
+
+		rxerr#:
+			alu[$stemp, --, b, _buffer_handle]
+			scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]
+			br[mpacket_receive_loop#]
+		.end
+	.end
+
+
+abort_rswerr#:
+	halt
+
+abort_proterr#:
+	halt
+
+state_corrupted#:
+	halt
+
+buffer_overflow#:
+	halt
+
+rx_done_ring_overflow#:
+	halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_rx.ucode b/drivers/net/ixp2000/ixp2400_rx.ucode
new file mode 100644
index 0000000..e8aee2f
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_rx.ucode
@@ -0,0 +1,130 @@
+static struct ixp2000_uengine_code ixp2400_rx =
+{
+	.cpu_model_bitmask	= 0x000003fe,
+	.cpu_min_revision	= 0,
+	.cpu_max_revision	= 255,
+
+	.uengine_parameters	= IXP2000_UENGINE_8_CONTEXTS |
+				  IXP2000_UENGINE_PRN_UPDATE_EVERY |
+				  IXP2000_UENGINE_NN_FROM_PREVIOUS |
+				  IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+				  IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+				  IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+	.initial_reg_values	= (struct ixp2000_reg_value []) {
+		{ -1, -1 }
+	},
+
+	.num_insns		= 109,
+	.insns			= (u8 []) {
+		0xf0, 0x00, 0x0c, 0xc0, 0x05,
+		0xf4, 0x44, 0x0c, 0x00, 0x05,
+		0xfc, 0x04, 0x4c, 0x00, 0x00,
+		0xf0, 0x00, 0x00, 0x3b, 0x00,
+		0xb4, 0x40, 0xf0, 0x3b, 0x1f,
+		0x8a, 0xc0, 0x50, 0x3e, 0x05,
+		0xb4, 0x40, 0xf0, 0x3b, 0x80,
+		0x9a, 0xe0, 0x00, 0x3e, 0x05,
+		0xf0, 0x00, 0x00, 0x07, 0x00,
+		0xd8, 0x05, 0xc0, 0x00, 0x11,
+		0xf0, 0x00, 0x00, 0x0f, 0x00,
+		0x91, 0xb0, 0x20, 0x0e, 0x00,
+		0xfc, 0x06, 0x60, 0x0b, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x02, 0x00,
+		0xb0, 0xc0, 0x30, 0x0f, 0x01,
+		0xa4, 0x70, 0x00, 0x0f, 0x20,
+		0xd8, 0x02, 0xc0, 0x01, 0x00,
+		0xfc, 0x10, 0xac, 0x23, 0x08,
+		0xfc, 0x10, 0xac, 0x43, 0x10,
+		0xfc, 0x10, 0xac, 0x63, 0x18,
+		0xe0, 0x00, 0x00, 0x00, 0x02,
+		0xfc, 0x10, 0xae, 0x23, 0x88,
+		0x3d, 0x00, 0x04, 0x03, 0x20,
+		0xe0, 0x00, 0x00, 0x00, 0x10,
+		0x84, 0x82, 0x02, 0x01, 0x3b,
+		0xd8, 0x1a, 0x00, 0x01, 0x01,
+		0xb4, 0x00, 0x8c, 0x7d, 0x80,
+		0x91, 0xb0, 0x80, 0x22, 0x00,
+		0xfc, 0x06, 0x60, 0x23, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0x94, 0xf0, 0x92, 0x01, 0x21,
+		0xac, 0x40, 0x60, 0x26, 0x00,
+		0xa4, 0x30, 0x0c, 0x04, 0x06,
+		0xd8, 0x1a, 0x40, 0x01, 0x00,
+		0x94, 0xe0, 0xa2, 0x01, 0x21,
+		0xac, 0x20, 0x00, 0x28, 0x06,
+		0x84, 0xf2, 0x02, 0x01, 0x21,
+		0xd8, 0x0b, 0x40, 0x01, 0x00,
+		0xf0, 0x00, 0x0c, 0x02, 0x01,
+		0xf0, 0x00, 0x0c, 0x02, 0x02,
+		0xa0, 0x00, 0x08, 0x04, 0x00,
+		0x95, 0x00, 0xc6, 0x01, 0xff,
+		0xa0, 0x80, 0x10, 0x30, 0x00,
+		0xa0, 0x60, 0x1c, 0x00, 0x01,
+		0xf0, 0x0f, 0xf0, 0x33, 0xff,
+		0xb4, 0x00, 0xc0, 0x31, 0x81,
+		0xb0, 0x80, 0xb0, 0x32, 0x02,
+		0xa0, 0x20, 0x20, 0x2c, 0x00,
+		0x94, 0xf0, 0xd2, 0x01, 0x21,
+		0xd8, 0x0f, 0x40, 0x01, 0x00,
+		0x19, 0x40, 0x10, 0x04, 0x20,
+		0xa0, 0x00, 0x26, 0x04, 0x00,
+		0xd8, 0x0d, 0xc0, 0x01, 0x00,
+		0x00, 0x42, 0x10, 0x80, 0x02,
+		0xb0, 0x00, 0x46, 0x04, 0x00,
+		0xb0, 0x00, 0x56, 0x08, 0x00,
+		0xe0, 0x00, 0x00, 0x00, 0x04,
+		0xfc, 0x10, 0xae, 0x43, 0x90,
+		0x84, 0xf0, 0x32, 0x01, 0x21,
+		0xd8, 0x11, 0x40, 0x01, 0x00,
+		0xa0, 0x60, 0x3c, 0x00, 0x02,
+		0xa0, 0x20, 0x40, 0x10, 0x00,
+		0xa0, 0x20, 0x50, 0x14, 0x00,
+		0xd8, 0x12, 0x00, 0x00, 0x18,
+		0xa0, 0x00, 0x28, 0x0c, 0x00,
+		0xb0, 0x00, 0x48, 0x10, 0x00,
+		0xb0, 0x00, 0x58, 0x14, 0x00,
+		0xaa, 0xf0, 0x00, 0x14, 0x01,
+		0xd8, 0x1a, 0xc0, 0x01, 0x05,
+		0x85, 0x80, 0x42, 0x01, 0xff,
+		0x95, 0x00, 0x66, 0x01, 0xff,
+		0xba, 0xc0, 0x60, 0x1b, 0x01,
+		0x9a, 0x30, 0x60, 0x19, 0x30,
+		0x9a, 0xb0, 0x70, 0x1a, 0x30,
+		0x9b, 0x50, 0x78, 0x1e, 0x04,
+		0x8a, 0xe2, 0x08, 0x1e, 0x21,
+		0x6a, 0x4e, 0x00, 0x13, 0x00,
+		0xe0, 0x00, 0x00, 0x00, 0x30,
+		0x9b, 0x00, 0x7a, 0x92, 0x04,
+		0x3d, 0x00, 0x04, 0x1f, 0x20,
+		0x84, 0xe2, 0x02, 0x01, 0x21,
+		0xd8, 0x16, 0x80, 0x01, 0x00,
+		0xa4, 0x18, 0x0c, 0x7d, 0x80,
+		0xa0, 0x58, 0x1c, 0x00, 0x01,
+		0x01, 0x42, 0x00, 0xa0, 0x02,
+		0xe0, 0x00, 0x00, 0x00, 0x08,
+		0xfc, 0x10, 0xae, 0x63, 0x98,
+		0xd8, 0x1b, 0x00, 0xc2, 0x14,
+		0x84, 0xe2, 0x02, 0x01, 0x21,
+		0xd8, 0x05, 0xc0, 0x01, 0x00,
+		0x84, 0xa2, 0x02, 0x01, 0x21,
+		0xd8, 0x19, 0x40, 0x01, 0x01,
+		0xa0, 0x58, 0x0c, 0x00, 0x02,
+		0x1a, 0x40, 0x00, 0x04, 0x24,
+		0x33, 0x00, 0x01, 0x2f, 0x20,
+		0xd8, 0x05, 0xc0, 0x00, 0x18,
+		0xa0, 0x58, 0x0c, 0x00, 0x02,
+		0x1a, 0x40, 0x00, 0x04, 0x20,
+		0xd8, 0x05, 0xc0, 0x00, 0x18,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+	}
+};
diff --git a/drivers/net/ixp2000/ixp2400_tx.uc b/drivers/net/ixp2000/ixp2400_tx.uc
new file mode 100644
index 0000000..d090d18
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_tx.uc
@@ -0,0 +1,272 @@
+/*
+ * TX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one TBUF partition is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4. (This
+ *   is not an exhaustive list.)
+ * - The TBUF uses 64-byte mpackets.
+ * - TX descriptors reside in SRAM, and have the following format:
+ *	struct tx_desc
+ *	{
+ *	// to uengine
+ *		u32	buf_phys_addr;
+ *		u32	pkt_length;
+ *		u32	channel;
+ *	};
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 2 is tx_pending.
+ * - Scratch ring 3 is tx_done, and has status condition 'full'.
+ * - This code is run on all eight threads of the microengine it runs on.
+ */
+
+#define TX_SEQUENCE_0		0x0060
+#define TBUF_CTRL		0x1800
+
+#define PARTITION_SIZE		128
+#define PARTITION_THRESH	96
+
+
+	.sig volatile sig1
+	.sig volatile sig2
+	.sig volatile sig3
+
+	.reg @old_tx_seq_0
+	.reg @mpkts_in_flight
+	.reg @next_tbuf_mpacket
+
+	.reg @buffer_handle
+	.reg @buffer_start
+	.reg @packet_length
+	.reg @channel
+	.reg @packet_offset
+
+	.reg zero
+
+	immed[zero, 0]
+
+	/*
+	 * Skip context 0 initialisation?
+	 */
+	.begin
+		br!=ctx[0, mpacket_tx_loop#]
+	.end
+
+	/*
+	 * Wait until all pending TBUF elements have been transmitted.
+	 */
+	.begin
+		.reg read $tx
+		.sig zzz
+
+	loop_empty#:
+		msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+		alu_shf[--, --, b, $tx, >>31]
+		beq[loop_empty#]
+
+		alu[@old_tx_seq_0, --, b, $tx]
+	.end
+
+	immed[@mpkts_in_flight, 0]
+	alu[@next_tbuf_mpacket, @old_tx_seq_0, and, (PARTITION_SIZE - 1)]
+
+	immed[@buffer_handle, 0]
+
+	/*
+	 * Initialise signal pipeline.
+	 */
+	.begin
+		local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+		.set_sig sig1
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+		.set_sig sig2
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+		.set_sig sig3
+	.end
+
+mpacket_tx_loop#:
+	.begin
+		.reg tbuf_element_index
+		.reg buffer_handle
+		.reg sop_eop
+		.reg packet_data
+		.reg channel
+		.reg mpacket_size
+
+		/*
+		 * If there is no packet currently being transmitted,
+		 * dequeue the next TX descriptor, and fetch the buffer
+		 * address, packet length and destination channel number.
+		 */
+		.begin
+			.reg read $stemp $stemp2 $stemp3
+			.xfer_order $stemp $stemp2 $stemp3
+			.sig zzz
+
+			ctx_arb[sig1]
+
+			alu[--, --, b, @buffer_handle]
+			bne[already_got_packet#]
+
+		tx_nobufs#:
+			scratch[get, $stemp, zero, 8, 1], ctx_swap[zzz]
+			alu[@buffer_handle, --, b, $stemp]
+			beq[tx_nobufs#]
+
+			sram[read, $stemp, $stemp, 0, 3], ctx_swap[zzz]
+			alu[@buffer_start, --, b, $stemp]
+			alu[@packet_length, --, b, $stemp2]
+			beq[zero_byte_packet#]
+			alu[@channel, --, b, $stemp3]
+			immed[@packet_offset, 0]
+
+		already_got_packet#:
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+		.end
+
+		/*
+		 * Determine tbuf element index, SOP/EOP flags, mpacket
+		 * offset and mpacket size and cache buffer_handle and
+		 * channel number.
+		 */
+		.begin
+			alu[tbuf_element_index, --, b, @next_tbuf_mpacket]
+			alu[@next_tbuf_mpacket, @next_tbuf_mpacket, +, 1]
+			alu[@next_tbuf_mpacket, @next_tbuf_mpacket, and,
+							(PARTITION_SIZE - 1)]
+
+			alu[buffer_handle, --, b, @buffer_handle]
+			immed[@buffer_handle, 0]
+
+			immed[sop_eop, 1]
+
+			alu[packet_data, --, b, @packet_offset]
+			bne[no_sop#]
+			alu[sop_eop, sop_eop, or, 2]
+		no_sop#:
+			alu[packet_data, packet_data, +, @buffer_start]
+
+			alu[channel, --, b, @channel]
+
+			alu[mpacket_size, @packet_length, -, @packet_offset]
+			alu[--, 64, -, mpacket_size]
+			bhs[eop#]
+			alu[@buffer_handle, --, b, buffer_handle]
+			immed[mpacket_size, 64]
+			alu[sop_eop, sop_eop, and, 2]
+		eop#:
+
+			alu[@packet_offset, @packet_offset, +, mpacket_size]
+		.end
+
+		/*
+		 * Wait until there's enough space in the TBUF.
+		 */
+		.begin
+			.reg read $tx
+			.reg temp
+			.sig zzz
+
+			ctx_arb[sig2]
+
+			br[test_space#]
+
+		loop_space#:
+			msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+
+			alu[temp, $tx, -, @old_tx_seq_0]
+			alu[temp, temp, and, 0xff]
+			alu[@mpkts_in_flight, @mpkts_in_flight, -, temp]
+
+			alu[@old_tx_seq_0, --, b, $tx]
+
+		test_space#:
+			alu[--, PARTITION_THRESH, -, @mpkts_in_flight]
+			blo[loop_space#]
+
+			alu[@mpkts_in_flight, @mpkts_in_flight, +, 1]
+
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+		.end
+
+		/*
+		 * Copy the packet data to the TBUF.
+		 */
+		.begin
+			.reg temp
+			.sig copy_sig
+
+			alu[temp, mpacket_size, -, 1]
+			alu_shf[temp, 0x10, or, temp, >>3]
+			alu_shf[temp, 0x10, or, temp, <<21]
+			alu_shf[temp, temp, or, tbuf_element_index, <<11]
+			alu_shf[--, temp, or, 1, <<18]
+
+			dram[tbuf_wr, --, packet_data, 0, max_8],
+					indirect_ref, sig_done[copy_sig]
+			ctx_arb[copy_sig]
+		.end
+
+		/*
+		 * Mark TBUF element as ready-to-be-transmitted.
+		 */
+		.begin
+			.reg write $tsw $tsw2
+			.xfer_order $tsw $tsw2
+			.reg temp
+			.sig zzz
+
+			alu_shf[temp, channel, or, mpacket_size, <<24]
+			alu_shf[$tsw, temp, or, sop_eop, <<8]
+			immed[$tsw2, 0]
+
+			immed[temp, TBUF_CTRL]
+			alu_shf[temp, temp, or, tbuf_element_index, <<3]
+			msf[write, $tsw, temp, 0, 2], ctx_swap[zzz]
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig3]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+		.end
+
+		/*
+		 * If this was an EOP mpacket, recycle the TX buffer
+	 	 * and signal the host.
+		 */
+		.begin
+			.reg write $stemp
+			.sig zzz
+
+			alu[--, sop_eop, and, 1]
+			beq[mpacket_tx_loop#]
+
+		tx_done_ring_full#:
+			br_inp_state[SCR_Ring3_Status, tx_done_ring_full#]
+
+			alu[$stemp, --, b, buffer_handle]
+			scratch[put, $stemp, zero, 12, 1], ctx_swap[zzz]
+			cap[fast_wr, 0, XSCALE_INT_A]
+			br[mpacket_tx_loop#]
+		.end
+	.end
+
+
+zero_byte_packet#:
+	halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_tx.ucode b/drivers/net/ixp2000/ixp2400_tx.ucode
new file mode 100644
index 0000000..a433e24
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_tx.ucode
@@ -0,0 +1,98 @@
+static struct ixp2000_uengine_code ixp2400_tx =
+{
+	.cpu_model_bitmask	= 0x000003fe,
+	.cpu_min_revision	= 0,
+	.cpu_max_revision	= 255,
+
+	.uengine_parameters	= IXP2000_UENGINE_8_CONTEXTS |
+				  IXP2000_UENGINE_PRN_UPDATE_EVERY |
+				  IXP2000_UENGINE_NN_FROM_PREVIOUS |
+				  IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+				  IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+				  IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+	.initial_reg_values	= (struct ixp2000_reg_value []) {
+		{ -1, -1 }
+	},
+
+	.num_insns		= 77,
+	.insns			= (u8 []) {
+		0xf0, 0x00, 0x00, 0x07, 0x00,
+		0xd8, 0x03, 0x00, 0x00, 0x11,
+		0x3c, 0x40, 0x00, 0x04, 0xe0,
+		0x81, 0xf2, 0x02, 0x01, 0x00,
+		0xd8, 0x00, 0x80, 0x01, 0x00,
+		0xb0, 0x08, 0x06, 0x00, 0x00,
+		0xf0, 0x00, 0x0c, 0x00, 0x80,
+		0xb4, 0x49, 0x02, 0x03, 0x7f,
+		0xf0, 0x00, 0x02, 0x83, 0x00,
+		0xfc, 0x10, 0xac, 0x23, 0x08,
+		0xfc, 0x10, 0xac, 0x43, 0x10,
+		0xfc, 0x10, 0xac, 0x63, 0x18,
+		0xe0, 0x00, 0x00, 0x00, 0x02,
+		0xa0, 0x30, 0x02, 0x80, 0x00,
+		0xd8, 0x06, 0x00, 0x01, 0x01,
+		0x19, 0x40, 0x00, 0x04, 0x28,
+		0xb0, 0x0a, 0x06, 0x00, 0x00,
+		0xd8, 0x03, 0xc0, 0x01, 0x00,
+		0x00, 0x44, 0x00, 0x80, 0x80,
+		0xa0, 0x09, 0x06, 0x00, 0x00,
+		0xb0, 0x0b, 0x06, 0x04, 0x00,
+		0xd8, 0x13, 0x00, 0x01, 0x00,
+		0xb0, 0x0c, 0x06, 0x08, 0x00,
+		0xf0, 0x00, 0x0c, 0x00, 0xa0,
+		0xfc, 0x10, 0xae, 0x23, 0x88,
+		0xa0, 0x00, 0x12, 0x40, 0x00,
+		0xb0, 0xc9, 0x02, 0x43, 0x01,
+		0xb4, 0x49, 0x02, 0x43, 0x7f,
+		0xb0, 0x00, 0x22, 0x80, 0x00,
+		0xf0, 0x00, 0x02, 0x83, 0x00,
+		0xf0, 0x00, 0x0c, 0x04, 0x02,
+		0xb0, 0x40, 0x6c, 0x00, 0xa0,
+		0xd8, 0x08, 0x80, 0x01, 0x01,
+		0xaa, 0x00, 0x2c, 0x08, 0x02,
+		0xa0, 0xc0, 0x30, 0x18, 0x90,
+		0xa0, 0x00, 0x43, 0x00, 0x00,
+		0xba, 0xc0, 0x32, 0xc0, 0xa0,
+		0xaa, 0xb0, 0x00, 0x0f, 0x40,
+		0xd8, 0x0a, 0x80, 0x01, 0x04,
+		0xb0, 0x0a, 0x00, 0x08, 0x00,
+		0xf0, 0x00, 0x00, 0x0f, 0x40,
+		0xa4, 0x00, 0x2c, 0x08, 0x02,
+		0xa0, 0x8a, 0x00, 0x0c, 0xa0,
+		0xe0, 0x00, 0x00, 0x00, 0x04,
+		0xd8, 0x0c, 0x80, 0x00, 0x18,
+		0x3c, 0x40, 0x00, 0x04, 0xe0,
+		0xba, 0x80, 0x42, 0x01, 0x80,
+		0xb4, 0x40, 0x40, 0x13, 0xff,
+		0xaa, 0x88, 0x00, 0x10, 0x80,
+		0xb0, 0x08, 0x06, 0x00, 0x00,
+		0xaa, 0xf0, 0x0d, 0x80, 0x80,
+		0xd8, 0x0b, 0x40, 0x01, 0x05,
+		0xa0, 0x88, 0x0c, 0x04, 0x80,
+		0xfc, 0x10, 0xae, 0x43, 0x90,
+		0xba, 0xc0, 0x50, 0x0f, 0x01,
+		0x9a, 0x30, 0x50, 0x15, 0x30,
+		0x9a, 0xb0, 0x50, 0x16, 0x30,
+		0x9b, 0x50, 0x58, 0x16, 0x01,
+		0x8a, 0xe2, 0x08, 0x16, 0x21,
+		0x6b, 0x4e, 0x00, 0x83, 0x03,
+		0xe0, 0x00, 0x00, 0x00, 0x30,
+		0x9a, 0x80, 0x70, 0x0e, 0x04,
+		0x8b, 0x88, 0x08, 0x1e, 0x02,
+		0xf0, 0x00, 0x0c, 0x01, 0x81,
+		0xf0, 0x01, 0x80, 0x1f, 0x00,
+		0x9b, 0xd0, 0x78, 0x1e, 0x01,
+		0x3d, 0x42, 0x00, 0x1c, 0x20,
+		0xe0, 0x00, 0x00, 0x00, 0x08,
+		0xfc, 0x10, 0xae, 0x63, 0x98,
+		0xa4, 0x30, 0x0c, 0x04, 0x02,
+		0xd8, 0x03, 0x00, 0x01, 0x00,
+		0xd8, 0x11, 0xc1, 0x42, 0x14,
+		0xa0, 0x18, 0x00, 0x08, 0x00,
+		0x1a, 0x40, 0x00, 0x04, 0x2c,
+		0x33, 0x00, 0x01, 0x2f, 0x20,
+		0xd8, 0x03, 0x00, 0x00, 0x18,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+	}
+};
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
new file mode 100644
index 0000000..09f03f4
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -0,0 +1,421 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixp2400_rx.ucode"
+#include "ixp2400_tx.ucode"
+#include "ixpdev_priv.h"
+#include "ixpdev.h"
+
+#define DRV_MODULE_VERSION	"0.2"
+
+static int nds_count;
+static struct net_device **nds;
+static int nds_open;
+static void (*set_port_admin_status)(int port, int up);
+
+static struct ixpdev_rx_desc * const rx_desc =
+	(struct ixpdev_rx_desc *)(IXP2000_SRAM0_VIRT_BASE + RX_BUF_DESC_BASE);
+static struct ixpdev_tx_desc * const tx_desc =
+	(struct ixpdev_tx_desc *)(IXP2000_SRAM0_VIRT_BASE + TX_BUF_DESC_BASE);
+static int tx_pointer;
+
+
+static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+	struct ixpdev_tx_desc *desc;
+	int entry;
+
+	if (unlikely(skb->len > PAGE_SIZE)) {
+		/* @@@ Count drops.  */
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	entry = tx_pointer;
+	tx_pointer = (tx_pointer + 1) % TX_BUF_COUNT;
+
+	desc = tx_desc + entry;
+	desc->pkt_length = skb->len;
+	desc->channel = ip->channel;
+
+	skb_copy_and_csum_dev(skb, phys_to_virt(desc->buf_addr));
+	dev_kfree_skb(skb);
+
+	ixp2000_reg_write(RING_TX_PENDING,
+		TX_BUF_DESC_BASE + (entry * sizeof(struct ixpdev_tx_desc)));
+
+	dev->trans_start = jiffies;
+
+	local_irq_disable();
+	ip->tx_queue_entries++;
+	if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+		netif_stop_queue(dev);
+	local_irq_enable();
+
+	return 0;
+}
+
+
+static int ixpdev_rx(struct net_device *dev, int *budget)
+{
+	while (*budget > 0) {
+		struct ixpdev_rx_desc *desc;
+		struct sk_buff *skb;
+		void *buf;
+		u32 _desc;
+
+		_desc = ixp2000_reg_read(RING_RX_DONE);
+		if (_desc == 0)
+			return 0;
+
+		desc = rx_desc +
+			((_desc - RX_BUF_DESC_BASE) / sizeof(struct ixpdev_rx_desc));
+		buf = phys_to_virt(desc->buf_addr);
+
+		if (desc->pkt_length < 4 || desc->pkt_length > PAGE_SIZE) {
+			printk(KERN_ERR "ixp2000: rx err, length %d\n",
+					desc->pkt_length);
+			goto err;
+		}
+
+		if (desc->channel < 0 || desc->channel >= nds_count) {
+			printk(KERN_ERR "ixp2000: rx err, channel %d\n",
+					desc->channel);
+			goto err;
+		}
+
+		/* @@@ Make FCS stripping configurable.  */
+		desc->pkt_length -= 4;
+
+		if (unlikely(!netif_running(nds[desc->channel])))
+			goto err;
+
+		skb = dev_alloc_skb(desc->pkt_length + 2);
+		if (likely(skb != NULL)) {
+			skb->dev = nds[desc->channel];
+			skb_reserve(skb, 2);
+			eth_copy_and_sum(skb, buf, desc->pkt_length, 0);
+			skb_put(skb, desc->pkt_length);
+			skb->protocol = eth_type_trans(skb, skb->dev);
+
+			skb->dev->last_rx = jiffies;
+
+			netif_receive_skb(skb);
+		}
+
+err:
+		ixp2000_reg_write(RING_RX_PENDING, _desc);
+		dev->quota--;
+		(*budget)--;
+	}
+
+	return 1;
+}
+
+/* dev always points to nds[0].  */
+static int ixpdev_poll(struct net_device *dev, int *budget)
+{
+	/* @@@ Have to stop polling when nds[0] is administratively
+	 * downed while we are polling.  */
+	do {
+		ixp2000_reg_write(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0x00ff);
+
+		if (ixpdev_rx(dev, budget))
+			return 1;
+	} while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
+
+	netif_rx_complete(dev);
+	ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
+
+	return 0;
+}
+
+static void ixpdev_tx_complete(void)
+{
+	int channel;
+	u32 wake;
+
+	wake = 0;
+	while (1) {
+		struct ixpdev_priv *ip;
+		u32 desc;
+		int entry;
+
+		desc = ixp2000_reg_read(RING_TX_DONE);
+		if (desc == 0)
+			break;
+
+		/* @@@ Check whether entries come back in order.  */
+		entry = (desc - TX_BUF_DESC_BASE) / sizeof(struct ixpdev_tx_desc);
+		channel = tx_desc[entry].channel;
+
+		if (channel < 0 || channel >= nds_count) {
+			printk(KERN_ERR "ixp2000: txcomp channel index "
+					"out of bounds (%d, %.8i, %d)\n",
+					channel, (unsigned int)desc, entry);
+			continue;
+		}
+
+		ip = netdev_priv(nds[channel]);
+		if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+			wake |= 1 << channel;
+		ip->tx_queue_entries--;
+	}
+
+	for (channel = 0; wake != 0; channel++) {
+		if (wake & (1 << channel)) {
+			netif_wake_queue(nds[channel]);
+			wake &= ~(1 << channel);
+		}
+	}
+}
+
+static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 status;
+
+	status = ixp2000_reg_read(IXP2000_IRQ_THD_STATUS_A_0);
+	if (status == 0)
+		return IRQ_NONE;
+
+	/*
+	 * Any of the eight receive units signaled RX?
+	 */
+	if (status & 0x00ff) {
+		ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
+		if (likely(__netif_rx_schedule_prep(nds[0]))) {
+			__netif_rx_schedule(nds[0]);
+		} else {
+			printk(KERN_CRIT "ixp2000: irq while polling!!\n");
+		}
+	}
+
+	/*
+	 * Any of the eight transmit units signaled TXdone?
+	 */
+	if (status & 0xff00) {
+		ixp2000_reg_wrb(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0xff00);
+		ixpdev_tx_complete();
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ixpdev_poll_controller(struct net_device *dev)
+{
+	disable_irq(IRQ_IXP2000_THDA0);
+	ixpdev_interrupt(IRQ_IXP2000_THDA0, dev, NULL);
+	enable_irq(IRQ_IXP2000_THDA0);
+}
+#endif
+
+static int ixpdev_open(struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+	int err;
+
+	if (!nds_open++) {
+		err = request_irq(IRQ_IXP2000_THDA0, ixpdev_interrupt,
+					SA_SHIRQ, "ixp2000_eth", nds);
+		if (err) {
+			nds_open--;
+			return err;
+		}
+
+		ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0xffff);
+	}
+
+	set_port_admin_status(ip->channel, 1);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int ixpdev_close(struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	set_port_admin_status(ip->channel, 0);
+
+	if (!--nds_open) {
+		ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0xffff);
+		free_irq(IRQ_IXP2000_THDA0, nds);
+	}
+
+	return 0;
+}
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
+{
+	struct net_device *dev;
+	struct ixpdev_priv *ip;
+
+	dev = alloc_etherdev(sizeof_priv);
+	if (dev == NULL)
+		return NULL;
+
+	dev->hard_start_xmit = ixpdev_xmit;
+	dev->poll = ixpdev_poll;
+	dev->open = ixpdev_open;
+	dev->stop = ixpdev_close;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = ixpdev_poll_controller;
+#endif
+
+	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->weight = 64;
+
+	ip = netdev_priv(dev);
+	ip->channel = channel;
+	ip->tx_queue_entries = 0;
+
+	return dev;
+}
+
+int ixpdev_init(int __nds_count, struct net_device **__nds,
+		void (*__set_port_admin_status)(int port, int up))
+{
+	int i;
+	int err;
+
+	if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) {
+		static void __too_many_rx_or_tx_buffers(void);
+		__too_many_rx_or_tx_buffers();
+	}
+
+	printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
+
+	nds_count = __nds_count;
+	nds = __nds;
+	set_port_admin_status = __set_port_admin_status;
+
+	for (i = 0; i < RX_BUF_COUNT; i++) {
+		void *buf;
+
+		buf = (void *)get_zeroed_page(GFP_KERNEL);
+		if (buf == NULL) {
+			err = -ENOMEM;
+			while (--i >= 0)
+				free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+			goto err_out;
+		}
+		rx_desc[i].buf_addr = virt_to_phys(buf);
+		rx_desc[i].buf_length = PAGE_SIZE;
+	}
+
+	/* @@@ Maybe we shouldn't be preallocating TX buffers.  */
+	for (i = 0; i < TX_BUF_COUNT; i++) {
+		void *buf;
+
+		buf = (void *)get_zeroed_page(GFP_KERNEL);
+		if (buf == NULL) {
+			err = -ENOMEM;
+			while (--i >= 0)
+				free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+			goto err_free_rx;
+		}
+		tx_desc[i].buf_addr = virt_to_phys(buf);
+	}
+
+	/* 256 entries, ring status set means 'empty', base address 0x0000.  */
+	ixp2000_reg_write(RING_RX_PENDING_BASE, 0x44000000);
+	ixp2000_reg_write(RING_RX_PENDING_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_RX_PENDING_TAIL, 0x00000000);
+
+	/* 256 entries, ring status set means 'full', base address 0x0400.  */
+	ixp2000_reg_write(RING_RX_DONE_BASE, 0x40000400);
+	ixp2000_reg_write(RING_RX_DONE_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_RX_DONE_TAIL, 0x00000000);
+
+	for (i = 0; i < RX_BUF_COUNT; i++) {
+		ixp2000_reg_write(RING_RX_PENDING,
+			RX_BUF_DESC_BASE + (i * sizeof(struct ixpdev_rx_desc)));
+	}
+
+	ixp2000_uengine_load(0, &ixp2400_rx);
+	ixp2000_uengine_start_contexts(0, 0xff);
+
+	/* 256 entries, ring status set means 'empty', base address 0x0800.  */
+	ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800);
+	ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_TX_PENDING_TAIL, 0x00000000);
+
+	/* 256 entries, ring status set means 'full', base address 0x0c00.  */
+	ixp2000_reg_write(RING_TX_DONE_BASE, 0x40000c00);
+	ixp2000_reg_write(RING_TX_DONE_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_TX_DONE_TAIL, 0x00000000);
+
+	ixp2000_uengine_load(1, &ixp2400_tx);
+	ixp2000_uengine_start_contexts(1, 0xff);
+
+	for (i = 0; i < nds_count; i++) {
+		err = register_netdev(nds[i]);
+		if (err) {
+			while (--i >= 0)
+				unregister_netdev(nds[i]);
+			goto err_free_tx;
+		}
+	}
+
+	for (i = 0; i < nds_count; i++) {
+		printk(KERN_INFO "%s: IXP2000 MSF ethernet (port %d), "
+			"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", nds[i]->name, i,
+			nds[i]->dev_addr[0], nds[i]->dev_addr[1],
+			nds[i]->dev_addr[2], nds[i]->dev_addr[3],
+			nds[i]->dev_addr[4], nds[i]->dev_addr[5]);
+	}
+
+	return 0;
+
+err_free_tx:
+	for (i = 0; i < TX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+err_free_rx:
+	for (i = 0; i < RX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+
+err_out:
+	return err;
+} 
+
+void ixpdev_deinit(void)
+{
+	int i;
+
+	/* @@@ Flush out pending packets.  */
+
+	for (i = 0; i < nds_count; i++)
+		unregister_netdev(nds[i]);
+
+	ixp2000_uengine_stop_contexts(1, 0xff);
+	ixp2000_uengine_stop_contexts(0, 0xff);
+	ixp2000_uengine_reset(0x3);
+
+	for (i = 0; i < TX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+	for (i = 0; i < RX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+}
diff --git a/drivers/net/ixp2000/ixpdev.h b/drivers/net/ixp2000/ixpdev.h
new file mode 100644
index 0000000..bd686cb
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev.h
@@ -0,0 +1,27 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __IXPDEV_H
+#define __IXPDEV_H
+
+struct ixpdev_priv
+{
+	int	channel;
+	int	tx_queue_entries;
+};
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv);
+int ixpdev_init(int num_ports, struct net_device **nds,
+		void (*set_port_admin_status)(int port, int up));
+void ixpdev_deinit(void);
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixpdev_priv.h b/drivers/net/ixp2000/ixpdev_priv.h
new file mode 100644
index 0000000..86aa08e
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev_priv.h
@@ -0,0 +1,57 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __IXPDEV_PRIV_H
+#define __IXPDEV_PRIV_H
+
+#define RX_BUF_DESC_BASE	0x00001000
+#define RX_BUF_COUNT		((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_rx_desc)))
+#define TX_BUF_DESC_BASE	0x00002000
+#define TX_BUF_COUNT		((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_tx_desc)))
+#define TX_BUF_COUNT_PER_CHAN	(TX_BUF_COUNT / 4)
+
+#define RING_RX_PENDING		((u32 *)IXP2000_SCRATCH_RING_VIRT_BASE)
+#define RING_RX_DONE		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 4))
+#define RING_TX_PENDING		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 8))
+#define RING_TX_DONE		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 12))
+
+#define SCRATCH_REG(x)		((u32 *)(IXP2000_GLOBAL_REG_VIRT_BASE | 0x0800 | (x)))
+#define RING_RX_PENDING_BASE	SCRATCH_REG(0x00)
+#define RING_RX_PENDING_HEAD	SCRATCH_REG(0x04)
+#define RING_RX_PENDING_TAIL	SCRATCH_REG(0x08)
+#define RING_RX_DONE_BASE	SCRATCH_REG(0x10)
+#define RING_RX_DONE_HEAD	SCRATCH_REG(0x14)
+#define RING_RX_DONE_TAIL	SCRATCH_REG(0x18)
+#define RING_TX_PENDING_BASE	SCRATCH_REG(0x20)
+#define RING_TX_PENDING_HEAD	SCRATCH_REG(0x24)
+#define RING_TX_PENDING_TAIL	SCRATCH_REG(0x28)
+#define RING_TX_DONE_BASE	SCRATCH_REG(0x30)
+#define RING_TX_DONE_HEAD	SCRATCH_REG(0x34)
+#define RING_TX_DONE_TAIL	SCRATCH_REG(0x38)
+
+struct ixpdev_rx_desc
+{
+	u32	buf_addr;
+	u32	buf_length;
+	u32	channel;
+	u32	pkt_length;
+};
+
+struct ixpdev_tx_desc
+{
+	u32	buf_addr;
+	u32	pkt_length;
+	u32	channel;
+	u32	unused;
+};
+
+
+#endif
diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c
new file mode 100644
index 0000000..5c7ab75
--- /dev/null
+++ b/drivers/net/ixp2000/pm3386.c
@@ -0,0 +1,334 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/module.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include "pm3386.h"
+
+/*
+ * Read from register 'reg' of PM3386 device 'pm'.
+ */
+static u16 pm3386_reg_read(int pm, int reg)
+{
+	void *_reg;
+	u16 value;
+
+	_reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+	if (pm == 1)
+		_reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+	value = *((volatile u16 *)(_reg + (reg << 1)));
+
+//	printk(KERN_INFO "pm3386_reg_read(%d, %.3x) = %.8x\n", pm, reg, value);
+
+	return value;
+}
+
+/*
+ * Write to register 'reg' of PM3386 device 'pm', and perform
+ * a readback from the identification register.
+ */
+static void pm3386_reg_write(int pm, int reg, u16 value)
+{
+	void *_reg;
+	u16 dummy;
+
+//	printk(KERN_INFO "pm3386_reg_write(%d, %.3x, %.8x)\n", pm, reg, value);
+
+	_reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+	if (pm == 1)
+		_reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+	*((volatile u16 *)(_reg + (reg << 1))) = value;
+
+	dummy = *((volatile u16 *)_reg);
+	__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+/*
+ * Read from port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static u16 pm3386_port_reg_read(int port, int _reg, int spacing)
+{
+	int reg;
+
+	reg = _reg;
+	if (port & 1)
+		reg += spacing;
+
+	return pm3386_reg_read(port >> 1, reg);
+}
+
+/*
+ * Write to port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value)
+{
+	int reg;
+
+	reg = _reg;
+	if (port & 1)
+		reg += spacing;
+
+	pm3386_reg_write(port >> 1, reg, value);
+}
+
+
+void pm3386_reset(void)
+{
+	u8 mac[3][6];
+
+	/* Save programmed MAC addresses.  */
+	pm3386_get_mac(0, mac[0]);
+	pm3386_get_mac(1, mac[1]);
+	pm3386_get_mac(2, mac[2]);
+
+	/* Assert analog and digital reset.  */
+	pm3386_reg_write(0, 0x002, 0x0060);
+	pm3386_reg_write(1, 0x002, 0x0060);
+	mdelay(1);
+
+	/* Deassert analog reset.  */
+	pm3386_reg_write(0, 0x002, 0x0062);
+	pm3386_reg_write(1, 0x002, 0x0062);
+	mdelay(10);
+
+	/* Deassert digital reset.  */
+	pm3386_reg_write(0, 0x002, 0x0063);
+	pm3386_reg_write(1, 0x002, 0x0063);
+	mdelay(10);
+
+	/* Restore programmed MAC addresses.  */
+	pm3386_set_mac(0, mac[0]);
+	pm3386_set_mac(1, mac[1]);
+	pm3386_set_mac(2, mac[2]);
+
+	/* Disable carrier on all ports.  */
+	pm3386_set_carrier(0, 0);
+	pm3386_set_carrier(1, 0);
+	pm3386_set_carrier(2, 0);
+}
+
+static u16 swaph(u16 x)
+{
+	return ((x << 8) | (x >> 8)) & 0xffff;
+}
+
+void pm3386_init_port(int port)
+{
+	int pm = port >> 1;
+
+	/*
+	 * Work around ENP2611 bootloader programming MAC address
+	 * in reverse.
+	 */
+	if (pm3386_port_reg_read(port, 0x30a, 0x100) == 0x0000 &&
+	    (pm3386_port_reg_read(port, 0x309, 0x100) & 0xff00) == 0x5000) {
+		u16 temp[3];
+
+		temp[0] = pm3386_port_reg_read(port, 0x308, 0x100);
+		temp[1] = pm3386_port_reg_read(port, 0x309, 0x100);
+		temp[2] = pm3386_port_reg_read(port, 0x30a, 0x100);
+		pm3386_port_reg_write(port, 0x308, 0x100, swaph(temp[2]));
+		pm3386_port_reg_write(port, 0x309, 0x100, swaph(temp[1]));
+		pm3386_port_reg_write(port, 0x30a, 0x100, swaph(temp[0]));
+	}
+
+	/*
+	 * Initialise narrowbanding mode.  See application note 2010486
+	 * for more information.  (@@@ We also need to issue a reset
+	 * when ROOL or DOOL are detected.)
+	 */
+	pm3386_port_reg_write(port, 0x708, 0x10, 0xd055);
+	udelay(500);
+	pm3386_port_reg_write(port, 0x708, 0x10, 0x5055);
+
+	/*
+	 * SPI-3 ingress block.  Set 64 bytes SPI-3 burst size
+	 * towards SPI-3 bridge.
+	 */
+	pm3386_port_reg_write(port, 0x122, 0x20, 0x0002);
+
+	/*
+	 * Enable ingress protocol checking, and soft reset the
+	 * SPI-3 ingress block.
+	 */
+	pm3386_reg_write(pm, 0x103, 0x0003);
+	while (!(pm3386_reg_read(pm, 0x103) & 0x80))
+		;
+
+	/*
+	 * SPI-3 egress block.  Gather 12288 bytes of the current
+	 * packet in the TX fifo before initiating transmit on the
+	 * SERDES interface.  (Prevents TX underflows.)
+	 */
+	pm3386_port_reg_write(port, 0x221, 0x20, 0x0007);
+
+	/*
+	 * Enforce odd parity from the SPI-3 bridge, and soft reset
+	 * the SPI-3 egress block.
+	 */
+	pm3386_reg_write(pm, 0x203, 0x000d & ~(4 << (port & 1)));
+	while ((pm3386_reg_read(pm, 0x203) & 0x000c) != 0x000c)
+		;
+
+	/*
+	 * EGMAC block.  Set this channels to reject long preambles,
+	 * not send or transmit PAUSE frames, enable preamble checking,
+	 * disable frame length checking, enable FCS appending, enable
+	 * TX frame padding.
+	 */
+	pm3386_port_reg_write(port, 0x302, 0x100, 0x0113);
+
+	/*
+	 * Soft reset the EGMAC block.
+	 */
+	pm3386_port_reg_write(port, 0x301, 0x100, 0x8000);
+	pm3386_port_reg_write(port, 0x301, 0x100, 0x0000);
+
+	/*
+	 * Auto-sense autonegotiation status.
+	 */
+	pm3386_port_reg_write(port, 0x306, 0x100, 0x0100);
+
+	/*
+	 * Allow reception of jumbo frames.
+	 */
+	pm3386_port_reg_write(port, 0x310, 0x100, 9018);
+
+	/*
+	 * Allow transmission of jumbo frames.
+	 */
+	pm3386_port_reg_write(port, 0x336, 0x100, 9018);
+
+	/* @@@ Should set 0x337/0x437 (RX forwarding threshold.)  */
+
+	/*
+	 * Set autonegotiation parameters to 'no PAUSE, full duplex.'
+	 */
+	pm3386_port_reg_write(port, 0x31c, 0x100, 0x0020);
+
+	/*
+	 * Enable and restart autonegotiation.
+	 */
+	pm3386_port_reg_write(port, 0x318, 0x100, 0x0003);
+	pm3386_port_reg_write(port, 0x318, 0x100, 0x0002);
+}
+
+void pm3386_get_mac(int port, u8 *mac)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x308, 0x100);
+	mac[0] = temp & 0xff;
+	mac[1] = (temp >> 8) & 0xff;
+
+	temp = pm3386_port_reg_read(port, 0x309, 0x100);
+	mac[2] = temp & 0xff;
+	mac[3] = (temp >> 8) & 0xff;
+
+	temp = pm3386_port_reg_read(port, 0x30a, 0x100);
+	mac[4] = temp & 0xff;
+	mac[5] = (temp >> 8) & 0xff;
+}
+
+void pm3386_set_mac(int port, u8 *mac)
+{
+	pm3386_port_reg_write(port, 0x308, 0x100, (mac[1] << 8) | mac[0]);
+	pm3386_port_reg_write(port, 0x309, 0x100, (mac[3] << 8) | mac[2]);
+	pm3386_port_reg_write(port, 0x30a, 0x100, (mac[5] << 8) | mac[4]);
+}
+
+static u32 pm3386_get_stat(int port, u16 base)
+{
+	u32 value;
+
+	value = pm3386_port_reg_read(port, base, 0x100);
+	value |= pm3386_port_reg_read(port, base + 1, 0x100) << 16;
+
+	return value;
+}
+
+void pm3386_get_stats(int port, struct net_device_stats *stats)
+{
+	/*
+	 * Snapshot statistics counters.
+	 */
+	pm3386_port_reg_write(port, 0x500, 0x100, 0x0001);
+	while (pm3386_port_reg_read(port, 0x500, 0x100) & 0x0001)
+		;
+
+	memset(stats, 0, sizeof(*stats));
+
+	stats->rx_packets = pm3386_get_stat(port, 0x510);
+	stats->tx_packets = pm3386_get_stat(port, 0x590);
+	stats->rx_bytes = pm3386_get_stat(port, 0x514);
+	stats->tx_bytes = pm3386_get_stat(port, 0x594);
+	/* @@@ Add other stats.  */
+}
+
+void pm3386_set_carrier(int port, int state)
+{
+	pm3386_port_reg_write(port, 0x703, 0x10, state ? 0x1001 : 0x0000);
+}
+
+int pm3386_is_link_up(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+	temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+
+	return !!(temp & 0x0002);
+}
+
+void pm3386_enable_rx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp |= 0x1000;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_rx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp &= 0xefff;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_enable_tx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp |= 0x4000;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_tx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp &= 0xbfff;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/pm3386.h b/drivers/net/ixp2000/pm3386.h
new file mode 100644
index 0000000..fe92bb0
--- /dev/null
+++ b/drivers/net/ixp2000/pm3386.h
@@ -0,0 +1,28 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __PM3386_H
+#define __PM3386_H
+
+void pm3386_reset(void);
+void pm3386_init_port(int port);
+void pm3386_get_mac(int port, u8 *mac);
+void pm3386_set_mac(int port, u8 *mac);
+void pm3386_get_stats(int port, struct net_device_stats *stats);
+void pm3386_set_carrier(int port, int state);
+int pm3386_is_link_up(int port);
+void pm3386_enable_rx(int port);
+void pm3386_disable_rx(int port);
+void pm3386_enable_tx(int port);
+void pm3386_disable_tx(int port);
+
+
+#endif
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index f857ae9..b0c3b6a 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -115,6 +115,7 @@
 #include <linux/ethtool.h>
 #include <linux/timer.h>
 #include <linux/if_vlan.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index a842ecc..9369f81 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -85,7 +85,7 @@
 static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
 static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
 
-static struct proto_ops pppoe_ops;
+static const struct proto_ops pppoe_ops;
 static DEFINE_RWLOCK(pppoe_hash_lock);
 
 static struct ppp_channel_ops pppoe_chan_ops;
@@ -383,8 +383,6 @@
 {
 	struct pppoe_hdr *ph;
 	struct pppox_sock *po;
-	struct sock *sk;
-	int ret;
 
 	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
 		goto drop;
@@ -395,24 +393,8 @@
 	ph = (struct pppoe_hdr *) skb->nh.raw;
 
 	po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
-	if (!po) 
-		goto drop;
-
-	sk = sk_pppox(po);
-	bh_lock_sock(sk);
-
-	/* Socket state is unknown, must put skb into backlog. */
-	if (sock_owned_by_user(sk) != 0) {
-		sk_add_backlog(sk, skb);
-		ret = NET_RX_SUCCESS;
-	} else {
-		ret = pppoe_rcv_core(sk, skb);
-	}
-
-	bh_unlock_sock(sk);
-	sock_put(sk);
-
-	return ret;
+	if (po != NULL) 
+		return sk_receive_skb(sk_pppox(po), skb);
 drop:
 	kfree_skb(skb);
 out:
@@ -1081,9 +1063,7 @@
 static inline int pppoe_proc_init(void) { return 0; }
 #endif /* CONFIG_PROC_FS */
 
-/* ->ioctl are set at pppox_create */
-
-static struct proto_ops pppoe_ops = {
+static const struct proto_ops pppoe_ops = {
     .family		= AF_PPPOX,
     .owner		= THIS_MODULE,
     .release		= pppoe_release,
@@ -1099,7 +1079,8 @@
     .getsockopt		= sock_no_getsockopt,
     .sendmsg		= pppoe_sendmsg,
     .recvmsg		= pppoe_recvmsg,
-    .mmap		= sock_no_mmap
+    .mmap		= sock_no_mmap,
+    .ioctl		= pppox_ioctl,
 };
 
 static struct pppox_proto pppoe_proto = {
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index 0c1e114..9315046 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -68,8 +68,7 @@
 EXPORT_SYMBOL(unregister_pppox_proto);
 EXPORT_SYMBOL(pppox_unbind_sock);
 
-static int pppox_ioctl(struct socket* sock, unsigned int cmd, 
-		       unsigned long arg)
+int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
 	struct pppox_sock *po = pppox_sk(sk);
@@ -105,6 +104,7 @@
 	return rc;
 }
 
+EXPORT_SYMBOL(pppox_ioctl);
 
 static int pppox_create(struct socket *sock, int protocol)
 {
@@ -119,11 +119,7 @@
 		goto out;
 
 	rc = pppox_protos[protocol]->create(sock);
-	if (!rc) {
-		/* We get to set the ioctl handler. */
-		/* For everything else, pppox is just a shell. */
-		sock->ops->ioctl = pppox_ioctl;
-	}
+
 	module_put(pppox_protos[protocol]->owner);
 out:
 	return rc;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 669dd52..89c4678 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -66,7 +66,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "Version 2.0.9.3"
+#define DRV_VERSION "Version 2.0.9.4"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -412,7 +412,7 @@
 		    config->tx_cfg[i].fifo_len - 1;
 		mac_control->fifos[i].fifo_no = i;
 		mac_control->fifos[i].nic = nic;
-		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 1;
+		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
 
 		for (j = 0; j < page_num; j++) {
 			int k = 0;
@@ -459,6 +459,10 @@
 		}
 	}
 
+	nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL);
+	if (!nic->ufo_in_band_v)
+		return -ENOMEM;
+
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
@@ -731,6 +735,8 @@
 				    mac_control->stats_mem,
 				    mac_control->stats_mem_phy);
 	}
+	if (nic->ufo_in_band_v)
+		kfree(nic->ufo_in_band_v);
 }
 
 /**
@@ -2003,6 +2009,49 @@
 
 	return SUCCESS;
 }
+/**
+ * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb
+ */
+static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, int get_off)
+{
+	nic_t *nic = fifo_data->nic;
+	struct sk_buff *skb;
+	TxD_t *txds;
+	u16 j, frg_cnt;
+
+	txds = txdlp;
+	if (txds->Host_Control == (u64)(long)nic->ufo_in_band_v) {
+		pci_unmap_single(nic->pdev, (dma_addr_t)
+			txds->Buffer_Pointer, sizeof(u64),
+			PCI_DMA_TODEVICE);
+		txds++;
+	}
+
+	skb = (struct sk_buff *) ((unsigned long)
+			txds->Host_Control);
+	if (!skb) {
+		memset(txdlp, 0, (sizeof(TxD_t) * fifo_data->max_txds));
+		return NULL;
+	}
+	pci_unmap_single(nic->pdev, (dma_addr_t)
+			 txds->Buffer_Pointer,
+			 skb->len - skb->data_len,
+			 PCI_DMA_TODEVICE);
+	frg_cnt = skb_shinfo(skb)->nr_frags;
+	if (frg_cnt) {
+		txds++;
+		for (j = 0; j < frg_cnt; j++, txds++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
+			if (!txds->Buffer_Pointer)
+				break;
+			pci_unmap_page(nic->pdev, (dma_addr_t) 
+					txds->Buffer_Pointer,
+				       frag->size, PCI_DMA_TODEVICE);
+		}
+	}
+	txdlp->Host_Control = 0;
+	return(skb);
+}
 
 /**
  *  free_tx_buffers - Free all queued Tx buffers
@@ -2020,7 +2069,7 @@
 	int i, j;
 	mac_info_t *mac_control;
 	struct config_param *config;
-	int cnt = 0, frg_cnt;
+	int cnt = 0;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -2029,38 +2078,11 @@
 		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
 			txdp = (TxD_t *) mac_control->fifos[i].list_info[j].
 			    list_virt_addr;
-			skb =
-			    (struct sk_buff *) ((unsigned long) txdp->
-						Host_Control);
-			if (skb == NULL) {
-				memset(txdp, 0, sizeof(TxD_t) *
-				       config->max_txds);
-				continue;
+			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+			if (skb) {
+				dev_kfree_skb(skb);
+				cnt++;
 			}
-			frg_cnt = skb_shinfo(skb)->nr_frags;
-			pci_unmap_single(nic->pdev, (dma_addr_t)
-					 txdp->Buffer_Pointer,
-					 skb->len - skb->data_len,
-					 PCI_DMA_TODEVICE);
-			if (frg_cnt) {
-				TxD_t *temp;
-				temp = txdp;
-				txdp++;
-				for (j = 0; j < frg_cnt; j++, txdp++) {
-					skb_frag_t *frag =
-					    &skb_shinfo(skb)->frags[j];
-					pci_unmap_page(nic->pdev,
-						       (dma_addr_t)
-						       txdp->
-						       Buffer_Pointer,
-						       frag->size,
-						       PCI_DMA_TODEVICE);
-				}
-				txdp = temp;
-			}
-			dev_kfree_skb(skb);
-			memset(txdp, 0, sizeof(TxD_t) * config->max_txds);
-			cnt++;
 		}
 		DBG_PRINT(INTR_DBG,
 			  "%s:forcibly freeing %d skbs on FIFO%d\n",
@@ -2661,7 +2683,6 @@
 	tx_curr_get_info_t get_info, put_info;
 	struct sk_buff *skb;
 	TxD_t *txdlp;
-	u16 j, frg_cnt;
 
 	get_info = fifo_data->tx_curr_get_info;
 	put_info = fifo_data->tx_curr_put_info;
@@ -2684,8 +2705,7 @@
 			}
 		}
 
-		skb = (struct sk_buff *) ((unsigned long)
-				txdlp->Host_Control);
+		skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
 		if (skb == NULL) {
 			DBG_PRINT(ERR_DBG, "%s: Null skb ",
 			__FUNCTION__);
@@ -2693,34 +2713,6 @@
 			return;
 		}
 
-		frg_cnt = skb_shinfo(skb)->nr_frags;
-		nic->tx_pkt_count++;
-
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 txdlp->Buffer_Pointer,
-				 skb->len - skb->data_len,
-				 PCI_DMA_TODEVICE);
-		if (frg_cnt) {
-			TxD_t *temp;
-			temp = txdlp;
-			txdlp++;
-			for (j = 0; j < frg_cnt; j++, txdlp++) {
-				skb_frag_t *frag =
-				    &skb_shinfo(skb)->frags[j];
-				if (!txdlp->Buffer_Pointer)
-					break;
-				pci_unmap_page(nic->pdev,
-					       (dma_addr_t)
-					       txdlp->
-					       Buffer_Pointer,
-					       frag->size,
-					       PCI_DMA_TODEVICE);
-			}
-			txdlp = temp;
-		}
-		memset(txdlp, 0,
-		       (sizeof(TxD_t) * fifo_data->max_txds));
-
 		/* Updating the statistics block */
 		nic->stats.tx_bytes += skb->len;
 		dev_kfree_skb_irq(skb);
@@ -3331,7 +3323,7 @@
 					  s2io_msix_fifo_handle, 0, sp->desc1,
 					  sp->s2io_entries[i].arg);
 				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, 
-							sp->msix_info[i].addr);
+				    (unsigned long long)sp->msix_info[i].addr);
 			} else {
 				sprintf(sp->desc2, "%s:MSI-X-%d-RX",
 					dev->name, i);
@@ -3339,7 +3331,7 @@
 					  s2io_msix_ring_handle, 0, sp->desc2,
 					  sp->s2io_entries[i].arg);
 				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, 
-							sp->msix_info[i].addr);
+				     (unsigned long long)sp->msix_info[i].addr);
 			}
 			if (err) {
 				DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
@@ -3527,6 +3519,8 @@
 		return 0;
 	}
 
+	txdp->Control_1 = 0;
+	txdp->Control_2 = 0;
 #ifdef NETIF_F_TSO
 	mss = skb_shinfo(skb)->tso_size;
 	if (mss) {
@@ -3534,19 +3528,13 @@
 		txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
 	}
 #endif
-
-	frg_cnt = skb_shinfo(skb)->nr_frags;
-	frg_len = skb->len - skb->data_len;
-
-	txdp->Buffer_Pointer = pci_map_single
-	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
-	txdp->Host_Control = (unsigned long) skb;
 	if (skb->ip_summed == CHECKSUM_HW) {
 		txdp->Control_2 |=
 		    (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN |
 		     TXD_TX_CKO_UDP_EN);
 	}
-
+	txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
+	txdp->Control_1 |= TXD_LIST_OWN_XENA;
 	txdp->Control_2 |= config->tx_intr_type;
 
 	if (sp->vlgrp && vlan_tx_tag_present(skb)) {
@@ -3554,10 +3542,40 @@
 		txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
 	}
 
-	txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
-			    TXD_GATHER_CODE_FIRST);
-	txdp->Control_1 |= TXD_LIST_OWN_XENA;
+	frg_len = skb->len - skb->data_len;
+	if (skb_shinfo(skb)->ufo_size) {
+		int ufo_size;
 
+		ufo_size = skb_shinfo(skb)->ufo_size;
+		ufo_size &= ~7;
+		txdp->Control_1 |= TXD_UFO_EN;
+		txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
+		txdp->Control_1 |= TXD_BUFFER0_SIZE(8);
+#ifdef __BIG_ENDIAN
+		sp->ufo_in_band_v[put_off] =
+				(u64)skb_shinfo(skb)->ip6_frag_id;
+#else
+		sp->ufo_in_band_v[put_off] =
+				(u64)skb_shinfo(skb)->ip6_frag_id << 32;
+#endif
+		txdp->Host_Control = (unsigned long)sp->ufo_in_band_v;
+		txdp->Buffer_Pointer = pci_map_single(sp->pdev,
+					sp->ufo_in_band_v,
+					sizeof(u64), PCI_DMA_TODEVICE);
+		txdp++;
+		txdp->Control_1 = 0;
+		txdp->Control_2 = 0;
+	}
+
+	txdp->Buffer_Pointer = pci_map_single
+	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+	txdp->Host_Control = (unsigned long) skb;
+	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
+
+	if (skb_shinfo(skb)->ufo_size)
+		txdp->Control_1 |= TXD_UFO_EN;
+
+	frg_cnt = skb_shinfo(skb)->nr_frags;
 	/* For fragmented SKB. */
 	for (i = 0; i < frg_cnt; i++) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -3569,9 +3587,14 @@
 		    (sp->pdev, frag->page, frag->page_offset,
 		     frag->size, PCI_DMA_TODEVICE);
 		txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size);
+		if (skb_shinfo(skb)->ufo_size)
+			txdp->Control_1 |= TXD_UFO_EN;
 	}
 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
 
+	if (skb_shinfo(skb)->ufo_size)
+		frg_cnt++; /* as Txd0 was used for inband header */
+
 	tx_fifo = mac_control->tx_FIFO_start[queue];
 	val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr;
 	writeq(val64, &tx_fifo->TxDL_Pointer);
@@ -3583,6 +3606,8 @@
 	if (mss)
 		val64 |= TX_FIFO_SPECIAL_FUNC;
 #endif
+	if (skb_shinfo(skb)->ufo_size)
+		val64 |= TX_FIFO_SPECIAL_FUNC;
 	writeq(val64, &tx_fifo->List_Control);
 
 	mmiowb();
@@ -4721,7 +4746,10 @@
 		fail = 1;
 
 	if (ret_data != 0x012345) {
-		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. "
+			"Data written %llx Data read %llx\n",
+			dev->name, (unsigned long long)0x12345,
+			(unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -4740,7 +4768,10 @@
 		fail = 1;
 
 	if (ret_data != 0x012345) {
-		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. "
+			"Data written %llx Data read %llx\n",
+			dev->name, (unsigned long long)0x12345,
+			(unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -5190,6 +5221,8 @@
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 #endif
+	.get_ufo = ethtool_op_get_ufo,
+	.set_ufo = ethtool_op_set_ufo,
 	.self_test_count = s2io_ethtool_self_test_count,
 	.self_test = s2io_ethtool_test,
 	.get_strings = s2io_ethtool_get_strings,
@@ -5941,7 +5974,8 @@
 			break;
 		}
 	}
-	config->max_txds = MAX_SKB_FRAGS + 1;
+	/* + 2 because one Txd for skb->data and one Txd for UFO */
+	config->max_txds = MAX_SKB_FRAGS + 2;
 
 	/* Rx side parameters. */
 	if (rx_ring_sz[0] == 0)
@@ -6035,6 +6069,10 @@
 #ifdef NETIF_F_TSO
 	dev->features |= NETIF_F_TSO;
 #endif
+	if (sp->device_type & XFRAME_II_DEVICE) {
+		dev->features |= NETIF_F_UFO;
+		dev->features |= NETIF_F_HW_CSUM;
+	}
 
 	dev->tx_timeout = &s2io_tx_watchdog;
 	dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 419aad7..852a6a8 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -393,7 +393,9 @@
 #define TXD_GATHER_CODE_LAST    BIT(23)
 #define TXD_TCP_LSO_EN          BIT(30)
 #define TXD_UDP_COF_EN          BIT(31)
+#define TXD_UFO_EN		BIT(31) | BIT(30)
 #define TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
+#define TXD_UFO_MSS(val)	vBIT(val,34,14)
 #define TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
 
 	u64 Control_2;
@@ -789,6 +791,7 @@
 
 	spinlock_t	rx_lock;
 	atomic_t	isr_cnt;
+	u64 *ufo_in_band_v;
 };
 
 #define RESET_ERROR 1;
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 1d4d886..3d95fa2 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.08 Jan. 22 2005
+   Revision:	1.08.09 Sep. 19 2005
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -17,6 +17,7 @@
    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
    preliminary Rev. 1.0 Jan. 18, 1998
 
+   Rev 1.08.09 Sep. 19 2005 Daniele Venzano add Wake on LAN support
    Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages
    Rev 1.08.07 Nov.  2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support
    Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
@@ -76,7 +77,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.08 Jan. 22 2005"
+#define SIS900_DRV_VERSION "v1.08.09 Sep. 19 2005"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -538,6 +539,11 @@
 		printk("%2.2x:", (u8)net_dev->dev_addr[i]);
 	printk("%2.2x.\n", net_dev->dev_addr[i]);
 
+	/* Detect Wake on Lan support */
+	ret = inl(CFGPMC & PMESP);
+	if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0)
+		printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name);
+
 	return 0;
 
  err_unmap_rx:
@@ -2015,6 +2021,67 @@
 	return mii_nway_restart(&sis_priv->mii_info);
 }
 
+/**
+ *	sis900_set_wol - Set up Wake on Lan registers
+ *	@net_dev: the net device to probe
+ *	@wol: container for info passed to the driver
+ *
+ *	Process ethtool command "wol" to setup wake on lan features.
+ *	SiS900 supports sending WoL events if a correct packet is received,
+ *	but there is no simple way to filter them to only a subset (broadcast,
+ *	multicast, unicast or arp).
+ */
+ 
+static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+	struct sis900_private *sis_priv = net_dev->priv;
+	long pmctrl_addr = net_dev->base_addr + pmctrl;
+	u32 cfgpmcsr = 0, pmctrl_bits = 0;
+
+	if (wol->wolopts == 0) {
+		pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+		cfgpmcsr |= ~PME_EN;
+		pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+		outl(pmctrl_bits, pmctrl_addr);
+		if (netif_msg_wol(sis_priv))
+			printk(KERN_DEBUG "%s: Wake on LAN disabled\n", net_dev->name);
+		return 0;
+	}
+
+	if (wol->wolopts & (WAKE_MAGICSECURE | WAKE_UCAST | WAKE_MCAST
+				| WAKE_BCAST | WAKE_ARP))
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		pmctrl_bits |= MAGICPKT;
+	if (wol->wolopts & WAKE_PHY)
+		pmctrl_bits |= LINKON;
+	
+	outl(pmctrl_bits, pmctrl_addr);
+
+	pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+	cfgpmcsr |= PME_EN;
+	pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+	if (netif_msg_wol(sis_priv))
+		printk(KERN_DEBUG "%s: Wake on LAN enabled\n", net_dev->name);
+
+	return 0;
+}
+
+static void sis900_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+	long pmctrl_addr = net_dev->base_addr + pmctrl;
+	u32 pmctrl_bits;
+
+	pmctrl_bits = inl(pmctrl_addr);
+	if (pmctrl_bits & MAGICPKT)
+		wol->wolopts |= WAKE_MAGIC;
+	if (pmctrl_bits & LINKON)
+		wol->wolopts |= WAKE_PHY;
+
+	wol->supported = (WAKE_PHY | WAKE_MAGIC);
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
 	.get_drvinfo 	= sis900_get_drvinfo,
 	.get_msglevel	= sis900_get_msglevel,
@@ -2023,6 +2090,8 @@
 	.get_settings	= sis900_get_settings,
 	.set_settings	= sis900_set_settings,
 	.nway_reset	= sis900_nway_reset,
+	.get_wol	= sis900_get_wol,
+	.set_wol	= sis900_set_wol
 };
 
 /**
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h
index de3c067..4233ea5 100644
--- a/drivers/net/sis900.h
+++ b/drivers/net/sis900.h
@@ -33,6 +33,7 @@
         rxcfg=0x34,             //Receive Configuration Register
         flctrl=0x38,            //Flow Control Register
         rxlen=0x3c,             //Receive Packet Length Register
+        cfgpmcsr=0x44,          //Configuration Power Management Control/Status Register
         rfcr=0x48,              //Receive Filter Control Register
         rfdr=0x4C,              //Receive Filter Data Register
         pmctrl=0xB0,            //Power Management Control Register
@@ -140,6 +141,50 @@
 	EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
 };
 
+/* PCI Registers */
+enum sis900_pci_registers {
+	CFGPMC 	 = 0x40,
+	CFGPMCSR = 0x44
+};
+
+/* Power management capabilities bits */
+enum sis900_cfgpmc_register_bits {
+	PMVER	= 0x00070000, 
+	DSI	= 0x00100000,
+	PMESP	= 0xf8000000
+};
+
+enum sis900_pmesp_bits {
+	PME_D0 = 0x1,
+	PME_D1 = 0x2,
+	PME_D2 = 0x4,
+	PME_D3H = 0x8,
+	PME_D3C = 0x10
+};
+
+/* Power management control/status bits */
+enum sis900_cfgpmcsr_register_bits {
+	PMESTS = 0x00004000,
+	PME_EN = 0x00000100, // Power management enable
+	PWR_STA = 0x00000003 // Current power state
+};
+
+/* Wake-on-LAN support. */
+enum sis900_power_management_control_register_bits {
+	LINKLOSS  = 0x00000001,
+	LINKON    = 0x00000002,
+	MAGICPKT  = 0x00000400,
+	ALGORITHM = 0x00000800,
+	FRM1EN    = 0x00100000,
+	FRM2EN    = 0x00200000,
+	FRM3EN    = 0x00400000,
+	FRM1ACS   = 0x01000000,
+	FRM2ACS   = 0x02000000,
+	FRM3ACS   = 0x04000000,
+	WAKEALL   = 0x40000000,
+	GATECLK   = 0x80000000
+};
+
 /* Management Data I/O (mdio) frame */
 #define MIIread         0x6000
 #define MIIwrite        0x5002
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
index 7653d6e..afd900d 100644
--- a/drivers/net/sk98lin/Makefile
+++ b/drivers/net/sk98lin/Makefile
@@ -26,8 +26,7 @@
 		skrlmt.o	\
 		sktimer.o	\
 		skvpd.o		\
-		skxmac2.o	\
-		skproc.o
+		skxmac2.o
 
 # DBGDEF =  \
 # -DDEBUG
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
index 2dc5728..778d9e6 100644
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -60,7 +60,6 @@
 extern int		SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
 extern int		SkPciReadCfgWord(SK_AC*, int, SK_U16*);
 extern int		SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int		SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
 extern int		SkPciWriteCfgWord(SK_AC*, int, SK_U16);
 extern int		SkPciWriteCfgByte(SK_AC*, int, SK_U8);
 extern int		SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
@@ -268,8 +267,6 @@
 struct s_DevNet {
 	int             PortNr;
 	int             NetNr;
-	int             Mtu;
-	int             Up;
 	SK_AC   *pAC;
 };  
 
@@ -298,6 +295,7 @@
 	RXD		*pRxdRingTail;	/* Tail of Rx rings */
 	RXD		*pRxdRingPrev;	/* descriptor given to BMU previously */
 	int		RxdRingFree;	/* # of free entrys */
+	int		RxCsum;		/* use receive checksum hardware */
 	spinlock_t	RxDesRingLock;	/* serialize descriptor accesses */
 	int		RxFillLimit;	/* limit for buffers in ring */
 	SK_IOC		HwAddr;		/* bmu registers address */
@@ -390,12 +388,10 @@
 	
 	SK_IOC		IoBase;		/* register set of adapter */
 	int		BoardLevel;	/* level of active hw init (0-2) */
-	char		DeviceStr[80];	/* adapter string from vpd */
+
 	SK_U32		AllocFlag;	/* flag allocation of resources */
 	struct pci_dev	*PciDev;	/* for access to pci config space */
-	SK_U32		PciDevId;	/* pci device id */
 	struct SK_NET_DEVICE	*dev[2];	/* pointer to device struct */
-	char		Name[30];	/* driver name */
 
 	int		RxBufSize;	/* length of receive buffers */
         struct net_device_stats stats;	/* linux 'netstat -i' statistics */
@@ -430,7 +426,6 @@
 	DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
 
 	/* Only for tests */
-	int		PortUp;
 	int		PortDown;
 	int		ChipsetType;	/*  Chipset family type 
 					 *  0 == Genesis family support
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
index bdc1a5e..daa9a8d 100644
--- a/drivers/net/sk98lin/h/skvpd.h
+++ b/drivers/net/sk98lin/h/skvpd.h
@@ -130,14 +130,12 @@
 #ifndef VPD_DO_IO
 #define VPD_OUT8(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgByte(pAC,Addr,Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgDWord(pAC,Addr,Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgByte(pAC,Addr,pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgWord(pAC,Addr,pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgDWord(pAC,Addr,pVal)
 #else	/* VPD_DO_IO */
 #define VPD_OUT8(pAC,IoC,Addr,Val)	SK_OUT8(IoC,PCI_C(Addr),Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)	SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)	SK_OUT32(IoC,PCI_C(Addr),Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)	SK_IN8(IoC,PCI_C(Addr),pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)	SK_IN16(IoC,PCI_C(Addr),pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)	SK_IN32(IoC,PCI_C(Addr),pVal)
@@ -155,12 +153,6 @@
 		else						\
 			SK_OUT16(pAC,PCI_C(Addr),Val);		\
 		}
-#define VPD_OUT32(pAC,Ioc,Addr,Val) {			\
-		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciWriteCfgDWord(pAC,Addr,Val);	\
-		else						\
-			SK_OUT32(pAC,PCI_C(Addr),Val); 		\
-		}
 #define VPD_IN8(pAC,Ioc,Addr,pVal) {			\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
 			SkPciReadCfgByte(pAC,Addr,pVal);	\
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
index b71769a..4265ed9 100644
--- a/drivers/net/sk98lin/skethtool.c
+++ b/drivers/net/sk98lin/skethtool.c
@@ -539,6 +539,48 @@
         return ret ? -EIO : 0;
 }
 
+/* Only Yukon supports checksum offload. */
+static int setScatterGather(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+	return ethtool_op_set_sg(dev, data);
+}
+
+static int setTxCsum(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+
+	return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 getRxCsum(struct net_device *dev)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	return pAC->RxPort[pNet->PortNr].RxCsum;
+}
+
+static int setRxCsum(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+
+	pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
+	return 0;
+}
+
 struct ethtool_ops SkGeEthtoolOps = {
 	.get_settings		= getSettings,
 	.set_settings		= setSettings,
@@ -551,4 +593,10 @@
 	.set_pauseparam		= setPauseParams,
 	.get_link		= ethtool_op_get_link,
 	.get_perm_addr		= ethtool_op_get_perm_addr,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= setScatterGather,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= setTxCsum,
+	.get_rx_csum		= getRxCsum,
+	.set_rx_csum		= setRxCsum,
 };
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index ae73439..9a76ac1 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -107,10 +107,10 @@
 
 #include	"h/skversion.h"
 
+#include	<linux/in.h>
 #include	<linux/module.h>
 #include	<linux/moduleparam.h>
 #include	<linux/init.h>
-#include 	<linux/proc_fs.h>
 #include	<linux/dma-mapping.h>
 #include	<linux/ip.h>
 
@@ -206,7 +206,6 @@
 static struct	net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
 static int	SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
 static void	GetConfiguration(SK_AC*);
-static void	ProductStr(SK_AC*);
 static int	XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
 static void	FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
 static void	FillRxRing(SK_AC*, RX_PORT*);
@@ -235,28 +234,6 @@
  * Extern Function Prototypes
  *
  ******************************************************************************/
-static const char 	SKRootName[] = "net/sk98lin";
-static struct		proc_dir_entry *pSkRootDir;
-extern struct	file_operations sk_proc_fops;
-
-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);
@@ -279,6 +256,27 @@
 
 /*****************************************************************************
  *
+ *	SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ *	This routine writes a 32 bit value to the pci configuration
+ *	space.
+ *
+ * Returns:
+ *	0 - indicate everything worked ok.
+ *	!= 0 - error indication
+ */
+static inline int SkPciWriteCfgDWord(
+SK_AC *pAC,	/* Adapter Control structure pointer */
+int PciAddr,		/* PCI register address */
+SK_U32 Val)		/* pointer to store the read value */
+{
+	pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+	return(0);
+} /* SkPciWriteCfgDWord */
+
+/*****************************************************************************
+ *
  * 	SkGeInitPCI - Init the PCI resources
  *
  * Description:
@@ -300,7 +298,7 @@
 	dev->mem_start = pci_resource_start (pdev, 0);
 	pci_set_master(pdev);
 
-	if (pci_request_regions(pdev, pAC->Name) != 0) {
+	if (pci_request_regions(pdev, "sk98lin") != 0) {
 		retval = 2;
 		goto out_disable;
 	}
@@ -578,10 +576,10 @@
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
 	if (pAC->GIni.GIMacsFound == 2) {
-		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
 	} else if (pAC->GIni.GIMacsFound == 1) {
 		Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
-			pAC->Name, dev);
+			"sk98lin", dev);
 	} else {
 		printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
 		       pAC->GIni.GIMacsFound);
@@ -1265,7 +1263,6 @@
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
 	pAC->MaxPorts++;
-	pNet->Up = 1;
 
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1395,7 +1392,6 @@
 			sizeof(SK_PNMI_STRUCT_DATA));
 
 	pAC->MaxPorts--;
-	pNet->Up = 0;
 
 	return (0);
 } /* SkGeClose */
@@ -2175,7 +2171,6 @@
 		pMsg->ip_summed = CHECKSUM_NONE;
 #endif
 
-
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
 		ForRlmt = SK_RLMT_RX_PROTOCOL;
 #if 0
@@ -2550,7 +2545,7 @@
 static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
 {
 DEV_NET		*pNet;
-DEV_NET		*pOtherNet;
+struct net_device *pOtherDev;
 SK_AC		*pAC;
 unsigned long	Flags;
 int		i;
@@ -2580,11 +2575,11 @@
 	}
 #endif
 
-	pNet->Mtu = NewMtu;
-	pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
-	if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
-		return(0);
-	}
+	pOtherDev = pAC->dev[1 - pNet->NetNr];
+
+	if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
+	     && (NewMtu <= 1500))
+		return 0;
 
 	pAC->RxBufSize = NewMtu + 32;
 	dev->mtu = NewMtu;
@@ -2746,7 +2741,8 @@
 		EvPara.Para32[1] = -1;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 			
-		if (pOtherNet->Up) {
+		if (netif_running(pOtherDev)) {
+			DEV_NET *pOtherNet = netdev_priv(pOtherDev);
 			EvPara.Para32[0] = pOtherNet->PortNr;
 			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 		}
@@ -2820,7 +2816,7 @@
 	pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
 	pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
 	
-        if (pNet->Mtu <= 1500) {
+        if (dev->mtu <= 1500) {
                 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
         } else {
                 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
@@ -3771,25 +3767,21 @@
  *
  * Returns: N/A
  */
-static void ProductStr(
-SK_AC	*pAC		/* pointer to adapter context */
+static inline int ProductStr(
+	SK_AC	*pAC,		/* pointer to adapter context */
+	char    *DeviceStr,	/* result string */
+	int      StrLen		/* length of the string */
 )
 {
-int	StrLen = 80;		/* length of the string, defined in SK_AC */
 char	Keyword[] = VPD_NAME;	/* vpd productname identifier */
 int	ReturnCode;		/* return code from vpd_read */
 unsigned long Flags;
 
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
-		&StrLen);
+	ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	if (ReturnCode != 0) {
-		/* there was an error reading the vpd data */
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-			("Error reading VPD data: %d\n", ReturnCode));
-		pAC->DeviceStr[0] = '\0';
-	}
+
+	return ReturnCode;
 } /* ProductStr */
 
 /*****************************************************************************
@@ -3992,28 +3984,6 @@
 
 /*****************************************************************************
  *
- *	SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- *	This routine writes a 32 bit value to the pci configuration
- *	space.
- *
- * Returns:
- *	0 - indicate everything worked ok.
- *	!= 0 - error indication
- */
-int SkPciWriteCfgDWord(
-SK_AC *pAC,	/* Adapter Control structure pointer */
-int PciAddr,		/* PCI register address */
-SK_U32 Val)		/* pointer to store the read value */
-{
-	pci_write_config_dword(pAC->PciDev, PciAddr, Val);
-	return(0);
-} /* SkPciWriteCfgDWord */
-
-
-/*****************************************************************************
- *
  *	SkPciWriteCfgWord - write a 16 bit value to pci config space
  *
  * Description:
@@ -4150,6 +4120,7 @@
 			Flags);
 		break;
 	case SK_DRV_NET_UP:	 /* SK_U32 PortIdx */
+	{	struct net_device *dev = pAC->dev[Param.Para32[0]];
 		/* action list 5 */
 		FromPort = Param.Para32[0];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4233,22 +4204,12 @@
 			printk("    irq moderation:  disabled\n");
 
 
-#ifdef SK_ZEROCOPY
-		if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
-			printk("    scatter-gather:  enabled\n");
-#else
-			printk("    tx-checksum:     disabled\n");
-#endif
-		else
-			printk("    scatter-gather:  disabled\n");
-#else
-			printk("    scatter-gather:  disabled\n");
-#endif
-
-#ifndef USE_SK_RX_CHECKSUM
-			printk("    rx-checksum:     disabled\n");
-#endif
+		printk("    scatter-gather:  %s\n",
+		       (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
+		printk("    tx-checksum:     %s\n",
+		       (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
+		printk("    rx-checksum:     %s\n",
+		       pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
 
 		} else {
                         DoPrintInterfaceChange = SK_TRUE;
@@ -4263,9 +4224,9 @@
 		}
 
 		/* Inform the world that link protocol is up. */
-		netif_carrier_on(pAC->dev[Param.Para32[0]]);
-
+		netif_carrier_on(dev);
 		break;
+	}
 	case SK_DRV_NET_DOWN:	 /* SK_U32 Reason */
 		/* action list 7 */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4479,7 +4440,7 @@
 
 	pAC->DiagModeActive = DIAG_ACTIVE;
 	if (pAC->BoardLevel > SK_INIT_DATA) {
-		if (pNet->Up) {
+		if (netif_running(pAC->dev[0])) {
 			pAC->WasIfUp[0] = SK_TRUE;
 			pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
 			DoPrintInterfaceChange = SK_FALSE;
@@ -4489,7 +4450,7 @@
 		}
 		if (pNet != netdev_priv(pAC->dev[1])) {
 			pNet = netdev_priv(pAC->dev[1]);
-			if (pNet->Up) {
+			if (netif_running(pAC->dev[1])) {
 				pAC->WasIfUp[1] = SK_TRUE;
 				pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
 				DoPrintInterfaceChange = SK_FALSE;
@@ -4815,6 +4776,7 @@
 	struct net_device	*dev = NULL;
 	static int boards_found = 0;
 	int error = -ENODEV;
+	char DeviceStr[80];
 
 	if (pci_enable_device(pdev))
 		goto out;
@@ -4842,14 +4804,11 @@
 	memset(pNet->pAC, 0, sizeof(SK_AC));
 	pAC = pNet->pAC;
 	pAC->PciDev = pdev;
-	pAC->PciDevId = pdev->device;
+
 	pAC->dev[0] = dev;
 	pAC->dev[1] = dev;
-	sprintf(pAC->Name, "SysKonnect SK-98xx");
 	pAC->CheckQueue = SK_FALSE;
 
-	pNet->Mtu = 1500;
-	pNet->Up = 0;
 	dev->irq = pdev->irq;
 	error = SkGeInitPCI(pAC);
 	if (error) {
@@ -4872,21 +4831,30 @@
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
+	/* Use only if yukon hardware */
 	if (pAC->ChipsetType) {
-		/* Use only if yukon hardware */
-		/* SK and ZEROCOPY - fly baby... */
-		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#ifdef USE_SK_TX_CHECKSUM
+		dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+		dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+		pAC->RxPort[0].RxCsum = 1;
+#endif
 	}
-#endif
-#endif
 
 	pAC->Index = boards_found++;
 
 	if (SkGeBoardInit(dev, pAC))
 		goto out_free_netdev;
 
+	/* Read Adapter name from VPD */
+	if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
+		printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
+		goto out_free_resources;
+	}
+
 	/* Register net device */
 	if (register_netdev(dev)) {
 		printk(KERN_ERR "sk98lin: Could not register device.\n");
@@ -4894,8 +4862,7 @@
 	}
 
 	/* Print adapter specific string from vpd */
-	ProductStr(pAC);
-	printk("%s: %s\n", dev->name, pAC->DeviceStr);
+	printk("%s: %s\n", dev->name, DeviceStr);
 
 	/* Print configuration settings */
 	printk("      PrefPort:%c  RlmtMode:%s\n",
@@ -4911,8 +4878,6 @@
 	memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	SkGeProcCreate(dev);
-
 	pNet->PortNr = 0;
 	pNet->NetNr  = 0;
 
@@ -4931,8 +4896,6 @@
 		pNet->PortNr  = 1;
 		pNet->NetNr   = 1;
 		pNet->pAC     = pAC;
-		pNet->Mtu     = 1500;
-		pNet->Up      = 0;
 
 		dev->open               = &SkGeOpen;
 		dev->stop               = &SkGeClose;
@@ -4945,26 +4908,28 @@
 		SET_NETDEV_DEV(dev, &pdev->dev);
 		SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
 		if (pAC->ChipsetType) {
-			/* SG and ZEROCOPY - fly baby... */
-			dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#ifdef USE_SK_TX_CHECKSUM
+			dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+			dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+			pAC->RxPort[1].RxCsum = 1;
+#endif
 		}
-#endif
-#endif
 
 		if (register_netdev(dev)) {
 			printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
 			free_netdev(dev);
 			pAC->dev[1] = pAC->dev[0];
 		} else {
-			SkGeProcCreate(dev);
 			memcpy(&dev->dev_addr,
 					&pAC->Addr.Net[1].CurrentMacAddress, 6);
 			memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	
-			printk("%s: %s\n", dev->name, pAC->DeviceStr);
+			printk("%s: %s\n", dev->name, DeviceStr);
 			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
 		}
 	}
@@ -5000,10 +4965,7 @@
 	SK_AC *pAC = pNet->pAC;
 	struct net_device *otherdev = pAC->dev[1];
 
-	SkGeProcRemove(dev);
 	unregister_netdev(dev);
-	if (otherdev != dev)
-		SkGeProcRemove(otherdev);
 
 	SkGeYellowLED(pAC, pAC->IoBase, 0);
 
@@ -5088,9 +5050,9 @@
 	pci_enable_device(pdev);
 	pci_set_master(pdev);
 	if (pAC->GIni.GIMacsFound == 2)
-		ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+		ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
 	else
-		ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+		ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, "sk98lin", dev);
 	if (ret) {
 		printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
 		pAC->AllocFlag &= ~SK_ALLOC_IRQ;
@@ -5148,23 +5110,12 @@
 
 static int __init skge_init(void)
 {
-	int error;
-
-	pSkRootDir = proc_mkdir(SKRootName, NULL);
-	if (pSkRootDir) 
-		pSkRootDir->owner = THIS_MODULE;
-	
-	error = pci_register_driver(&skge_driver);
-	if (error)
-		remove_proc_entry(SKRootName, NULL);
-	return error;
+	return pci_module_init(&skge_driver);
 }
 
 static void __exit skge_exit(void)
 {
 	pci_unregister_driver(&skge_driver);
-	remove_proc_entry(SKRootName, NULL);
-
 }
 
 module_init(skge_init);
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
deleted file mode 100644
index 5cece25..0000000
--- a/drivers/net/sk98lin/skproc.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/******************************************************************************
- *
- * Name:	skproc.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.11 $
- * Date:	$Date: 2003/12/11 16:03:57 $
- * Purpose:	Funktions to display statictic data
- *
- ******************************************************************************/
- 
-/******************************************************************************
- *
- *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	Created 22-Nov-2000
- *	Author: Mirko Lindner (mlindner@syskonnect.de)
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-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,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-
-/*****************************************************************************
- *
- *      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: 0
- *      
- */
-static int sk_seq_show(struct seq_file *seq, void *v)
-{
-	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;
-	char			sens_msg[50];
-	int 			t;
-	int 			i;
-
-	/* 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;
-#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);
-		}
-#else
-		SkPnmiGetStruct(pAC, pAC->IoBase, 
-				pPnmiStruct, &Size, t-1);
-#endif
-		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	
-		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 */
-			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 */
-			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;
-			}
-#endif
-			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");
-				
-			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);
-				
-		}
-	}
-	return 0;
-}
-
-/*****************************************************************************
- *
- *      sk_proc_open - register the show function when proc is open'ed
- *  
- * Description:
- *  This function is called whenever a sk98lin proc file is queried.
- *  
- * Returns: the return value of single_open()
- *      
- */
-static int sk_proc_open(struct inode *inode, struct file *file)
-{
-    return single_open(file, sk_seq_show, PDE(inode)->data);
-}
-
-/*******************************************************************************
- *
- * End of file
- *
- ******************************************************************************/
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 00d6830..b538e30 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -25,6 +25,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -43,7 +44,7 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"1.2"
+#define DRV_VERSION		"1.3"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
@@ -88,15 +89,14 @@
 
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
+static void skge_phy_reset(struct skge_port *skge);
 static void skge_tx_clean(struct skge_port *skge);
 static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
-static void yukon_reset(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
-static void genesis_reset(struct skge_hw *hw, int port);
 static void genesis_link_up(struct skge_port *skge);
 
 /* Avoid conditionals by using array */
@@ -276,10 +276,9 @@
 	skge->autoneg = ecmd->autoneg;
 	skge->advertising = ecmd->advertising;
 
-	if (netif_running(dev)) {
-		skge_down(dev);
-		skge_up(dev);
-	}
+	if (netif_running(dev))
+		skge_phy_reset(skge);
+
 	return (0);
 }
 
@@ -399,6 +398,7 @@
 			       struct ethtool_ringparam *p)
 {
 	struct skge_port *skge = netdev_priv(dev);
+	int err;
 
 	if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
 	    p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
@@ -409,7 +409,9 @@
 
 	if (netif_running(dev)) {
 		skge_down(dev);
-		skge_up(dev);
+		err = skge_up(dev);
+		if (err)
+			dev_close(dev);
 	}
 
 	return 0;
@@ -430,21 +432,11 @@
 static int skge_nway_reset(struct net_device *dev)
 {
 	struct skge_port *skge = netdev_priv(dev);
-	struct skge_hw *hw = skge->hw;
-	int port = skge->port;
 
 	if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_bh(&hw->phy_lock);
-	if (hw->chip_id == CHIP_ID_GENESIS) {
-		genesis_reset(hw, port);
-		genesis_mac_init(hw, port);
-	} else {
-		yukon_reset(hw, port);
-		yukon_init(hw, port);
-	}
-	spin_unlock_bh(&hw->phy_lock);
+	skge_phy_reset(skge);
 	return 0;
 }
 
@@ -516,10 +508,8 @@
 	else
 		skge->flow_control = FLOW_MODE_NONE;
 
-	if (netif_running(dev)) {
-		skge_down(dev);
-		skge_up(dev);
-	}
+	if (netif_running(dev))
+		skge_phy_reset(skge);
 	return 0;
 }
 
@@ -2019,6 +2009,25 @@
 	/* XXX restart autonegotiation? */
 }
 
+static void skge_phy_reset(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	netif_stop_queue(skge->netdev);
+	netif_carrier_off(skge->netdev);
+
+	spin_lock_bh(&hw->phy_lock);
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		genesis_reset(hw, port);
+		genesis_mac_init(hw, port);
+	} else {
+		yukon_reset(hw, port);
+		yukon_init(hw, port);
+	}
+	spin_unlock_bh(&hw->phy_lock);
+}
+
 /* Basic MII support */
 static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -2187,6 +2196,7 @@
 	kfree(skge->rx_ring.start);
  free_pci_mem:
 	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+	skge->mem = NULL;
 
 	return err;
 }
@@ -2197,6 +2207,9 @@
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 
+	if (skge->mem == NULL)
+		return 0;
+
 	if (netif_msg_ifdown(skge))
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
@@ -2253,6 +2266,7 @@
 	kfree(skge->rx_ring.start);
 	kfree(skge->tx_ring.start);
 	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+	skge->mem = NULL;
 	return 0;
 }
 
@@ -2413,18 +2427,23 @@
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
-	int err = 0;
-	int running = netif_running(dev);
+	int err;
 
 	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
 
+	if (!netif_running(dev)) {
+		dev->mtu = new_mtu;
+		return 0;
+	}
 
-	if (running)
-		skge_down(dev);
+	skge_down(dev);
+
 	dev->mtu = new_mtu;
-	if (running)
-		skge_up(dev);
+
+	err = skge_up(dev);
+	if (err)
+		dev_close(dev);
 
 	return err;
 }
@@ -3398,8 +3417,8 @@
 		struct net_device *dev = hw->dev[i];
 		if (dev) {
 			netif_device_attach(dev);
-			if (netif_running(dev))
-				skge_up(dev);
+			if (netif_running(dev) && skge_up(dev))
+				dev_close(dev);
 		}
 	}
 	return 0;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index ee123c1..2efdacc 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -475,18 +475,6 @@
 	Q_T2	= 0x40,	/* 32 bit	Test Register 2	*/
 	Q_T3	= 0x44,	/* 32 bit	Test Register 3	*/
 
-/* Yukon-2 */
-	Q_DONE	= 0x24,	/* 16 bit	Done Index 		(Yukon-2 only) */
-	Q_WM	= 0x40,	/* 16 bit	FIFO Watermark */
-	Q_AL	= 0x42,	/*  8 bit	FIFO Alignment */
-	Q_RSP	= 0x44,	/* 16 bit	FIFO Read Shadow Pointer */
-	Q_RSL	= 0x46,	/*  8 bit	FIFO Read Shadow Level */
-	Q_RP	= 0x48,	/*  8 bit	FIFO Read Pointer */
-	Q_RL	= 0x4a,	/*  8 bit	FIFO Read Level */
-	Q_WP	= 0x4c,	/*  8 bit	FIFO Write Pointer */
-	Q_WSP	= 0x4d,	/*  8 bit	FIFO Write Shadow Pointer */
-	Q_WL	= 0x4e,	/*  8 bit	FIFO Write Level */
-	Q_WSL	= 0x4f,	/*  8 bit	FIFO Write Shadow Level */
 };
 #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
 
@@ -675,22 +663,16 @@
 	LED_OFF	= 1<<0,	/* switch LED off */
 };
 
-/* Receive GMAC FIFO (YUKON and Yukon-2) */
+/* Receive GMAC FIFO (YUKON) */
 enum {
 	RX_GMF_EA	= 0x0c40,/* 32 bit	Rx GMAC FIFO End Address */
 	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
 	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
 	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
 	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
-	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
-
-	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
 	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
-
 	RX_GMF_WLEV	= 0x0c68,/* 32 bit	Rx GMAC FIFO Write Level */
-
 	RX_GMF_RP	= 0x0c70,/* 32 bit	Rx GMAC FIFO Read Pointer */
-
 	RX_GMF_RLEV	= 0x0c78,/* 32 bit	Rx GMAC FIFO Read Level */
 };
 
@@ -855,48 +837,6 @@
 	GMAC_TI_ST_TST	= 0x0e1a,/*  8 bit	Time Stamp Timer Test Reg */
 };
 
-/* Status BMU Registers (Yukon-2 only)*/
-enum {
-	STAT_CTRL	= 0x0e80,/* 32 bit	Status BMU Control Reg */
-	STAT_LAST_IDX	= 0x0e84,/* 16 bit	Status BMU Last Index */
-	/* 0x0e85 - 0x0e86:	reserved */
-	STAT_LIST_ADDR_LO	= 0x0e88,/* 32 bit	Status List Start Addr (low) */
-	STAT_LIST_ADDR_HI	= 0x0e8c,/* 32 bit	Status List Start Addr (high) */
-	STAT_TXA1_RIDX	= 0x0e90,/* 16 bit	Status TxA1 Report Index Reg */
-	STAT_TXS1_RIDX	= 0x0e92,/* 16 bit	Status TxS1 Report Index Reg */
-	STAT_TXA2_RIDX	= 0x0e94,/* 16 bit	Status TxA2 Report Index Reg */
-	STAT_TXS2_RIDX	= 0x0e96,/* 16 bit	Status TxS2 Report Index Reg */
-	STAT_TX_IDX_TH	= 0x0e98,/* 16 bit	Status Tx Index Threshold Reg */
-	STAT_PUT_IDX	= 0x0e9c,/* 16 bit	Status Put Index Reg */
-
-/* FIFO Control/Status Registers (Yukon-2 only)*/
-	STAT_FIFO_WP	= 0x0ea0,/*  8 bit	Status FIFO Write Pointer Reg */
-	STAT_FIFO_RP	= 0x0ea4,/*  8 bit	Status FIFO Read Pointer Reg */
-	STAT_FIFO_RSP	= 0x0ea6,/*  8 bit	Status FIFO Read Shadow Ptr */
-	STAT_FIFO_LEVEL	= 0x0ea8,/*  8 bit	Status FIFO Level Reg */
-	STAT_FIFO_SHLVL	= 0x0eaa,/*  8 bit	Status FIFO Shadow Level Reg */
-	STAT_FIFO_WM	= 0x0eac,/*  8 bit	Status FIFO Watermark Reg */
-	STAT_FIFO_ISR_WM	= 0x0ead,/*  8 bit	Status FIFO ISR Watermark Reg */
-
-/* Level and ISR Timer Registers (Yukon-2 only)*/
-	STAT_LEV_TIMER_INI	= 0x0eb0,/* 32 bit	Level Timer Init. Value Reg */
-	STAT_LEV_TIMER_CNT	= 0x0eb4,/* 32 bit	Level Timer Counter Reg */
-	STAT_LEV_TIMER_CTRL	= 0x0eb8,/*  8 bit	Level Timer Control Reg */
-	STAT_LEV_TIMER_TEST	= 0x0eb9,/*  8 bit	Level Timer Test Reg */
-	STAT_TX_TIMER_INI	= 0x0ec0,/* 32 bit	Tx Timer Init. Value Reg */
-	STAT_TX_TIMER_CNT	= 0x0ec4,/* 32 bit	Tx Timer Counter Reg */
-	STAT_TX_TIMER_CTRL	= 0x0ec8,/*  8 bit	Tx Timer Control Reg */
-	STAT_TX_TIMER_TEST	= 0x0ec9,/*  8 bit	Tx Timer Test Reg */
-	STAT_ISR_TIMER_INI	= 0x0ed0,/* 32 bit	ISR Timer Init. Value Reg */
-	STAT_ISR_TIMER_CNT	= 0x0ed4,/* 32 bit	ISR Timer Counter Reg */
-	STAT_ISR_TIMER_CTRL	= 0x0ed8,/*  8 bit	ISR Timer Control Reg */
-	STAT_ISR_TIMER_TEST	= 0x0ed9,/*  8 bit	ISR Timer Test Reg */
-
-	ST_LAST_IDX_MASK	= 0x007f,/* Last Index Mask */
-	ST_TXRP_IDX_MASK	= 0x0fff,/* Tx Report Index Mask */
-	ST_TXTH_IDX_MASK	= 0x0fff,/* Tx Threshold Index Mask */
-	ST_WM_IDX_MASK	= 0x3f,/* FIFO Watermark Index Mask */
-};
 
 enum {
 	LINKLED_OFF 	     = 0x01,
@@ -923,8 +863,6 @@
 	WOL_MATCH_CTL	= 0x0f22,/*  8 bit	WOL Match Control Reg */
 	WOL_MATCH_RES	= 0x0f23,/*  8 bit	WOL Match Result Reg */
 	WOL_MAC_ADDR	= 0x0f24,/* 32 bit	WOL MAC Address */
-	WOL_PATT_PME	= 0x0f2a,/*  8 bit	WOL PME Match Enable (Yukon-2) */
-	WOL_PATT_ASFM	= 0x0f2b,/*  8 bit	WOL ASF Match Enable (Yukon-2) */
 	WOL_PATT_RPTR	= 0x0f2c,/*  8 bit	WOL Pattern Read Pointer */
 
 /* WOL Pattern Length Registers (YUKON only) */
@@ -1641,15 +1579,6 @@
 	PHY_M_FESC_SEL_CL_A	= 1<<0, /* Select Class A driver (100B-TX) */
 };
 
-/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
-/*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
-enum {
-	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
-	PHY_M_MAC_MD_AUTO	= 3,/* Auto Copper/1000Base-X */
-	PHY_M_MAC_MD_COPPER	= 5,/* Copper only */
-	PHY_M_MAC_MD_1000BX	= 7,/* 1000Base-X only */
-};
-#define PHY_M_MAC_MODE_SEL(x)	(((x)<<7) & PHY_M_MAC_MD_MSK)
 
 /*****  PHY_MARV_PHY_CTRL (page 3)		16 bit r/w	LED Control Reg. *****/
 enum {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
new file mode 100644
index 0000000..f5d697c
--- /dev/null
+++ b/drivers/net/sky2.c
@@ -0,0 +1,3262 @@
+/*
+ * New driver for Marvell Yukon 2 chipset.
+ * Based on earlier sk98lin, and skge driver.
+ *
+ * This driver intentionally does not support all the features
+ * of the original driver such as link fail-over and link management because
+ * those should be done at higher levels.
+ *
+ * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * TOTEST
+ *	- speed setting
+ *	- suspend/resume
+ */
+
+#include <linux/config.h>
+#include <linux/crc32.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/if_vlan.h>
+#include <linux/prefetch.h>
+#include <linux/mii.h>
+
+#include <asm/irq.h>
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define SKY2_VLAN_TAG_USED 1
+#endif
+
+#include "sky2.h"
+
+#define DRV_NAME		"sky2"
+#define DRV_VERSION		"0.11"
+#define PFX			DRV_NAME " "
+
+/*
+ * The Yukon II chipset takes 64 bit command blocks (called list elements)
+ * that are organized into three (receive, transmit, status) different rings
+ * similar to Tigon3. A transmit can require several elements;
+ * a receive requires one (or two if using 64 bit dma).
+ */
+
+#define is_ec_a1(hw) \
+	unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
+		 (hw)->chip_rev == CHIP_REV_YU_EC_A1)
+
+#define RX_LE_SIZE	    	512
+#define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
+#define RX_MAX_PENDING		(RX_LE_SIZE/2 - 2)
+#define RX_DEF_PENDING		RX_MAX_PENDING
+
+#define TX_RING_SIZE		512
+#define TX_DEF_PENDING		(TX_RING_SIZE - 1)
+#define TX_MIN_PENDING		64
+#define MAX_SKB_TX_LE		(4 + 2*MAX_SKB_FRAGS)
+
+#define STATUS_RING_SIZE	2048	/* 2 ports * (TX + 2*RX) */
+#define STATUS_LE_BYTES		(STATUS_RING_SIZE*sizeof(struct sky2_status_le))
+#define ETH_JUMBO_MTU		9000
+#define TX_WATCHDOG		(5 * HZ)
+#define NAPI_WEIGHT		64
+#define PHY_RETRIES		1000
+
+static const u32 default_msg =
+    NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
+    | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR;
+
+static int debug = -1;		/* defaults above */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static int copybreak __read_mostly = 256;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+static const struct pci_device_id sky2_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, sky2_id_table);
+
+/* Avoid conditionals by using array */
+static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
+static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
+
+/* This driver supports yukon2 chipset only */
+static const char *yukon2_name[] = {
+	"XL",		/* 0xb3 */
+	"EC Ultra", 	/* 0xb4 */
+	"UNKNOWN",	/* 0xb5 */
+	"EC",		/* 0xb6 */
+	"FE",		/* 0xb7 */
+};
+
+/* Access to external PHY */
+static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_DATA, val);
+	gma_write16(hw, port, GM_SMI_CTRL,
+		    GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+			return 0;
+		udelay(1);
+	}
+
+	printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
+	return -ETIMEDOUT;
+}
+
+static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
+		    | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
+			*val = gma_read16(hw, port, GM_SMI_DATA);
+			return 0;
+		}
+
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+{
+	u16 v;
+
+	if (__gm_phy_read(hw, port, reg, &v) != 0)
+		printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+	return v;
+}
+
+static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
+{
+	u16 power_control;
+	u32 reg1;
+	int vaux;
+	int ret = 0;
+
+	pr_debug("sky2_set_power_state %d\n", state);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
+	vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+		(power_control & PCI_PM_CAP_PME_D3cold);
+
+	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
+
+	power_control |= PCI_PM_CTRL_PME_STATUS;
+	power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+
+	switch (state) {
+	case PCI_D0:
+		/* switch power to VCC (WA for VAUX problem) */
+		sky2_write8(hw, B0_POWER_CTRL,
+			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+
+		/* disable Core Clock Division, */
+		sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			/* enable bits are inverted */
+			sky2_write8(hw, B2_Y2_CLK_GATE,
+				    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+				    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+				    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+		else
+			sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+
+		/* Turn off phy power saving */
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+		reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+
+		/* looks like this XL is back asswards .. */
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) {
+			reg1 |= PCI_Y2_PHY1_COMA;
+			if (hw->ports > 1)
+				reg1 |= PCI_Y2_PHY2_COMA;
+		}
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+		break;
+
+	case PCI_D3hot:
+	case PCI_D3cold:
+		/* Turn on phy power saving */
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+		else
+			reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+		else
+			/* enable bits are inverted */
+			sky2_write8(hw, B2_Y2_CLK_GATE,
+				    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+				    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+				    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+
+		/* switch power to VAUX */
+		if (vaux && state != PCI_D3cold)
+			sky2_write8(hw, B0_POWER_CTRL,
+				    (PC_VAUX_ENA | PC_VCC_ENA |
+				     PC_VAUX_ON | PC_VCC_OFF));
+		break;
+	default:
+		printk(KERN_ERR PFX "Unknown power state %d\n", state);
+		ret = -1;
+	}
+
+	pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+	return ret;
+}
+
+static void sky2_phy_reset(struct sky2_hw *hw, unsigned port)
+{
+	u16 reg;
+
+	/* disable all GMAC IRQ's */
+	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+	/* disable PHY IRQs */
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
+	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+
+	reg = gma_read16(hw, port, GM_RX_CTRL);
+	reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
+	gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
+{
+	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+	u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
+
+	if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) {
+		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+
+		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+			   PHY_M_EC_MAC_S_MSK);
+		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+		if (hw->chip_id == CHIP_ID_YUKON_EC)
+			ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
+		else
+			ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+	}
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+	if (hw->copper) {
+		if (hw->chip_id == CHIP_ID_YUKON_FE) {
+			/* enable automatic crossover */
+			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
+		} else {
+			/* disable energy detect */
+			ctrl &= ~PHY_M_PC_EN_DET_MSK;
+
+			/* enable automatic crossover */
+			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
+
+			if (sky2->autoneg == AUTONEG_ENABLE &&
+			    hw->chip_id == CHIP_ID_YUKON_XL) {
+				ctrl &= ~PHY_M_PC_DSC_MSK;
+				ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
+			}
+		}
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+	} else {
+		/* workaround for deviation #4.88 (CRC errors) */
+		/* disable Automatic Crossover */
+
+		ctrl &= ~PHY_M_PC_MDIX_MSK;
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL) {
+			/* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+			ctrl &= ~PHY_M_MAC_MD_MSK;
+			ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+			/* select page 1 to access Fiber registers */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
+		}
+	}
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+	if (sky2->autoneg == AUTONEG_DISABLE)
+		ctrl &= ~PHY_CT_ANE;
+	else
+		ctrl |= PHY_CT_ANE;
+
+	ctrl |= PHY_CT_RESET;
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	ctrl = 0;
+	ct1000 = 0;
+	adv = PHY_AN_CSMA;
+
+	if (sky2->autoneg == AUTONEG_ENABLE) {
+		if (hw->copper) {
+			if (sky2->advertising & ADVERTISED_1000baseT_Full)
+				ct1000 |= PHY_M_1000C_AFD;
+			if (sky2->advertising & ADVERTISED_1000baseT_Half)
+				ct1000 |= PHY_M_1000C_AHD;
+			if (sky2->advertising & ADVERTISED_100baseT_Full)
+				adv |= PHY_M_AN_100_FD;
+			if (sky2->advertising & ADVERTISED_100baseT_Half)
+				adv |= PHY_M_AN_100_HD;
+			if (sky2->advertising & ADVERTISED_10baseT_Full)
+				adv |= PHY_M_AN_10_FD;
+			if (sky2->advertising & ADVERTISED_10baseT_Half)
+				adv |= PHY_M_AN_10_HD;
+		} else		/* special defines for FIBER (88E1011S only) */
+			adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+
+		/* Set Flow-control capabilities */
+		if (sky2->tx_pause && sky2->rx_pause)
+			adv |= PHY_AN_PAUSE_CAP;	/* symmetric */
+		else if (sky2->rx_pause && !sky2->tx_pause)
+			adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP;
+		else if (!sky2->rx_pause && sky2->tx_pause)
+			adv |= PHY_AN_PAUSE_ASYM;	/* local */
+
+		/* Restart Auto-negotiation */
+		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+	} else {
+		/* forced speed/duplex settings */
+		ct1000 = PHY_M_1000C_MSE;
+
+		if (sky2->duplex == DUPLEX_FULL)
+			ctrl |= PHY_CT_DUP_MD;
+
+		switch (sky2->speed) {
+		case SPEED_1000:
+			ctrl |= PHY_CT_SP1000;
+			break;
+		case SPEED_100:
+			ctrl |= PHY_CT_SP100;
+			break;
+		}
+
+		ctrl |= PHY_CT_RESET;
+	}
+
+	if (hw->chip_id != CHIP_ID_YUKON_FE)
+		gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+
+	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	/* Setup Phy LED's */
+	ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
+	ledover = 0;
+
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_FE:
+		/* on 88E3082 these bits are at 11..9 (shifted left) */
+		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+
+		ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
+
+		/* delete ACT LED control bits */
+		ctrl &= ~PHY_M_FELP_LED1_MSK;
+		/* change ACT LED control to blink mode */
+		ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
+		gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+		break;
+
+	case CHIP_ID_YUKON_XL:
+		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+		/* select page 3 to access LED control register */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+
+		/* set LED Function Control register */
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
+							   PHY_M_LEDC_INIT_CTRL(7) |	/* 10 Mbps */
+							   PHY_M_LEDC_STA1_CTRL(7) |	/* 100 Mbps */
+							   PHY_M_LEDC_STA0_CTRL(7)));	/* 1000 Mbps */
+
+		/* set Polarity Control register */
+		gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
+			     (PHY_M_POLC_LS1_P_MIX(4) |
+			      PHY_M_POLC_IS0_P_MIX(4) |
+			      PHY_M_POLC_LOS_CTRL(2) |
+			      PHY_M_POLC_INIT_CTRL(2) |
+			      PHY_M_POLC_STA1_CTRL(2) |
+			      PHY_M_POLC_STA0_CTRL(2)));
+
+		/* restore page register */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+		break;
+
+	default:
+		/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+		/* turn off the Rx LED (LED_RX) */
+		ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+	}
+
+	gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+
+	if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+		/* turn on 100 Mbps LED (LED_LINK100) */
+		ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+	}
+
+	if (ledover)
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+
+	/* Enable phy interrupt on auto-negotiation complete (or link up) */
+	if (sky2->autoneg == AUTONEG_ENABLE)
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+	else
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+}
+
+/* Force a renegotiation */
+static void sky2_phy_reinit(struct sky2_port *sky2)
+{
+	down(&sky2->phy_sema);
+	sky2_phy_init(sky2->hw, sky2->port);
+	up(&sky2->phy_sema);
+}
+
+static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
+{
+	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+	u16 reg;
+	int i;
+	const u8 *addr = hw->dev[port]->dev_addr;
+
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+
+	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
+		/* WA DEV_472 -- looks like crossed wires on port 2 */
+		/* clear GMAC 1 Control reset */
+		sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
+		do {
+			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
+			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
+		} while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
+			 gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
+			 gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
+	}
+
+	if (sky2->autoneg == AUTONEG_DISABLE) {
+		reg = gma_read16(hw, port, GM_GP_CTRL);
+		reg |= GM_GPCR_AU_ALL_DIS;
+		gma_write16(hw, port, GM_GP_CTRL, reg);
+		gma_read16(hw, port, GM_GP_CTRL);
+
+		switch (sky2->speed) {
+		case SPEED_1000:
+			reg |= GM_GPCR_SPEED_1000;
+			/* fallthru */
+		case SPEED_100:
+			reg |= GM_GPCR_SPEED_100;
+		}
+
+		if (sky2->duplex == DUPLEX_FULL)
+			reg |= GM_GPCR_DUP_FULL;
+	} else
+		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
+
+	if (!sky2->tx_pause && !sky2->rx_pause) {
+		sky2_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+		reg |=
+		    GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+	} else if (sky2->tx_pause && !sky2->rx_pause) {
+		/* disable Rx flow-control */
+		reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+	}
+
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+
+	sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+	down(&sky2->phy_sema);
+	sky2_phy_init(hw, port);
+	up(&sky2->phy_sema);
+
+	/* MIB clear */
+	reg = gma_read16(hw, port, GM_PHY_ADDR);
+	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+
+	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
+		gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
+	gma_write16(hw, port, GM_PHY_ADDR, reg);
+
+	/* transmit control */
+	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+
+	/* receive control reg: unicast + multicast + no FCS  */
+	gma_write16(hw, port, GM_RX_CTRL,
+		    GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
+
+	/* transmit flow control */
+	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+
+	/* transmit parameter */
+	gma_write16(hw, port, GM_TX_PARAM,
+		    TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
+		    TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
+		    TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
+		    TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
+
+	/* serial mode register */
+	reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+	if (hw->dev[port]->mtu > ETH_DATA_LEN)
+		reg |= GM_SMOD_JUMBO_ENA;
+
+	gma_write16(hw, port, GM_SERIAL_MODE, reg);
+
+	/* virtual address for data */
+	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+
+	/* physical address: used for pause frames */
+	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+
+	/* ignore counter overflows */
+	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+
+	/* Configure Rx MAC FIFO */
+	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+	sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
+		     GMF_RX_CTRL_DEF);
+
+	/* Flush Rx MAC FIFO on any flow control or error */
+	sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+
+	/* Set threshold to 0xa (64 bytes)
+	 *  ASF disabled so no need to do WA dev #4.30
+	 */
+	sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+
+	/* Configure Tx MAC FIFO */
+	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+	sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+		if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+			/* set Tx GMAC FIFO Almost Empty Threshold */
+			sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180);
+			/* Disable Store & Forward mode for TX */
+			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+		}
+	}
+
+}
+
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len)
+{
+	u32 end;
+
+	start /= 8;
+	len /= 8;
+	end = start + len - 1;
+
+	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+	sky2_write32(hw, RB_ADDR(q, RB_START), start);
+	sky2_write32(hw, RB_ADDR(q, RB_END), end);
+	sky2_write32(hw, RB_ADDR(q, RB_WP), start);
+	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
+
+	if (q == Q_R1 || q == Q_R2) {
+		u32 rxup, rxlo;
+
+		rxlo = len/2;
+		rxup = rxlo + len/4;
+
+		/* Set thresholds on receive queue's */
+		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo);
+	} else {
+		/* Enable store & forward on Tx queue's because
+		 * Tx FIFO is only 1K on Yukon
+		 */
+		sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+	}
+
+	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
+	sky2_read8(hw, RB_ADDR(q, RB_CTRL));
+}
+
+/* Setup Bus Memory Interface */
+static void sky2_qset(struct sky2_hw *hw, u16 q)
+{
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
+	sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
+}
+
+/* Setup prefetch unit registers. This is the interface between
+ * hardware and driver list elements
+ */
+static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
+				      u64 addr, u32 last)
+{
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
+	sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
+
+	sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
+}
+
+static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
+{
+	struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
+
+	sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE;
+	return le;
+}
+
+/*
+ * This is a workaround code taken from SysKonnect sk98lin driver
+ * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
+ */
+static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q,
+				u16 idx, u16 *last, u16 size)
+{
+	if (is_ec_a1(hw) && idx < *last) {
+		u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
+
+		if (hwget == 0) {
+			/* Start prefetching again */
+			sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
+			goto setnew;
+		}
+
+		if (hwget == size - 1) {
+			/* set watermark to one list element */
+			sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
+
+			/* set put index to first list element */
+			sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
+		} else		/* have hardware go to end of list */
+			sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
+				     size - 1);
+	} else {
+setnew:
+		sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
+	}
+	*last = idx;
+}
+
+
+static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
+{
+	struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
+	sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE;
+	return le;
+}
+
+/* Return high part of DMA address (could be 32 or 64 bit) */
+static inline u32 high32(dma_addr_t a)
+{
+	return (a >> 16) >> 16;
+}
+
+/* Build description to hardware about buffer */
+static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+{
+	struct sky2_rx_le *le;
+	u32 hi = high32(map);
+	u16 len = sky2->rx_bufsize;
+
+	if (sky2->rx_addr64 != hi) {
+		le = sky2_next_rx(sky2);
+		le->addr = cpu_to_le32(hi);
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+		sky2->rx_addr64 = high32(map + len);
+	}
+
+	le = sky2_next_rx(sky2);
+	le->addr = cpu_to_le32((u32) map);
+	le->length = cpu_to_le16(len);
+	le->ctrl = 0;
+	le->opcode = OP_PACKET | HW_OWNER;
+}
+
+
+/* Tell chip where to start receive checksum.
+ * Actually has two checksums, but set both same to avoid possible byte
+ * order problems.
+ */
+static void rx_set_checksum(struct sky2_port *sky2)
+{
+	struct sky2_rx_le *le;
+
+	le = sky2_next_rx(sky2);
+	le->addr = (ETH_HLEN << 16) | ETH_HLEN;
+	le->ctrl = 0;
+	le->opcode = OP_TCPSTART | HW_OWNER;
+
+	sky2_write32(sky2->hw,
+		     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+		     sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+}
+
+/*
+ * The RX Stop command will not work for Yukon-2 if the BMU does not
+ * reach the end of packet and since we can't make sure that we have
+ * incoming data, we must reset the BMU while it is not doing a DMA
+ * transfer. Since it is possible that the RX path is still active,
+ * the RX RAM buffer will be stopped first, so any possible incoming
+ * data will not trigger a DMA. After the RAM buffer is stopped, the
+ * BMU is polled until any DMA in progress is ended and only then it
+ * will be reset.
+ */
+static void sky2_rx_stop(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned rxq = rxqaddr[sky2->port];
+	int i;
+
+	/* disable the RAM Buffer receive queue */
+	sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
+
+	for (i = 0; i < 0xffff; i++)
+		if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
+		    == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
+			goto stopped;
+
+	printk(KERN_WARNING PFX "%s: receiver stop failed\n",
+	       sky2->netdev->name);
+stopped:
+	sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
+
+	/* reset the Rx prefetch unit */
+	sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+}
+
+/* Clean out receive buffer area, assumes receiver hardware stopped */
+static void sky2_rx_clean(struct sky2_port *sky2)
+{
+	unsigned i;
+
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+	for (i = 0; i < sky2->rx_pending; i++) {
+		struct ring_info *re = sky2->rx_ring + i;
+
+		if (re->skb) {
+			pci_unmap_single(sky2->hw->pdev,
+					 re->mapaddr, sky2->rx_bufsize,
+					 PCI_DMA_FROMDEVICE);
+			kfree_skb(re->skb);
+			re->skb = NULL;
+		}
+	}
+}
+
+/* Basic MII support */
+static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct mii_ioctl_data *data = if_mii(ifr);
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	int err = -EOPNOTSUPP;
+
+	if (!netif_running(dev))
+		return -ENODEV;	/* Phy still in reset */
+
+	switch(cmd) {
+	case SIOCGMIIPHY:
+		data->phy_id = PHY_ADDR_MARV;
+
+		/* fallthru */
+	case SIOCGMIIREG: {
+		u16 val = 0;
+
+		down(&sky2->phy_sema);
+		err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
+		up(&sky2->phy_sema);
+
+		data->val_out = val;
+		break;
+	}
+
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		down(&sky2->phy_sema);
+		err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
+				   data->val_in);
+		up(&sky2->phy_sema);
+		break;
+	}
+	return err;
+}
+
+#ifdef SKY2_VLAN_TAG_USED
+static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	u16 port = sky2->port;
+
+	spin_lock(&sky2->tx_lock);
+
+	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
+	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
+	sky2->vlgrp = grp;
+
+	spin_unlock(&sky2->tx_lock);
+}
+
+static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	u16 port = sky2->port;
+
+	spin_lock(&sky2->tx_lock);
+
+	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
+	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
+	if (sky2->vlgrp)
+		sky2->vlgrp->vlan_devices[vid] = NULL;
+
+	spin_unlock(&sky2->tx_lock);
+}
+#endif
+
+/*
+ * Allocate and setup receiver buffer pool.
+ * In case of 64 bit dma, there are 2X as many list elements
+ * available as ring entries
+ * and need to reserve one list element so we don't wrap around.
+ *
+ * It appears the hardware has a bug in the FIFO logic that
+ * cause it to hang if the FIFO gets overrun and the receive buffer
+ * is not aligned.  This means we can't use skb_reserve to align
+ * the IP header.
+ */
+static int sky2_rx_start(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned rxq = rxqaddr[sky2->port];
+	int i;
+
+	sky2->rx_put = sky2->rx_next = 0;
+	sky2_qset(hw, rxq);
+	sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
+
+	rx_set_checksum(sky2);
+	for (i = 0; i < sky2->rx_pending; i++) {
+		struct ring_info *re = sky2->rx_ring + i;
+
+		re->skb = dev_alloc_skb(sky2->rx_bufsize);
+		if (!re->skb)
+			goto nomem;
+
+		re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
+					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+		sky2_rx_add(sky2, re->mapaddr);
+	}
+
+	/* Tell chip about available buffers */
+	sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
+	sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
+	return 0;
+nomem:
+	sky2_rx_clean(sky2);
+	return -ENOMEM;
+}
+
+/* Bring up network interface. */
+static int sky2_up(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u32 ramsize, rxspace;
+	int err = -ENOMEM;
+
+	if (netif_msg_ifup(sky2))
+		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
+	/* must be power of 2 */
+	sky2->tx_le = pci_alloc_consistent(hw->pdev,
+					   TX_RING_SIZE *
+					   sizeof(struct sky2_tx_le),
+					   &sky2->tx_le_map);
+	if (!sky2->tx_le)
+		goto err_out;
+
+	sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->tx_ring)
+		goto err_out;
+	sky2->tx_prod = sky2->tx_cons = 0;
+
+	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+					   &sky2->rx_le_map);
+	if (!sky2->rx_le)
+		goto err_out;
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+				GFP_KERNEL);
+	if (!sky2->rx_ring)
+		goto err_out;
+
+	sky2_mac_init(hw, port);
+
+	/* Configure RAM buffers */
+	if (hw->chip_id == CHIP_ID_YUKON_FE ||
+	    (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2))
+		ramsize = 4096;
+	else {
+		u8 e0 = sky2_read8(hw, B2_E_0);
+		ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096);
+	}
+
+	/* 2/3 for Rx */
+	rxspace = (2 * ramsize) / 3;
+	sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+	sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
+
+	/* Make sure SyncQ is disabled */
+	sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+		    RB_RST_SET);
+
+	sky2_qset(hw, txqaddr[port]);
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U)
+		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
+
+
+	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
+			   TX_RING_SIZE - 1);
+
+	err = sky2_rx_start(sky2);
+	if (err)
+		goto err_out;
+
+	/* Enable interrupts from phy/mac for port */
+	hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	return 0;
+
+err_out:
+	if (sky2->rx_le) {
+		pci_free_consistent(hw->pdev, RX_LE_BYTES,
+				    sky2->rx_le, sky2->rx_le_map);
+		sky2->rx_le = NULL;
+	}
+	if (sky2->tx_le) {
+		pci_free_consistent(hw->pdev,
+				    TX_RING_SIZE * sizeof(struct sky2_tx_le),
+				    sky2->tx_le, sky2->tx_le_map);
+		sky2->tx_le = NULL;
+	}
+	kfree(sky2->tx_ring);
+	kfree(sky2->rx_ring);
+
+	sky2->tx_ring = NULL;
+	sky2->rx_ring = NULL;
+	return err;
+}
+
+/* Modular subtraction in ring */
+static inline int tx_dist(unsigned tail, unsigned head)
+{
+	return (head - tail) % TX_RING_SIZE;
+}
+
+/* Number of list elements available for next tx */
+static inline int tx_avail(const struct sky2_port *sky2)
+{
+	return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
+}
+
+/* Estimate of number of transmit list elements required */
+static inline unsigned tx_le_req(const struct sk_buff *skb)
+{
+	unsigned count;
+
+	count = sizeof(dma_addr_t) / sizeof(u32);
+	count += skb_shinfo(skb)->nr_frags * count;
+
+	if (skb_shinfo(skb)->tso_size)
+		++count;
+
+	if (skb->ip_summed == CHECKSUM_HW)
+		++count;
+
+	return count;
+}
+
+/*
+ * Put one packet in ring for transmit.
+ * A single packet can generate multiple list elements, and
+ * the number of ring elements will probably be less than the number
+ * of list elements used.
+ *
+ * No BH disabling for tx_lock here (like tg3)
+ */
+static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	struct sky2_tx_le *le = NULL;
+	struct tx_ring_info *re;
+	unsigned i, len;
+	dma_addr_t mapping;
+	u32 addr64;
+	u16 mss;
+	u8 ctrl;
+
+	if (!spin_trylock(&sky2->tx_lock))
+		return NETDEV_TX_LOCKED;
+
+	if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
+		/* There is a known but harmless race with lockless tx
+		 * and netif_stop_queue.
+		 */
+		if (!netif_queue_stopped(dev)) {
+			netif_stop_queue(dev);
+			printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+			       dev->name);
+		}
+		spin_unlock(&sky2->tx_lock);
+
+		return NETDEV_TX_BUSY;
+	}
+
+	if (unlikely(netif_msg_tx_queued(sky2)))
+		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+		       dev->name, sky2->tx_prod, skb->len);
+
+	len = skb_headlen(skb);
+	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	addr64 = high32(mapping);
+
+	re = sky2->tx_ring + sky2->tx_prod;
+
+	/* Send high bits if changed or crosses boundary */
+	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+		le = get_tx_le(sky2);
+		le->tx.addr = cpu_to_le32(addr64);
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+		sky2->tx_addr64 = high32(mapping + len);
+	}
+
+	/* Check for TCP Segmentation Offload */
+	mss = skb_shinfo(skb)->tso_size;
+	if (mss != 0) {
+		/* just drop the packet if non-linear expansion fails */
+		if (skb_header_cloned(skb) &&
+		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+			dev_kfree_skb_any(skb);
+			goto out_unlock;
+		}
+
+		mss += ((skb->h.th->doff - 5) * 4);	/* TCP options */
+		mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr);
+		mss += ETH_HLEN;
+	}
+
+	if (mss != sky2->tx_last_mss) {
+		le = get_tx_le(sky2);
+		le->tx.tso.size = cpu_to_le16(mss);
+		le->tx.tso.rsvd = 0;
+		le->opcode = OP_LRGLEN | HW_OWNER;
+		le->ctrl = 0;
+		sky2->tx_last_mss = mss;
+	}
+
+	ctrl = 0;
+#ifdef SKY2_VLAN_TAG_USED
+	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
+	if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
+		if (!le) {
+			le = get_tx_le(sky2);
+			le->tx.addr = 0;
+			le->opcode = OP_VLAN|HW_OWNER;
+			le->ctrl = 0;
+		} else
+			le->opcode |= OP_VLAN;
+		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
+		ctrl |= INS_VLAN;
+	}
+#endif
+
+	/* Handle TCP checksum offload */
+	if (skb->ip_summed == CHECKSUM_HW) {
+		u16 hdr = skb->h.raw - skb->data;
+		u16 offset = hdr + skb->csum;
+
+		ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+		if (skb->nh.iph->protocol == IPPROTO_UDP)
+			ctrl |= UDPTCP;
+
+		le = get_tx_le(sky2);
+		le->tx.csum.start = cpu_to_le16(hdr);
+		le->tx.csum.offset = cpu_to_le16(offset);
+		le->length = 0;	/* initial checksum value */
+		le->ctrl = 1;	/* one packet */
+		le->opcode = OP_TCPLISW | HW_OWNER;
+	}
+
+	le = get_tx_le(sky2);
+	le->tx.addr = cpu_to_le32((u32) mapping);
+	le->length = cpu_to_le16(len);
+	le->ctrl = ctrl;
+	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
+
+	/* Record the transmit mapping info */
+	re->skb = skb;
+	pci_unmap_addr_set(re, mapaddr, mapping);
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		struct tx_ring_info *fre;
+
+		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
+				       frag->size, PCI_DMA_TODEVICE);
+		addr64 = (mapping >> 16) >> 16;
+		if (addr64 != sky2->tx_addr64) {
+			le = get_tx_le(sky2);
+			le->tx.addr = cpu_to_le32(addr64);
+			le->ctrl = 0;
+			le->opcode = OP_ADDR64 | HW_OWNER;
+			sky2->tx_addr64 = addr64;
+		}
+
+		le = get_tx_le(sky2);
+		le->tx.addr = cpu_to_le32((u32) mapping);
+		le->length = cpu_to_le16(frag->size);
+		le->ctrl = ctrl;
+		le->opcode = OP_BUFFER | HW_OWNER;
+
+		fre = sky2->tx_ring
+		    + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
+		pci_unmap_addr_set(fre, mapaddr, mapping);
+	}
+
+	re->idx = sky2->tx_prod;
+	le->ctrl |= EOP;
+
+	sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
+		     &sky2->tx_last_put, TX_RING_SIZE);
+
+	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+		netif_stop_queue(dev);
+
+out_unlock:
+	mmiowb();
+	spin_unlock(&sky2->tx_lock);
+
+	dev->trans_start = jiffies;
+	return NETDEV_TX_OK;
+}
+
+/*
+ * Free ring elements from starting at tx_cons until "done"
+ *
+ * NB: the hardware will tell us about partial completion of multi-part
+ *     buffers; these are deferred until completion.
+ */
+static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+{
+	struct net_device *dev = sky2->netdev;
+	struct pci_dev *pdev = sky2->hw->pdev;
+	u16 nxt, put;
+	unsigned i;
+
+	BUG_ON(done >= TX_RING_SIZE);
+
+	if (unlikely(netif_msg_tx_done(sky2)))
+		printk(KERN_DEBUG "%s: tx done, up to %u\n",
+		       dev->name, done);
+
+	for (put = sky2->tx_cons; put != done; put = nxt) {
+		struct tx_ring_info *re = sky2->tx_ring + put;
+		struct sk_buff *skb = re->skb;
+
+  		nxt = re->idx;
+		BUG_ON(nxt >= TX_RING_SIZE);
+		prefetch(sky2->tx_ring + nxt);
+
+		/* Check for partial status */
+		if (tx_dist(put, done) < tx_dist(put, nxt))
+			break;
+
+		skb = re->skb;
+		pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
+				 skb_headlen(skb), PCI_DMA_TODEVICE);
+
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			struct tx_ring_info *fre;
+			fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
+			pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
+  				       skb_shinfo(skb)->frags[i].size,
+				       PCI_DMA_TODEVICE);
+		}
+
+		dev_kfree_skb_any(skb);
+	}
+
+	spin_lock(&sky2->tx_lock);
+	sky2->tx_cons = put;
+	if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
+		netif_wake_queue(dev);
+	spin_unlock(&sky2->tx_lock);
+}
+
+/* Cleanup all untransmitted buffers, assume transmitter not running */
+static void sky2_tx_clean(struct sky2_port *sky2)
+{
+	sky2_tx_complete(sky2, sky2->tx_prod);
+}
+
+/* Network shutdown */
+static int sky2_down(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 ctrl;
+
+	/* Never really got started! */
+	if (!sky2->tx_le)
+		return 0;
+
+	if (netif_msg_ifdown(sky2))
+		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+
+	/* Stop more packets from being queued */
+	netif_stop_queue(dev);
+
+	/* Disable port IRQ */
+	local_irq_disable();
+	hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+
+	flush_scheduled_work();
+
+	sky2_phy_reset(hw, port);
+
+	/* Stop transmitter */
+	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
+	sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
+
+	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
+		     RB_RST_SET | RB_DIS_OP_MD);
+
+	ctrl = gma_read16(hw, port, GM_GP_CTRL);
+	ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
+	gma_write16(hw, port, GM_GP_CTRL, ctrl);
+
+	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+
+	/* Workaround shared GMAC reset */
+	if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
+	      && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+
+	/* Disable Force Sync bit and Enable Alloc bit */
+	sky2_write8(hw, SK_REG(port, TXA_CTRL),
+		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
+	sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+	sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+
+	/* Reset the PCI FIFO of the async Tx queue */
+	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
+		     BMU_RST_SET | BMU_FIFO_RST);
+
+	/* Reset the Tx prefetch units */
+	sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
+		     PREF_UNIT_RST_SET);
+
+	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+
+	sky2_rx_stop(sky2);
+
+	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+	/* turn off LED's */
+	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+
+	synchronize_irq(hw->pdev->irq);
+
+	sky2_tx_clean(sky2);
+	sky2_rx_clean(sky2);
+
+	pci_free_consistent(hw->pdev, RX_LE_BYTES,
+			    sky2->rx_le, sky2->rx_le_map);
+	kfree(sky2->rx_ring);
+
+	pci_free_consistent(hw->pdev,
+			    TX_RING_SIZE * sizeof(struct sky2_tx_le),
+			    sky2->tx_le, sky2->tx_le_map);
+	kfree(sky2->tx_ring);
+
+	sky2->tx_le = NULL;
+	sky2->rx_le = NULL;
+
+	sky2->rx_ring = NULL;
+	sky2->tx_ring = NULL;
+
+	return 0;
+}
+
+static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
+{
+	if (!hw->copper)
+		return SPEED_1000;
+
+	if (hw->chip_id == CHIP_ID_YUKON_FE)
+		return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
+
+	switch (aux & PHY_M_PS_SPEED_MSK) {
+	case PHY_M_PS_SPEED_1000:
+		return SPEED_1000;
+	case PHY_M_PS_SPEED_100:
+		return SPEED_100;
+	default:
+		return SPEED_10;
+	}
+}
+
+static void sky2_link_up(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 reg;
+
+	/* Enable Transmit FIFO Underrun */
+	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
+		reg |= GM_GPCR_DUP_FULL;
+
+	/* enable Rx/Tx */
+	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_read16(hw, port, GM_GP_CTRL);
+
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+
+	netif_carrier_on(sky2->netdev);
+	netif_wake_queue(sky2->netdev);
+
+	/* Turn on link LED */
+	sky2_write8(hw, SK_REG(port, LNK_LED_REG),
+		    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
+			     PHY_M_LEDC_INIT_CTRL(sky2->speed ==
+						  SPEED_10 ? 7 : 0) |
+			     PHY_M_LEDC_STA1_CTRL(sky2->speed ==
+						  SPEED_100 ? 7 : 0) |
+			     PHY_M_LEDC_STA0_CTRL(sky2->speed ==
+						  SPEED_1000 ? 7 : 0));
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	}
+
+	if (netif_msg_link(sky2))
+		printk(KERN_INFO PFX
+		       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
+		       sky2->netdev->name, sky2->speed,
+		       sky2->duplex == DUPLEX_FULL ? "full" : "half",
+		       (sky2->tx_pause && sky2->rx_pause) ? "both" :
+		       sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none");
+}
+
+static void sky2_link_down(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 reg;
+
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_read16(hw, port, GM_GP_CTRL);	/* PCI post */
+
+	if (sky2->rx_pause && !sky2->tx_pause) {
+		/* restore Asymmetric Pause bit */
+		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+			     gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
+			     | PHY_M_AN_ASP);
+	}
+
+	netif_carrier_off(sky2->netdev);
+	netif_stop_queue(sky2->netdev);
+
+	/* Turn on link LED */
+	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+
+	if (netif_msg_link(sky2))
+		printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name);
+	sky2_phy_init(hw, port);
+}
+
+static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 lpa;
+
+	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
+
+	if (lpa & PHY_M_AN_RF) {
+		printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
+		return -1;
+	}
+
+	if (hw->chip_id != CHIP_ID_YUKON_FE &&
+	    gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
+		printk(KERN_ERR PFX "%s: master/slave fault",
+		       sky2->netdev->name);
+		return -1;
+	}
+
+	if (!(aux & PHY_M_PS_SPDUP_RES)) {
+		printk(KERN_ERR PFX "%s: speed/duplex mismatch",
+		       sky2->netdev->name);
+		return -1;
+	}
+
+	sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+	sky2->speed = sky2_phy_speed(hw, aux);
+
+	/* Pause bits are offset (9..8) */
+	if (hw->chip_id == CHIP_ID_YUKON_XL)
+		aux >>= 6;
+
+	sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
+	sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0;
+
+	if ((sky2->tx_pause || sky2->rx_pause)
+	    && !(sky2->speed < SPEED_1000 && sky2->duplex == DUPLEX_HALF))
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+	else
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+
+	return 0;
+}
+
+/*
+ * Interrupt from PHY are handled outside of interrupt context
+ * because accessing phy registers requires spin wait which might
+ * cause excess interrupt latency.
+ */
+static void sky2_phy_task(void *arg)
+{
+	struct sky2_port *sky2 = arg;
+	struct sky2_hw *hw = sky2->hw;
+	u16 istatus, phystat;
+
+	down(&sky2->phy_sema);
+	istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT);
+	phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT);
+
+	if (netif_msg_intr(sky2))
+		printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
+		       sky2->netdev->name, istatus, phystat);
+
+	if (istatus & PHY_M_IS_AN_COMPL) {
+		if (sky2_autoneg_done(sky2, phystat) == 0)
+			sky2_link_up(sky2);
+		goto out;
+	}
+
+	if (istatus & PHY_M_IS_LSP_CHANGE)
+		sky2->speed = sky2_phy_speed(hw, phystat);
+
+	if (istatus & PHY_M_IS_DUP_CHANGE)
+		sky2->duplex =
+		    (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+	if (istatus & PHY_M_IS_LST_CHANGE) {
+		if (phystat & PHY_M_PS_LINK_UP)
+			sky2_link_up(sky2);
+		else
+			sky2_link_down(sky2);
+	}
+out:
+	up(&sky2->phy_sema);
+
+	local_irq_disable();
+	hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+}
+
+static void sky2_tx_timeout(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned txq = txqaddr[sky2->port];
+
+	if (netif_msg_timer(sky2))
+		printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
+	sky2_read32(hw, Q_ADDR(txq, Q_CSR));
+
+	sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+
+	sky2_tx_clean(sky2);
+
+	sky2_qset(hw, txq);
+	sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
+
+	netif_wake_queue(dev);
+}
+
+
+#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
+static inline unsigned sky2_buf_size(int mtu)
+{
+	return roundup(mtu + ETH_HLEN + 4, 8);
+}
+
+static int sky2_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	int err;
+	u16 ctl, mode;
+
+	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+		return -EINVAL;
+
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN)
+		return -EINVAL;
+
+	if (!netif_running(dev)) {
+		dev->mtu = new_mtu;
+		return 0;
+	}
+
+	sky2_write32(hw, B0_IMSK, 0);
+
+	dev->trans_start = jiffies;	/* prevent tx timeout */
+	netif_stop_queue(dev);
+	netif_poll_disable(hw->dev[0]);
+
+	ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
+	gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+	sky2_rx_stop(sky2);
+	sky2_rx_clean(sky2);
+
+	dev->mtu = new_mtu;
+	sky2->rx_bufsize = sky2_buf_size(new_mtu);
+	mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+	if (dev->mtu > ETH_DATA_LEN)
+		mode |= GM_SMOD_JUMBO_ENA;
+
+	gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode);
+
+	sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
+
+	err = sky2_rx_start(sky2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+	if (err)
+		dev_close(dev);
+	else {
+		gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
+
+		netif_poll_enable(hw->dev[0]);
+		netif_wake_queue(dev);
+	}
+
+	return err;
+}
+
+/*
+ * Receive one packet.
+ * For small packets or errors, just reuse existing skb.
+ * For larger packets, get new buffer.
+ */
+static struct sk_buff *sky2_receive(struct sky2_port *sky2,
+				    u16 length, u32 status)
+{
+	struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+	struct sk_buff *skb = NULL;
+
+	if (unlikely(netif_msg_rx_status(sky2)))
+		printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
+		       sky2->netdev->name, sky2->rx_next, status, length);
+
+	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
+	prefetch(sky2->rx_ring + sky2->rx_next);
+
+	if (status & GMR_FS_ANY_ERR)
+		goto error;
+
+	if (!(status & GMR_FS_RX_OK))
+		goto resubmit;
+
+	if ((status >> 16) != length || length > sky2->rx_bufsize)
+		goto oversize;
+
+	if (length < copybreak) {
+		skb = alloc_skb(length + 2, GFP_ATOMIC);
+		if (!skb)
+			goto resubmit;
+
+		skb_reserve(skb, 2);
+		pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
+					    length, PCI_DMA_FROMDEVICE);
+		memcpy(skb->data, re->skb->data, length);
+		skb->ip_summed = re->skb->ip_summed;
+		skb->csum = re->skb->csum;
+		pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
+					       length, PCI_DMA_FROMDEVICE);
+	} else {
+		struct sk_buff *nskb;
+
+		nskb = dev_alloc_skb(sky2->rx_bufsize);
+		if (!nskb)
+			goto resubmit;
+
+		skb = re->skb;
+		re->skb = nskb;
+		pci_unmap_single(sky2->hw->pdev, re->mapaddr,
+				 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+		prefetch(skb->data);
+
+		re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
+					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+	}
+
+	skb_put(skb, length);
+resubmit:
+	re->skb->ip_summed = CHECKSUM_NONE;
+	sky2_rx_add(sky2, re->mapaddr);
+
+	/* Tell receiver about new buffers. */
+	sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
+		     &sky2->rx_last_put, RX_LE_SIZE);
+
+	return skb;
+
+oversize:
+	++sky2->net_stats.rx_over_errors;
+	goto resubmit;
+
+error:
+	++sky2->net_stats.rx_errors;
+
+	if (netif_msg_rx_err(sky2))
+		printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
+		       sky2->netdev->name, status, length);
+
+	if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
+		sky2->net_stats.rx_length_errors++;
+	if (status & GMR_FS_FRAGMENT)
+		sky2->net_stats.rx_frame_errors++;
+	if (status & GMR_FS_CRC_ERR)
+		sky2->net_stats.rx_crc_errors++;
+	if (status & GMR_FS_RX_FF_OV)
+		sky2->net_stats.rx_fifo_errors++;
+
+	goto resubmit;
+}
+
+/*
+ * Check for transmit complete
+ */
+#define TX_NO_STATUS	0xffff
+
+static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
+{
+	if (last != TX_NO_STATUS) {
+		struct net_device *dev = hw->dev[port];
+		if (dev && netif_running(dev)) {
+			struct sky2_port *sky2 = netdev_priv(dev);
+			sky2_tx_complete(sky2, last);
+		}
+	}
+}
+
+/*
+ * Both ports share the same status interrupt, therefore there is only
+ * one poll routine.
+ */
+static int sky2_poll(struct net_device *dev0, int *budget)
+{
+	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
+	unsigned int to_do = min(dev0->quota, *budget);
+	unsigned int work_done = 0;
+	u16 hwidx;
+	u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
+
+	hwidx = sky2_read16(hw, STAT_PUT_IDX);
+	BUG_ON(hwidx >= STATUS_RING_SIZE);
+	rmb();
+
+	while (hwidx != hw->st_idx) {
+		struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+		struct net_device *dev;
+		struct sky2_port *sky2;
+		struct sk_buff *skb;
+		u32 status;
+		u16 length;
+		u8 op;
+
+		le = hw->st_le + hw->st_idx;
+		hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
+		prefetch(hw->st_le + hw->st_idx);
+
+		BUG_ON(le->link >= 2);
+		dev = hw->dev[le->link];
+		if (dev == NULL || !netif_running(dev))
+			continue;
+
+		sky2 = netdev_priv(dev);
+		status = le32_to_cpu(le->status);
+		length = le16_to_cpu(le->length);
+		op = le->opcode & ~HW_OWNER;
+		le->opcode = 0;
+
+		switch (op) {
+		case OP_RXSTAT:
+			skb = sky2_receive(sky2, length, status);
+			if (!skb)
+				break;
+
+			skb->dev = dev;
+			skb->protocol = eth_type_trans(skb, dev);
+			dev->last_rx = jiffies;
+
+#ifdef SKY2_VLAN_TAG_USED
+			if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
+				vlan_hwaccel_receive_skb(skb,
+							 sky2->vlgrp,
+							 be16_to_cpu(sky2->rx_tag));
+			} else
+#endif
+				netif_receive_skb(skb);
+
+			if (++work_done >= to_do)
+				goto exit_loop;
+			break;
+
+#ifdef SKY2_VLAN_TAG_USED
+		case OP_RXVLAN:
+			sky2->rx_tag = length;
+			break;
+
+		case OP_RXCHKSVLAN:
+			sky2->rx_tag = length;
+			/* fall through */
+#endif
+		case OP_RXCHKS:
+			skb = sky2->rx_ring[sky2->rx_next].skb;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = le16_to_cpu(status);
+			break;
+
+		case OP_TXINDEXLE:
+			/* TX index reports status for both ports */
+			tx_done[0] = status & 0xffff;
+			tx_done[1] = ((status >> 24) & 0xff)
+				| (u16)(length & 0xf) << 8;
+			break;
+
+		default:
+			if (net_ratelimit())
+				printk(KERN_WARNING PFX
+				       "unknown status opcode 0x%x\n", op);
+			break;
+		}
+	}
+
+exit_loop:
+	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+	mmiowb();
+
+	sky2_tx_check(hw, 0, tx_done[0]);
+	sky2_tx_check(hw, 1, tx_done[1]);
+
+	if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+		/* need to restart TX timer */
+		if (is_ec_a1(hw)) {
+			sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+			sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+		}
+
+		netif_rx_complete(dev0);
+		hw->intr_mask |= Y2_IS_STAT_BMU;
+		sky2_write32(hw, B0_IMSK, hw->intr_mask);
+		mmiowb();
+		return 0;
+	} else {
+		*budget -= work_done;
+		dev0->quota -= work_done;
+		return 1;
+	}
+}
+
+static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
+{
+	struct net_device *dev = hw->dev[port];
+
+	printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
+	       dev->name, status);
+
+	if (status & Y2_IS_PAR_RD1) {
+		printk(KERN_ERR PFX "%s: ram data read parity error\n",
+		       dev->name);
+		/* Clear IRQ */
+		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
+	}
+
+	if (status & Y2_IS_PAR_WR1) {
+		printk(KERN_ERR PFX "%s: ram data write parity error\n",
+		       dev->name);
+
+		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
+	}
+
+	if (status & Y2_IS_PAR_MAC1) {
+		printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
+	}
+
+	if (status & Y2_IS_PAR_RX1) {
+		printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
+	}
+
+	if (status & Y2_IS_TCP_TXA1) {
+		printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name);
+		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
+	}
+}
+
+static void sky2_hw_intr(struct sky2_hw *hw)
+{
+	u32 status = sky2_read32(hw, B0_HWE_ISRC);
+
+	if (status & Y2_IS_TIST_OV)
+		sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+	if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
+		u16 pci_err;
+
+		pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
+		printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
+		       pci_name(hw->pdev), pci_err);
+
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		pci_write_config_word(hw->pdev, PCI_STATUS,
+				      pci_err | PCI_STATUS_ERROR_BITS);
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+	}
+
+	if (status & Y2_IS_PCI_EXP) {
+		/* PCI-Express uncorrectable Error occurred */
+		u32 pex_err;
+
+		pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
+
+		printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
+		       pci_name(hw->pdev), pex_err);
+
+		/* clear the interrupt */
+		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+				       0xffffffffUL);
+		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		if (pex_err & PEX_FATAL_ERRORS) {
+			u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+			hwmsk &= ~Y2_IS_PCI_EXP;
+			sky2_write32(hw, B0_HWE_IMSK, hwmsk);
+		}
+	}
+
+	if (status & Y2_HWE_L1_MASK)
+		sky2_hw_error(hw, 0, status);
+	status >>= 8;
+	if (status & Y2_HWE_L1_MASK)
+		sky2_hw_error(hw, 1, status);
+}
+
+static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+	if (netif_msg_intr(sky2))
+		printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
+		       dev->name, status);
+
+	if (status & GM_IS_RX_FF_OR) {
+		++sky2->net_stats.rx_fifo_errors;
+		sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
+	}
+
+	if (status & GM_IS_TX_FF_UR) {
+		++sky2->net_stats.tx_fifo_errors;
+		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
+	}
+}
+
+static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	schedule_work(&sky2->phy_task);
+}
+
+static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sky2_hw *hw = dev_id;
+	struct net_device *dev0 = hw->dev[0];
+	u32 status;
+
+	status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+	if (status == 0 || status == ~0)
+		return IRQ_NONE;
+
+	if (status & Y2_IS_HW_ERR)
+		sky2_hw_intr(hw);
+
+	/* Do NAPI for Rx and Tx status */
+	if (status & Y2_IS_STAT_BMU) {
+		hw->intr_mask &= ~Y2_IS_STAT_BMU;
+		sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+		if (likely(__netif_rx_schedule_prep(dev0))) {
+			prefetch(&hw->st_le[hw->st_idx]);
+			__netif_rx_schedule(dev0);
+		}
+	}
+
+	if (status & Y2_IS_IRQ_PHY1)
+		sky2_phy_intr(hw, 0);
+
+	if (status & Y2_IS_IRQ_PHY2)
+		sky2_phy_intr(hw, 1);
+
+	if (status & Y2_IS_IRQ_MAC1)
+		sky2_mac_intr(hw, 0);
+
+	if (status & Y2_IS_IRQ_MAC2)
+		sky2_mac_intr(hw, 1);
+
+	sky2_write32(hw, B0_Y2_SP_ICR, 2);
+
+	sky2_read32(hw, B0_IMSK);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void sky2_netpoll(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL);
+}
+#endif
+
+/* Chip internal frequency for clock calculations */
+static inline u32 sky2_mhz(const struct sky2_hw *hw)
+{
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_EC:
+	case CHIP_ID_YUKON_EC_U:
+		return 125;	/* 125 Mhz */
+	case CHIP_ID_YUKON_FE:
+		return 100;	/* 100 Mhz */
+	default:		/* YUKON_XL */
+		return 156;	/* 156 Mhz */
+	}
+}
+
+static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
+{
+	return sky2_mhz(hw) * us;
+}
+
+static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
+{
+	return clk / sky2_mhz(hw);
+}
+
+
+static int sky2_reset(struct sky2_hw *hw)
+{
+	u32 ctst;
+	u16 status;
+	u8 t8, pmd_type;
+	int i;
+
+	ctst = sky2_read32(hw, B0_CTST);
+
+	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+	hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
+	if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
+		printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
+		       pci_name(hw->pdev), hw->chip_id);
+		return -EOPNOTSUPP;
+	}
+
+	/* ring for status responses */
+	hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+					 &hw->st_dma);
+	if (!hw->st_le)
+		return -ENOMEM;
+
+	/* disable ASF */
+	if (hw->chip_id <= CHIP_ID_YUKON_EC) {
+		sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+		sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
+	}
+
+	/* do a SW reset */
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+
+	/* clear PCI errors, if any */
+	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+	pci_write_config_word(hw->pdev, PCI_STATUS,
+			      status | PCI_STATUS_ERROR_BITS);
+
+	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
+
+	/* clear any PEX errors */
+	if (is_pciex(hw)) {
+		u16 lstat;
+		pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+				       0xffffffffUL);
+		pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+	}
+
+	pmd_type = sky2_read8(hw, B2_PMD_TYP);
+	hw->copper = !(pmd_type == 'L' || pmd_type == 'S');
+
+	hw->ports = 1;
+	t8 = sky2_read8(hw, B2_Y2_HW_RES);
+	if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+		if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
+			++hw->ports;
+	}
+	hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
+
+	sky2_set_power_state(hw, PCI_D0);
+
+	for (i = 0; i < hw->ports; i++) {
+		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+	}
+
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+	/* Clear I2C IRQ noise */
+	sky2_write32(hw, B2_I2C_IRQ, 1);
+
+	/* turn off hardware timer (unused) */
+	sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
+	sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
+
+	sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
+
+	/* Turn off descriptor polling */
+	sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
+
+	/* Turn off receive timestamp */
+	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
+	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+	/* enable the Tx Arbiters */
+	for (i = 0; i < hw->ports; i++)
+		sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+
+	/* Initialize ram interface */
+	for (i = 0; i < hw->ports; i++) {
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
+
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
+	}
+
+	sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+
+	for (i = 0; i < hw->ports; i++)
+		sky2_phy_reset(hw, i);
+
+	memset(hw->st_le, 0, STATUS_LE_BYTES);
+	hw->st_idx = 0;
+
+	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
+	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
+
+	sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
+	sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
+
+	/* Set the list last index */
+	sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
+
+	/* These status setup values are copied from SysKonnect's driver */
+	if (is_ec_a1(hw)) {
+		/* WA for dev. #4.3 */
+		sky2_write16(hw, STAT_TX_IDX_TH, 0xfff);	/* Tx Threshold */
+
+		/* set Status-FIFO watermark */
+		sky2_write8(hw, STAT_FIFO_WM, 0x21);	/* WA for dev. #4.18 */
+
+		/* set Status-FIFO ISR watermark */
+		sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07);	/* WA for dev. #4.18 */
+		sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
+	} else {
+		sky2_write16(hw, STAT_TX_IDX_TH, 10);
+		sky2_write8(hw, STAT_FIFO_WM, 16);
+
+		/* set Status-FIFO ISR watermark */
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
+			sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
+		else
+			sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
+
+		sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
+		sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
+		sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
+	}
+
+	/* enable status unit */
+	sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
+
+	sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+	sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+
+	return 0;
+}
+
+static inline u32 sky2_supported_modes(const struct sky2_hw *hw)
+{
+	u32 modes;
+	if (hw->copper) {
+		modes = SUPPORTED_10baseT_Half
+		    | SUPPORTED_10baseT_Full
+		    | SUPPORTED_100baseT_Half
+		    | SUPPORTED_100baseT_Full
+		    | SUPPORTED_Autoneg | SUPPORTED_TP;
+
+		if (hw->chip_id != CHIP_ID_YUKON_FE)
+			modes |= SUPPORTED_1000baseT_Half
+			    | SUPPORTED_1000baseT_Full;
+	} else
+		modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+		    | SUPPORTED_Autoneg;
+	return modes;
+}
+
+static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	ecmd->transceiver = XCVR_INTERNAL;
+	ecmd->supported = sky2_supported_modes(hw);
+	ecmd->phy_address = PHY_ADDR_MARV;
+	if (hw->copper) {
+		ecmd->supported = SUPPORTED_10baseT_Half
+		    | SUPPORTED_10baseT_Full
+		    | SUPPORTED_100baseT_Half
+		    | SUPPORTED_100baseT_Full
+		    | SUPPORTED_1000baseT_Half
+		    | SUPPORTED_1000baseT_Full
+		    | SUPPORTED_Autoneg | SUPPORTED_TP;
+		ecmd->port = PORT_TP;
+	} else
+		ecmd->port = PORT_FIBRE;
+
+	ecmd->advertising = sky2->advertising;
+	ecmd->autoneg = sky2->autoneg;
+	ecmd->speed = sky2->speed;
+	ecmd->duplex = sky2->duplex;
+	return 0;
+}
+
+static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	const struct sky2_hw *hw = sky2->hw;
+	u32 supported = sky2_supported_modes(hw);
+
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		ecmd->advertising = supported;
+		sky2->duplex = -1;
+		sky2->speed = -1;
+	} else {
+		u32 setting;
+
+		switch (ecmd->speed) {
+		case SPEED_1000:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_1000baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_1000baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		case SPEED_100:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_100baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_100baseT_Half;
+			else
+				return -EINVAL;
+			break;
+
+		case SPEED_10:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_10baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_10baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if ((setting & supported) == 0)
+			return -EINVAL;
+
+		sky2->speed = ecmd->speed;
+		sky2->duplex = ecmd->duplex;
+	}
+
+	sky2->autoneg = ecmd->autoneg;
+	sky2->advertising = ecmd->advertising;
+
+	if (netif_running(dev))
+		sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_get_drvinfo(struct net_device *dev,
+			     struct ethtool_drvinfo *info)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, pci_name(sky2->hw->pdev));
+}
+
+static const struct sky2_stat {
+	char name[ETH_GSTRING_LEN];
+	u16 offset;
+} sky2_stats[] = {
+	{ "tx_bytes",	   GM_TXO_OK_HI },
+	{ "rx_bytes",	   GM_RXO_OK_HI },
+	{ "tx_broadcast",  GM_TXF_BC_OK },
+	{ "rx_broadcast",  GM_RXF_BC_OK },
+	{ "tx_multicast",  GM_TXF_MC_OK },
+	{ "rx_multicast",  GM_RXF_MC_OK },
+	{ "tx_unicast",    GM_TXF_UC_OK },
+	{ "rx_unicast",    GM_RXF_UC_OK },
+	{ "tx_mac_pause",  GM_TXF_MPAUSE },
+	{ "rx_mac_pause",  GM_RXF_MPAUSE },
+	{ "collisions",    GM_TXF_SNG_COL },
+	{ "late_collision",GM_TXF_LAT_COL },
+	{ "aborted", 	   GM_TXF_ABO_COL },
+	{ "multi_collisions", GM_TXF_MUL_COL },
+	{ "fifo_underrun", GM_TXE_FIFO_UR },
+	{ "fifo_overflow", GM_RXE_FIFO_OV },
+	{ "rx_toolong",    GM_RXF_LNG_ERR },
+	{ "rx_jabber",     GM_RXF_JAB_PKT },
+	{ "rx_runt", 	   GM_RXE_FRAG },
+	{ "rx_too_long",   GM_RXF_LNG_ERR },
+	{ "rx_fcs_error",   GM_RXF_FCS_ERR },
+};
+
+static u32 sky2_get_rx_csum(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	return sky2->rx_csum;
+}
+
+static int sky2_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2->rx_csum = data;
+
+	sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+		     data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+	return 0;
+}
+
+static u32 sky2_get_msglevel(struct net_device *netdev)
+{
+	struct sky2_port *sky2 = netdev_priv(netdev);
+	return sky2->msg_enable;
+}
+
+static int sky2_nway_reset(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	if (sky2->autoneg != AUTONEG_ENABLE)
+		return -EINVAL;
+
+	sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	int i;
+
+	data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
+	    | (u64) gma_read32(hw, port, GM_TXO_OK_LO);
+	data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
+	    | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
+
+	for (i = 2; i < count; i++)
+		data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset);
+}
+
+static void sky2_set_msglevel(struct net_device *netdev, u32 value)
+{
+	struct sky2_port *sky2 = netdev_priv(netdev);
+	sky2->msg_enable = value;
+}
+
+static int sky2_get_stats_count(struct net_device *dev)
+{
+	return ARRAY_SIZE(sky2_stats);
+}
+
+static void sky2_get_ethtool_stats(struct net_device *dev,
+				   struct ethtool_stats *stats, u64 * data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
+}
+
+static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       sky2_stats[i].name, ETH_GSTRING_LEN);
+		break;
+	}
+}
+
+/* Use hardware MIB variables for critical path statistics and
+ * transmit feedback not reported at interrupt.
+ * Other errors are accounted for in interrupt handler.
+ */
+static struct net_device_stats *sky2_get_stats(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u64 data[13];
+
+	sky2_phy_stats(sky2, data, ARRAY_SIZE(data));
+
+	sky2->net_stats.tx_bytes = data[0];
+	sky2->net_stats.rx_bytes = data[1];
+	sky2->net_stats.tx_packets = data[2] + data[4] + data[6];
+	sky2->net_stats.rx_packets = data[3] + data[5] + data[7];
+	sky2->net_stats.multicast = data[5] + data[7];
+	sky2->net_stats.collisions = data[10];
+	sky2->net_stats.tx_aborted_errors = data[12];
+
+	return &sky2->net_stats;
+}
+
+static int sky2_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
+		    dev->dev_addr, ETH_ALEN);
+	memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
+		    dev->dev_addr, ETH_ALEN);
+
+	if (netif_running(dev))
+		sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_set_multicast(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	struct dev_mc_list *list = dev->mc_list;
+	u16 reg;
+	u8 filter[8];
+
+	memset(filter, 0, sizeof(filter));
+
+	reg = gma_read16(hw, port, GM_RX_CTRL);
+	reg |= GM_RXCR_UCF_ENA;
+
+	if (dev->flags & IFF_PROMISC)	/* promiscuous */
+		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)	/* all multicast */
+		memset(filter, 0xff, sizeof(filter));
+	else if (dev->mc_count == 0)	/* no multicast */
+		reg &= ~GM_RXCR_MCF_ENA;
+	else {
+		int i;
+		reg |= GM_RXCR_MCF_ENA;
+
+		for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+			u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
+			filter[bit / 8] |= 1 << (bit % 8);
+		}
+	}
+
+	gma_write16(hw, port, GM_MC_ADDR_H1,
+		    (u16) filter[0] | ((u16) filter[1] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H2,
+		    (u16) filter[2] | ((u16) filter[3] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H3,
+		    (u16) filter[4] | ((u16) filter[5] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H4,
+		    (u16) filter[6] | ((u16) filter[7] << 8));
+
+	gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+/* Can have one global because blinking is controlled by
+ * ethtool and that is always under RTNL mutex
+ */
+static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
+{
+	u16 pg;
+
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_XL:
+		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+			     on ? (PHY_M_LEDC_LOS_CTRL(1) |
+				   PHY_M_LEDC_INIT_CTRL(7) |
+				   PHY_M_LEDC_STA1_CTRL(7) |
+				   PHY_M_LEDC_STA0_CTRL(7))
+			     : 0);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+		break;
+
+	default:
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+			     on ? 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)
+			     : 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));
+
+	}
+}
+
+/* blink LED's for finding board */
+static int sky2_phys_id(struct net_device *dev, u32 data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 ledctrl, ledover = 0;
+	long ms;
+	int interrupted;
+	int onoff = 1;
+
+	if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
+		ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
+	else
+		ms = data * 1000;
+
+	/* save initial values */
+	down(&sky2->phy_sema);
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	} else {
+		ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
+		ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
+	}
+
+	interrupted = 0;
+	while (!interrupted && ms > 0) {
+		sky2_led(hw, port, onoff);
+		onoff = !onoff;
+
+		up(&sky2->phy_sema);
+		interrupted = msleep_interruptible(250);
+		down(&sky2->phy_sema);
+
+		ms -= 250;
+	}
+
+	/* resume regularly scheduled programming */
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	} else {
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+	}
+	up(&sky2->phy_sema);
+
+	return 0;
+}
+
+static void sky2_get_pauseparam(struct net_device *dev,
+				struct ethtool_pauseparam *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	ecmd->tx_pause = sky2->tx_pause;
+	ecmd->rx_pause = sky2->rx_pause;
+	ecmd->autoneg = sky2->autoneg;
+}
+
+static int sky2_set_pauseparam(struct net_device *dev,
+			       struct ethtool_pauseparam *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int err = 0;
+
+	sky2->autoneg = ecmd->autoneg;
+	sky2->tx_pause = ecmd->tx_pause != 0;
+	sky2->rx_pause = ecmd->rx_pause != 0;
+
+	sky2_phy_reinit(sky2);
+
+	return err;
+}
+
+#ifdef CONFIG_PM
+static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	wol->supported = WAKE_MAGIC;
+	wol->wolopts = sky2->wol ? WAKE_MAGIC : 0;
+}
+
+static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+		return -EOPNOTSUPP;
+
+	sky2->wol = wol->wolopts == WAKE_MAGIC;
+
+	if (sky2->wol) {
+		memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
+
+		sky2_write16(hw, WOL_CTRL_STAT,
+			     WOL_CTL_ENA_PME_ON_MAGIC_PKT |
+			     WOL_CTL_ENA_MAGIC_PKT_UNIT);
+	} else
+		sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
+
+	return 0;
+}
+#endif
+
+static int sky2_get_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
+		ecmd->tx_coalesce_usecs = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
+		ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
+	}
+	ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
+
+	if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
+		ecmd->rx_coalesce_usecs = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
+		ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
+	}
+	ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
+
+	if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
+		ecmd->rx_coalesce_usecs_irq = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
+		ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
+	}
+
+	ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
+
+	return 0;
+}
+
+/* Note: this affect both ports */
+static int sky2_set_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	const u32 tmin = sky2_clk2us(hw, 1);
+	const u32 tmax = 5000;
+
+	if (ecmd->tx_coalesce_usecs != 0 &&
+	    (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
+		return -EINVAL;
+
+	if (ecmd->rx_coalesce_usecs != 0 &&
+	    (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
+		return -EINVAL;
+
+	if (ecmd->rx_coalesce_usecs_irq != 0 &&
+	    (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
+		return -EINVAL;
+
+	if (ecmd->tx_max_coalesced_frames > 0xffff)
+		return -EINVAL;
+	if (ecmd->rx_max_coalesced_frames > 0xff)
+		return -EINVAL;
+	if (ecmd->rx_max_coalesced_frames_irq > 0xff)
+		return -EINVAL;
+
+	if (ecmd->tx_coalesce_usecs == 0)
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_TX_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+	}
+	sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
+
+	if (ecmd->rx_coalesce_usecs == 0)
+		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_LEV_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
+		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+	}
+	sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
+
+	if (ecmd->rx_coalesce_usecs_irq == 0)
+		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_TX_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
+		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+	}
+	sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
+	return 0;
+}
+
+static void sky2_get_ringparam(struct net_device *dev,
+			       struct ethtool_ringparam *ering)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	ering->rx_max_pending = RX_MAX_PENDING;
+	ering->rx_mini_max_pending = 0;
+	ering->rx_jumbo_max_pending = 0;
+	ering->tx_max_pending = TX_RING_SIZE - 1;
+
+	ering->rx_pending = sky2->rx_pending;
+	ering->rx_mini_pending = 0;
+	ering->rx_jumbo_pending = 0;
+	ering->tx_pending = sky2->tx_pending;
+}
+
+static int sky2_set_ringparam(struct net_device *dev,
+			      struct ethtool_ringparam *ering)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int err = 0;
+
+	if (ering->rx_pending > RX_MAX_PENDING ||
+	    ering->rx_pending < 8 ||
+	    ering->tx_pending < MAX_SKB_TX_LE ||
+	    ering->tx_pending > TX_RING_SIZE - 1)
+		return -EINVAL;
+
+	if (netif_running(dev))
+		sky2_down(dev);
+
+	sky2->rx_pending = ering->rx_pending;
+	sky2->tx_pending = ering->tx_pending;
+
+	if (netif_running(dev)) {
+		err = sky2_up(dev);
+		if (err)
+			dev_close(dev);
+		else
+			sky2_set_multicast(dev);
+	}
+
+	return err;
+}
+
+static int sky2_get_regs_len(struct net_device *dev)
+{
+	return 0x4000;
+}
+
+/*
+ * Returns copy of control register region
+ * Note: access to the RAM address register set will cause timeouts.
+ */
+static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+			  void *p)
+{
+	const struct sky2_port *sky2 = netdev_priv(dev);
+	const void __iomem *io = sky2->hw->regs;
+
+	BUG_ON(regs->len < B3_RI_WTO_R1);
+	regs->version = 1;
+	memset(p, 0, regs->len);
+
+	memcpy_fromio(p, io, B3_RAM_ADDR);
+
+	memcpy_fromio(p + B3_RI_WTO_R1,
+		      io + B3_RI_WTO_R1,
+		      regs->len - B3_RI_WTO_R1);
+}
+
+static struct ethtool_ops sky2_ethtool_ops = {
+	.get_settings = sky2_get_settings,
+	.set_settings = sky2_set_settings,
+	.get_drvinfo = sky2_get_drvinfo,
+	.get_msglevel = sky2_get_msglevel,
+	.set_msglevel = sky2_set_msglevel,
+	.nway_reset   = sky2_nway_reset,
+	.get_regs_len = sky2_get_regs_len,
+	.get_regs = sky2_get_regs,
+	.get_link = ethtool_op_get_link,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = ethtool_op_set_sg,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = ethtool_op_set_tx_csum,
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = ethtool_op_set_tso,
+	.get_rx_csum = sky2_get_rx_csum,
+	.set_rx_csum = sky2_set_rx_csum,
+	.get_strings = sky2_get_strings,
+	.get_coalesce = sky2_get_coalesce,
+	.set_coalesce = sky2_set_coalesce,
+	.get_ringparam = sky2_get_ringparam,
+	.set_ringparam = sky2_set_ringparam,
+	.get_pauseparam = sky2_get_pauseparam,
+	.set_pauseparam = sky2_set_pauseparam,
+#ifdef CONFIG_PM
+	.get_wol = sky2_get_wol,
+	.set_wol = sky2_set_wol,
+#endif
+	.phys_id = sky2_phys_id,
+	.get_stats_count = sky2_get_stats_count,
+	.get_ethtool_stats = sky2_get_ethtool_stats,
+	.get_perm_addr	= ethtool_op_get_perm_addr,
+};
+
+/* Initialize network device */
+static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
+						     unsigned port, int highmem)
+{
+	struct sky2_port *sky2;
+	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+
+	if (!dev) {
+		printk(KERN_ERR "sky2 etherdev alloc failed");
+		return NULL;
+	}
+
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, &hw->pdev->dev);
+	dev->irq = hw->pdev->irq;
+	dev->open = sky2_up;
+	dev->stop = sky2_down;
+	dev->do_ioctl = sky2_ioctl;
+	dev->hard_start_xmit = sky2_xmit_frame;
+	dev->get_stats = sky2_get_stats;
+	dev->set_multicast_list = sky2_set_multicast;
+	dev->set_mac_address = sky2_set_mac_address;
+	dev->change_mtu = sky2_change_mtu;
+	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
+	dev->tx_timeout = sky2_tx_timeout;
+	dev->watchdog_timeo = TX_WATCHDOG;
+	if (port == 0)
+		dev->poll = sky2_poll;
+	dev->weight = NAPI_WEIGHT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = sky2_netpoll;
+#endif
+
+	sky2 = netdev_priv(dev);
+	sky2->netdev = dev;
+	sky2->hw = hw;
+	sky2->msg_enable = netif_msg_init(debug, default_msg);
+
+	spin_lock_init(&sky2->tx_lock);
+	/* Auto speed and flow control */
+	sky2->autoneg = AUTONEG_ENABLE;
+	sky2->tx_pause = 1;
+	sky2->rx_pause = 1;
+	sky2->duplex = -1;
+	sky2->speed = -1;
+	sky2->advertising = sky2_supported_modes(hw);
+
+ 	/* Receive checksum disabled for Yukon XL
+	 * because of observed problems with incorrect
+	 * values when multiple packets are received in one interrupt
+	 */
+	sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
+
+	INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
+	init_MUTEX(&sky2->phy_sema);
+	sky2->tx_pending = TX_DEF_PENDING;
+	sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
+	sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
+
+	hw->dev[port] = dev;
+
+	sky2->port = port;
+
+	dev->features |= NETIF_F_LLTX;
+	if (hw->chip_id != CHIP_ID_YUKON_EC_U)
+		dev->features |= NETIF_F_TSO;
+	if (highmem)
+		dev->features |= NETIF_F_HIGHDMA;
+	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+
+#ifdef SKY2_VLAN_TAG_USED
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = sky2_vlan_rx_register;
+	dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
+#endif
+
+	/* read the mac address */
+	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
+	/* device is off until link detection */
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	return dev;
+}
+
+static inline void sky2_show_addr(struct net_device *dev)
+{
+	const struct sky2_port *sky2 = netdev_priv(dev);
+
+	if (netif_msg_probe(sky2))
+		printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+		       dev->name,
+		       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+static int __devinit sky2_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct net_device *dev, *dev1 = NULL;
+	struct sky2_hw *hw;
+	int err, pm_cap, using_dac = 0;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "%s cannot enable PCI device\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+
+	err = pci_request_regions(pdev, DRV_NAME);
+	if (err) {
+		printk(KERN_ERR PFX "%s cannot obtain PCI resources\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+
+	pci_set_master(pdev);
+
+	/* Find power-management capability. */
+	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pm_cap == 0) {
+		printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
+		       "aborting.\n");
+		err = -EIO;
+		goto err_out_free_regions;
+	}
+
+	if (sizeof(dma_addr_t) > sizeof(u32)) {
+		err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+		if (!err)
+			using_dac = 1;
+	}
+
+	if (!using_dac) {
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			printk(KERN_ERR PFX "%s no usable DMA configuration\n",
+			       pci_name(pdev));
+			goto err_out_free_regions;
+		}
+	}
+#ifdef __BIG_ENDIAN
+	/* byte swap descriptors in hardware */
+	{
+		u32 reg;
+
+		pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+		reg |= PCI_REV_DESC;
+		pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+	}
+#endif
+
+	err = -ENOMEM;
+	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
+		       pci_name(pdev));
+		goto err_out_free_regions;
+	}
+
+	memset(hw, 0, sizeof(*hw));
+	hw->pdev = pdev;
+
+	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
+	if (!hw->regs) {
+		printk(KERN_ERR PFX "%s: cannot map device registers\n",
+		       pci_name(pdev));
+		goto err_out_free_hw;
+	}
+	hw->pm_cap = pm_cap;
+
+	err = sky2_reset(hw);
+	if (err)
+		goto err_out_iounmap;
+
+	printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n",
+	       DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq,
+	       yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
+	       hw->chip_id, hw->chip_rev);
+
+	dev = sky2_init_netdev(hw, 0, using_dac);
+	if (!dev)
+		goto err_out_free_pci;
+
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot register net device\n",
+		       pci_name(pdev));
+		goto err_out_free_netdev;
+	}
+
+	sky2_show_addr(dev);
+
+	if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
+		if (register_netdev(dev1) == 0)
+			sky2_show_addr(dev1);
+		else {
+			/* Failure to register second port need not be fatal */
+			printk(KERN_WARNING PFX
+			       "register of second port failed\n");
+			hw->dev[1] = NULL;
+			free_netdev(dev1);
+		}
+	}
+
+	err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+		       pci_name(pdev), pdev->irq);
+		goto err_out_unregister;
+	}
+
+	hw->intr_mask = Y2_IS_BASE;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+	pci_set_drvdata(pdev, hw);
+
+	return 0;
+
+err_out_unregister:
+	if (dev1) {
+		unregister_netdev(dev1);
+		free_netdev(dev1);
+	}
+	unregister_netdev(dev);
+err_out_free_netdev:
+	free_netdev(dev);
+err_out_free_pci:
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	pci_free_consistent(hw->pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+err_out_iounmap:
+	iounmap(hw->regs);
+err_out_free_hw:
+	kfree(hw);
+err_out_free_regions:
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+err_out:
+	return err;
+}
+
+static void __devexit sky2_remove(struct pci_dev *pdev)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	struct net_device *dev0, *dev1;
+
+	if (!hw)
+		return;
+
+	dev0 = hw->dev[0];
+	dev1 = hw->dev[1];
+	if (dev1)
+		unregister_netdev(dev1);
+	unregister_netdev(dev0);
+
+	sky2_write32(hw, B0_IMSK, 0);
+	sky2_set_power_state(hw, PCI_D3hot);
+	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	sky2_read8(hw, B0_CTST);
+
+	free_irq(pdev->irq, hw);
+	pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+	if (dev1)
+		free_netdev(dev1);
+	free_netdev(dev0);
+	iounmap(hw->regs);
+	kfree(hw);
+
+	pci_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+
+		if (dev) {
+			if (!netif_running(dev))
+				continue;
+
+			sky2_down(dev);
+			netif_device_detach(dev);
+		}
+	}
+
+	return sky2_set_power_state(hw, pci_choose_state(pdev, state));
+}
+
+static int sky2_resume(struct pci_dev *pdev)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	int i;
+
+	pci_restore_state(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	sky2_set_power_state(hw, PCI_D0);
+
+	sky2_reset(hw);
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+		if (dev) {
+			if (netif_running(dev)) {
+				netif_device_attach(dev);
+				if (sky2_up(dev))
+					dev_close(dev);
+			}
+		}
+	}
+	return 0;
+}
+#endif
+
+static struct pci_driver sky2_driver = {
+	.name = DRV_NAME,
+	.id_table = sky2_id_table,
+	.probe = sky2_probe,
+	.remove = __devexit_p(sky2_remove),
+#ifdef CONFIG_PM
+	.suspend = sky2_suspend,
+	.resume = sky2_resume,
+#endif
+};
+
+static int __init sky2_init_module(void)
+{
+	return pci_register_driver(&sky2_driver);
+}
+
+static void __exit sky2_cleanup_module(void)
+{
+	pci_unregister_driver(&sky2_driver);
+}
+
+module_init(sky2_init_module);
+module_exit(sky2_cleanup_module);
+
+MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
new file mode 100644
index 0000000..9551892
--- /dev/null
+++ b/drivers/net/sky2.h
@@ -0,0 +1,1922 @@
+/*
+ * Definitions for the new Marvell Yukon 2 driver.
+ */
+#ifndef _SKY2_H
+#define _SKY2_H
+
+/* PCI config registers */
+#define PCI_DEV_REG1	0x40
+#define PCI_DEV_REG2	0x44
+#define PCI_DEV_STATUS  0x7c
+#define PCI_OS_PCI_X    (1<<26)
+
+#define PEX_LNK_STAT	0xf2
+#define PEX_UNC_ERR_STAT 0x104
+#define PEX_DEV_CTRL	0xe8
+
+/* Yukon-2 */
+enum pci_dev_reg_1 {
+	PCI_Y2_PIG_ENA	 = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
+	PCI_Y2_DLL_DIS	 = 1<<30, /* Disable PCI DLL (YUKON-2) */
+	PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */
+	PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
+	PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
+	PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */
+};
+
+enum pci_dev_reg_2 {
+	PCI_VPD_WR_THR	= 0xffL<<24,	/* Bit 31..24:	VPD Write Threshold */
+	PCI_DEV_SEL	= 0x7fL<<17,	/* Bit 23..17:	EEPROM Device Select */
+	PCI_VPD_ROM_SZ	= 7L<<14,	/* Bit 16..14:	VPD ROM Size	*/
+
+	PCI_PATCH_DIR	= 0xfL<<8,	/* Bit 11.. 8:	Ext Patches dir 3..0 */
+	PCI_EXT_PATCHS	= 0xfL<<4,	/* Bit	7.. 4:	Extended Patches 3..0 */
+	PCI_EN_DUMMY_RD	= 1<<3,		/* Enable Dummy Read */
+	PCI_REV_DESC	= 1<<2,		/* Reverse Desc. Bytes */
+
+	PCI_USEDATA64	= 1<<0,		/* Use 64Bit Data bus ext */
+};
+
+
+#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
+			       PCI_STATUS_SIG_SYSTEM_ERROR | \
+			       PCI_STATUS_REC_MASTER_ABORT | \
+			       PCI_STATUS_REC_TARGET_ABORT | \
+			       PCI_STATUS_PARITY)
+
+enum pex_dev_ctrl {
+	PEX_DC_MAX_RRS_MSK	= 7<<12, /* Bit 14..12:	Max. Read Request Size */
+	PEX_DC_EN_NO_SNOOP	= 1<<11,/* Enable No Snoop */
+	PEX_DC_EN_AUX_POW	= 1<<10,/* Enable AUX Power */
+	PEX_DC_EN_PHANTOM	= 1<<9,	/* Enable Phantom Functions */
+	PEX_DC_EN_EXT_TAG	= 1<<8,	/* Enable Extended Tag Field */
+	PEX_DC_MAX_PLS_MSK	= 7<<5,	/* Bit  7.. 5:	Max. Payload Size Mask */
+	PEX_DC_EN_REL_ORD	= 1<<4,	/* Enable Relaxed Ordering */
+	PEX_DC_EN_UNS_RQ_RP	= 1<<3,	/* Enable Unsupported Request Reporting */
+	PEX_DC_EN_FAT_ER_RP	= 1<<2,	/* Enable Fatal Error Reporting */
+	PEX_DC_EN_NFA_ER_RP	= 1<<1,	/* Enable Non-Fatal Error Reporting */
+	PEX_DC_EN_COR_ER_RP	= 1<<0,	/* Enable Correctable Error Reporting */
+};
+#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
+
+/* PEX_UNC_ERR_STAT	 PEX Uncorrectable Errors Status Register (Yukon-2) */
+enum pex_err {
+	PEX_UNSUP_REQ 	= 1<<20, /* Unsupported Request Error */
+
+	PEX_MALFOR_TLP	= 1<<18, /* Malformed TLP */
+
+	PEX_UNEXP_COMP	= 1<<16, /* Unexpected Completion */
+
+	PEX_COMP_TO	= 1<<14, /* Completion Timeout */
+	PEX_FLOW_CTRL_P	= 1<<13, /* Flow Control Protocol Error */
+	PEX_POIS_TLP	= 1<<12, /* Poisoned TLP */
+
+	PEX_DATA_LINK_P = 1<<4,	/* Data Link Protocol Error */
+	PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
+};
+
+
+enum csr_regs {
+	B0_RAP		= 0x0000,
+	B0_CTST		= 0x0004,
+	B0_Y2LED	= 0x0005,
+	B0_POWER_CTRL	= 0x0007,
+	B0_ISRC		= 0x0008,
+	B0_IMSK		= 0x000c,
+	B0_HWE_ISRC	= 0x0010,
+	B0_HWE_IMSK	= 0x0014,
+
+	/* Special ISR registers (Yukon-2 only) */
+	B0_Y2_SP_ISRC2	= 0x001c,
+	B0_Y2_SP_ISRC3	= 0x0020,
+	B0_Y2_SP_EISR	= 0x0024,
+	B0_Y2_SP_LISR	= 0x0028,
+	B0_Y2_SP_ICR	= 0x002c,
+
+	B2_MAC_1	= 0x0100,
+	B2_MAC_2	= 0x0108,
+	B2_MAC_3	= 0x0110,
+	B2_CONN_TYP	= 0x0118,
+	B2_PMD_TYP	= 0x0119,
+	B2_MAC_CFG	= 0x011a,
+	B2_CHIP_ID	= 0x011b,
+	B2_E_0		= 0x011c,
+
+	B2_Y2_CLK_GATE  = 0x011d,
+	B2_Y2_HW_RES	= 0x011e,
+	B2_E_3		= 0x011f,
+	B2_Y2_CLK_CTRL	= 0x0120,
+
+	B2_TI_INI	= 0x0130,
+	B2_TI_VAL	= 0x0134,
+	B2_TI_CTRL	= 0x0138,
+	B2_TI_TEST	= 0x0139,
+
+	B2_TST_CTRL1	= 0x0158,
+	B2_TST_CTRL2	= 0x0159,
+	B2_GP_IO	= 0x015c,
+
+	B2_I2C_CTRL	= 0x0160,
+	B2_I2C_DATA	= 0x0164,
+	B2_I2C_IRQ	= 0x0168,
+	B2_I2C_SW	= 0x016c,
+
+	B3_RAM_ADDR	= 0x0180,
+	B3_RAM_DATA_LO	= 0x0184,
+	B3_RAM_DATA_HI	= 0x0188,
+
+/* RAM Interface Registers */
+/* Yukon-2: use RAM_BUFFER() to access the RAM buffer */
+/*
+ * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+ * not usable in SW. Please notice these are NOT real timeouts, these are
+ * the number of qWords transferred continuously.
+ */
+#define RAM_BUFFER(port, reg)	(reg | (port <<6))
+
+	B3_RI_WTO_R1	= 0x0190,
+	B3_RI_WTO_XA1	= 0x0191,
+	B3_RI_WTO_XS1	= 0x0192,
+	B3_RI_RTO_R1	= 0x0193,
+	B3_RI_RTO_XA1	= 0x0194,
+	B3_RI_RTO_XS1	= 0x0195,
+	B3_RI_WTO_R2	= 0x0196,
+	B3_RI_WTO_XA2	= 0x0197,
+	B3_RI_WTO_XS2	= 0x0198,
+	B3_RI_RTO_R2	= 0x0199,
+	B3_RI_RTO_XA2	= 0x019a,
+	B3_RI_RTO_XS2	= 0x019b,
+	B3_RI_TO_VAL	= 0x019c,
+	B3_RI_CTRL	= 0x01a0,
+	B3_RI_TEST	= 0x01a2,
+	B3_MA_TOINI_RX1	= 0x01b0,
+	B3_MA_TOINI_RX2	= 0x01b1,
+	B3_MA_TOINI_TX1	= 0x01b2,
+	B3_MA_TOINI_TX2	= 0x01b3,
+	B3_MA_TOVAL_RX1	= 0x01b4,
+	B3_MA_TOVAL_RX2	= 0x01b5,
+	B3_MA_TOVAL_TX1	= 0x01b6,
+	B3_MA_TOVAL_TX2	= 0x01b7,
+	B3_MA_TO_CTRL	= 0x01b8,
+	B3_MA_TO_TEST	= 0x01ba,
+	B3_MA_RCINI_RX1	= 0x01c0,
+	B3_MA_RCINI_RX2	= 0x01c1,
+	B3_MA_RCINI_TX1	= 0x01c2,
+	B3_MA_RCINI_TX2	= 0x01c3,
+	B3_MA_RCVAL_RX1	= 0x01c4,
+	B3_MA_RCVAL_RX2	= 0x01c5,
+	B3_MA_RCVAL_TX1	= 0x01c6,
+	B3_MA_RCVAL_TX2	= 0x01c7,
+	B3_MA_RC_CTRL	= 0x01c8,
+	B3_MA_RC_TEST	= 0x01ca,
+	B3_PA_TOINI_RX1	= 0x01d0,
+	B3_PA_TOINI_RX2	= 0x01d4,
+	B3_PA_TOINI_TX1	= 0x01d8,
+	B3_PA_TOINI_TX2	= 0x01dc,
+	B3_PA_TOVAL_RX1	= 0x01e0,
+	B3_PA_TOVAL_RX2	= 0x01e4,
+	B3_PA_TOVAL_TX1	= 0x01e8,
+	B3_PA_TOVAL_TX2	= 0x01ec,
+	B3_PA_CTRL	= 0x01f0,
+	B3_PA_TEST	= 0x01f2,
+
+	Y2_CFG_SPC	= 0x1c00,
+};
+
+/*	B0_CTST			16 bit	Control/Status register */
+enum {
+	Y2_VMAIN_AVAIL	= 1<<17,/* VMAIN available (YUKON-2 only) */
+	Y2_VAUX_AVAIL	= 1<<16,/* VAUX available (YUKON-2 only) */
+	Y2_ASF_ENABLE	= 1<<13,/* ASF Unit Enable (YUKON-2 only) */
+	Y2_ASF_DISABLE	= 1<<12,/* ASF Unit Disable (YUKON-2 only) */
+	Y2_CLK_RUN_ENA	= 1<<11,/* CLK_RUN Enable  (YUKON-2 only) */
+	Y2_CLK_RUN_DIS	= 1<<10,/* CLK_RUN Disable (YUKON-2 only) */
+	Y2_LED_STAT_ON	= 1<<9, /* Status LED On  (YUKON-2 only) */
+	Y2_LED_STAT_OFF	= 1<<8, /* Status LED Off (YUKON-2 only) */
+
+	CS_ST_SW_IRQ	= 1<<7,	/* Set IRQ SW Request */
+	CS_CL_SW_IRQ	= 1<<6,	/* Clear IRQ SW Request */
+	CS_STOP_DONE	= 1<<5,	/* Stop Master is finished */
+	CS_STOP_MAST	= 1<<4,	/* Command Bit to stop the master */
+	CS_MRST_CLR	= 1<<3,	/* Clear Master reset	*/
+	CS_MRST_SET	= 1<<2,	/* Set Master reset	*/
+	CS_RST_CLR	= 1<<1,	/* Clear Software reset	*/
+	CS_RST_SET	= 1,	/* Set   Software reset	*/
+};
+
+/*	B0_LED			 8 Bit	LED register */
+enum {
+/* Bit  7.. 2:	reserved */
+	LED_STAT_ON	= 1<<1,	/* Status LED on	*/
+	LED_STAT_OFF	= 1,	/* Status LED off	*/
+};
+
+/*	B0_POWER_CTRL	 8 Bit	Power Control reg (YUKON only) */
+enum {
+	PC_VAUX_ENA	= 1<<7,	/* Switch VAUX Enable  */
+	PC_VAUX_DIS	= 1<<6,	/* Switch VAUX Disable */
+	PC_VCC_ENA	= 1<<5,	/* Switch VCC Enable  */
+	PC_VCC_DIS	= 1<<4,	/* Switch VCC Disable */
+	PC_VAUX_ON	= 1<<3,	/* Switch VAUX On  */
+	PC_VAUX_OFF	= 1<<2,	/* Switch VAUX Off */
+	PC_VCC_ON	= 1<<1,	/* Switch VCC On  */
+	PC_VCC_OFF	= 1<<0,	/* Switch VCC Off */
+};
+
+/*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
+
+/*	B0_Y2_SP_ISRC2	32 bit	Special Interrupt Source Reg 2 */
+/*	B0_Y2_SP_ISRC3	32 bit	Special Interrupt Source Reg 3 */
+/*	B0_Y2_SP_EISR	32 bit	Enter ISR Reg */
+/*	B0_Y2_SP_LISR	32 bit	Leave ISR Reg */
+enum {
+	Y2_IS_HW_ERR	= 1<<31,	/* Interrupt HW Error */
+	Y2_IS_STAT_BMU	= 1<<30,	/* Status BMU Interrupt */
+	Y2_IS_ASF	= 1<<29,	/* ASF subsystem Interrupt */
+
+	Y2_IS_POLL_CHK	= 1<<27,	/* Check IRQ from polling unit */
+	Y2_IS_TWSI_RDY	= 1<<26,	/* IRQ on end of TWSI Tx */
+	Y2_IS_IRQ_SW	= 1<<25,	/* SW forced IRQ	*/
+	Y2_IS_TIMINT	= 1<<24,	/* IRQ from Timer	*/
+
+	Y2_IS_IRQ_PHY2	= 1<<12,	/* Interrupt from PHY 2 */
+	Y2_IS_IRQ_MAC2	= 1<<11,	/* Interrupt from MAC 2 */
+	Y2_IS_CHK_RX2	= 1<<10,	/* Descriptor error Rx 2 */
+	Y2_IS_CHK_TXS2	= 1<<9,		/* Descriptor error TXS 2 */
+	Y2_IS_CHK_TXA2	= 1<<8,		/* Descriptor error TXA 2 */
+
+	Y2_IS_IRQ_PHY1	= 1<<4,		/* Interrupt from PHY 1 */
+	Y2_IS_IRQ_MAC1	= 1<<3,		/* Interrupt from MAC 1 */
+	Y2_IS_CHK_RX1	= 1<<2,		/* Descriptor error Rx 1 */
+	Y2_IS_CHK_TXS1	= 1<<1,		/* Descriptor error TXS 1 */
+	Y2_IS_CHK_TXA1	= 1<<0,		/* Descriptor error TXA 1 */
+
+	Y2_IS_BASE	= Y2_IS_HW_ERR | Y2_IS_STAT_BMU |
+			  Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY |
+			  Y2_IS_IRQ_SW | Y2_IS_TIMINT,
+	Y2_IS_PORT_1	= Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 |
+			  Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1,
+	Y2_IS_PORT_2	= Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 |
+			  Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2,
+};
+
+/*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
+enum {
+	IS_ERR_MSK	= 0x00003fff,/* 		All Error bits */
+
+	IS_IRQ_TIST_OV	= 1<<13, /* Time Stamp Timer Overflow (YUKON only) */
+	IS_IRQ_SENSOR	= 1<<12, /* IRQ from Sensor (YUKON only) */
+	IS_IRQ_MST_ERR	= 1<<11, /* IRQ master error detected */
+	IS_IRQ_STAT	= 1<<10, /* IRQ status exception */
+	IS_NO_STAT_M1	= 1<<9,	/* No Rx Status from MAC 1 */
+	IS_NO_STAT_M2	= 1<<8,	/* No Rx Status from MAC 2 */
+	IS_NO_TIST_M1	= 1<<7,	/* No Time Stamp from MAC 1 */
+	IS_NO_TIST_M2	= 1<<6,	/* No Time Stamp from MAC 2 */
+	IS_RAM_RD_PAR	= 1<<5,	/* RAM Read  Parity Error */
+	IS_RAM_WR_PAR	= 1<<4,	/* RAM Write Parity Error */
+	IS_M1_PAR_ERR	= 1<<3,	/* MAC 1 Parity Error */
+	IS_M2_PAR_ERR	= 1<<2,	/* MAC 2 Parity Error */
+	IS_R1_PAR_ERR	= 1<<1,	/* Queue R1 Parity Error */
+	IS_R2_PAR_ERR	= 1<<0,	/* Queue R2 Parity Error */
+};
+
+/* Hardware error interrupt mask for Yukon 2 */
+enum {
+	Y2_IS_TIST_OV	= 1<<29,/* Time Stamp Timer overflow interrupt */
+	Y2_IS_SENSOR	= 1<<28, /* Sensor interrupt */
+	Y2_IS_MST_ERR	= 1<<27, /* Master error interrupt */
+	Y2_IS_IRQ_STAT	= 1<<26, /* Status exception interrupt */
+	Y2_IS_PCI_EXP	= 1<<25, /* PCI-Express interrupt */
+	Y2_IS_PCI_NEXP	= 1<<24, /* PCI-Express error similar to PCI error */
+						/* Link 2 */
+	Y2_IS_PAR_RD2	= 1<<13, /* Read RAM parity error interrupt */
+	Y2_IS_PAR_WR2	= 1<<12, /* Write RAM parity error interrupt */
+	Y2_IS_PAR_MAC2	= 1<<11, /* MAC hardware fault interrupt */
+	Y2_IS_PAR_RX2	= 1<<10, /* Parity Error Rx Queue 2 */
+	Y2_IS_TCP_TXS2	= 1<<9, /* TCP length mismatch sync Tx queue IRQ */
+	Y2_IS_TCP_TXA2	= 1<<8, /* TCP length mismatch async Tx queue IRQ */
+						/* Link 1 */
+	Y2_IS_PAR_RD1	= 1<<5, /* Read RAM parity error interrupt */
+	Y2_IS_PAR_WR1	= 1<<4, /* Write RAM parity error interrupt */
+	Y2_IS_PAR_MAC1	= 1<<3, /* MAC hardware fault interrupt */
+	Y2_IS_PAR_RX1	= 1<<2, /* Parity Error Rx Queue 1 */
+	Y2_IS_TCP_TXS1	= 1<<1, /* TCP length mismatch sync Tx queue IRQ */
+	Y2_IS_TCP_TXA1	= 1<<0, /* TCP length mismatch async Tx queue IRQ */
+
+	Y2_HWE_L1_MASK	= Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |
+			  Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1,
+	Y2_HWE_L2_MASK	= Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |
+			  Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
+
+	Y2_HWE_ALL_MASK	= Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
+			  Y2_IS_PCI_EXP |
+			  Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
+};
+
+/*	B28_DPT_CTRL	 8 bit	Descriptor Poll Timer Ctrl Reg */
+enum {
+	DPT_START	= 1<<1,
+	DPT_STOP	= 1<<0,
+};
+
+/*	B2_TST_CTRL1	 8 bit	Test Control Register 1 */
+enum {
+	TST_FRC_DPERR_MR = 1<<7, /* force DATAPERR on MST RD */
+	TST_FRC_DPERR_MW = 1<<6, /* force DATAPERR on MST WR */
+	TST_FRC_DPERR_TR = 1<<5, /* force DATAPERR on TRG RD */
+	TST_FRC_DPERR_TW = 1<<4, /* force DATAPERR on TRG WR */
+	TST_FRC_APERR_M	 = 1<<3, /* force ADDRPERR on MST */
+	TST_FRC_APERR_T	 = 1<<2, /* force ADDRPERR on TRG */
+	TST_CFG_WRITE_ON = 1<<1, /* Enable  Config Reg WR */
+	TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
+};
+
+/*	B2_MAC_CFG		 8 bit	MAC Configuration / Chip Revision */
+enum {
+	CFG_CHIP_R_MSK	  = 0xf<<4,	/* Bit 7.. 4: Chip Revision */
+					/* Bit 3.. 2:	reserved */
+	CFG_DIS_M2_CLK	  = 1<<1,	/* Disable Clock for 2nd MAC */
+	CFG_SNG_MAC	  = 1<<0,	/* MAC Config: 0=2 MACs / 1=1 MAC*/
+};
+
+/*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
+enum {
+	CHIP_ID_GENESIS	   = 0x0a, /* Chip ID for GENESIS */
+	CHIP_ID_YUKON	   = 0xb0, /* Chip ID for YUKON */
+	CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+	CHIP_ID_YUKON_LP   = 0xb2, /* Chip ID for YUKON-LP */
+	CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
+	CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
+	CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
+ 	CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
+
+	CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
+	CHIP_REV_YU_EC_A2    = 1,  /* Chip Rev. for Yukon-EC A2 */
+	CHIP_REV_YU_EC_A3    = 2,  /* Chip Rev. for Yukon-EC A3 */
+};
+
+/*	B2_Y2_CLK_GATE	 8 bit	Clock Gating (Yukon-2 only) */
+enum {
+	Y2_STATUS_LNK2_INAC	= 1<<7, /* Status Link 2 inactive (0 = active) */
+	Y2_CLK_GAT_LNK2_DIS	= 1<<6, /* Disable clock gating Link 2 */
+	Y2_COR_CLK_LNK2_DIS	= 1<<5, /* Disable Core clock Link 2 */
+	Y2_PCI_CLK_LNK2_DIS	= 1<<4, /* Disable PCI clock Link 2 */
+	Y2_STATUS_LNK1_INAC	= 1<<3, /* Status Link 1 inactive (0 = active) */
+	Y2_CLK_GAT_LNK1_DIS	= 1<<2, /* Disable clock gating Link 1 */
+	Y2_COR_CLK_LNK1_DIS	= 1<<1, /* Disable Core clock Link 1 */
+	Y2_PCI_CLK_LNK1_DIS	= 1<<0, /* Disable PCI clock Link 1 */
+};
+
+/*	B2_Y2_HW_RES	8 bit	HW Resources (Yukon-2 only) */
+enum {
+	CFG_LED_MODE_MSK	= 7<<2,	/* Bit  4.. 2:	LED Mode Mask */
+	CFG_LINK_2_AVAIL	= 1<<1,	/* Link 2 available */
+	CFG_LINK_1_AVAIL	= 1<<0,	/* Link 1 available */
+};
+#define CFG_LED_MODE(x)		(((x) & CFG_LED_MODE_MSK) >> 2)
+#define CFG_DUAL_MAC_MSK	(CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL)
+
+
+/* B2_Y2_CLK_CTRL	32 bit	Clock Frequency Control Register (Yukon-2/EC) */
+enum {
+	Y2_CLK_DIV_VAL_MSK	= 0xff<<16,/* Bit 23..16: Clock Divisor Value */
+#define	Y2_CLK_DIV_VAL(x)	(((x)<<16) & Y2_CLK_DIV_VAL_MSK)
+	Y2_CLK_DIV_VAL2_MSK	= 7<<21,   /* Bit 23..21: Clock Divisor Value */
+	Y2_CLK_SELECT2_MSK	= 0x1f<<16,/* Bit 20..16: Clock Select */
+#define Y2_CLK_DIV_VAL_2(x)	(((x)<<21) & Y2_CLK_DIV_VAL2_MSK)
+#define Y2_CLK_SEL_VAL_2(x)	(((x)<<16) & Y2_CLK_SELECT2_MSK)
+	Y2_CLK_DIV_ENA		= 1<<1, /* Enable  Core Clock Division */
+	Y2_CLK_DIV_DIS		= 1<<0,	/* Disable Core Clock Division */
+};
+
+/*	B2_TI_CTRL		 8 bit	Timer control */
+/*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
+enum {
+	TIM_START	= 1<<2,	/* Start Timer */
+	TIM_STOP	= 1<<1,	/* Stop  Timer */
+	TIM_CLR_IRQ	= 1<<0,	/* Clear Timer IRQ (!IRQM) */
+};
+
+/*	B2_TI_TEST		 8 Bit	Timer Test */
+/*	B2_IRQM_TEST	 8 bit	IRQ Moderation Timer Test */
+/*	B28_DPT_TST		 8 bit	Descriptor Poll Timer Test Reg */
+enum {
+	TIM_T_ON	= 1<<2,	/* Test mode on */
+	TIM_T_OFF	= 1<<1,	/* Test mode off */
+	TIM_T_STEP	= 1<<0,	/* Test step */
+};
+
+/*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
+					/* Bit 31..19:	reserved */
+#define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
+/* RAM Interface Registers */
+
+/*	B3_RI_CTRL		16 bit	RAM Interface Control Register */
+enum {
+	RI_CLR_RD_PERR	= 1<<9,	/* Clear IRQ RAM Read Parity Err */
+	RI_CLR_WR_PERR	= 1<<8,	/* Clear IRQ RAM Write Parity Err*/
+
+	RI_RST_CLR	= 1<<1,	/* Clear RAM Interface Reset */
+	RI_RST_SET	= 1<<0,	/* Set   RAM Interface Reset */
+};
+
+#define SK_RI_TO_53	36		/* RAM interface timeout */
+
+
+/* Port related registers FIFO, and Arbiter */
+#define SK_REG(port,reg)	(((port)<<7)+(reg))
+
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/*	TXA_ITI_INI		32 bit	Tx Arb Interval Timer Init Val */
+/*	TXA_ITI_VAL		32 bit	Tx Arb Interval Timer Value */
+/*	TXA_LIM_INI		32 bit	Tx Arb Limit Counter Init Val */
+/*	TXA_LIM_VAL		32 bit	Tx Arb Limit Counter Value */
+
+#define TXA_MAX_VAL	0x00ffffffUL	/* Bit 23.. 0:	Max TXA Timer/Cnt Val */
+
+/*	TXA_CTRL		 8 bit	Tx Arbiter Control Register */
+enum {
+	TXA_ENA_FSYNC	= 1<<7,	/* Enable  force of sync Tx queue */
+	TXA_DIS_FSYNC	= 1<<6,	/* Disable force of sync Tx queue */
+	TXA_ENA_ALLOC	= 1<<5,	/* Enable  alloc of free bandwidth */
+	TXA_DIS_ALLOC	= 1<<4,	/* Disable alloc of free bandwidth */
+	TXA_START_RC	= 1<<3,	/* Start sync Rate Control */
+	TXA_STOP_RC	= 1<<2,	/* Stop  sync Rate Control */
+	TXA_ENA_ARB	= 1<<1,	/* Enable  Tx Arbiter */
+	TXA_DIS_ARB	= 1<<0,	/* Disable Tx Arbiter */
+};
+
+/*
+ *	Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+enum {
+	TXA_ITI_INI	= 0x0200,/* 32 bit	Tx Arb Interval Timer Init Val*/
+	TXA_ITI_VAL	= 0x0204,/* 32 bit	Tx Arb Interval Timer Value */
+	TXA_LIM_INI	= 0x0208,/* 32 bit	Tx Arb Limit Counter Init Val */
+	TXA_LIM_VAL	= 0x020c,/* 32 bit	Tx Arb Limit Counter Value */
+	TXA_CTRL	= 0x0210,/*  8 bit	Tx Arbiter Control Register */
+	TXA_TEST	= 0x0211,/*  8 bit	Tx Arbiter Test Register */
+	TXA_STAT	= 0x0212,/*  8 bit	Tx Arbiter Status Register */
+};
+
+
+enum {
+	B6_EXT_REG	= 0x0300,/* External registers (GENESIS only) */
+	B7_CFG_SPC	= 0x0380,/* copy of the Configuration register */
+	B8_RQ1_REGS	= 0x0400,/* Receive Queue 1 */
+	B8_RQ2_REGS	= 0x0480,/* Receive Queue 2 */
+	B8_TS1_REGS	= 0x0600,/* Transmit sync queue 1 */
+	B8_TA1_REGS	= 0x0680,/* Transmit async queue 1 */
+	B8_TS2_REGS	= 0x0700,/* Transmit sync queue 2 */
+	B8_TA2_REGS	= 0x0780,/* Transmit sync queue 2 */
+	B16_RAM_REGS	= 0x0800,/* RAM Buffer Registers */
+};
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+enum {
+	B8_Q_REGS = 0x0400, /* base of Queue registers */
+	Q_D	= 0x00,	/* 8*32	bit	Current Descriptor */
+	Q_DA_L	= 0x20,	/* 32 bit	Current Descriptor Address Low dWord */
+	Q_DA_H	= 0x24,	/* 32 bit	Current Descriptor Address High dWord */
+	Q_AC_L	= 0x28,	/* 32 bit	Current Address Counter Low dWord */
+	Q_AC_H	= 0x2c,	/* 32 bit	Current Address Counter High dWord */
+	Q_BC	= 0x30,	/* 32 bit	Current Byte Counter */
+	Q_CSR	= 0x34,	/* 32 bit	BMU Control/Status Register */
+	Q_F	= 0x38,	/* 32 bit	Flag Register */
+	Q_T1	= 0x3c,	/* 32 bit	Test Register 1 */
+	Q_T1_TR	= 0x3c,	/*  8 bit	Test Register 1 Transfer SM */
+	Q_T1_WR	= 0x3d,	/*  8 bit	Test Register 1 Write Descriptor SM */
+	Q_T1_RD	= 0x3e,	/*  8 bit	Test Register 1 Read Descriptor SM */
+	Q_T1_SV	= 0x3f,	/*  8 bit	Test Register 1 Supervisor SM */
+	Q_T2	= 0x40,	/* 32 bit	Test Register 2	*/
+	Q_T3	= 0x44,	/* 32 bit	Test Register 3	*/
+
+/* Yukon-2 */
+	Q_DONE	= 0x24,	/* 16 bit	Done Index 		(Yukon-2 only) */
+	Q_WM	= 0x40,	/* 16 bit	FIFO Watermark */
+	Q_AL	= 0x42,	/*  8 bit	FIFO Alignment */
+	Q_RSP	= 0x44,	/* 16 bit	FIFO Read Shadow Pointer */
+	Q_RSL	= 0x46,	/*  8 bit	FIFO Read Shadow Level */
+	Q_RP	= 0x48,	/*  8 bit	FIFO Read Pointer */
+	Q_RL	= 0x4a,	/*  8 bit	FIFO Read Level */
+	Q_WP	= 0x4c,	/*  8 bit	FIFO Write Pointer */
+	Q_WSP	= 0x4d,	/*  8 bit	FIFO Write Shadow Pointer */
+	Q_WL	= 0x4e,	/*  8 bit	FIFO Write Level */
+	Q_WSL	= 0x4f,	/*  8 bit	FIFO Write Shadow Level */
+};
+#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
+
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+enum {
+	Y2_B8_PREF_REGS		= 0x0450,
+
+	PREF_UNIT_CTRL		= 0x00,	/* 32 bit	Control register */
+	PREF_UNIT_LAST_IDX	= 0x04,	/* 16 bit	Last Index */
+	PREF_UNIT_ADDR_LO	= 0x08,	/* 32 bit	List start addr, low part */
+	PREF_UNIT_ADDR_HI	= 0x0c,	/* 32 bit	List start addr, high part*/
+	PREF_UNIT_GET_IDX	= 0x10,	/* 16 bit	Get Index */
+	PREF_UNIT_PUT_IDX	= 0x14,	/* 16 bit	Put Index */
+	PREF_UNIT_FIFO_WP	= 0x20,	/*  8 bit	FIFO write pointer */
+	PREF_UNIT_FIFO_RP	= 0x24,	/*  8 bit	FIFO read pointer */
+	PREF_UNIT_FIFO_WM	= 0x28,	/*  8 bit	FIFO watermark */
+	PREF_UNIT_FIFO_LEV	= 0x2c,	/*  8 bit	FIFO level */
+
+	PREF_UNIT_MASK_IDX	= 0x0fff,
+};
+#define Y2_QADDR(q,reg)		(Y2_B8_PREF_REGS + (q) + (reg))
+
+/* RAM Buffer Register Offsets */
+enum {
+
+	RB_START	= 0x00,/* 32 bit	RAM Buffer Start Address */
+	RB_END	= 0x04,/* 32 bit	RAM Buffer End Address */
+	RB_WP	= 0x08,/* 32 bit	RAM Buffer Write Pointer */
+	RB_RP	= 0x0c,/* 32 bit	RAM Buffer Read Pointer */
+	RB_RX_UTPP	= 0x10,/* 32 bit	Rx Upper Threshold, Pause Packet */
+	RB_RX_LTPP	= 0x14,/* 32 bit	Rx Lower Threshold, Pause Packet */
+	RB_RX_UTHP	= 0x18,/* 32 bit	Rx Upper Threshold, High Prio */
+	RB_RX_LTHP	= 0x1c,/* 32 bit	Rx Lower Threshold, High Prio */
+	/* 0x10 - 0x1f:	reserved at Tx RAM Buffer Registers */
+	RB_PC	= 0x20,/* 32 bit	RAM Buffer Packet Counter */
+	RB_LEV	= 0x24,/* 32 bit	RAM Buffer Level Register */
+	RB_CTRL	= 0x28,/* 32 bit	RAM Buffer Control Register */
+	RB_TST1	= 0x29,/*  8 bit	RAM Buffer Test Register 1 */
+	RB_TST2	= 0x2a,/*  8 bit	RAM Buffer Test Register 2 */
+};
+
+/* Receive and Transmit Queues */
+enum {
+	Q_R1	= 0x0000,	/* Receive Queue 1 */
+	Q_R2	= 0x0080,	/* Receive Queue 2 */
+	Q_XS1	= 0x0200,	/* Synchronous Transmit Queue 1 */
+	Q_XA1	= 0x0280,	/* Asynchronous Transmit Queue 1 */
+	Q_XS2	= 0x0300,	/* Synchronous Transmit Queue 2 */
+	Q_XA2	= 0x0380,	/* Asynchronous Transmit Queue 2 */
+};
+
+/* Different PHY Types */
+enum {
+	PHY_ADDR_MARV	= 0,
+};
+
+#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+
+
+enum {
+	LNK_SYNC_INI	= 0x0c30,/* 32 bit	Link Sync Cnt Init Value */
+	LNK_SYNC_VAL	= 0x0c34,/* 32 bit	Link Sync Cnt Current Value */
+	LNK_SYNC_CTRL	= 0x0c38,/*  8 bit	Link Sync Cnt Control Register */
+	LNK_SYNC_TST	= 0x0c39,/*  8 bit	Link Sync Cnt Test Register */
+
+	LNK_LED_REG	= 0x0c3c,/*  8 bit	Link LED Register */
+
+/* Receive GMAC FIFO (YUKON and Yukon-2) */
+
+	RX_GMF_EA	= 0x0c40,/* 32 bit	Rx GMAC FIFO End Address */
+	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
+	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
+	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
+	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
+	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
+	RX_GMF_UP_THR	= 0x0c58,/*  8 bit	Rx Upper Pause Thr (Yukon-EC_U) */
+	RX_GMF_LP_THR	= 0x0c5a,/*  8 bit	Rx Lower Pause Thr (Yukon-EC_U) */
+	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
+	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
+
+	RX_GMF_WLEV	= 0x0c68,/* 32 bit	Rx GMAC FIFO Write Level */
+
+	RX_GMF_RP	= 0x0c70,/* 32 bit	Rx GMAC FIFO Read Pointer */
+
+	RX_GMF_RLEV	= 0x0c78,/* 32 bit	Rx GMAC FIFO Read Level */
+};
+
+
+/*	Q_BC			32 bit	Current Byte Counter */
+
+/* BMU Control Status Registers */
+/*	B0_R1_CSR		32 bit	BMU Ctrl/Stat Rx Queue 1 */
+/*	B0_R2_CSR		32 bit	BMU Ctrl/Stat Rx Queue 2 */
+/*	B0_XA1_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
+/*	B0_XS1_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 1 */
+/*	B0_XA2_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
+/*	B0_XS2_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
+/*	Q_CSR			32 bit	BMU Control/Status Register */
+
+/* Rx BMU Control / Status Registers (Yukon-2) */
+enum {
+	BMU_IDLE	= 1<<31, /* BMU Idle State */
+	BMU_RX_TCP_PKT	= 1<<30, /* Rx TCP Packet (when RSS Hash enabled) */
+	BMU_RX_IP_PKT	= 1<<29, /* Rx IP  Packet (when RSS Hash enabled) */
+
+	BMU_ENA_RX_RSS_HASH = 1<<15, /* Enable  Rx RSS Hash */
+	BMU_DIS_RX_RSS_HASH = 1<<14, /* Disable Rx RSS Hash */
+	BMU_ENA_RX_CHKSUM = 1<<13, /* Enable  Rx TCP/IP Checksum Check */
+	BMU_DIS_RX_CHKSUM = 1<<12, /* Disable Rx TCP/IP Checksum Check */
+	BMU_CLR_IRQ_PAR	= 1<<11, /* Clear IRQ on Parity errors (Rx) */
+	BMU_CLR_IRQ_TCP	= 1<<11, /* Clear IRQ on TCP segment. error (Tx) */
+	BMU_CLR_IRQ_CHK	= 1<<10, /* Clear IRQ Check */
+	BMU_STOP	= 1<<9, /* Stop  Rx/Tx Queue */
+	BMU_START	= 1<<8, /* Start Rx/Tx Queue */
+	BMU_FIFO_OP_ON	= 1<<7, /* FIFO Operational On */
+	BMU_FIFO_OP_OFF	= 1<<6, /* FIFO Operational Off */
+	BMU_FIFO_ENA	= 1<<5, /* Enable FIFO */
+	BMU_FIFO_RST	= 1<<4, /* Reset  FIFO */
+	BMU_OP_ON	= 1<<3, /* BMU Operational On */
+	BMU_OP_OFF	= 1<<2, /* BMU Operational Off */
+	BMU_RST_CLR	= 1<<1, /* Clear BMU Reset (Enable) */
+	BMU_RST_SET	= 1<<0, /* Set   BMU Reset */
+
+	BMU_CLR_RESET	= BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR,
+	BMU_OPER_INIT	= BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START |
+			  BMU_FIFO_ENA | BMU_OP_ON,
+
+	BMU_WM_DEFAULT = 0x600,
+};
+
+/* Tx BMU Control / Status Registers (Yukon-2) */
+								/* Bit 31: same as for Rx */
+enum {
+	BMU_TX_IPIDINCR_ON	= 1<<13, /* Enable  IP ID Increment */
+	BMU_TX_IPIDINCR_OFF	= 1<<12, /* Disable IP ID Increment */
+	BMU_TX_CLR_IRQ_TCP	= 1<<11, /* Clear IRQ on TCP segment length mismatch */
+};
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+/* PREF_UNIT_CTRL	32 bit	Prefetch Control register */
+enum {
+	PREF_UNIT_OP_ON		= 1<<3,	/* prefetch unit operational */
+	PREF_UNIT_OP_OFF	= 1<<2,	/* prefetch unit not operational */
+	PREF_UNIT_RST_CLR	= 1<<1,	/* Clear Prefetch Unit Reset */
+	PREF_UNIT_RST_SET	= 1<<0,	/* Set   Prefetch Unit Reset */
+};
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/*	RB_START		32 bit	RAM Buffer Start Address */
+/*	RB_END			32 bit	RAM Buffer End Address */
+/*	RB_WP			32 bit	RAM Buffer Write Pointer */
+/*	RB_RP			32 bit	RAM Buffer Read Pointer */
+/*	RB_RX_UTPP		32 bit	Rx Upper Threshold, Pause Pack */
+/*	RB_RX_LTPP		32 bit	Rx Lower Threshold, Pause Pack */
+/*	RB_RX_UTHP		32 bit	Rx Upper Threshold, High Prio */
+/*	RB_RX_LTHP		32 bit	Rx Lower Threshold, High Prio */
+/*	RB_PC			32 bit	RAM Buffer Packet Counter */
+/*	RB_LEV			32 bit	RAM Buffer Level Register */
+
+#define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
+/*	RB_TST2			 8 bit	RAM Buffer Test Register 2 */
+/*	RB_TST1			 8 bit	RAM Buffer Test Register 1 */
+
+/*	RB_CTRL			 8 bit	RAM Buffer Control Register */
+enum {
+	RB_ENA_STFWD	= 1<<5,	/* Enable  Store & Forward */
+	RB_DIS_STFWD	= 1<<4,	/* Disable Store & Forward */
+	RB_ENA_OP_MD	= 1<<3,	/* Enable  Operation Mode */
+	RB_DIS_OP_MD	= 1<<2,	/* Disable Operation Mode */
+	RB_RST_CLR	= 1<<1,	/* Clear RAM Buf STM Reset */
+	RB_RST_SET	= 1<<0,	/* Set   RAM Buf STM Reset */
+};
+
+
+/* Transmit GMAC FIFO (YUKON only) */
+enum {
+	TX_GMF_EA	= 0x0d40,/* 32 bit	Tx GMAC FIFO End Address */
+	TX_GMF_AE_THR	= 0x0d44,/* 32 bit	Tx GMAC FIFO Almost Empty Thresh.*/
+	TX_GMF_CTRL_T	= 0x0d48,/* 32 bit	Tx GMAC FIFO Control/Test */
+
+	TX_GMF_WP	= 0x0d60,/* 32 bit 	Tx GMAC FIFO Write Pointer */
+	TX_GMF_WSP	= 0x0d64,/* 32 bit 	Tx GMAC FIFO Write Shadow Ptr. */
+	TX_GMF_WLEV	= 0x0d68,/* 32 bit 	Tx GMAC FIFO Write Level */
+
+	TX_GMF_RP	= 0x0d70,/* 32 bit 	Tx GMAC FIFO Read Pointer */
+	TX_GMF_RSTP	= 0x0d74,/* 32 bit 	Tx GMAC FIFO Restart Pointer */
+	TX_GMF_RLEV	= 0x0d78,/* 32 bit 	Tx GMAC FIFO Read Level */
+};
+
+/* Descriptor Poll Timer Registers */
+enum {
+	B28_DPT_INI	= 0x0e00,/* 24 bit	Descriptor Poll Timer Init Val */
+	B28_DPT_VAL	= 0x0e04,/* 24 bit	Descriptor Poll Timer Curr Val */
+	B28_DPT_CTRL	= 0x0e08,/*  8 bit	Descriptor Poll Timer Ctrl Reg */
+
+	B28_DPT_TST	= 0x0e0a,/*  8 bit	Descriptor Poll Timer Test Reg */
+};
+
+/* Time Stamp Timer Registers (YUKON only) */
+enum {
+	GMAC_TI_ST_VAL	= 0x0e14,/* 32 bit	Time Stamp Timer Curr Val */
+	GMAC_TI_ST_CTRL	= 0x0e18,/*  8 bit	Time Stamp Timer Ctrl Reg */
+	GMAC_TI_ST_TST	= 0x0e1a,/*  8 bit	Time Stamp Timer Test Reg */
+};
+
+/* Polling Unit Registers (Yukon-2 only) */
+enum {
+	POLL_CTRL	= 0x0e20, /* 32 bit	Polling Unit Control Reg */
+	POLL_LAST_IDX	= 0x0e24,/* 16 bit	Polling Unit List Last Index */
+
+	POLL_LIST_ADDR_LO= 0x0e28,/* 32 bit	Poll. List Start Addr (low) */
+	POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit	Poll. List Start Addr (high) */
+};
+
+/* ASF Subsystem Registers (Yukon-2 only) */
+enum {
+	B28_Y2_SMB_CONFIG  = 0x0e40,/* 32 bit	ASF SMBus Config Register */
+	B28_Y2_SMB_CSD_REG = 0x0e44,/* 32 bit	ASF SMB Control/Status/Data */
+	B28_Y2_ASF_IRQ_V_BASE=0x0e60,/* 32 bit	ASF IRQ Vector Base */
+
+	B28_Y2_ASF_STAT_CMD= 0x0e68,/* 32 bit	ASF Status and Command Reg */
+	B28_Y2_ASF_HOST_COM= 0x0e6c,/* 32 bit	ASF Host Communication Reg */
+	B28_Y2_DATA_REG_1  = 0x0e70,/* 32 bit	ASF/Host Data Register 1 */
+	B28_Y2_DATA_REG_2  = 0x0e74,/* 32 bit	ASF/Host Data Register 2 */
+	B28_Y2_DATA_REG_3  = 0x0e78,/* 32 bit	ASF/Host Data Register 3 */
+	B28_Y2_DATA_REG_4  = 0x0e7c,/* 32 bit	ASF/Host Data Register 4 */
+};
+
+/* Status BMU Registers (Yukon-2 only)*/
+enum {
+	STAT_CTRL	= 0x0e80,/* 32 bit	Status BMU Control Reg */
+	STAT_LAST_IDX	= 0x0e84,/* 16 bit	Status BMU Last Index */
+
+	STAT_LIST_ADDR_LO= 0x0e88,/* 32 bit	Status List Start Addr (low) */
+	STAT_LIST_ADDR_HI= 0x0e8c,/* 32 bit	Status List Start Addr (high) */
+	STAT_TXA1_RIDX	= 0x0e90,/* 16 bit	Status TxA1 Report Index Reg */
+	STAT_TXS1_RIDX	= 0x0e92,/* 16 bit	Status TxS1 Report Index Reg */
+	STAT_TXA2_RIDX	= 0x0e94,/* 16 bit	Status TxA2 Report Index Reg */
+	STAT_TXS2_RIDX	= 0x0e96,/* 16 bit	Status TxS2 Report Index Reg */
+	STAT_TX_IDX_TH	= 0x0e98,/* 16 bit	Status Tx Index Threshold Reg */
+	STAT_PUT_IDX	= 0x0e9c,/* 16 bit	Status Put Index Reg */
+
+/* FIFO Control/Status Registers (Yukon-2 only)*/
+	STAT_FIFO_WP	= 0x0ea0,/*  8 bit	Status FIFO Write Pointer Reg */
+	STAT_FIFO_RP	= 0x0ea4,/*  8 bit	Status FIFO Read Pointer Reg */
+	STAT_FIFO_RSP	= 0x0ea6,/*  8 bit	Status FIFO Read Shadow Ptr */
+	STAT_FIFO_LEVEL	= 0x0ea8,/*  8 bit	Status FIFO Level Reg */
+	STAT_FIFO_SHLVL	= 0x0eaa,/*  8 bit	Status FIFO Shadow Level Reg */
+	STAT_FIFO_WM	= 0x0eac,/*  8 bit	Status FIFO Watermark Reg */
+	STAT_FIFO_ISR_WM= 0x0ead,/*  8 bit	Status FIFO ISR Watermark Reg */
+
+/* Level and ISR Timer Registers (Yukon-2 only)*/
+	STAT_LEV_TIMER_INI= 0x0eb0,/* 32 bit	Level Timer Init. Value Reg */
+	STAT_LEV_TIMER_CNT= 0x0eb4,/* 32 bit	Level Timer Counter Reg */
+	STAT_LEV_TIMER_CTRL= 0x0eb8,/*  8 bit	Level Timer Control Reg */
+	STAT_LEV_TIMER_TEST= 0x0eb9,/*  8 bit	Level Timer Test Reg */
+	STAT_TX_TIMER_INI  = 0x0ec0,/* 32 bit	Tx Timer Init. Value Reg */
+	STAT_TX_TIMER_CNT  = 0x0ec4,/* 32 bit	Tx Timer Counter Reg */
+	STAT_TX_TIMER_CTRL = 0x0ec8,/*  8 bit	Tx Timer Control Reg */
+	STAT_TX_TIMER_TEST = 0x0ec9,/*  8 bit	Tx Timer Test Reg */
+	STAT_ISR_TIMER_INI = 0x0ed0,/* 32 bit	ISR Timer Init. Value Reg */
+	STAT_ISR_TIMER_CNT = 0x0ed4,/* 32 bit	ISR Timer Counter Reg */
+	STAT_ISR_TIMER_CTRL= 0x0ed8,/*  8 bit	ISR Timer Control Reg */
+	STAT_ISR_TIMER_TEST= 0x0ed9,/*  8 bit	ISR Timer Test Reg */
+};
+
+enum {
+	LINKLED_OFF 	     = 0x01,
+	LINKLED_ON  	     = 0x02,
+	LINKLED_LINKSYNC_OFF = 0x04,
+	LINKLED_LINKSYNC_ON  = 0x08,
+	LINKLED_BLINK_OFF    = 0x10,
+	LINKLED_BLINK_ON     = 0x20,
+};
+
+/* GMAC and GPHY Control Registers (YUKON only) */
+enum {
+	GMAC_CTRL	= 0x0f00,/* 32 bit	GMAC Control Reg */
+	GPHY_CTRL	= 0x0f04,/* 32 bit	GPHY Control Reg */
+	GMAC_IRQ_SRC	= 0x0f08,/*  8 bit	GMAC Interrupt Source Reg */
+	GMAC_IRQ_MSK	= 0x0f0c,/*  8 bit	GMAC Interrupt Mask Reg */
+	GMAC_LINK_CTRL	= 0x0f10,/* 16 bit	Link Control Reg */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+	WOL_REG_OFFS	= 0x20,/* HW-Bug: Address is + 0x20 against spec. */
+
+	WOL_CTRL_STAT	= 0x0f20,/* 16 bit	WOL Control/Status Reg */
+	WOL_MATCH_CTL	= 0x0f22,/*  8 bit	WOL Match Control Reg */
+	WOL_MATCH_RES	= 0x0f23,/*  8 bit	WOL Match Result Reg */
+	WOL_MAC_ADDR	= 0x0f24,/* 32 bit	WOL MAC Address */
+	WOL_PATT_PME	= 0x0f2a,/*  8 bit	WOL PME Match Enable (Yukon-2) */
+	WOL_PATT_ASFM	= 0x0f2b,/*  8 bit	WOL ASF Match Enable (Yukon-2) */
+	WOL_PATT_RPTR	= 0x0f2c,/*  8 bit	WOL Pattern Read Pointer */
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+	WOL_PATT_LEN_LO	= 0x0f30,/* 32 bit	WOL Pattern Length 3..0 */
+	WOL_PATT_LEN_HI	= 0x0f34,/* 24 bit	WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+
+	WOL_PATT_CNT_0	= 0x0f38,/* 32 bit	WOL Pattern Counter 3..0 */
+	WOL_PATT_CNT_4	= 0x0f3c,/* 24 bit	WOL Pattern Counter 6..4 */
+};
+
+enum {
+	WOL_PATT_RAM_1	= 0x1000,/*  WOL Pattern RAM Link 1 */
+	WOL_PATT_RAM_2	= 0x1400,/*  WOL Pattern RAM Link 2 */
+};
+
+enum {
+	BASE_GMAC_1	= 0x2800,/* GMAC 1 registers */
+	BASE_GMAC_2	= 0x3800,/* GMAC 2 registers */
+};
+
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+enum {
+	PHY_MARV_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
+	PHY_MARV_STAT		= 0x01,/* 16 bit r/o	PHY Status Register */
+	PHY_MARV_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
+	PHY_MARV_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
+	PHY_MARV_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
+	PHY_MARV_AUNE_LP	= 0x05,/* 16 bit r/o	Link Part Ability Reg */
+	PHY_MARV_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
+	PHY_MARV_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
+	PHY_MARV_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
+	/* Marvel-specific registers */
+	PHY_MARV_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
+	PHY_MARV_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
+	PHY_MARV_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Reg */
+	PHY_MARV_PHY_CTRL	= 0x10,/* 16 bit r/w	PHY Specific Ctrl Reg */
+	PHY_MARV_PHY_STAT	= 0x11,/* 16 bit r/o	PHY Specific Stat Reg */
+	PHY_MARV_INT_MASK	= 0x12,/* 16 bit r/w	Interrupt Mask Reg */
+	PHY_MARV_INT_STAT	= 0x13,/* 16 bit r/o	Interrupt Status Reg */
+	PHY_MARV_EXT_CTRL	= 0x14,/* 16 bit r/w	Ext. PHY Specific Ctrl */
+	PHY_MARV_RXE_CNT	= 0x15,/* 16 bit r/w	Receive Error Counter */
+	PHY_MARV_EXT_ADR	= 0x16,/* 16 bit r/w	Ext. Ad. for Cable Diag. */
+	PHY_MARV_PORT_IRQ	= 0x17,/* 16 bit r/o	Port 0 IRQ (88E1111 only) */
+	PHY_MARV_LED_CTRL	= 0x18,/* 16 bit r/w	LED Control Reg */
+	PHY_MARV_LED_OVER	= 0x19,/* 16 bit r/w	Manual LED Override Reg */
+	PHY_MARV_EXT_CTRL_2	= 0x1a,/* 16 bit r/w	Ext. PHY Specific Ctrl 2 */
+	PHY_MARV_EXT_P_STAT	= 0x1b,/* 16 bit r/w	Ext. PHY Spec. Stat Reg */
+	PHY_MARV_CABLE_DIAG	= 0x1c,/* 16 bit r/o	Cable Diagnostic Reg */
+	PHY_MARV_PAGE_ADDR	= 0x1d,/* 16 bit r/w	Extended Page Address Reg */
+	PHY_MARV_PAGE_DATA	= 0x1e,/* 16 bit r/w	Extended Page Data Reg */
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+	PHY_MARV_FE_LED_PAR	= 0x16,/* 16 bit r/w	LED Parallel Select Reg. */
+	PHY_MARV_FE_LED_SER	= 0x17,/* 16 bit r/w	LED Stream Select S. LED */
+	PHY_MARV_FE_VCT_TX	= 0x1a,/* 16 bit r/w	VCT Reg. for TXP/N Pins */
+	PHY_MARV_FE_VCT_RX	= 0x1b,/* 16 bit r/o	VCT Reg. for RXP/N Pins */
+	PHY_MARV_FE_SPEC_2	= 0x1c,/* 16 bit r/w	Specific Control Reg. 2 */
+};
+
+enum {
+	PHY_CT_RESET	= 1<<15, /* Bit 15: (sc)	clear all PHY related regs */
+	PHY_CT_LOOP	= 1<<14, /* Bit 14:	enable Loopback over PHY */
+	PHY_CT_SPS_LSB	= 1<<13, /* Bit 13:	Speed select, lower bit */
+	PHY_CT_ANE	= 1<<12, /* Bit 12:	Auto-Negotiation Enabled */
+	PHY_CT_PDOWN	= 1<<11, /* Bit 11:	Power Down Mode */
+	PHY_CT_ISOL	= 1<<10, /* Bit 10:	Isolate Mode */
+	PHY_CT_RE_CFG	= 1<<9, /* Bit  9:	(sc) Restart Auto-Negotiation */
+	PHY_CT_DUP_MD	= 1<<8, /* Bit  8:	Duplex Mode */
+	PHY_CT_COL_TST	= 1<<7, /* Bit  7:	Collision Test enabled */
+	PHY_CT_SPS_MSB	= 1<<6, /* Bit  6:	Speed select, upper bit */
+};
+
+enum {
+	PHY_CT_SP1000	= PHY_CT_SPS_MSB, /* enable speed of 1000 Mbps */
+	PHY_CT_SP100	= PHY_CT_SPS_LSB, /* enable speed of  100 Mbps */
+	PHY_CT_SP10	= 0,		  /* enable speed of   10 Mbps */
+};
+
+enum {
+	PHY_ST_EXT_ST	= 1<<8, /* Bit  8:	Extended Status Present */
+
+	PHY_ST_PRE_SUP	= 1<<6, /* Bit  6:	Preamble Suppression */
+	PHY_ST_AN_OVER	= 1<<5, /* Bit  5:	Auto-Negotiation Over */
+	PHY_ST_REM_FLT	= 1<<4, /* Bit  4:	Remote Fault Condition Occured */
+	PHY_ST_AN_CAP	= 1<<3, /* Bit  3:	Auto-Negotiation Capability */
+	PHY_ST_LSYNC	= 1<<2, /* Bit  2:	Link Synchronized */
+	PHY_ST_JAB_DET	= 1<<1, /* Bit  1:	Jabber Detected */
+	PHY_ST_EXT_REG	= 1<<0, /* Bit  0:	Extended Register available */
+};
+
+enum {
+	PHY_I1_OUI_MSK	= 0x3f<<10, /* Bit 15..10:	Organization Unique ID */
+	PHY_I1_MOD_NUM	= 0x3f<<4, /* Bit  9.. 4:	Model Number */
+	PHY_I1_REV_MSK	= 0xf, /* Bit  3.. 0:	Revision Number */
+};
+
+/* different Marvell PHY Ids */
+enum {
+	PHY_MARV_ID0_VAL= 0x0141, /* Marvell Unique Identifier */
+
+	PHY_BCOM_ID1_A1	= 0x6041,
+	PHY_BCOM_ID1_B2	= 0x6043,
+	PHY_BCOM_ID1_C0	= 0x6044,
+	PHY_BCOM_ID1_C5	= 0x6047,
+
+	PHY_MARV_ID1_B0	= 0x0C23, /* Yukon (PHY 88E1011) */
+	PHY_MARV_ID1_B2	= 0x0C25, /* Yukon-Plus (PHY 88E1011) */
+	PHY_MARV_ID1_C2	= 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+	PHY_MARV_ID1_Y2	= 0x0C91, /* Yukon-2 (PHY 88E1112) */
+};
+
+/* Advertisement register bits */
+enum {
+	PHY_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
+	PHY_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
+	PHY_AN_RF	= 1<<13, /* Bit 13:	Remote Fault Bits */
+
+	PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11:	Try for asymmetric */
+	PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10:	Try for pause */
+	PHY_AN_100BASE4	= 1<<9, /* Bit 9:	Try for 100mbps 4k packets */
+	PHY_AN_100FULL	= 1<<8, /* Bit 8:	Try for 100mbps full-duplex */
+	PHY_AN_100HALF	= 1<<7, /* Bit 7:	Try for 100mbps half-duplex */
+	PHY_AN_10FULL	= 1<<6, /* Bit 6:	Try for 10mbps full-duplex */
+	PHY_AN_10HALF	= 1<<5, /* Bit 5:	Try for 10mbps half-duplex */
+	PHY_AN_CSMA	= 1<<0, /* Bit 0:	Only selector supported */
+	PHY_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
+	PHY_AN_FULL	= PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
+	PHY_AN_ALL	= PHY_AN_10HALF | PHY_AN_10FULL |
+		  	  PHY_AN_100HALF | PHY_AN_100FULL,
+};
+
+/*****  PHY_BCOM_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+/*****  PHY_MARV_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+enum {
+	PHY_B_1000S_MSF	= 1<<15, /* Bit 15:	Master/Slave Fault */
+	PHY_B_1000S_MSR	= 1<<14, /* Bit 14:	Master/Slave Result */
+	PHY_B_1000S_LRS	= 1<<13, /* Bit 13:	Local Receiver Status */
+	PHY_B_1000S_RRS	= 1<<12, /* Bit 12:	Remote Receiver Status */
+	PHY_B_1000S_LP_FD	= 1<<11, /* Bit 11:	Link Partner can FD */
+	PHY_B_1000S_LP_HD	= 1<<10, /* Bit 10:	Link Partner can HD */
+									/* Bit  9..8:	reserved */
+	PHY_B_1000S_IEC	= 0xff, /* Bit  7..0:	Idle Error Count */
+};
+
+/** Marvell-Specific */
+enum {
+	PHY_M_AN_NXT_PG	= 1<<15, /* Request Next Page */
+	PHY_M_AN_ACK	= 1<<14, /* (ro)	Acknowledge Received */
+	PHY_M_AN_RF	= 1<<13, /* Remote Fault */
+
+	PHY_M_AN_ASP	= 1<<11, /* Asymmetric Pause */
+	PHY_M_AN_PC	= 1<<10, /* MAC Pause implemented */
+	PHY_M_AN_100_T4	= 1<<9, /* Not cap. 100Base-T4 (always 0) */
+	PHY_M_AN_100_FD	= 1<<8, /* Advertise 100Base-TX Full Duplex */
+	PHY_M_AN_100_HD	= 1<<7, /* Advertise 100Base-TX Half Duplex */
+	PHY_M_AN_10_FD	= 1<<6, /* Advertise 10Base-TX Full Duplex */
+	PHY_M_AN_10_HD	= 1<<5, /* Advertise 10Base-TX Half Duplex */
+	PHY_M_AN_SEL_MSK =0x1f<<4,	/* Bit  4.. 0: Selector Field Mask */
+};
+
+/* special defines for FIBER (88E1011S only) */
+enum {
+	PHY_M_AN_ASP_X	= 1<<8, /* Asymmetric Pause */
+	PHY_M_AN_PC_X	= 1<<7, /* MAC Pause implemented */
+	PHY_M_AN_1000X_AHD	= 1<<6, /* Advertise 10000Base-X Half Duplex */
+	PHY_M_AN_1000X_AFD	= 1<<5, /* Advertise 10000Base-X Full Duplex */
+};
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+enum {
+	PHY_M_P_NO_PAUSE_X	= 0<<7,/* Bit  8.. 7:	no Pause Mode */
+	PHY_M_P_SYM_MD_X	= 1<<7, /* Bit  8.. 7:	symmetric Pause Mode */
+	PHY_M_P_ASYM_MD_X	= 2<<7,/* Bit  8.. 7:	asymmetric Pause Mode */
+	PHY_M_P_BOTH_MD_X	= 3<<7,/* Bit  8.. 7:	both Pause Mode */
+};
+
+/*****  PHY_MARV_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
+enum {
+	PHY_M_1000C_TEST	= 7<<13,/* Bit 15..13:	Test Modes */
+	PHY_M_1000C_MSE	= 1<<12, /* Manual Master/Slave Enable */
+	PHY_M_1000C_MSC	= 1<<11, /* M/S Configuration (1=Master) */
+	PHY_M_1000C_MPD	= 1<<10, /* Multi-Port Device */
+	PHY_M_1000C_AFD	= 1<<9, /* Advertise Full Duplex */
+	PHY_M_1000C_AHD	= 1<<8, /* Advertise Half Duplex */
+};
+
+/*****  PHY_MARV_PHY_CTRL	16 bit r/w	PHY Specific Ctrl Reg *****/
+enum {
+	PHY_M_PC_TX_FFD_MSK	= 3<<14,/* Bit 15..14: Tx FIFO Depth Mask */
+	PHY_M_PC_RX_FFD_MSK	= 3<<12,/* Bit 13..12: Rx FIFO Depth Mask */
+	PHY_M_PC_ASS_CRS_TX	= 1<<11, /* Assert CRS on Transmit */
+	PHY_M_PC_FL_GOOD	= 1<<10, /* Force Link Good */
+	PHY_M_PC_EN_DET_MSK	= 3<<8,/* Bit  9.. 8: Energy Detect Mask */
+	PHY_M_PC_ENA_EXT_D	= 1<<7, /* Enable Ext. Distance (10BT) */
+	PHY_M_PC_MDIX_MSK	= 3<<5,/* Bit  6.. 5: MDI/MDIX Config. Mask */
+	PHY_M_PC_DIS_125CLK	= 1<<4, /* Disable 125 CLK */
+	PHY_M_PC_MAC_POW_UP	= 1<<3, /* MAC Power up */
+	PHY_M_PC_SQE_T_ENA	= 1<<2, /* SQE Test Enabled */
+	PHY_M_PC_POL_R_DIS	= 1<<1, /* Polarity Reversal Disabled */
+	PHY_M_PC_DIS_JABBER	= 1<<0, /* Disable Jabber */
+};
+
+enum {
+	PHY_M_PC_EN_DET		= 2<<8,	/* Energy Detect (Mode 1) */
+	PHY_M_PC_EN_DET_PLUS	= 3<<8, /* Energy Detect Plus (Mode 2) */
+};
+
+#define PHY_M_PC_MDI_XMODE(x)	(((x)<<5) & PHY_M_PC_MDIX_MSK)
+
+enum {
+	PHY_M_PC_MAN_MDI	= 0, /* 00 = Manual MDI configuration */
+	PHY_M_PC_MAN_MDIX	= 1, /* 01 = Manual MDIX configuration */
+	PHY_M_PC_ENA_AUTO	= 3, /* 11 = Enable Automatic Crossover */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PC_ENA_DTE_DT	= 1<<15, /* Enable Data Terminal Equ. (DTE) Detect */
+	PHY_M_PC_ENA_ENE_DT	= 1<<14, /* Enable Energy Detect (sense & pulse) */
+	PHY_M_PC_DIS_NLP_CK	= 1<<13, /* Disable Normal Link Puls (NLP) Check */
+	PHY_M_PC_ENA_LIP_NP	= 1<<12, /* Enable Link Partner Next Page Reg. */
+	PHY_M_PC_DIS_NLP_GN	= 1<<11, /* Disable Normal Link Puls Generation */
+
+	PHY_M_PC_DIS_SCRAMB	= 1<<9, /* Disable Scrambler */
+	PHY_M_PC_DIS_FEFI	= 1<<8, /* Disable Far End Fault Indic. (FEFI) */
+
+	PHY_M_PC_SH_TP_SEL	= 1<<6, /* Shielded Twisted Pair Select */
+	PHY_M_PC_RX_FD_MSK	= 3<<2,/* Bit  3.. 2: Rx FIFO Depth Mask */
+};
+
+/*****  PHY_MARV_PHY_STAT	16 bit r/o	PHY Specific Status Reg *****/
+enum {
+	PHY_M_PS_SPEED_MSK	= 3<<14, /* Bit 15..14: Speed Mask */
+	PHY_M_PS_SPEED_1000	= 1<<15, /*		10 = 1000 Mbps */
+	PHY_M_PS_SPEED_100	= 1<<14, /*		01 =  100 Mbps */
+	PHY_M_PS_SPEED_10	= 0,	 /*		00 =   10 Mbps */
+	PHY_M_PS_FULL_DUP	= 1<<13, /* Full Duplex */
+	PHY_M_PS_PAGE_REC	= 1<<12, /* Page Received */
+	PHY_M_PS_SPDUP_RES	= 1<<11, /* Speed & Duplex Resolved */
+	PHY_M_PS_LINK_UP	= 1<<10, /* Link Up */
+	PHY_M_PS_CABLE_MSK	= 7<<7,  /* Bit  9.. 7: Cable Length Mask */
+	PHY_M_PS_MDI_X_STAT	= 1<<6,  /* MDI Crossover Stat (1=MDIX) */
+	PHY_M_PS_DOWNS_STAT	= 1<<5,  /* Downshift Status (1=downsh.) */
+	PHY_M_PS_ENDET_STAT	= 1<<4,  /* Energy Detect Status (1=act) */
+	PHY_M_PS_TX_P_EN	= 1<<3,  /* Tx Pause Enabled */
+	PHY_M_PS_RX_P_EN	= 1<<2,  /* Rx Pause Enabled */
+	PHY_M_PS_POL_REV	= 1<<1,  /* Polarity Reversed */
+	PHY_M_PS_JABBER		= 1<<0,  /* Jabber */
+};
+
+#define PHY_M_PS_PAUSE_MSK	(PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PS_DTE_DETECT	= 1<<15, /* Data Terminal Equipment (DTE) Detected */
+	PHY_M_PS_RES_SPEED	= 1<<14, /* Resolved Speed (1=100 Mbps, 0=10 Mbps */
+};
+
+enum {
+	PHY_M_IS_AN_ERROR	= 1<<15, /* Auto-Negotiation Error */
+	PHY_M_IS_LSP_CHANGE	= 1<<14, /* Link Speed Changed */
+	PHY_M_IS_DUP_CHANGE	= 1<<13, /* Duplex Mode Changed */
+	PHY_M_IS_AN_PR		= 1<<12, /* Page Received */
+	PHY_M_IS_AN_COMPL	= 1<<11, /* Auto-Negotiation Completed */
+	PHY_M_IS_LST_CHANGE	= 1<<10, /* Link Status Changed */
+	PHY_M_IS_SYMB_ERROR	= 1<<9, /* Symbol Error */
+	PHY_M_IS_FALSE_CARR	= 1<<8, /* False Carrier */
+	PHY_M_IS_FIFO_ERROR	= 1<<7, /* FIFO Overflow/Underrun Error */
+	PHY_M_IS_MDI_CHANGE	= 1<<6, /* MDI Crossover Changed */
+	PHY_M_IS_DOWNSH_DET	= 1<<5, /* Downshift Detected */
+	PHY_M_IS_END_CHANGE	= 1<<4, /* Energy Detect Changed */
+
+	PHY_M_IS_DTE_CHANGE	= 1<<2, /* DTE Power Det. Status Changed */
+	PHY_M_IS_POL_CHANGE	= 1<<1, /* Polarity Changed */
+	PHY_M_IS_JABBER		= 1<<0, /* Jabber */
+
+	PHY_M_DEF_MSK		= PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
+				 | PHY_M_IS_FIFO_ERROR,
+	PHY_M_AN_MSK	       = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
+};
+
+
+/*****  PHY_MARV_EXT_CTRL	16 bit r/w	Ext. PHY Specific Ctrl *****/
+enum {
+	PHY_M_EC_ENA_BC_EXT = 1<<15, /* Enable Block Carr. Ext. (88E1111 only) */
+	PHY_M_EC_ENA_LIN_LB = 1<<14, /* Enable Line Loopback (88E1111 only) */
+
+	PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */
+	PHY_M_EC_M_DSC_MSK  = 3<<10, /* Bit 11..10:	Master Downshift Counter */
+					/* (88E1011 only) */
+	PHY_M_EC_S_DSC_MSK  = 3<<8,/* Bit  9.. 8:	Slave  Downshift Counter */
+				       /* (88E1011 only) */
+	PHY_M_EC_M_DSC_MSK2 = 7<<9,/* Bit 11.. 9:	Master Downshift Counter */
+					/* (88E1111 only) */
+	PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */
+					/* !!! Errata in spec. (1 = disable) */
+	PHY_M_EC_RX_TIM_CT  = 1<<7, /* RGMII Rx Timing Control*/
+	PHY_M_EC_MAC_S_MSK  = 7<<4,/* Bit  6.. 4:	Def. MAC interface speed */
+	PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
+	PHY_M_EC_DTE_D_ENA  = 1<<2, /* DTE Detect Enable (88E1111 only) */
+	PHY_M_EC_TX_TIM_CT  = 1<<1, /* RGMII Tx Timing Control */
+	PHY_M_EC_TRANS_DIS  = 1<<0, /* Transmitter Disable (88E1111 only) */};
+
+#define PHY_M_EC_M_DSC(x)	((x)<<10 & PHY_M_EC_M_DSC_MSK)
+					/* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x)	((x)<<8 & PHY_M_EC_S_DSC_MSK)
+					/* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_DSC_2(x)	((x)<<9 & PHY_M_EC_M_DSC_MSK2)
+					/* 000=1x; 001=2x; 010=3x; 011=4x */
+#define PHY_M_EC_MAC_S(x)	((x)<<4 & PHY_M_EC_MAC_S_MSK)
+					/* 01X=0; 110=2.5; 111=25 (MHz) */
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+enum {
+	PHY_M_PC_DIS_LINK_Pa	= 1<<15,/* Disable Link Pulses */
+	PHY_M_PC_DSC_MSK	= 7<<12,/* Bit 14..12:	Downshift Counter */
+	PHY_M_PC_DOWN_S_ENA	= 1<<11,/* Downshift Enable */
+};
+/* !!! Errata in spec. (1 = disable) */
+
+#define PHY_M_PC_DSC(x)			(((x)<<12) & PHY_M_PC_DSC_MSK)
+											/* 100=5x; 101=6x; 110=7x; 111=8x */
+enum {
+	MAC_TX_CLK_0_MHZ	= 2,
+	MAC_TX_CLK_2_5_MHZ	= 6,
+	MAC_TX_CLK_25_MHZ 	= 7,
+};
+
+/*****  PHY_MARV_LED_CTRL	16 bit r/w	LED Control Reg *****/
+enum {
+	PHY_M_LEDC_DIS_LED	= 1<<15, /* Disable LED */
+	PHY_M_LEDC_PULS_MSK	= 7<<12,/* Bit 14..12: Pulse Stretch Mask */
+	PHY_M_LEDC_F_INT	= 1<<11, /* Force Interrupt */
+	PHY_M_LEDC_BL_R_MSK	= 7<<8,/* Bit 10.. 8: Blink Rate Mask */
+	PHY_M_LEDC_DP_C_LSB	= 1<<7, /* Duplex Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_TX_C_LSB	= 1<<6, /* Tx Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_LK_C_MSK	= 7<<3,/* Bit  5.. 3: Link Control Mask */
+					/* (88E1111 only) */
+};
+
+enum {
+	PHY_M_LEDC_LINK_MSK	= 3<<3,/* Bit  4.. 3: Link Control Mask */
+									/* (88E1011 only) */
+	PHY_M_LEDC_DP_CTRL	= 1<<2, /* Duplex Control */
+	PHY_M_LEDC_DP_C_MSB	= 1<<2, /* Duplex Control (MSB, 88E1111 only) */
+	PHY_M_LEDC_RX_CTRL	= 1<<1, /* Rx Activity / Link */
+	PHY_M_LEDC_TX_CTRL	= 1<<0, /* Tx Activity / Link */
+	PHY_M_LEDC_TX_C_MSB	= 1<<0, /* Tx Control (MSB, 88E1111 only) */
+};
+
+#define PHY_M_LED_PULS_DUR(x)	(((x)<<12) & PHY_M_LEDC_PULS_MSK)
+
+/*****  PHY_MARV_PHY_STAT (page 3)16 bit r/w	Polarity Control Reg. *****/
+enum {
+	PHY_M_POLC_LS1M_MSK	= 0xf<<12, /* Bit 15..12: LOS,STAT1 Mix % Mask */
+	PHY_M_POLC_IS0M_MSK	= 0xf<<8,  /* Bit 11.. 8: INIT,STAT0 Mix % Mask */
+	PHY_M_POLC_LOS_MSK	= 0x3<<6,  /* Bit  7.. 6: LOS Pol. Ctrl. Mask */
+	PHY_M_POLC_INIT_MSK	= 0x3<<4,  /* Bit  5.. 4: INIT Pol. Ctrl. Mask */
+	PHY_M_POLC_STA1_MSK	= 0x3<<2,  /* Bit  3.. 2: STAT1 Pol. Ctrl. Mask */
+	PHY_M_POLC_STA0_MSK	= 0x3,     /* Bit  1.. 0: STAT0 Pol. Ctrl. Mask */
+};
+
+#define PHY_M_POLC_LS1_P_MIX(x)	(((x)<<12) & PHY_M_POLC_LS1M_MSK)
+#define PHY_M_POLC_IS0_P_MIX(x)	(((x)<<8) & PHY_M_POLC_IS0M_MSK)
+#define PHY_M_POLC_LOS_CTRL(x)	(((x)<<6) & PHY_M_POLC_LOS_MSK)
+#define PHY_M_POLC_INIT_CTRL(x)	(((x)<<4) & PHY_M_POLC_INIT_MSK)
+#define PHY_M_POLC_STA1_CTRL(x)	(((x)<<2) & PHY_M_POLC_STA1_MSK)
+#define PHY_M_POLC_STA0_CTRL(x)	(((x)<<0) & PHY_M_POLC_STA0_MSK)
+
+enum {
+	PULS_NO_STR	= 0,/* no pulse stretching */
+	PULS_21MS	= 1,/* 21 ms to 42 ms */
+	PULS_42MS	= 2,/* 42 ms to 84 ms */
+	PULS_84MS	= 3,/* 84 ms to 170 ms */
+	PULS_170MS	= 4,/* 170 ms to 340 ms */
+	PULS_340MS	= 5,/* 340 ms to 670 ms */
+	PULS_670MS	= 6,/* 670 ms to 1.3 s */
+	PULS_1300MS	= 7,/* 1.3 s to 2.7 s */
+};
+
+#define PHY_M_LED_BLINK_RT(x)	(((x)<<8) & PHY_M_LEDC_BL_R_MSK)
+
+enum {
+	BLINK_42MS	= 0,/* 42 ms */
+	BLINK_84MS	= 1,/* 84 ms */
+	BLINK_170MS	= 2,/* 170 ms */
+	BLINK_340MS	= 3,/* 340 ms */
+	BLINK_670MS	= 4,/* 670 ms */
+};
+
+/*****  PHY_MARV_LED_OVER	16 bit r/w	Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x)	((x)<<14) /* Bit 15..14:  SGMII AN Timer */
+										/* Bit 13..12:	reserved */
+#define PHY_M_LED_MO_DUP(x)	((x)<<10) /* Bit 11..10:  Duplex */
+#define PHY_M_LED_MO_10(x)	((x)<<8) /* Bit  9.. 8:  Link 10 */
+#define PHY_M_LED_MO_100(x)	((x)<<6) /* Bit  7.. 6:  Link 100 */
+#define PHY_M_LED_MO_1000(x)	((x)<<4) /* Bit  5.. 4:  Link 1000 */
+#define PHY_M_LED_MO_RX(x)	((x)<<2) /* Bit  3.. 2:  Rx */
+#define PHY_M_LED_MO_TX(x)	((x)<<0) /* Bit  1.. 0:  Tx */
+
+enum {
+	MO_LED_NORM	= 0,
+	MO_LED_BLINK	= 1,
+	MO_LED_OFF	= 2,
+	MO_LED_ON	= 3,
+};
+
+/*****  PHY_MARV_EXT_CTRL_2	16 bit r/w	Ext. PHY Specific Ctrl 2 *****/
+enum {
+	PHY_M_EC2_FI_IMPED	= 1<<6, /* Fiber Input  Impedance */
+	PHY_M_EC2_FO_IMPED	= 1<<5, /* Fiber Output Impedance */
+	PHY_M_EC2_FO_M_CLK	= 1<<4, /* Fiber Mode Clock Enable */
+	PHY_M_EC2_FO_BOOST	= 1<<3, /* Fiber Output Boost */
+	PHY_M_EC2_FO_AM_MSK	= 7,/* Bit  2.. 0:	Fiber Output Amplitude */
+};
+
+/*****  PHY_MARV_EXT_P_STAT 16 bit r/w	Ext. PHY Specific Status *****/
+enum {
+	PHY_M_FC_AUTO_SEL	= 1<<15, /* Fiber/Copper Auto Sel. Dis. */
+	PHY_M_FC_AN_REG_ACC	= 1<<14, /* Fiber/Copper AN Reg. Access */
+	PHY_M_FC_RESOLUTION	= 1<<13, /* Fiber/Copper Resolution */
+	PHY_M_SER_IF_AN_BP	= 1<<12, /* Ser. IF AN Bypass Enable */
+	PHY_M_SER_IF_BP_ST	= 1<<11, /* Ser. IF AN Bypass Status */
+	PHY_M_IRQ_POLARITY	= 1<<10, /* IRQ polarity */
+	PHY_M_DIS_AUT_MED	= 1<<9, /* Disable Aut. Medium Reg. Selection */
+	/* (88E1111 only) */
+
+	PHY_M_UNDOC1		= 1<<7, /* undocumented bit !! */
+	PHY_M_DTE_POW_STAT	= 1<<4, /* DTE Power Status (88E1111 only) */
+	PHY_M_MODE_MASK	= 0xf, /* Bit  3.. 0: copy of HWCFG MODE[3:0] */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+/*****  PHY_MARV_FE_LED_PAR		16 bit r/w	LED Parallel Select Reg. *****/
+									/* Bit 15..12: reserved (used internally) */
+enum {
+	PHY_M_FELP_LED2_MSK = 0xf<<8,	/* Bit 11.. 8: LED2 Mask (LINK) */
+	PHY_M_FELP_LED1_MSK = 0xf<<4,	/* Bit  7.. 4: LED1 Mask (ACT) */
+	PHY_M_FELP_LED0_MSK = 0xf, /* Bit  3.. 0: LED0 Mask (SPEED) */
+};
+
+#define PHY_M_FELP_LED2_CTRL(x)	(((x)<<8) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x)	(((x)<<4) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x)	(((x)<<0) & PHY_M_FELP_LED0_MSK)
+
+enum {
+	LED_PAR_CTRL_COLX	= 0x00,
+	LED_PAR_CTRL_ERROR	= 0x01,
+	LED_PAR_CTRL_DUPLEX	= 0x02,
+	LED_PAR_CTRL_DP_COL	= 0x03,
+	LED_PAR_CTRL_SPEED	= 0x04,
+	LED_PAR_CTRL_LINK	= 0x05,
+	LED_PAR_CTRL_TX		= 0x06,
+	LED_PAR_CTRL_RX		= 0x07,
+	LED_PAR_CTRL_ACT	= 0x08,
+	LED_PAR_CTRL_LNK_RX	= 0x09,
+	LED_PAR_CTRL_LNK_AC	= 0x0a,
+	LED_PAR_CTRL_ACT_BL	= 0x0b,
+	LED_PAR_CTRL_TX_BL	= 0x0c,
+	LED_PAR_CTRL_RX_BL	= 0x0d,
+	LED_PAR_CTRL_COL_BL	= 0x0e,
+	LED_PAR_CTRL_INACT	= 0x0f
+};
+
+/*****,PHY_MARV_FE_SPEC_2		16 bit r/w	Specific Control Reg. 2 *****/
+enum {
+	PHY_M_FESC_DIS_WAIT	= 1<<2, /* Disable TDR Waiting Period */
+	PHY_M_FESC_ENA_MCLK	= 1<<1, /* Enable MAC Rx Clock in sleep mode */
+	PHY_M_FESC_SEL_CL_A	= 1<<0, /* Select Class A driver (100B-TX) */
+};
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+/*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
+enum {
+	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
+	PHY_M_MAC_MD_AUTO	= 3,/* Auto Copper/1000Base-X */
+	PHY_M_MAC_MD_COPPER	= 5,/* Copper only */
+	PHY_M_MAC_MD_1000BX	= 7,/* 1000Base-X only */
+};
+#define PHY_M_MAC_MODE_SEL(x)	(((x)<<7) & PHY_M_MAC_MD_MSK)
+
+/*****  PHY_MARV_PHY_CTRL (page 3)		16 bit r/w	LED Control Reg. *****/
+enum {
+	PHY_M_LEDC_LOS_MSK	= 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */
+	PHY_M_LEDC_INIT_MSK	= 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */
+	PHY_M_LEDC_STA1_MSK	= 0xf<<4,/* Bit  7.. 4: STAT1 LED Ctrl. Mask */
+	PHY_M_LEDC_STA0_MSK	= 0xf, /* Bit  3.. 0: STAT0 LED Ctrl. Mask */
+};
+
+#define PHY_M_LEDC_LOS_CTRL(x)	(((x)<<12) & PHY_M_LEDC_LOS_MSK)
+#define PHY_M_LEDC_INIT_CTRL(x)	(((x)<<8) & PHY_M_LEDC_INIT_MSK)
+#define PHY_M_LEDC_STA1_CTRL(x)	(((x)<<4) & PHY_M_LEDC_STA1_MSK)
+#define PHY_M_LEDC_STA0_CTRL(x)	(((x)<<0) & PHY_M_LEDC_STA0_MSK)
+
+/* GMAC registers  */
+/* Port Registers */
+enum {
+	GM_GP_STAT	= 0x0000,	/* 16 bit r/o	General Purpose Status */
+	GM_GP_CTRL	= 0x0004,	/* 16 bit r/w	General Purpose Control */
+	GM_TX_CTRL	= 0x0008,	/* 16 bit r/w	Transmit Control Reg. */
+	GM_RX_CTRL	= 0x000c,	/* 16 bit r/w	Receive Control Reg. */
+	GM_TX_FLOW_CTRL	= 0x0010,	/* 16 bit r/w	Transmit Flow-Control */
+	GM_TX_PARAM	= 0x0014,	/* 16 bit r/w	Transmit Parameter Reg. */
+	GM_SERIAL_MODE	= 0x0018,	/* 16 bit r/w	Serial Mode Register */
+/* Source Address Registers */
+	GM_SRC_ADDR_1L	= 0x001c,	/* 16 bit r/w	Source Address 1 (low) */
+	GM_SRC_ADDR_1M	= 0x0020,	/* 16 bit r/w	Source Address 1 (middle) */
+	GM_SRC_ADDR_1H	= 0x0024,	/* 16 bit r/w	Source Address 1 (high) */
+	GM_SRC_ADDR_2L	= 0x0028,	/* 16 bit r/w	Source Address 2 (low) */
+	GM_SRC_ADDR_2M	= 0x002c,	/* 16 bit r/w	Source Address 2 (middle) */
+	GM_SRC_ADDR_2H	= 0x0030,	/* 16 bit r/w	Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+	GM_MC_ADDR_H1	= 0x0034,	/* 16 bit r/w	Multicast Address Hash 1 */
+	GM_MC_ADDR_H2	= 0x0038,	/* 16 bit r/w	Multicast Address Hash 2 */
+	GM_MC_ADDR_H3	= 0x003c,	/* 16 bit r/w	Multicast Address Hash 3 */
+	GM_MC_ADDR_H4	= 0x0040,	/* 16 bit r/w	Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+	GM_TX_IRQ_SRC	= 0x0044,	/* 16 bit r/o	Tx Overflow IRQ Source */
+	GM_RX_IRQ_SRC	= 0x0048,	/* 16 bit r/o	Rx Overflow IRQ Source */
+	GM_TR_IRQ_SRC	= 0x004c,	/* 16 bit r/o	Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+	GM_TX_IRQ_MSK	= 0x0050,	/* 16 bit r/w	Tx Overflow IRQ Mask */
+	GM_RX_IRQ_MSK	= 0x0054,	/* 16 bit r/w	Rx Overflow IRQ Mask */
+	GM_TR_IRQ_MSK	= 0x0058,	/* 16 bit r/w	Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+	GM_SMI_CTRL	= 0x0080,	/* 16 bit r/w	SMI Control Register */
+	GM_SMI_DATA	= 0x0084,	/* 16 bit r/w	SMI Data Register */
+	GM_PHY_ADDR	= 0x0088,	/* 16 bit r/w	GPHY Address Register */
+};
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE	0x0100		/* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE	44		/* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word	(32 bit r/o)
+ */
+enum {
+	GM_RXF_UC_OK  = GM_MIB_CNT_BASE + 0,	/* Unicast Frames Received OK */
+	GM_RXF_BC_OK	= GM_MIB_CNT_BASE + 8,	/* Broadcast Frames Received OK */
+	GM_RXF_MPAUSE	= GM_MIB_CNT_BASE + 16,	/* Pause MAC Ctrl Frames Received */
+	GM_RXF_MC_OK	= GM_MIB_CNT_BASE + 24,	/* Multicast Frames Received OK */
+	GM_RXF_FCS_ERR	= GM_MIB_CNT_BASE + 32,	/* Rx Frame Check Seq. Error */
+	/* GM_MIB_CNT_BASE + 40:	reserved */
+	GM_RXO_OK_LO	= GM_MIB_CNT_BASE + 48,	/* Octets Received OK Low */
+	GM_RXO_OK_HI	= GM_MIB_CNT_BASE + 56,	/* Octets Received OK High */
+	GM_RXO_ERR_LO	= GM_MIB_CNT_BASE + 64,	/* Octets Received Invalid Low */
+	GM_RXO_ERR_HI	= GM_MIB_CNT_BASE + 72,	/* Octets Received Invalid High */
+	GM_RXF_SHT	= GM_MIB_CNT_BASE + 80,	/* Frames <64 Byte Received OK */
+	GM_RXE_FRAG	= GM_MIB_CNT_BASE + 88,	/* Frames <64 Byte Received with FCS Err */
+	GM_RXF_64B	= GM_MIB_CNT_BASE + 96,	/* 64 Byte Rx Frame */
+	GM_RXF_127B	= GM_MIB_CNT_BASE + 104,	/* 65-127 Byte Rx Frame */
+	GM_RXF_255B	= GM_MIB_CNT_BASE + 112,	/* 128-255 Byte Rx Frame */
+	GM_RXF_511B	= GM_MIB_CNT_BASE + 120,	/* 256-511 Byte Rx Frame */
+	GM_RXF_1023B	= GM_MIB_CNT_BASE + 128,	/* 512-1023 Byte Rx Frame */
+	GM_RXF_1518B	= GM_MIB_CNT_BASE + 136,	/* 1024-1518 Byte Rx Frame */
+	GM_RXF_MAX_SZ	= GM_MIB_CNT_BASE + 144,	/* 1519-MaxSize Byte Rx Frame */
+	GM_RXF_LNG_ERR	= GM_MIB_CNT_BASE + 152,	/* Rx Frame too Long Error */
+	GM_RXF_JAB_PKT	= GM_MIB_CNT_BASE + 160,	/* Rx Jabber Packet Frame */
+	/* GM_MIB_CNT_BASE + 168:	reserved */
+	GM_RXE_FIFO_OV	= GM_MIB_CNT_BASE + 176,	/* Rx FIFO overflow Event */
+	/* GM_MIB_CNT_BASE + 184:	reserved */
+	GM_TXF_UC_OK	= GM_MIB_CNT_BASE + 192,	/* Unicast Frames Xmitted OK */
+	GM_TXF_BC_OK	= GM_MIB_CNT_BASE + 200,	/* Broadcast Frames Xmitted OK */
+	GM_TXF_MPAUSE	= GM_MIB_CNT_BASE + 208,	/* Pause MAC Ctrl Frames Xmitted */
+	GM_TXF_MC_OK	= GM_MIB_CNT_BASE + 216,	/* Multicast Frames Xmitted OK */
+	GM_TXO_OK_LO	= GM_MIB_CNT_BASE + 224,	/* Octets Transmitted OK Low */
+	GM_TXO_OK_HI	= GM_MIB_CNT_BASE + 232,	/* Octets Transmitted OK High */
+	GM_TXF_64B	= GM_MIB_CNT_BASE + 240,	/* 64 Byte Tx Frame */
+	GM_TXF_127B	= GM_MIB_CNT_BASE + 248,	/* 65-127 Byte Tx Frame */
+	GM_TXF_255B	= GM_MIB_CNT_BASE + 256,	/* 128-255 Byte Tx Frame */
+	GM_TXF_511B	= GM_MIB_CNT_BASE + 264,	/* 256-511 Byte Tx Frame */
+	GM_TXF_1023B	= GM_MIB_CNT_BASE + 272,	/* 512-1023 Byte Tx Frame */
+	GM_TXF_1518B	= GM_MIB_CNT_BASE + 280,	/* 1024-1518 Byte Tx Frame */
+	GM_TXF_MAX_SZ	= GM_MIB_CNT_BASE + 288,	/* 1519-MaxSize Byte Tx Frame */
+
+	GM_TXF_COL	= GM_MIB_CNT_BASE + 304,	/* Tx Collision */
+	GM_TXF_LAT_COL	= GM_MIB_CNT_BASE + 312,	/* Tx Late Collision */
+	GM_TXF_ABO_COL	= GM_MIB_CNT_BASE + 320,	/* Tx aborted due to Exces. Col. */
+	GM_TXF_MUL_COL	= GM_MIB_CNT_BASE + 328,	/* Tx Multiple Collision */
+	GM_TXF_SNG_COL	= GM_MIB_CNT_BASE + 336,	/* Tx Single Collision */
+	GM_TXE_FIFO_UR	= GM_MIB_CNT_BASE + 344,	/* Tx FIFO Underrun Event */
+};
+
+/* GMAC Bit Definitions */
+/*	GM_GP_STAT	16 bit r/o	General Purpose Status Register */
+enum {
+	GM_GPSR_SPEED		= 1<<15, /* Bit 15:	Port Speed (1 = 100 Mbps) */
+	GM_GPSR_DUPLEX		= 1<<14, /* Bit 14:	Duplex Mode (1 = Full) */
+	GM_GPSR_FC_TX_DIS	= 1<<13, /* Bit 13:	Tx Flow-Control Mode Disabled */
+	GM_GPSR_LINK_UP		= 1<<12, /* Bit 12:	Link Up Status */
+	GM_GPSR_PAUSE		= 1<<11, /* Bit 11:	Pause State */
+	GM_GPSR_TX_ACTIVE	= 1<<10, /* Bit 10:	Tx in Progress */
+	GM_GPSR_EXC_COL		= 1<<9,	/* Bit  9:	Excessive Collisions Occured */
+	GM_GPSR_LAT_COL		= 1<<8,	/* Bit  8:	Late Collisions Occured */
+
+	GM_GPSR_PHY_ST_CH	= 1<<5,	/* Bit  5:	PHY Status Change */
+	GM_GPSR_GIG_SPEED	= 1<<4,	/* Bit  4:	Gigabit Speed (1 = 1000 Mbps) */
+	GM_GPSR_PART_MODE	= 1<<3,	/* Bit  3:	Partition mode */
+	GM_GPSR_FC_RX_DIS	= 1<<2,	/* Bit  2:	Rx Flow-Control Mode Disabled */
+	GM_GPSR_PROM_EN		= 1<<1,	/* Bit  1:	Promiscuous Mode Enabled */
+};
+
+/*	GM_GP_CTRL	16 bit r/w	General Purpose Control Register */
+enum {
+	GM_GPCR_PROM_ENA	= 1<<14,	/* Bit 14:	Enable Promiscuous Mode */
+	GM_GPCR_FC_TX_DIS	= 1<<13, /* Bit 13:	Disable Tx Flow-Control Mode */
+	GM_GPCR_TX_ENA		= 1<<12, /* Bit 12:	Enable Transmit */
+	GM_GPCR_RX_ENA		= 1<<11, /* Bit 11:	Enable Receive */
+	GM_GPCR_BURST_ENA	= 1<<10, /* Bit 10:	Enable Burst Mode */
+	GM_GPCR_LOOP_ENA	= 1<<9,	/* Bit  9:	Enable MAC Loopback Mode */
+	GM_GPCR_PART_ENA	= 1<<8,	/* Bit  8:	Enable Partition Mode */
+	GM_GPCR_GIGS_ENA	= 1<<7,	/* Bit  7:	Gigabit Speed (1000 Mbps) */
+	GM_GPCR_FL_PASS		= 1<<6,	/* Bit  6:	Force Link Pass */
+	GM_GPCR_DUP_FULL	= 1<<5,	/* Bit  5:	Full Duplex Mode */
+	GM_GPCR_FC_RX_DIS	= 1<<4,	/* Bit  4:	Disable Rx Flow-Control Mode */
+	GM_GPCR_SPEED_100	= 1<<3,   /* Bit  3:	Port Speed 100 Mbps */
+	GM_GPCR_AU_DUP_DIS	= 1<<2,	/* Bit  2:	Disable Auto-Update Duplex */
+	GM_GPCR_AU_FCT_DIS	= 1<<1,	/* Bit  1:	Disable Auto-Update Flow-C. */
+	GM_GPCR_AU_SPD_DIS	= 1<<0,	/* Bit  0:	Disable Auto-Update Speed */
+};
+
+#define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
+
+/*	GM_TX_CTRL			16 bit r/w	Transmit Control Register */
+enum {
+	GM_TXCR_FORCE_JAM	= 1<<15, /* Bit 15:	Force Jam / Flow-Control */
+	GM_TXCR_CRC_DIS		= 1<<14, /* Bit 14:	Disable insertion of CRC */
+	GM_TXCR_PAD_DIS		= 1<<13, /* Bit 13:	Disable padding of packets */
+	GM_TXCR_COL_THR_MSK	= 1<<10, /* Bit 12..10:	Collision Threshold */
+};
+
+#define TX_COL_THR(x)		(((x)<<10) & GM_TXCR_COL_THR_MSK)
+#define TX_COL_DEF		0x04
+
+/*	GM_RX_CTRL			16 bit r/w	Receive Control Register */
+enum {
+	GM_RXCR_UCF_ENA	= 1<<15, /* Bit 15:	Enable Unicast filtering */
+	GM_RXCR_MCF_ENA	= 1<<14, /* Bit 14:	Enable Multicast filtering */
+	GM_RXCR_CRC_DIS	= 1<<13, /* Bit 13:	Remove 4-byte CRC */
+	GM_RXCR_PASS_FC	= 1<<12, /* Bit 12:	Pass FC packets to FIFO */
+};
+
+/*	GM_TX_PARAM		16 bit r/w	Transmit Parameter Register */
+enum {
+	GM_TXPA_JAMLEN_MSK	= 0x03<<14,	/* Bit 15..14:	Jam Length */
+	GM_TXPA_JAMIPG_MSK	= 0x1f<<9,	/* Bit 13..9:	Jam IPG */
+	GM_TXPA_JAMDAT_MSK	= 0x1f<<4,	/* Bit  8..4:	IPG Jam to Data */
+	GM_TXPA_BO_LIM_MSK	= 0x0f,		/* Bit  3.. 0: Backoff Limit Mask */
+
+	TX_JAM_LEN_DEF		= 0x03,
+	TX_JAM_IPG_DEF		= 0x0b,
+	TX_IPG_JAM_DEF		= 0x1c,
+	TX_BOF_LIM_DEF		= 0x04,
+};
+
+#define TX_JAM_LEN_VAL(x)	(((x)<<14) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x)	(((x)<<9)  & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x)	(((x)<<4)  & GM_TXPA_JAMDAT_MSK)
+#define TX_BACK_OFF_LIM(x)	((x) & GM_TXPA_BO_LIM_MSK)
+
+
+/*	GM_SERIAL_MODE			16 bit r/w	Serial Mode Register */
+enum {
+	GM_SMOD_DATABL_MSK	= 0x1f<<11, /* Bit 15..11:	Data Blinder (r/o) */
+	GM_SMOD_LIMIT_4		= 1<<10, /* Bit 10:	4 consecutive Tx trials */
+	GM_SMOD_VLAN_ENA	= 1<<9,	/* Bit  9:	Enable VLAN  (Max. Frame Len) */
+	GM_SMOD_JUMBO_ENA	= 1<<8,	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
+	 GM_SMOD_IPG_MSK	= 0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
+};
+
+#define DATA_BLIND_VAL(x)	(((x)<<11) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF		0x04
+
+#define IPG_DATA_VAL(x)		(x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF		0x1e
+
+/*	GM_SMI_CTRL			16 bit r/w	SMI Control Register */
+enum {
+	GM_SMI_CT_PHY_A_MSK	= 0x1f<<11,/* Bit 15..11:	PHY Device Address */
+	GM_SMI_CT_REG_A_MSK	= 0x1f<<6,/* Bit 10.. 6:	PHY Register Address */
+	GM_SMI_CT_OP_RD		= 1<<5,	/* Bit  5:	OpCode Read (0=Write)*/
+	GM_SMI_CT_RD_VAL	= 1<<4,	/* Bit  4:	Read Valid (Read completed) */
+	GM_SMI_CT_BUSY		= 1<<3,	/* Bit  3:	Busy (Operation in progress) */
+};
+
+#define GM_SMI_CT_PHY_AD(x)	(((x)<<11) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x)	(((x)<<6) & GM_SMI_CT_REG_A_MSK)
+
+/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
+enum {
+	GM_PAR_MIB_CLR	= 1<<5,	/* Bit  5:	Set MIB Clear Counter Mode */
+	GM_PAR_MIB_TST	= 1<<4,	/* Bit  4:	MIB Load Counter (Test Mode) */
+};
+
+/* Receive Frame Status Encoding */
+enum {
+	GMR_FS_LEN	= 0xffff<<16, /* Bit 31..16:	Rx Frame Length */
+	GMR_FS_VLAN	= 1<<13, /* VLAN Packet */
+	GMR_FS_JABBER	= 1<<12, /* Jabber Packet */
+	GMR_FS_UN_SIZE	= 1<<11, /* Undersize Packet */
+	GMR_FS_MC	= 1<<10, /* Multicast Packet */
+	GMR_FS_BC	= 1<<9,  /* Broadcast Packet */
+	GMR_FS_RX_OK	= 1<<8,  /* Receive OK (Good Packet) */
+	GMR_FS_GOOD_FC	= 1<<7,  /* Good Flow-Control Packet */
+	GMR_FS_BAD_FC	= 1<<6,  /* Bad  Flow-Control Packet */
+	GMR_FS_MII_ERR	= 1<<5,  /* MII Error */
+	GMR_FS_LONG_ERR	= 1<<4,  /* Too Long Packet */
+	GMR_FS_FRAGMENT	= 1<<3,  /* Fragment */
+
+	GMR_FS_CRC_ERR	= 1<<1,  /* CRC Error */
+	GMR_FS_RX_FF_OV	= 1<<0,  /* Rx FIFO Overflow */
+
+	GMR_FS_ANY_ERR	= GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
+			  GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
+		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+			  GMR_FS_UN_SIZE | GMR_FS_JABBER,
+};
+
+/*	RX_GMF_CTRL_T	32 bit	Rx GMAC FIFO Control/Test */
+enum {
+	RX_TRUNC_ON	= 1<<27,  	/* enable  packet truncation */
+	RX_TRUNC_OFF	= 1<<26, 	/* disable packet truncation */
+	RX_VLAN_STRIP_ON = 1<<25,	/* enable  VLAN stripping */
+	RX_VLAN_STRIP_OFF = 1<<24,	/* disable VLAN stripping */
+
+	GMF_WP_TST_ON	= 1<<14,	/* Write Pointer Test On */
+	GMF_WP_TST_OFF	= 1<<13,	/* Write Pointer Test Off */
+	GMF_WP_STEP	= 1<<12,	/* Write Pointer Step/Increment */
+
+	GMF_RP_TST_ON	= 1<<10,	/* Read Pointer Test On */
+	GMF_RP_TST_OFF	= 1<<9,		/* Read Pointer Test Off */
+	GMF_RP_STEP	= 1<<8,		/* Read Pointer Step/Increment */
+	GMF_RX_F_FL_ON	= 1<<7,		/* Rx FIFO Flush Mode On */
+	GMF_RX_F_FL_OFF	= 1<<6,		/* Rx FIFO Flush Mode Off */
+	GMF_CLI_RX_FO	= 1<<5,		/* Clear IRQ Rx FIFO Overrun */
+	GMF_CLI_RX_C	= 1<<4,		/* Clear IRQ Rx Frame Complete */
+
+	GMF_OPER_ON	= 1<<3,		/* Operational Mode On */
+	GMF_OPER_OFF	= 1<<2,		/* Operational Mode Off */
+	GMF_RST_CLR	= 1<<1,		/* Clear GMAC FIFO Reset */
+	GMF_RST_SET	= 1<<0,		/* Set   GMAC FIFO Reset */
+
+	RX_GMF_FL_THR_DEF = 0xa,	/* flush threshold (default) */
+
+	GMF_RX_CTRL_DEF	= GMF_OPER_ON | GMF_RX_F_FL_ON,
+};
+
+
+/*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test */
+enum {
+	TX_STFW_DIS	= 1<<31,/* Disable Store & Forward (Yukon-EC Ultra) */
+	TX_STFW_ENA	= 1<<30,/* Enable  Store & Forward (Yukon-EC Ultra) */
+
+	TX_VLAN_TAG_ON	= 1<<25,/* enable  VLAN tagging */
+	TX_VLAN_TAG_OFF	= 1<<24,/* disable VLAN tagging */
+
+	GMF_WSP_TST_ON	= 1<<18,/* Write Shadow Pointer Test On */
+	GMF_WSP_TST_OFF	= 1<<17,/* Write Shadow Pointer Test Off */
+	GMF_WSP_STEP	= 1<<16,/* Write Shadow Pointer Step/Increment */
+
+	GMF_CLI_TX_FU	= 1<<6,	/* Clear IRQ Tx FIFO Underrun */
+	GMF_CLI_TX_FC	= 1<<5,	/* Clear IRQ Tx Frame Complete */
+	GMF_CLI_TX_PE	= 1<<4,	/* Clear IRQ Tx Parity Error */
+};
+
+/*	GMAC_TI_ST_CTRL	 8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
+enum {
+	GMT_ST_START	= 1<<2,	/* Start Time Stamp Timer */
+	GMT_ST_STOP	= 1<<1,	/* Stop  Time Stamp Timer */
+	GMT_ST_CLR_IRQ	= 1<<0,	/* Clear Time Stamp Timer IRQ */
+};
+
+/* B28_Y2_ASF_STAT_CMD		32 bit	ASF Status and Command Reg */
+enum {
+	Y2_ASF_OS_PRES	= 1<<4,	/* ASF operation system present */
+	Y2_ASF_RESET	= 1<<3,	/* ASF system in reset state */
+	Y2_ASF_RUNNING	= 1<<2,	/* ASF system operational */
+	Y2_ASF_CLR_HSTI = 1<<1,	/* Clear ASF IRQ */
+	Y2_ASF_IRQ	= 1<<0,	/* Issue an IRQ to ASF system */
+
+	Y2_ASF_UC_STATE = 3<<2,	/* ASF uC State */
+	Y2_ASF_CLK_HALT	= 0,	/* ASF system clock stopped */
+};
+
+/* B28_Y2_ASF_HOST_COM	32 bit	ASF Host Communication Reg */
+enum {
+	Y2_ASF_CLR_ASFI = 1<<1,	/* Clear host IRQ */
+	Y2_ASF_HOST_IRQ = 1<<0,	/* Issue an IRQ to HOST system */
+};
+
+/*	STAT_CTRL		32 bit	Status BMU control register (Yukon-2 only) */
+enum {
+	SC_STAT_CLR_IRQ	= 1<<4,	/* Status Burst IRQ clear */
+	SC_STAT_OP_ON	= 1<<3,	/* Operational Mode On */
+	SC_STAT_OP_OFF	= 1<<2,	/* Operational Mode Off */
+	SC_STAT_RST_CLR	= 1<<1,	/* Clear Status Unit Reset (Enable) */
+	SC_STAT_RST_SET	= 1<<0,	/* Set   Status Unit Reset */
+};
+
+/*	GMAC_CTRL		32 bit	GMAC Control Reg (YUKON only) */
+enum {
+	GMC_H_BURST_ON	= 1<<7,	/* Half Duplex Burst Mode On */
+	GMC_H_BURST_OFF	= 1<<6,	/* Half Duplex Burst Mode Off */
+	GMC_F_LOOPB_ON	= 1<<5,	/* FIFO Loopback On */
+	GMC_F_LOOPB_OFF	= 1<<4,	/* FIFO Loopback Off */
+	GMC_PAUSE_ON	= 1<<3,	/* Pause On */
+	GMC_PAUSE_OFF	= 1<<2,	/* Pause Off */
+	GMC_RST_CLR	= 1<<1,	/* Clear GMAC Reset */
+	GMC_RST_SET	= 1<<0,	/* Set   GMAC Reset */
+};
+
+/*	GPHY_CTRL		32 bit	GPHY Control Reg (YUKON only) */
+enum {
+	GPC_SEL_BDT	= 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
+	GPC_INT_POL_HI	= 1<<27, /* IRQ Polarity is Active HIGH */
+	GPC_75_OHM	= 1<<26, /* Use 75 Ohm Termination instead of 50 */
+	GPC_DIS_FC	= 1<<25, /* Disable Automatic Fiber/Copper Detection */
+	GPC_DIS_SLEEP	= 1<<24, /* Disable Energy Detect */
+	GPC_HWCFG_M_3	= 1<<23, /* HWCFG_MODE[3] */
+	GPC_HWCFG_M_2	= 1<<22, /* HWCFG_MODE[2] */
+	GPC_HWCFG_M_1	= 1<<21, /* HWCFG_MODE[1] */
+	GPC_HWCFG_M_0	= 1<<20, /* HWCFG_MODE[0] */
+	GPC_ANEG_0	= 1<<19, /* ANEG[0] */
+	GPC_ENA_XC	= 1<<18, /* Enable MDI crossover */
+	GPC_DIS_125	= 1<<17, /* Disable 125 MHz clock */
+	GPC_ANEG_3	= 1<<16, /* ANEG[3] */
+	GPC_ANEG_2	= 1<<15, /* ANEG[2] */
+	GPC_ANEG_1	= 1<<14, /* ANEG[1] */
+	GPC_ENA_PAUSE	= 1<<13, /* Enable Pause (SYM_OR_REM) */
+	GPC_PHYADDR_4	= 1<<12, /* Bit 4 of Phy Addr */
+	GPC_PHYADDR_3	= 1<<11, /* Bit 3 of Phy Addr */
+	GPC_PHYADDR_2	= 1<<10, /* Bit 2 of Phy Addr */
+	GPC_PHYADDR_1	= 1<<9,	 /* Bit 1 of Phy Addr */
+	GPC_PHYADDR_0	= 1<<8,	 /* Bit 0 of Phy Addr */
+						/* Bits  7..2:	reserved */
+	GPC_RST_CLR	= 1<<1,	/* Clear GPHY Reset */
+	GPC_RST_SET	= 1<<0,	/* Set   GPHY Reset */
+};
+
+/*	GMAC_IRQ_SRC	 8 bit	GMAC Interrupt Source Reg (YUKON only) */
+/*	GMAC_IRQ_MSK	 8 bit	GMAC Interrupt Mask   Reg (YUKON only) */
+enum {
+	GM_IS_TX_CO_OV	= 1<<5,	/* Transmit Counter Overflow IRQ */
+	GM_IS_RX_CO_OV	= 1<<4,	/* Receive Counter Overflow IRQ */
+	GM_IS_TX_FF_UR	= 1<<3,	/* Transmit FIFO Underrun */
+	GM_IS_TX_COMPL	= 1<<2,	/* Frame Transmission Complete */
+	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */
+	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */
+
+#define GMAC_DEF_MSK     GM_IS_TX_FF_UR
+
+/*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
+						/* Bits 15.. 2:	reserved */
+	GMLC_RST_CLR	= 1<<1,	/* Clear GMAC Link Reset */
+	GMLC_RST_SET	= 1<<0,	/* Set   GMAC Link Reset */
+
+
+/*	WOL_CTRL_STAT	16 bit	WOL Control/Status Reg */
+	WOL_CTL_LINK_CHG_OCC		= 1<<15,
+	WOL_CTL_MAGIC_PKT_OCC		= 1<<14,
+	WOL_CTL_PATTERN_OCC		= 1<<13,
+	WOL_CTL_CLEAR_RESULT		= 1<<12,
+	WOL_CTL_ENA_PME_ON_LINK_CHG	= 1<<11,
+	WOL_CTL_DIS_PME_ON_LINK_CHG	= 1<<10,
+	WOL_CTL_ENA_PME_ON_MAGIC_PKT	= 1<<9,
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT	= 1<<8,
+	WOL_CTL_ENA_PME_ON_PATTERN	= 1<<7,
+	WOL_CTL_DIS_PME_ON_PATTERN	= 1<<6,
+	WOL_CTL_ENA_LINK_CHG_UNIT	= 1<<5,
+	WOL_CTL_DIS_LINK_CHG_UNIT	= 1<<4,
+	WOL_CTL_ENA_MAGIC_PKT_UNIT	= 1<<3,
+	WOL_CTL_DIS_MAGIC_PKT_UNIT	= 1<<2,
+	WOL_CTL_ENA_PATTERN_UNIT	= 1<<1,
+	WOL_CTL_DIS_PATTERN_UNIT	= 1<<0,
+};
+
+#define WOL_CTL_DEFAULT				\
+	(WOL_CTL_DIS_PME_ON_LINK_CHG |	\
+	WOL_CTL_DIS_PME_ON_PATTERN |	\
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT |	\
+	WOL_CTL_DIS_LINK_CHG_UNIT |		\
+	WOL_CTL_DIS_PATTERN_UNIT |		\
+	WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/*	WOL_MATCH_CTL	 8 bit	WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x)	(1 << (x))
+
+
+/* Control flags */
+enum {
+	UDPTCP	= 1<<0,
+	CALSUM	= 1<<1,
+	WR_SUM	= 1<<2,
+	INIT_SUM= 1<<3,
+	LOCK_SUM= 1<<4,
+	INS_VLAN= 1<<5,
+	FRC_STAT= 1<<6,
+	EOP	= 1<<7,
+};
+
+enum {
+	HW_OWNER 	= 1<<7,
+	OP_TCPWRITE	= 0x11,
+	OP_TCPSTART	= 0x12,
+	OP_TCPINIT	= 0x14,
+	OP_TCPLCK	= 0x18,
+	OP_TCPCHKSUM	= OP_TCPSTART,
+	OP_TCPIS	= OP_TCPINIT | OP_TCPSTART,
+	OP_TCPLW	= OP_TCPLCK | OP_TCPWRITE,
+	OP_TCPLSW	= OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE,
+	OP_TCPLISW	= OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE,
+
+	OP_ADDR64	= 0x21,
+	OP_VLAN		= 0x22,
+	OP_ADDR64VLAN	= OP_ADDR64 | OP_VLAN,
+	OP_LRGLEN	= 0x24,
+	OP_LRGLENVLAN	= OP_LRGLEN | OP_VLAN,
+	OP_BUFFER	= 0x40,
+	OP_PACKET	= 0x41,
+	OP_LARGESEND	= 0x43,
+
+/* YUKON-2 STATUS opcodes defines */
+	OP_RXSTAT	= 0x60,
+	OP_RXTIMESTAMP	= 0x61,
+	OP_RXVLAN	= 0x62,
+	OP_RXCHKS	= 0x64,
+	OP_RXCHKSVLAN	= OP_RXCHKS | OP_RXVLAN,
+	OP_RXTIMEVLAN	= OP_RXTIMESTAMP | OP_RXVLAN,
+	OP_RSS_HASH	= 0x65,
+	OP_TXINDEXLE	= 0x68,
+};
+
+/* Yukon 2 hardware interface
+ * Not tested on big endian
+ */
+struct sky2_tx_le {
+	union {
+		__le32	addr;
+		struct {
+			__le16	offset;
+			__le16	start;
+		} csum  __attribute((packed));
+		struct {
+			__le16	size;
+			__le16	rsvd;
+		} tso  __attribute((packed));
+	} tx;
+	__le16	length;	/* also vlan tag or checksum start */
+	u8	ctrl;
+	u8	opcode;
+} __attribute((packed));
+
+struct sky2_rx_le {
+	__le32	addr;
+	__le16	length;
+	u8	ctrl;
+	u8	opcode;
+} __attribute((packed));;
+
+struct sky2_status_le {
+	__le32	status;	/* also checksum */
+	__le16	length;	/* also vlan tag */
+	u8	link;
+	u8	opcode;
+} __attribute((packed));
+
+struct tx_ring_info {
+	struct sk_buff	*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapaddr);
+	u16		idx;
+};
+
+struct ring_info {
+	struct sk_buff	*skb;
+	dma_addr_t	mapaddr;
+};
+
+struct sky2_port {
+	struct sky2_hw	     *hw;
+	struct net_device    *netdev;
+	unsigned	     port;
+	u32		     msg_enable;
+
+	spinlock_t	     tx_lock  ____cacheline_aligned_in_smp;
+	struct tx_ring_info  *tx_ring;
+	struct sky2_tx_le    *tx_le;
+	u16		     tx_cons;		/* next le to check */
+	u16		     tx_prod;		/* next le to use */
+	u32		     tx_addr64;
+	u16		     tx_pending;
+	u16		     tx_last_put;
+	u16		     tx_last_mss;
+
+	struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
+	struct sky2_rx_le    *rx_le;
+	u32		     rx_addr64;
+	u16		     rx_next;		/* next re to check */
+	u16		     rx_put;		/* next le index to use */
+	u16		     rx_pending;
+	u16		     rx_last_put;
+	u16		     rx_bufsize;
+#ifdef SKY2_VLAN_TAG_USED
+	u16		     rx_tag;
+	struct vlan_group    *vlgrp;
+#endif
+
+	dma_addr_t	     rx_le_map;
+	dma_addr_t	     tx_le_map;
+	u32		     advertising;	/* ADVERTISED_ bits */
+	u16		     speed;	/* SPEED_1000, SPEED_100, ... */
+	u8		     autoneg;	/* AUTONEG_ENABLE, AUTONEG_DISABLE */
+	u8		     duplex;	/* DUPLEX_HALF, DUPLEX_FULL */
+	u8		     rx_pause;
+	u8		     tx_pause;
+	u8		     rx_csum;
+	u8		     wol;
+
+	struct net_device_stats net_stats;
+
+	struct work_struct   phy_task;
+	struct semaphore     phy_sema;
+};
+
+struct sky2_hw {
+	void __iomem  	     *regs;
+	struct pci_dev	     *pdev;
+	u32		     intr_mask;
+	struct net_device    *dev[2];
+
+	int		     pm_cap;
+	u8	     	     chip_id;
+	u8		     chip_rev;
+	u8		     copper;
+	u8		     ports;
+
+	struct sky2_status_le *st_le;
+	u32		     st_idx;
+	dma_addr_t   	     st_dma;
+};
+
+/* Register accessor for memory mapped device */
+static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
+{
+	return readl(hw->regs + reg);
+}
+
+static inline u16 sky2_read16(const struct sky2_hw *hw, unsigned reg)
+{
+	return readw(hw->regs + reg);
+}
+
+static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg)
+{
+	return readb(hw->regs + reg);
+}
+
+/* This should probably go away, bus based tweeks suck */
+static inline int is_pciex(const struct sky2_hw *hw)
+{
+	u32 status;
+	pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
+	return (status & PCI_OS_PCI_X) == 0;
+}
+
+static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
+{
+	writel(val, hw->regs + reg);
+}
+
+static inline void sky2_write16(const struct sky2_hw *hw, unsigned reg, u16 val)
+{
+	writew(val, hw->regs + reg);
+}
+
+static inline void sky2_write8(const struct sky2_hw *hw, unsigned reg, u8 val)
+{
+	writeb(val, hw->regs + reg);
+}
+
+/* Yukon PHY related registers */
+#define SK_GMAC_REG(port,reg) \
+	(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
+#define GM_PHY_RETRIES	100
+
+static inline u16 gma_read16(const struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+	return sky2_read16(hw, SK_GMAC_REG(port,reg));
+}
+
+static inline u32 gma_read32(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+	unsigned base = SK_GMAC_REG(port, reg);
+	return (u32) sky2_read16(hw, base)
+		| (u32) sky2_read16(hw, base+4) << 16;
+}
+
+static inline void gma_write16(const struct sky2_hw *hw, unsigned port, int r, u16 v)
+{
+	sky2_write16(hw, SK_GMAC_REG(port,r), v);
+}
+
+static inline void gma_set_addr(struct sky2_hw *hw, unsigned port, unsigned reg,
+				    const u8 *addr)
+{
+	gma_write16(hw, port, reg,  (u16) addr[0] | ((u16) addr[1] << 8));
+	gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
+	gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
+}
+#endif
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 2fc9893..eb86b05 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -24,6 +24,7 @@
 #include <linux/compiler.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/in.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
@@ -3650,7 +3651,7 @@
 			       TXD_FLAG_CPU_POST_DMA);
 
 		skb->nh.iph->check = 0;
-		skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
+		skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
 		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
 			skb->h.th->check = 0;
 			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
diff --git a/drivers/net/wan/lmc/lmc_prot.h b/drivers/net/wan/lmc/lmc_prot.h
deleted file mode 100644
index f3b1df9..0000000
--- a/drivers/net/wan/lmc/lmc_prot.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _LMC_PROTO_H_
-#define _LMC_PROTO_H_
-
-void lmc_proto_init(lmc_softc_t * const)
-void lmc_proto_attach(lmc_softc_t *sc const)
-void lmc_proto_detach(lmc_softc *sc const)
-void lmc_proto_reopen(lmc_softc_t *sc const)
-int lmc_proto_ioctl(lmc_softc_t *sc const, struct ifreq *ifr, int cmd)
-void lmc_proto_open(lmc_softc_t *sc const)
-void lmc_proto_close(lmc_softc_t *sc const)
-unsigned short lmc_proto_type(lmc_softc_t *sc const, struct skbuff *skb)
-
-
-#endif
-
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 00e5516..24f7967 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -173,7 +173,7 @@
 	  promiscuous mode via the Wireless Tool's Monitor mode.  While in this
 	  mode, no packets can be sent.
 
-config IPW_DEBUG
+config IPW2100_DEBUG
 	bool "Enable full debugging output in IPW2100 module."
 	depends on IPW2100
 	---help---
@@ -192,7 +192,7 @@
 
 config IPW2200
 	tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-	depends on IEEE80211 && PCI
+	depends on NET_RADIO && IEEE80211 && PCI
 	select FW_LOADER
 	---help---
           A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
@@ -217,7 +217,7 @@
           say M here and read <file:Documentation/modules.txt>.  The module
           will be called ipw2200.ko.
 
-config IPW_DEBUG
+config IPW2200_DEBUG
 	bool "Enable full debugging output in IPW2200 module."
 	depends on IPW2200
 	---help---
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 7a92b1c..ee866fd 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4037,7 +4037,7 @@
 		Cmd cmd;
 		Resp rsp;
 
-		if (test_bit(FLAG_ENABLED, &ai->flags))
+		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
 			printk(KERN_ERR
 				"%s: MAC should be disabled (rid=%04x)\n",
 				__FUNCTION__, rid);
@@ -5093,9 +5093,9 @@
 		printk(KERN_INFO "Setting key %d\n", index);
 	}
 
-	disable_MAC(ai, lock);
+	if (perm) disable_MAC(ai, lock);
 	writeWepKeyRid(ai, &wkr, perm, lock);
-	enable_MAC(ai, &rsp, lock);
+	if (perm) enable_MAC(ai, &rsp, lock);
 	return 0;
 }
 
@@ -6170,6 +6170,8 @@
 {
 	struct airo_info *local = dev->priv;
 	CapabilityRid cap_rid;		/* Card capability info */
+	int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+	u16 currentAuthType = local->config.authType;
 
 	/* Is WEP supported ? */
 	readCapabilityRid(local, &cap_rid, 1);
@@ -6212,7 +6214,7 @@
 			/* Copy the key in the driver */
 			memcpy(key.key, extra, dwrq->length);
 			/* Send the key to the card */
-			set_wep_key(local, index, key.key, key.len, 1, 1);
+			set_wep_key(local, index, key.key, key.len, perm, 1);
 		}
 		/* WE specify that if a valid key is set, encryption
 		 * should be enabled (user may turn it off later)
@@ -6220,13 +6222,12 @@
 		if((index == current_index) && (key.len > 0) &&
 		   (local->config.authType == AUTH_OPEN)) {
 			local->config.authType = AUTH_ENCRYPT;
-			set_bit (FLAG_COMMIT, &local->flags);
 		}
 	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 		if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
-			set_wep_key(local, index, NULL, 0, 1, 1);
+			set_wep_key(local, index, NULL, 0, perm, 1);
 		} else
 			/* Don't complain if only change the mode */
 			if(!dwrq->flags & IW_ENCODE_MODE) {
@@ -6241,7 +6242,7 @@
 	if(dwrq->flags & IW_ENCODE_OPEN)
 		local->config.authType = AUTH_ENCRYPT;	// Only Wep
 	/* Commit the changes to flags if needed */
-	if(dwrq->flags & IW_ENCODE_MODE)
+	if (local->config.authType != currentAuthType)
 		set_bit (FLAG_COMMIT, &local->flags);
 	return -EINPROGRESS;		/* Call commit handler */
 }
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 5e53c52..e4729dd 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -5,9 +5,9 @@
         Copyright 2000-2001 ATMEL Corporation.
         Copyright 2003-2004 Simon Kelley.
 
-    This code was developed from version 2.1.1 of the Atmel drivers, 
-    released by Atmel corp. under the GPL in December 2002. It also 
-    includes code from the Linux aironet drivers (C) Benjamin Reed, 
+    This code was developed from version 2.1.1 of the Atmel drivers,
+    released by Atmel corp. under the GPL in December 2002. It also
+    includes code from the Linux aironet drivers (C) Benjamin Reed,
     and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
     extensions, (C) Jean Tourrilhes.
 
@@ -31,7 +31,7 @@
     along with Atmel wireless lan drivers; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-    For all queries about this code, please contact the current author, 
+    For all queries about this code, please contact the current author,
     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
 
     Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
@@ -79,13 +79,13 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
 
-/* The name of the firmware file to be loaded 
+/* The name of the firmware file to be loaded
    over-rides any automatic selection */
 static char *firmware = NULL;
 module_param(firmware, charp, 0);
 
 /* table of firmware file names */
-static struct { 
+static struct {
 	AtmelFWType fw_type;
 	const char *fw_file;
 	const char *fw_file_ext;
@@ -104,17 +104,17 @@
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
 
-#define MAX_BSS_ENTRIES	64	
+#define MAX_BSS_ENTRIES	64
 
 /* registers */
-#define GCR  0x00    //      (SIR0)  General Configuration Register        
-#define BSR  0x02    //      (SIR1)  Bank Switching Select Register 
+#define GCR  0x00    //      (SIR0)  General Configuration Register
+#define BSR  0x02    //      (SIR1)  Bank Switching Select Register
 #define AR   0x04
 #define DR   0x08
-#define MR1  0x12    //      Mirror Register 1                  
-#define MR2  0x14    //      Mirror Register 2  
-#define MR3  0x16    //      Mirror Register 3  
-#define MR4  0x18    //      Mirror Register 4   
+#define MR1  0x12    //      Mirror Register 1
+#define MR2  0x14    //      Mirror Register 2
+#define MR3  0x16    //      Mirror Register 3
+#define MR4  0x18    //      Mirror Register 4
 
 #define GPR1                            0x0c
 #define GPR2                            0x0e
@@ -123,9 +123,9 @@
 // Constants for the GCR register.
 //
 #define GCR_REMAP     0x0400          // Remap internal SRAM to 0
-#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset) 
+#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset)
 #define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT     0x0002          // Enable Interrupts    
+#define GCR_ENINT     0x0002          // Enable Interrupts
 #define GCR_ACKINT    0x0008          // Acknowledge Interrupts
 
 #define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
@@ -190,7 +190,7 @@
         u32          Next;
         u16          MsduPos;
         u16          MsduSize;
-	
+
         u8           State;
         u8           Status;
         u8           Rate;
@@ -199,7 +199,6 @@
         u8           PreambleType;
         u16          Duration;
         u32          RxTime;
-
 };
 
 #define RX_DESC_FLAG_VALID       0x80
@@ -218,16 +217,15 @@
 #define RX_DESC_DURATION_OFFSET      14
 #define RX_DESC_RX_TIME_OFFSET       16
 
-
 struct tx_desc {
 	u32       NextDescriptor;
 	u16       TxStartOfFrame;
 	u16       TxLength;
-	
+
 	u8        TxState;
 	u8        TxStatus;
 	u8        RetryCount;
-	
+
 	u8        TxRate;
 
 	u8        KeyIndex;
@@ -238,10 +236,8 @@
 	u8        Reserved;
 	u8        PacketType;
 	u16       HostTxLength;
-	
 };
 
-
 #define TX_DESC_NEXT_OFFSET          0
 #define TX_DESC_POS_OFFSET           4
 #define TX_DESC_SIZE_OFFSET          6
@@ -255,8 +251,6 @@
 #define TX_DESC_PACKET_TYPE_OFFSET   17
 #define TX_DESC_HOST_LENGTH_OFFSET   18
 
-
-
 ///////////////////////////////////////////////////////
 // Host-MAC interface
 ///////////////////////////////////////////////////////
@@ -266,7 +260,6 @@
 #define TX_FIRM_OWN             0x80
 #define TX_DONE                 0x40
 
-
 #define TX_ERROR                0x01
 
 #define TX_PACKET_TYPE_DATA     0x01
@@ -280,8 +273,7 @@
 #define ISR_COMMAND_COMPLETE    0x10        // command completed
 #define ISR_OUT_OF_RANGE        0x20        // command completed
 #define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
-#define ISR_GENERIC_IRQ         0x80                
-
+#define ISR_GENERIC_IRQ         0x80
 
 #define Local_Mib_Type          0x01
 #define Mac_Address_Mib_Type    0x02
@@ -317,7 +309,6 @@
 #define LOCAL_MIB_PREAMBLE_TYPE               9
 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
 
-
 #define         CMD_Set_MIB_Vars              0x01
 #define         CMD_Get_MIB_Vars              0x02
 #define         CMD_Scan                      0x03
@@ -338,7 +329,6 @@
 #define         CMD_STATUS_HOST_ERROR             0xFF
 #define         CMD_STATUS_BUSY                   0xFE
 
-
 #define CMD_BLOCK_COMMAND_OFFSET        0
 #define CMD_BLOCK_STATUS_OFFSET         1
 #define CMD_BLOCK_PARAMETERS_OFFSET     4
@@ -347,15 +337,15 @@
 
 #define MGMT_FRAME_BODY_OFFSET		24
 #define MAX_AUTHENTICATION_RETRIES	3
-#define MAX_ASSOCIATION_RETRIES 	3
+#define MAX_ASSOCIATION_RETRIES		3
 
 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
 
 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
 #define LOOP_RETRY_LIMIT   500000
 
-#define ACTIVE_MODE 	1
-#define PS_MODE 	2
+#define ACTIVE_MODE	1
+#define PS_MODE		2
 
 #define MAX_ENCRYPTION_KEYS 4
 #define MAX_ENCRYPTION_KEY_SIZE 40
@@ -377,7 +367,7 @@
 #define REG_DOMAIN_MKK1		0x41	//Channel	1-14	Japan(MKK1)
 #define REG_DOMAIN_ISRAEL	0x50	//Channel	3-9	ISRAEL
 
-#define BSS_TYPE_AD_HOC 	1
+#define BSS_TYPE_AD_HOC		1
 #define BSS_TYPE_INFRASTRUCTURE 2
 
 #define SCAN_TYPE_ACTIVE	0
@@ -389,7 +379,7 @@
 
 #define DATA_FRAME_WS_HEADER_SIZE   30
 
-/* promiscuous mode control */ 
+/* promiscuous mode control */
 #define PROM_MODE_OFF			0x0
 #define PROM_MODE_UNKNOWN		0x1
 #define PROM_MODE_CRC_FAILED		0x2
@@ -398,8 +388,7 @@
 #define PROM_MODE_CTRL			0x10
 #define PROM_MODE_BAD_PROTOCOL		0x20
 
-
-#define IFACE_INT_STATUS_OFFSET 	0
+#define IFACE_INT_STATUS_OFFSET		0
 #define IFACE_INT_MASK_OFFSET		1
 #define IFACE_LOCKOUT_HOST_OFFSET	2
 #define IFACE_LOCKOUT_MAC_OFFSET	3
@@ -407,7 +396,7 @@
 #define IFACE_MAC_STAT_OFFSET		30
 #define IFACE_GENERIC_INT_TYPE_OFFSET	32
 
-#define CIPHER_SUITE_NONE     0 
+#define CIPHER_SUITE_NONE     0
 #define CIPHER_SUITE_WEP_64   1
 #define CIPHER_SUITE_TKIP     2
 #define CIPHER_SUITE_AES      3
@@ -419,11 +408,11 @@
 //
 //
 
-// FuncCtrl field: 
+// FuncCtrl field:
 //
 #define FUNC_CTRL_TxENABLE		0x10
 #define FUNC_CTRL_RxENABLE		0x20
-#define FUNC_CTRL_INIT_COMPLETE 	0x01
+#define FUNC_CTRL_INIT_COMPLETE		0x01
 
 /* A stub firmware image which reads the MAC address from NVRAM on the card.
    For copyright information and source see the end of this file. */
@@ -486,10 +475,10 @@
 	struct net_device_stats	stats;	// device stats
 	spinlock_t irqlock, timerlock;	// spinlocks
 	enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
-	enum { 
-		CARD_TYPE_PARALLEL_FLASH, 
+	enum {
+		CARD_TYPE_PARALLEL_FLASH,
 		CARD_TYPE_SPI_FLASH,
-		CARD_TYPE_EEPROM 
+		CARD_TYPE_EEPROM
 	} card_type;
 	int do_rx_crc; /* If we need to CRC incoming packets */
 	int probe_crc; /* set if we don't yet know */
@@ -497,18 +486,18 @@
 	u16 rx_desc_head;
 	u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
 	u16 tx_free_mem, tx_buff_head, tx_buff_tail;
-	
+
 	u16 frag_seq, frag_len, frag_no;
-	u8 frag_source[6]; 
-	
+	u8 frag_source[6];
+
 	u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
 	u8 group_cipher_suite, pairwise_cipher_suite;
 	u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
-	int wep_key_len[MAX_ENCRYPTION_KEYS]; 
+	int wep_key_len[MAX_ENCRYPTION_KEYS];
 	int use_wpa, radio_on_broken; /* firmware dependent stuff. */
 
 	u16 host_info_base;
-	struct host_info_struct { 
+	struct host_info_struct {
 		/* NB this is matched to the hardware, don't change. */
 		u8 volatile int_status;
 		u8 volatile int_mask;
@@ -524,20 +513,20 @@
 		u16 rx_buff_size;
 		u16 rx_desc_pos;
 		u16 rx_desc_count;
-		
+
 		u16 build_version;
-		u16 command_pos; 	
-		
+		u16 command_pos;
+
 		u16 major_version;
 		u16 minor_version;
-		
+
 		u16 func_ctrl;
 		u16 mac_status;
 		u16 generic_IRQ_type;
 		u8  reserved[2];
 	} host_info;
 
-	enum { 
+	enum {
 		STATION_STATE_SCANNING,
 		STATION_STATE_JOINNING,
 		STATION_STATE_AUTHENTICATING,
@@ -547,7 +536,7 @@
 		STATION_STATE_DOWN,
 		STATION_STATE_MGMT_ERROR
 	} station_state;
-	
+
 	int operating_mode, power_mode;
 	time_t last_qual;
 	int beacons_this_sec;
@@ -560,18 +549,18 @@
 	int long_retry, short_retry;
 	int preamble;
 	int default_beacon_period, beacon_period, listen_interval;
-	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;	
+	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
 	int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
 	enum {
 		SITE_SURVEY_IDLE,
 		SITE_SURVEY_IN_PROGRESS,
-		SITE_SURVEY_COMPLETED 
+		SITE_SURVEY_COMPLETED
 	} site_survey_state;
 	time_t last_survey;
 
 	int station_was_associated, station_is_associated;
 	int fast_scan;
-				
+
 	struct bss_info {
 		int channel;
 		int SSIDsize;
@@ -584,13 +573,12 @@
 		u8 SSID[MAX_SSID_LENGTH];
 	} BSSinfo[MAX_BSS_ENTRIES];
 	int BSS_list_entries, current_BSS;
-	int connect_to_any_BSS; 
+	int connect_to_any_BSS;
 	int SSID_size, new_SSID_size;
 	u8 CurrentBSSID[6], BSSID[6];
 	u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
 	u64 last_beacon_timestamp;
 	u8 rx_buf[MAX_WIRELESS_BODY];
-	
 };
 
 static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
@@ -598,39 +586,49 @@
 static const struct {
 	int reg_domain;
 	int min, max;
-	char *name; 
+	char *name;
 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
 		      { REG_DOMAIN_DOC, 1, 11, "Canada" },
 		      { REG_DOMAIN_ETSI, 1, 13, "Europe" },
 		      { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
-		      { REG_DOMAIN_FRANCE, 10, 13, "France" }, 
+		      { REG_DOMAIN_FRANCE, 10, 13, "France" },
 		      { REG_DOMAIN_MKK, 14, 14, "MKK" },
 		      { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
 		      { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
 
 static void build_wpa_mib(struct atmel_private *priv);
 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+			       unsigned char *src, u16 len);
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+			       u16 src, u16 len);
 static void atmel_set_gcr(struct net_device *dev, u16 mask);
 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
 static int atmel_lock_mac(struct atmel_private *priv);
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+static void atmel_management_frame(struct atmel_private *priv,
+				   struct ieee80211_hdr_4addr *header,
 				   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
+static void atmel_send_command(struct atmel_private *priv, int command,
+			       void *cmd, int cmd_size);
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+				   void *cmd, int cmd_size);
+static void atmel_transmit_management_frame(struct atmel_private *priv,
+					    struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
-static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
+static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
+			   u8 data);
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+			    u16 data);
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len);
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len);
 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
 static void atmel_smooth_qual(struct atmel_private *priv);
@@ -650,12 +648,12 @@
 	return priv->host_info.command_pos + offset;
 }
 
-static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
 {
 	return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
 }
 
-static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
 {
 	return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
 }
@@ -682,25 +680,25 @@
 
 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
 {
-	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	return atmel_read8(priv->dev, DR);
 }
 
 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
 {
-	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write8(priv->dev, DR, data);
 }
 
 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	return atmel_read16(priv->dev, DR);
 }
 
 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write16(priv->dev, DR, data);
 }
 
@@ -710,11 +708,10 @@
 {
 	int i;
 
-	for (i = 0; 
+	for (i = 0;
 	     atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
 		     i < priv->host_info.tx_desc_count;
 	     i++) {
-		
 		u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
 		u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
 		u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
@@ -728,16 +725,16 @@
 			priv->tx_buff_head = 0;
 		else
 			priv->tx_buff_head += msdu_size;
-			
+
 		if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
-			priv->tx_desc_head++ ;					
+			priv->tx_desc_head++ ;
 		else
 			priv->tx_desc_head = 0;
-		
+
 		if (type == TX_PACKET_TYPE_DATA) {
 			if (status == TX_STATUS_SUCCESS)
 				priv->stats.tx_packets++;
-			else 
+			else
 				priv->stats.tx_errors++;
 			netif_wake_queue(priv->dev);
 		}
@@ -748,21 +745,22 @@
 {
 	u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
 
-	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) 
+	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
 		return 0;
-	
+
 	if (bottom_free >= len)
 		return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
-	
+
 	if (priv->tx_free_mem - bottom_free >= len) {
 		priv->tx_buff_tail = 0;
 		return priv->host_info.tx_buff_pos;
 	}
-	
+
 	return 0;
 }
 
-static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 len, u16 buff, u8 type)
+static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
+				 u16 len, u16 buff, u8 type)
 {
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
@@ -775,8 +773,8 @@
 		int cipher_type, cipher_length;
 		if (is_bcast) {
 			cipher_type = priv->group_cipher_suite;
-			if (cipher_type == CIPHER_SUITE_WEP_64 || 
-			    cipher_type == CIPHER_SUITE_WEP_128 )
+			if (cipher_type == CIPHER_SUITE_WEP_64 ||
+			    cipher_type == CIPHER_SUITE_WEP_128)
 				cipher_length = 8;
 			else if (cipher_type == CIPHER_SUITE_TKIP)
 				cipher_length = 12;
@@ -790,8 +788,8 @@
 			}
 		} else {
 			cipher_type = priv->pairwise_cipher_suite;
-			if (cipher_type == CIPHER_SUITE_WEP_64 || 
-			    cipher_type == CIPHER_SUITE_WEP_128 )
+			if (cipher_type == CIPHER_SUITE_WEP_64 ||
+			    cipher_type == CIPHER_SUITE_WEP_128)
 				cipher_length = 8;
 			else if (cipher_type == CIPHER_SUITE_TKIP)
 				cipher_length = 12;
@@ -804,9 +802,9 @@
 				cipher_length = 0;
 			}
 		}
-		
+
 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
-			    cipher_type);	
+			    cipher_type);
 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
 			    cipher_length);
 	}
@@ -815,46 +813,46 @@
 	if (priv->tx_desc_previous != priv->tx_desc_tail)
 		atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
 	priv->tx_desc_previous = priv->tx_desc_tail;
-	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -1 ))
+	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
 		priv->tx_desc_tail++;
 	else
 		priv->tx_desc_tail = 0;
 	priv->tx_desc_free--;
 	priv->tx_free_mem -= len;
-
 }
 
-static int start_tx (struct sk_buff *skb, struct net_device *dev)
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	struct ieee80211_hdr_4addr header;
 	unsigned long flags;
 	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
 	u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
- 
-	if (priv->card && priv->present_callback && 
+
+	if (priv->card && priv->present_callback &&
 	    !(*priv->present_callback)(priv->card)) {
 		priv->stats.tx_errors++;
 		dev_kfree_skb(skb);
 		return 0;
 	}
-	
+
 	if (priv->station_state != STATION_STATE_READY) {
 		priv->stats.tx_errors++;
 		dev_kfree_skb(skb);
 		return 0;
 	}
-	
+
 	/* first ensure the timer func cannot run */
-	spin_lock_bh(&priv->timerlock); 
+	spin_lock_bh(&priv->timerlock);
 	/* then stop the hardware ISR */
-	spin_lock_irqsave(&priv->irqlock, flags); 
+	spin_lock_irqsave(&priv->irqlock, flags);
 	/* nb doing the above in the opposite order will deadlock */
-	
+
 	/* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
-	   12 first bytes (containing DA/SA) and put them in the appropriate fields of
-	   the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
-	
+	   12 first bytes (containing DA/SA) and put them in the appropriate
+	   fields of the Wireless Header. Thus the packet length is then the
+	   initial + 18 (+30-12) */
+
 	if (!(buff = find_tx_buff(priv, len + 18))) {
 		priv->stats.tx_dropped++;
 		spin_unlock_irqrestore(&priv->irqlock, flags);
@@ -862,7 +860,7 @@
 		netif_stop_queue(dev);
 		return 1;
 	}
-	
+
 	frame_ctl = IEEE80211_FTYPE_DATA;
 	header.duration_id = 0;
 	header.seq_ctl = 0;
@@ -878,7 +876,7 @@
 		memcpy(&header.addr2, dev->dev_addr, 6);
 		memcpy(&header.addr3, skb->data, 6);
 	}
-	
+
 	if (priv->use_wpa)
 		memcpy(&header.addr4, SNAP_RFC1024, 6);
 
@@ -888,27 +886,27 @@
 	/* Copy the packet sans its 802.3 header addresses which have been replaced */
 	atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
 	priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
-	
+
 	/* low bit of first byte of destination tells us if broadcast */
 	tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
 	dev->trans_start = jiffies;
 	priv->stats.tx_bytes += len;
-	
+
 	spin_unlock_irqrestore(&priv->irqlock, flags);
 	spin_unlock_bh(&priv->timerlock);
 	dev_kfree_skb(skb);
-	
-	return 0;	
+
+	return 0;
 }
 
-static void atmel_transmit_management_frame(struct atmel_private *priv, 
+static void atmel_transmit_management_frame(struct atmel_private *priv,
 					    struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len)
 {
 	u16 buff;
-	int len =  MGMT_FRAME_BODY_OFFSET + body_len;
-	
-	if (!(buff = find_tx_buff(priv, len))) 
+	int len = MGMT_FRAME_BODY_OFFSET + body_len;
+
+	if (!(buff = find_tx_buff(priv, len)))
 		return;
 
 	atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
@@ -916,24 +914,25 @@
 	priv->tx_buff_tail += len;
 	tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
 }
-	
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+
+static void fast_rx_path(struct atmel_private *priv,
+			 struct ieee80211_hdr_4addr *header,
 			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
 	/* fast path: unfragmented packet copy directly into skbuf */
-	u8 mac4[6]; 
-	struct sk_buff 	*skb;
+	u8 mac4[6];
+	struct sk_buff	*skb;
 	unsigned char *skbp;
-	
+
 	/* get the final, mac 4 header field, this tells us encapsulation */
 	atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
 	msdu_size -= 6;
-	
+
 	if (priv->do_rx_crc) {
 		crc = crc32_le(crc, mac4, 6);
 		msdu_size -= 4;
 	}
-	
+
 	if (!(skb = dev_alloc_skb(msdu_size + 14))) {
 		priv->stats.rx_dropped++;
 		return;
@@ -942,7 +941,7 @@
 	skb_reserve(skb, 2);
 	skbp = skb_put(skb, msdu_size + 12);
 	atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
-	
+
 	if (priv->do_rx_crc) {
 		u32 netcrc;
 		crc = crc32_le(crc, skbp + 12, msdu_size);
@@ -953,24 +952,25 @@
 			return;
 		}
 	}
-	
+
 	memcpy(skbp, header->addr1, 6); /* destination address */
-	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		memcpy(&skbp[6], header->addr3, 6);
 	else
 		memcpy(&skbp[6], header->addr2, 6); /* source address */
-	
-	priv->dev->last_rx=jiffies;
+
+	priv->dev->last_rx = jiffies;
 	skb->dev = priv->dev;
 	skb->protocol = eth_type_trans(skb, priv->dev);
-	skb->ip_summed = CHECKSUM_NONE;	
+	skb->ip_summed = CHECKSUM_NONE;
 	netif_rx(skb);
 	priv->stats.rx_bytes += 12 + msdu_size;
 	priv->stats.rx_packets++;
 }
 
 /* Test to see if the packet in card memory at packet_loc has a valid CRC
-   It doesn't matter that this is slow: it is only used to proble the first few packets. */
+   It doesn't matter that this is slow: it is only used to proble the first few
+   packets. */
 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
 {
 	int i = msdu_size - 4;
@@ -980,7 +980,7 @@
 		return 0;
 
 	atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
-	
+
 	atmel_writeAR(priv->dev, packet_loc);
 	while (i--) {
 		u8 octet = atmel_read8(priv->dev, DR);
@@ -990,20 +990,22 @@
 	return (crc ^ 0xffffffff) == netcrc;
 }
 
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
+static void frag_rx_path(struct atmel_private *priv,
+			 struct ieee80211_hdr_4addr *header,
+			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
+			 u8 frag_no, int more_frags)
 {
-	u8 mac4[6]; 
+	u8 mac4[6];
 	u8 source[6];
 	struct sk_buff *skb;
 
-	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		memcpy(source, header->addr3, 6);
 	else
-		memcpy(source, header->addr2, 6); 
-	
+		memcpy(source, header->addr2, 6);
+
 	rx_packet_loc += 24; /* skip header */
-	
+
 	if (priv->do_rx_crc)
 		msdu_size -= 4;
 
@@ -1012,16 +1014,16 @@
 		msdu_size -= 6;
 		rx_packet_loc += 6;
 
-		if (priv->do_rx_crc) 
+		if (priv->do_rx_crc)
 			crc = crc32_le(crc, mac4, 6);
-	       
+
 		priv->frag_seq = seq_no;
 		priv->frag_no = 1;
 		priv->frag_len = msdu_size;
-		memcpy(priv->frag_source, source, 6); 
+		memcpy(priv->frag_source, source, 6);
 		memcpy(&priv->rx_buf[6], source, 6);
 		memcpy(priv->rx_buf, header->addr1, 6);
-				
+
 		atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
 
 		if (priv->do_rx_crc) {
@@ -1033,17 +1035,17 @@
 				memset(priv->frag_source, 0xff, 6);
 			}
 		}
-		
+
 	} else if (priv->frag_no == frag_no &&
 		   priv->frag_seq == seq_no &&
 		   memcmp(priv->frag_source, source, 6) == 0) {
-		
-		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], 
+
+		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
 				   rx_packet_loc, msdu_size);
 		if (priv->do_rx_crc) {
 			u32 netcrc;
-			crc = crc32_le(crc, 
-				       &priv->rx_buf[12 + priv->frag_len], 
+			crc = crc32_le(crc,
+				       &priv->rx_buf[12 + priv->frag_len],
 				       msdu_size);
 			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
 			if ((crc ^ 0xffffffff) != netcrc) {
@@ -1052,7 +1054,7 @@
 				more_frags = 1; /* don't send broken assembly */
 			}
 		}
-		
+
 		priv->frag_len += msdu_size;
 		priv->frag_no++;
 
@@ -1062,60 +1064,60 @@
 				priv->stats.rx_dropped++;
 			} else {
 				skb_reserve(skb, 2);
-				memcpy(skb_put(skb, priv->frag_len + 12), 
+				memcpy(skb_put(skb, priv->frag_len + 12),
 				       priv->rx_buf,
 				       priv->frag_len + 12);
 				priv->dev->last_rx = jiffies;
 				skb->dev = priv->dev;
 				skb->protocol = eth_type_trans(skb, priv->dev);
-				skb->ip_summed = CHECKSUM_NONE;	
+				skb->ip_summed = CHECKSUM_NONE;
 				netif_rx(skb);
 				priv->stats.rx_bytes += priv->frag_len + 12;
 				priv->stats.rx_packets++;
 			}
 		}
-		
 	} else
 		priv->wstats.discard.fragment++;
 }
-		
+
 static void rx_done_irq(struct atmel_private *priv)
 {
 	int i;
 	struct ieee80211_hdr_4addr header;
-	
-	for (i = 0; 
+
+	for (i = 0;
 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
 		     i < priv->host_info.rx_desc_count;
 	     i++) {
-				
+
 		u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
 		u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
 		u32 crc = 0xffffffff;
-		
+
 		if (status != RX_STATUS_SUCCESS) {
 			if (status == 0xc1) /* determined by experiment */
 				priv->wstats.discard.nwid++;
 			else
-				priv->stats.rx_errors++; 
+				priv->stats.rx_errors++;
 			goto next;
 		}
 
 		msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
 		rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
-		
+
 		if (msdu_size < 30) {
-			priv->stats.rx_errors++; 
+			priv->stats.rx_errors++;
 			goto next;
 		}
-		
+
 		/* Get header as far as end of seq_ctl */
 		atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
 		frame_ctl = le16_to_cpu(header.frame_ctl);
 		seq_control = le16_to_cpu(header.seq_ctl);
 
-		/* probe for CRC use here if needed  once five packets have arrived with
-		   the same crc status, we assume we know what's happening and stop probing */
+		/* probe for CRC use here if needed  once five packets have
+		   arrived with the same crc status, we assume we know what's
+		   happening and stop probing */
 		if (priv->probe_crc) {
 			if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
@@ -1130,34 +1132,33 @@
 					priv->probe_crc = 0;
 			}
 		}
-		    
+
 		/* don't CRC header when WEP in use */
 		if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
 			crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
 		}
 		msdu_size -= 24; /* header */
 
-		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { 
-			
+		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
 			int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
 			u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
 			u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
-			
-			if (!more_fragments && packet_fragment_no == 0 ) {
+
+			if (!more_fragments && packet_fragment_no == 0) {
 				fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
 			} else {
 				frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
 					     packet_sequence_no, packet_fragment_no, more_fragments);
 			}
 		}
-		
+
 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
 			/* copy rest of packet into buffer */
 			atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
-			
+
 			/* we use the same buffer for frag reassembly and control packets */
 			memset(priv->frag_source, 0xff, 6);
-			
+
 			if (priv->do_rx_crc) {
 				/* last 4 octets is crc */
 				msdu_size -= 4;
@@ -1170,18 +1171,18 @@
 
 			atmel_management_frame(priv, &header, msdu_size,
 					       atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
-		} 
+		}
 
-	next:
+next:
 		/* release descriptor */
-		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);  
-		
+		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
+
 		if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
-			priv->rx_desc_head++;					
+			priv->rx_desc_head++;
 		else
 			priv->rx_desc_head = 0;
 	}
-}	
+}
 
 static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1189,7 +1190,7 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	u8 isr;
 	int i = -1;
-	static u8 irq_order[] = { 
+	static u8 irq_order[] = {
 		ISR_OUT_OF_RANGE,
 		ISR_RxCOMPLETE,
 		ISR_TxCOMPLETE,
@@ -1199,20 +1200,19 @@
 		ISR_IBSS_MERGE,
 		ISR_GENERIC_IRQ
 	};
-		
 
-	if (priv->card && priv->present_callback && 
+	if (priv->card && priv->present_callback &&
 	    !(*priv->present_callback)(priv->card))
 		return IRQ_HANDLED;
 
 	/* In this state upper-level code assumes it can mess with
 	   the card unhampered by interrupts which may change register state.
 	   Note that even though the card shouldn't generate interrupts
-	   the inturrupt line may be shared. This allows card setup 
+	   the inturrupt line may be shared. This allows card setup
 	   to go on without disabling interrupts for a long time. */
 	if (priv->station_state == STATION_STATE_DOWN)
 		return IRQ_NONE;
-     	
+
 	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
 
 	while (1) {
@@ -1221,36 +1221,36 @@
 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
 			return IRQ_HANDLED;
 		}
-		
+
 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		
+
 		if (!isr) {
 			atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
 			return i == -1 ? IRQ_NONE : IRQ_HANDLED;
 		}
-		
+
 		atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
-		
+
 		for (i = 0; i < sizeof(irq_order)/sizeof(u8); i++)
 			if (isr & irq_order[i])
 				break;
-		
+
 		if (!atmel_lock_mac(priv)) {
 			/* failed to contact card */
 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
 			return IRQ_HANDLED;
 		}
-		
+
 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
 		isr ^= irq_order[i];
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		
+
 		switch (irq_order[i]) {
-			
-		case ISR_OUT_OF_RANGE: 
-			if (priv->operating_mode == IW_MODE_INFRA && 
+
+		case ISR_OUT_OF_RANGE:
+			if (priv->operating_mode == IW_MODE_INFRA &&
 			    priv->station_state == STATION_STATE_READY) {
 				priv->station_is_associated = 0;
 				atmel_scan(priv, 1);
@@ -1261,24 +1261,24 @@
 			priv->wstats.discard.misc++;
 			/* fall through */
 		case ISR_RxCOMPLETE:
-			rx_done_irq(priv); 
+			rx_done_irq(priv);
 			break;
-			
+
 		case ISR_TxCOMPLETE:
-			tx_done_irq(priv); 
+			tx_done_irq(priv);
 			break;
-			
+
 		case ISR_FATAL_ERROR:
 			printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 			break;
-			
-		case ISR_COMMAND_COMPLETE: 
+
+		case ISR_COMMAND_COMPLETE:
 			atmel_command_irq(priv);
 			break;
 
 		case ISR_IBSS_MERGE:
-			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 
+			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
 				      priv->CurrentBSSID, 6);
 			/* The WPA stuff cares about the current AP address */
 			if (priv->use_wpa)
@@ -1288,24 +1288,23 @@
 			printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
 			break;
 		}
-	}	
+	}
 }
 
-
-static struct net_device_stats *atmel_get_stats (struct net_device *dev)
+static struct net_device_stats *atmel_get_stats(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	return &priv->stats;
 }
 
-static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
+static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 
-	/* update the link quality here in case we are seeing no beacons 
+	/* update the link quality here in case we are seeing no beacons
 	   at all to drive the process */
 	atmel_smooth_qual(priv);
-	
+
 	priv->wstats.status = priv->station_state;
 
 	if (priv->operating_mode == IW_MODE_INFRA) {
@@ -1328,8 +1327,8 @@
 					| IW_QUAL_NOISE_INVALID;
 		priv->wstats.miss.beacon = 0;
 	}
-	
-	return (&priv->wstats);
+
+	return &priv->wstats;
 }
 
 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
@@ -1343,21 +1342,21 @@
 static int atmel_set_mac_address(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
-        
+
         memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
 	return atmel_open(dev);
 }
 
 EXPORT_SYMBOL(atmel_open);
 
-int atmel_open (struct net_device *dev)
+int atmel_open(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int i, channel;
 
 	/* any scheduled timer is no longer needed and might screw things up.. */
 	del_timer_sync(&priv->management_timer);
-	
+
 	/* Interrupts will not touch the card once in this state... */
 	priv->station_state = STATION_STATE_DOWN;
 
@@ -1377,7 +1376,7 @@
 	priv->site_survey_state = SITE_SURVEY_IDLE;
 	priv->station_is_associated = 0;
 
-	if (!reset_atmel_card(dev)) 
+	if (!reset_atmel_card(dev))
 		return -EAGAIN;
 
 	if (priv->config_reg_domain) {
@@ -1391,26 +1390,26 @@
 		if (i == sizeof(channel_table)/sizeof(channel_table[0])) {
 			priv->reg_domain = REG_DOMAIN_MKK1;
 			printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
-		} 
+		}
 	}
-	
+
 	if ((channel = atmel_validate_channel(priv, priv->channel)))
 		priv->channel = channel;
 
-	/* this moves station_state on.... */ 
-	atmel_scan(priv, 1);	
+	/* this moves station_state on.... */
+	atmel_scan(priv, 1);
 
 	atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
 	return 0;
 }
 
-static int atmel_close (struct net_device *dev)
+static int atmel_close(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-		
+
 	atmel_enter_state(priv, STATION_STATE_DOWN);
-	
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
 	atmel_write16(dev, GCR, 0x0040);
 	return 0;
@@ -1438,43 +1437,46 @@
 	int i;
 	char *p = buf;
 	char *s, *r, *c;
-	
-	p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
-	
+
+	p += sprintf(p, "Driver version:\t\t%d.%d\n",
+		     DRIVER_MAJOR, DRIVER_MINOR);
+
 	if (priv->station_state != STATION_STATE_DOWN) {
-		p += sprintf(p, "Firmware version:\t%d.%d build %d\nFirmware location:\t", 
+		p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
+				"Firmware location:\t",
 			     priv->host_info.major_version,
 			     priv->host_info.minor_version,
 			     priv->host_info.build_version);
-		
-		if (priv->card_type != CARD_TYPE_EEPROM) 
+
+		if (priv->card_type != CARD_TYPE_EEPROM)
 			p += sprintf(p, "on card\n");
-		else if (priv->firmware) 
-			p += sprintf(p, "%s loaded by host\n", priv->firmware_id);
+		else if (priv->firmware)
+			p += sprintf(p, "%s loaded by host\n",
+				     priv->firmware_id);
 		else
-			p += sprintf(p, "%s loaded by hotplug\n", priv->firmware_id);
-		
-		switch(priv->card_type) {
+			p += sprintf(p, "%s loaded by hotplug\n",
+				     priv->firmware_id);
+
+		switch (priv->card_type) {
 		case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
 		case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
 		case CARD_TYPE_EEPROM: c = "EEPROM"; break;
 		default: c = "<unknown>";
 		}
 
-		
 		r = "<unknown>";
 		for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
 			if (priv->reg_domain == channel_table[i].reg_domain)
 				r = channel_table[i].name;
-		
+
 		p += sprintf(p, "MAC memory type:\t%s\n", c);
 		p += sprintf(p, "Regulatory domain:\t%s\n", r);
-		p += sprintf(p, "Host CRC checking:\t%s\n", 
+		p += sprintf(p, "Host CRC checking:\t%s\n",
 			     priv->do_rx_crc ? "On" : "Off");
 		p += sprintf(p, "WPA-capable firmware:\t%s\n",
 			     priv->use_wpa ? "Yes" : "No");
 	}
-	
+
 	switch(priv->station_state) {
 	case STATION_STATE_SCANNING: s = "Scanning"; break;
 	case STATION_STATE_JOINNING: s = "Joining"; break;
@@ -1486,9 +1488,9 @@
 	case STATION_STATE_DOWN: s = "Down"; break;
 	default: s = "<unknown>";
 	}
-      
+
 	p += sprintf(p, "Current state:\t\t%s\n", s);
-	return  p - buf;
+	return p - buf;
 }
 
 static int atmel_read_proc(char *page, char **start, off_t off,
@@ -1504,9 +1506,12 @@
         return len;
 }
 
-struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,  
-				    struct device *sys_dev, int (*card_present)(void *), void *card)
+struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
+				   const AtmelFWType fw_type,
+				   struct device *sys_dev,
+				   int (*card_present)(void *), void *card)
 {
+	struct proc_dir_entry *ent;
 	struct net_device *dev;
 	struct atmel_private *priv;
 	int rc;
@@ -1514,11 +1519,11 @@
 	/* Create the network device object. */
         dev = alloc_etherdev(sizeof(*priv));
         if (!dev) {
-		printk(KERN_ERR "atmel:  Couldn't alloc_etherdev\n");
+		printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
 		return NULL;
         }
 	if (dev_alloc_name(dev, dev->name) < 0) {
-		printk(KERN_ERR "atmel:  Couldn't get name!\n");
+		printk(KERN_ERR "atmel: Couldn't get name!\n");
 		goto err_out_free;
 	}
 
@@ -1550,7 +1555,7 @@
 	memset(priv->BSSID, 0, 6);
 	priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
 	priv->station_was_associated = 0;
-	
+
 	priv->last_survey = jiffies;
 	priv->preamble = LONG_PREAMBLE;
 	priv->operating_mode = IW_MODE_INFRA;
@@ -1586,7 +1591,7 @@
 	spin_lock_init(&priv->timerlock);
 	priv->management_timer.function = atmel_management_timer;
 	priv->management_timer.data = (unsigned long) dev;
-	
+
 	dev->open = atmel_open;
 	dev->stop = atmel_close;
 	dev->change_mtu = atmel_change_mtu;
@@ -1597,44 +1602,46 @@
 	dev->do_ioctl = atmel_ioctl;
 	dev->irq = irq;
 	dev->base_addr = port;
-	
+
 	SET_NETDEV_DEV(dev, sys_dev);
-	
+
 	if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
-		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
+		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
 		goto err_out_free;
 	}
 
-	if (!request_region(dev->base_addr, 32, 
+	if (!request_region(dev->base_addr, 32,
 			    priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
 		goto err_out_irq;
 	}
-	
+
 	if (register_netdev(dev))
 		goto err_out_res;
-	
+
 	if (!probe_atmel_card(dev)){
 		unregister_netdev(dev);
 		goto err_out_res;
 	}
-	
+
 	netif_carrier_off(dev);
-	
-	create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);	
-	
+
+	ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
+	if (!ent)
+		printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
+
 	printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
 	       dev->name, DRIVER_MAJOR, DRIVER_MINOR,
 	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
-	
+
 	SET_MODULE_OWNER(dev);
 	return dev;
-	
- err_out_res:
+
+err_out_res:
 	release_region( dev->base_addr, 32);
- err_out_irq:
+err_out_irq:
 	free_irq(dev->irq, dev);
- err_out_free:
+err_out_free:
 	free_netdev(dev);
 	return NULL;
 }
@@ -1644,12 +1651,12 @@
 void stop_atmel_card(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-		
+
 	/* put a brick on it... */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
 	atmel_write16(dev, GCR, 0x0040);
-	
+
 	del_timer_sync(&priv->management_timer);
 	unregister_netdev(dev);
 	remove_proc_entry("driver/atmel", NULL);
@@ -1675,13 +1682,13 @@
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
 		priv->connect_to_any_BSS = 0;
-		
+
 		/* Check the size of the string */
 		if (dwrq->length > MAX_SSID_LENGTH + 1)
-			 return -E2BIG ;
+			 return -E2BIG;
 		if (index != 0)
 			return -EINVAL;
-		
+
 		memcpy(priv->new_SSID, extra, dwrq->length - 1);
 		priv->new_SSID_size = dwrq->length - 1;
 	}
@@ -1706,7 +1713,7 @@
 		extra[priv->SSID_size] = '\0';
 		dwrq->length = priv->SSID_size + 1;
 	}
-	
+
 	dwrq->flags = !priv->connect_to_any_BSS; /* active */
 
 	return 0;
@@ -1768,7 +1775,7 @@
 		/* WE specify that if a valid key is set, encryption
 		 * should be enabled (user may turn it off later)
 		 * This is also how "iwconfig ethX key on" works */
-		if (index == current_index && 
+		if (index == current_index &&
 		    priv->wep_key_len[index] > 0) {
 			priv->wep_is_on = 1;
 			priv->exclude_unencrypted = 1;
@@ -1783,18 +1790,18 @@
 	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-		if ( index>=0 && index < 4 ) {
+		if (index >= 0 && index < 4) {
 			priv->default_key = index;
 		} else
 			/* Don't complain if only change the mode */
-			if(!dwrq->flags & IW_ENCODE_MODE) {
+			if (!dwrq->flags & IW_ENCODE_MODE) {
 				return -EINVAL;
 			}
 	}
 	/* Read the flags */
-	if(dwrq->flags & IW_ENCODE_DISABLED) {
+	if (dwrq->flags & IW_ENCODE_DISABLED) {
 		priv->wep_is_on = 0;
-		priv->encryption_level = 0; 	
+		priv->encryption_level = 0;
 		priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
 	} else {
 		priv->wep_is_on = 1;
@@ -1806,15 +1813,14 @@
 			priv->encryption_level = 1;
 		}
 	}
-	if(dwrq->flags & IW_ENCODE_RESTRICTED)
+	if (dwrq->flags & IW_ENCODE_RESTRICTED)
 		priv->exclude_unencrypted = 1;
-       	if(dwrq->flags & IW_ENCODE_OPEN) 
+	if(dwrq->flags & IW_ENCODE_OPEN)
 		priv->exclude_unencrypted = 0;
-       
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
-
 static int atmel_get_encode(struct net_device *dev,
 			    struct iw_request_info *info,
 			    struct iw_point *dwrq,
@@ -1822,7 +1828,7 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-	
+
 	if (!priv->wep_is_on)
 		dwrq->flags = IW_ENCODE_DISABLED;
 	else {
@@ -1843,7 +1849,7 @@
 		memset(extra, 0, 16);
 		memcpy(extra, priv->wep_keys[index], dwrq->length);
 	}
-	
+
 	return 0;
 }
 
@@ -1862,17 +1868,17 @@
 			  char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	if (vwrq->fixed == 0) {
 		priv->tx_rate = 3;
 		priv->auto_tx_rate = 1;
 	} else {
 		priv->auto_tx_rate = 0;
-		
+
 		/* Which type of value ? */
-		if((vwrq->value < 4) && (vwrq->value >= 0)) {
+		if ((vwrq->value < 4) && (vwrq->value >= 0)) {
 			/* Setting by rate index */
-		priv->tx_rate = vwrq->value;
+			priv->tx_rate = vwrq->value;
 		} else {
 		/* Setting by frequency value */
 			switch (vwrq->value) {
@@ -1899,7 +1905,7 @@
 		return -EINVAL;
 
 	priv->operating_mode = *uwrq;
-	return -EINPROGRESS;  
+	return -EINPROGRESS;
 }
 
 static int atmel_get_mode(struct net_device *dev,
@@ -1908,7 +1914,7 @@
 			  char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	*uwrq = priv->operating_mode;
 	return 0;
 }
@@ -1962,9 +1968,9 @@
 			   char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
-	if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
-		if(vwrq->flags & IW_RETRY_MAX)
+
+	if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
+		if (vwrq->flags & IW_RETRY_MAX)
 			priv->long_retry = vwrq->value;
 		else if (vwrq->flags & IW_RETRY_MIN)
 			priv->short_retry = vwrq->value;
@@ -1973,9 +1979,9 @@
 			priv->long_retry = vwrq->value;
 			priv->short_retry = vwrq->value;
 		}
-		return -EINPROGRESS;		
+		return -EINPROGRESS;
 	}
-	   
+
 	return -EINVAL;
 }
 
@@ -1989,13 +1995,13 @@
 	vwrq->disabled = 0;      /* Can't be disabled */
 
 	/* Note : by default, display the min retry number */
-	if((vwrq->flags & IW_RETRY_MAX)) {
+	if (vwrq->flags & IW_RETRY_MAX) {
 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 		vwrq->value = priv->long_retry;
 	} else {
 		vwrq->flags = IW_RETRY_LIMIT;
 		vwrq->value = priv->short_retry;
-		if(priv->long_retry != priv->short_retry)
+		if (priv->long_retry != priv->short_retry)
 			vwrq->flags |= IW_RETRY_MIN;
 	}
 
@@ -2010,13 +2016,13 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	int rthr = vwrq->value;
 
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		rthr = 2347;
-	if((rthr < 0) || (rthr > 2347)) {
+	if ((rthr < 0) || (rthr > 2347)) {
 		return -EINVAL;
 	}
 	priv->rts_threshold = rthr;
-	
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
@@ -2026,7 +2032,7 @@
 			 char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	vwrq->value = priv->rts_threshold;
 	vwrq->disabled = (vwrq->value >= 2347);
 	vwrq->fixed = 1;
@@ -2042,14 +2048,14 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	int fthr = vwrq->value;
 
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		fthr = 2346;
-	if((fthr < 256) || (fthr > 2346)) {
+	if ((fthr < 256) || (fthr > 2346)) {
 		return -EINVAL;
 	}
 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
 	priv->frag_threshold = fthr;
-	
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
@@ -2077,21 +2083,21 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int rc = -EINPROGRESS;		/* Call commit handler */
-	
+
 	/* If setting by frequency, convert to a channel */
-	if((fwrq->e == 1) &&
-	   (fwrq->m >= (int) 241200000) &&
-	   (fwrq->m <= (int) 248700000)) {
+	if ((fwrq->e == 1) &&
+	    (fwrq->m >= (int) 241200000) &&
+	    (fwrq->m <= (int) 248700000)) {
 		int f = fwrq->m / 100000;
 		int c = 0;
-		while((c < 14) && (f != frequency_list[c]))
+		while ((c < 14) && (f != frequency_list[c]))
 			c++;
 		/* Hack to fall through... */
 		fwrq->e = 0;
 		fwrq->m = c + 1;
 	}
 	/* Setting by channel number */
-	if((fwrq->m > 1000) || (fwrq->e > 0))
+	if ((fwrq->m > 1000) || (fwrq->e > 0))
 		rc = -EOPNOTSUPP;
 	else {
 		int channel = fwrq->m;
@@ -2099,7 +2105,7 @@
 			priv->channel = channel;
 		} else {
 			rc = -EINVAL;
-		} 
+		}
 	}
 	return rc;
 }
@@ -2130,7 +2136,7 @@
 	 * This is not an error, while the device perform scanning,
 	 * traffic doesn't flow, so it's a perfect DoS...
 	 * Jean II */
-	
+
 	if (priv->station_state == STATION_STATE_DOWN)
 		return -EAGAIN;
 
@@ -2142,15 +2148,15 @@
 	/* Initiate a scan command */
 	if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
 		return -EBUSY;
-		
+
 	del_timer_sync(&priv->management_timer);
 	spin_lock_irqsave(&priv->irqlock, flags);
-	
+
 	priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
 	priv->fast_scan = 0;
 	atmel_scan(priv, 0);
 	spin_unlock_irqrestore(&priv->irqlock, flags);
-	
+
 	return 0;
 }
 
@@ -2163,11 +2169,11 @@
 	int i;
 	char *current_ev = extra;
 	struct iw_event	iwe;
-	
+
 	if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
 		return -EAGAIN;
-	
-	for(i=0; i<priv->BSS_list_entries; i++) { 
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		iwe.cmd = SIOCGIWAP;
 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 		memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
@@ -2179,16 +2185,16 @@
 		iwe.cmd = SIOCGIWESSID;
 		iwe.u.data.flags = 1;
 		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
-		
+
 		iwe.cmd = SIOCGIWMODE;
 		iwe.u.mode = priv->BSSinfo[i].BSStype;
 		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
-	
+
 		iwe.cmd = SIOCGIWFREQ;
 		iwe.u.freq.m = priv->BSSinfo[i].channel;
 		iwe.u.freq.e = 0;
 		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
-		
+
 		iwe.cmd = SIOCGIWENCODE;
 		if (priv->BSSinfo[i].UsingWEP)
 			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -2196,13 +2202,12 @@
 			iwe.u.data.flags = IW_ENCODE_DISABLED;
 		iwe.u.data.length = 0;
 		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
-		
 	}
 
 	/* Length of data */
 	dwrq->length = (current_ev - extra);
-	dwrq->flags = 0;   
-	
+	dwrq->flags = 0;
+
 	return 0;
 }
 
@@ -2213,7 +2218,7 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	struct iw_range *range = (struct iw_range *) extra;
-	int k,i,j;
+	int k, i, j;
 
 	dwrq->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(struct iw_range));
@@ -2226,14 +2231,14 @@
 			break;
 		}
 	if (range->num_channels != 0) {
-		for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
+		for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
 			range->freq[k].i = i; /* List index */
-			range->freq[k].m = frequency_list[i-1] * 100000;
+			range->freq[k].m = frequency_list[i - 1] * 100000;
 			range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
 		}
 		range->num_frequency = k;
 	}
-	
+
 	range->max_qual.qual = 100;
 	range->max_qual.level = 100;
 	range->max_qual.noise = 0;
@@ -2261,11 +2266,11 @@
 	range->encoding_size[1] = 13;
 	range->num_encoding_sizes = 2;
 	range->max_encoding_tokens = 4;
-	
+
 	range->pmp_flags = IW_POWER_ON;
 	range->pmt_flags = IW_POWER_ON;
 	range->pm_capa = 0;
-	
+
 	range->we_version_source = WIRELESS_EXT;
 	range->we_version_compiled = WIRELESS_EXT;
 	range->retry_capa = IW_RETRY_LIMIT ;
@@ -2289,7 +2294,7 @@
 
 	if (awrq->sa_family != ARPHRD_ETHER)
 		return -EINVAL;
-	
+
 	if (memcmp(bcast, awrq->sa_data, 6) == 0) {
 		del_timer_sync(&priv->management_timer);
 		spin_lock_irqsave(&priv->irqlock, flags);
@@ -2297,8 +2302,8 @@
 		spin_unlock_irqrestore(&priv->irqlock, flags);
 		return 0;
 	}
-	
-	for(i=0; i<priv->BSS_list_entries; i++) {
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
 			if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
 				return -EINVAL;
@@ -2313,10 +2318,10 @@
 			}
 		}
 	}
-		
+
 	return -EINVAL;
 }
-	
+
 static int atmel_config_commit(struct net_device *dev,
 			       struct iw_request_info *info,	/* NULL */
 			       void *zwrq,			/* NULL */
@@ -2325,18 +2330,18 @@
 	return atmel_open(dev);
 }
 
-static const iw_handler		atmel_handler[] =
+static const iw_handler atmel_handler[] =
 {
 	(iw_handler) atmel_config_commit,	/* SIOCSIWCOMMIT */
-	(iw_handler) atmel_get_name,    	/* SIOCGIWNAME */
+	(iw_handler) atmel_get_name,		/* SIOCGIWNAME */
 	(iw_handler) NULL,			/* SIOCSIWNWID */
 	(iw_handler) NULL,			/* SIOCGIWNWID */
 	(iw_handler) atmel_set_freq,		/* SIOCSIWFREQ */
 	(iw_handler) atmel_get_freq,		/* SIOCGIWFREQ */
 	(iw_handler) atmel_set_mode,		/* SIOCSIWMODE */
 	(iw_handler) atmel_get_mode,		/* SIOCGIWMODE */
-	(iw_handler) NULL,                  	/* SIOCSIWSENS */
-	(iw_handler) NULL,           		/* SIOCGIWSENS */
+	(iw_handler) NULL,			/* SIOCSIWSENS */
+	(iw_handler) NULL,			/* SIOCGIWSENS */
 	(iw_handler) NULL,			/* SIOCSIWRANGE */
 	(iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
 	(iw_handler) NULL,			/* SIOCSIWPRIV */
@@ -2350,13 +2355,13 @@
 	(iw_handler) atmel_set_wap,		/* SIOCSIWAP */
 	(iw_handler) atmel_get_wap,		/* SIOCGIWAP */
 	(iw_handler) NULL,			/* -- hole -- */
-	(iw_handler) NULL,       		/* SIOCGIWAPLIST */
+	(iw_handler) NULL,			/* SIOCGIWAPLIST */
 	(iw_handler) atmel_set_scan,		/* SIOCSIWSCAN */
 	(iw_handler) atmel_get_scan,		/* SIOCGIWSCAN */
 	(iw_handler) atmel_set_essid,		/* SIOCSIWESSID */
 	(iw_handler) atmel_get_essid,		/* SIOCGIWESSID */
-	(iw_handler) NULL,         		/* SIOCSIWNICKN */
-	(iw_handler) NULL,          		/* SIOCGIWNICKN */
+	(iw_handler) NULL,			/* SIOCSIWNICKN */
+	(iw_handler) NULL,			/* SIOCGIWNICKN */
 	(iw_handler) NULL,			/* -- hole -- */
 	(iw_handler) NULL,			/* -- hole -- */
 	(iw_handler) atmel_set_rate,		/* SIOCSIWRATE */
@@ -2365,8 +2370,8 @@
 	(iw_handler) atmel_get_rts,		/* SIOCGIWRTS */
 	(iw_handler) atmel_set_frag,		/* SIOCSIWFRAG */
 	(iw_handler) atmel_get_frag,		/* SIOCGIWFRAG */
-	(iw_handler) NULL,         		/* SIOCSIWTXPOW */
-	(iw_handler) NULL,          		/* SIOCGIWTXPOW */
+	(iw_handler) NULL,			/* SIOCSIWTXPOW */
+	(iw_handler) NULL,			/* SIOCGIWTXPOW */
 	(iw_handler) atmel_set_retry,		/* SIOCSIWRETRY */
 	(iw_handler) atmel_get_retry,		/* SIOCGIWRETRY */
 	(iw_handler) atmel_set_encode,		/* SIOCSIWENCODE */
@@ -2375,39 +2380,51 @@
 	(iw_handler) atmel_get_power,		/* SIOCGIWPOWER */
 };
 
-
-static const iw_handler		atmel_private_handler[] =
+static const iw_handler atmel_private_handler[] =
 {
 	NULL,				/* SIOCIWFIRSTPRIV */
 };
 
 typedef struct atmel_priv_ioctl {
 	char id[32];
-	unsigned char __user *data;		
-	unsigned short len;		
+	unsigned char __user *data;
+	unsigned short len;
 } atmel_priv_ioctl;
 
-	
-#define ATMELFWL SIOCIWFIRSTPRIV
-#define ATMELIDIFC ATMELFWL + 1
-#define ATMELRD ATMELFWL + 2
-#define ATMELMAGIC 0x51807 
+#define ATMELFWL	SIOCIWFIRSTPRIV
+#define ATMELIDIFC	ATMELFWL + 1
+#define ATMELRD		ATMELFWL + 2
+#define ATMELMAGIC 0x51807
 #define REGDOMAINSZ 20
 
 static const struct iw_priv_args atmel_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { ATMELFWL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (atmel_priv_ioctl), IW_PRIV_TYPE_NONE, "atmelfwl" },
-  { ATMELIDIFC, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "atmelidifc" },
-  { ATMELRD, IW_PRIV_TYPE_CHAR | REGDOMAINSZ, IW_PRIV_TYPE_NONE, "regdomain" },
+	{
+		.cmd = ATMELFWL,
+		.set_args = IW_PRIV_TYPE_BYTE
+				| IW_PRIV_SIZE_FIXED
+				| sizeof (atmel_priv_ioctl),
+		.get_args = IW_PRIV_TYPE_NONE,
+		.name = "atmelfwl"
+	}, {
+		.cmd = ATMELIDIFC,
+		.set_args = IW_PRIV_TYPE_NONE,
+		.get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		.name = "atmelidifc"
+	}, {
+		.cmd = ATMELRD,
+		.set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
+		.get_args = IW_PRIV_TYPE_NONE,
+		.name = "regdomain"
+	},
 };
 
-static const struct iw_handler_def	atmel_handler_def =
+static const struct iw_handler_def atmel_handler_def =
 {
 	.num_standard	= sizeof(atmel_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(atmel_private_handler)/sizeof(iw_handler), 
-	.num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), 
+	.num_private	= sizeof(atmel_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args),
 	.standard	= (iw_handler *) atmel_handler,
-	.private	= (iw_handler *) atmel_private_handler, 
+	.private	= (iw_handler *) atmel_private_handler,
 	.private_args	= (struct iw_priv_args *) atmel_private_args,
 	.get_wireless_stats = atmel_get_wireless_stats
 };
@@ -2419,13 +2436,13 @@
 	atmel_priv_ioctl com;
 	struct iwreq *wrq = (struct iwreq *) rq;
 	unsigned char *new_firmware;
-	char domain[REGDOMAINSZ+1];
+	char domain[REGDOMAINSZ + 1];
 
 	switch (cmd) {
 	case ATMELIDIFC:
-		wrq->u.param.value = ATMELMAGIC;		
+		wrq->u.param.value = ATMELMAGIC;
 		break;
-	
+
 	case ATMELFWL:
 		if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
 			rc = -EFAULT;
@@ -2449,7 +2466,7 @@
 		}
 
 		kfree(priv->firmware);
-		
+
 		priv->firmware = new_firmware;
 		priv->firmware_length = com.len;
 		strncpy(priv->firmware_id, com.id, 31);
@@ -2461,7 +2478,7 @@
 			rc = -EFAULT;
 			break;
 		}
-		
+
 		if (!capable(CAP_NET_ADMIN)) {
 			rc = -EPERM;
 			break;
@@ -2484,15 +2501,15 @@
 				rc = 0;
 			}
 		}
-		
+
 		if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
 			rc = atmel_open(dev);
 		break;
-		
+
 	default:
 		rc = -EOPNOTSUPP;
 	}
-	
+
 	return rc;
 }
 
@@ -2503,17 +2520,17 @@
 	u8 el_id;
 	u8 chall_text_len;
 	u8 chall_text[253];
-}; 
+};
 
 static void atmel_enter_state(struct atmel_private *priv, int new_state)
 {
 	int old_state = priv->station_state;
-		
+
 	if (new_state == old_state)
 		return;
-	
+
 	priv->station_state = new_state;
-		
+
 	if (new_state == STATION_STATE_READY) {
 		netif_start_queue(priv->dev);
 		netif_carrier_on(priv->dev);
@@ -2540,7 +2557,7 @@
 		u8 options;
 		u8 SSID_size;
 	} cmd;
-	
+
 	memset(cmd.BSSID, 0xff, 6);
 
 	if (priv->fast_scan) {
@@ -2554,17 +2571,17 @@
 		cmd.min_channel_time = cpu_to_le16(10);
 		cmd.max_channel_time = cpu_to_le16(120);
 	}
-	
+
 	cmd.options = 0;
-	
+
 	if (!specific_ssid)
 		cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
-	
-	cmd.channel = (priv->channel & 0x7f); 
+
+	cmd.channel = (priv->channel & 0x7f);
 	cmd.scan_type = SCAN_TYPE_ACTIVE;
-	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 
+	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
 		BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
-	
+
 	atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
 
 	/* This must come after all hardware access to avoid being messed up
@@ -2591,16 +2608,15 @@
 	cmd.BSS_type = type;
 	cmd.timeout = cpu_to_le16(2000);
 
- 	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
+	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
 }
 
-
 static void start(struct atmel_private *priv, int type)
 {
 	struct {
 		u8 BSSID[6];
 		u8 SSID[MAX_SSID_LENGTH];
-		u8 BSS_type;                                
+		u8 BSS_type;
 		u8 channel;
 		u8 SSID_size;
 		u8 reserved[3];
@@ -2612,13 +2628,14 @@
 	cmd.BSS_type = type;
 	cmd.channel = (priv->channel & 0x7f);
 
-	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 
+	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
 }
 
-static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
+static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
+				u8 channel)
 {
 	int rejoin = 0;
-	int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+	int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ?
 		SHORT_PREAMBLE : LONG_PREAMBLE;
 
 	if (priv->preamble != new) {
@@ -2626,48 +2643,48 @@
 		rejoin = 1;
 		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
 	}
-		
+
 	if (priv->channel != channel) {
 		priv->channel = channel;
 		rejoin = 1;
 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
 	}
-	
+
 	if (rejoin) {
 		priv->station_is_associated = 0;
 		atmel_enter_state(priv, STATION_STATE_JOINNING);
-		
+
 		if (priv->operating_mode == IW_MODE_INFRA)
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
-		else 
+		else
 			join(priv, BSS_TYPE_AD_HOC);
-	} 
+	}
 }
 
-
-static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
+static void send_authentication_request(struct atmel_private *priv, u16 system,
+					u8 *challenge, int challenge_len)
 {
 	struct ieee80211_hdr_4addr header;
 	struct auth_body auth;
-	
-	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
-	header.duration_id	= cpu_to_le16(0x8000);	
+
+	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+	header.duration_id = cpu_to_le16(0x8000);
 	header.seq_ctl = 0;
 	memcpy(header.addr1, priv->CurrentBSSID, 6);
 	memcpy(header.addr2, priv->dev->dev_addr, 6);
 	memcpy(header.addr3, priv->CurrentBSSID, 6);
-	
-	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) 
+
+	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
 		/* no WEP for authentication frames with TrSeqNo 1 */
                 header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-	
-	auth.alg = cpu_to_le16(system); 
+
+	auth.alg = cpu_to_le16(system);
 
 	auth.status = 0;
 	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
-	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 
+	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
 	priv->CurrentAuthentTransactionSeqNum += 2;
-	
+
 	if (challenge_len != 0)	{
 		auth.el_id = 16; /* challenge_text */
 		auth.chall_text_len = challenge_len;
@@ -2685,7 +2702,7 @@
 	struct ieee80211_hdr_4addr header;
 	struct ass_req_format {
 		u16 capability;
-		u16 listen_interval; 
+		u16 listen_interval;
 		u8 ap[6]; /* nothing after here directly accessible */
 		u8 ssid_el_id;
 		u8 ssid_len;
@@ -2694,15 +2711,15 @@
 		u8 sup_rates_len;
 		u8 rates[4];
 	} body;
-		
-	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
+
+	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 		(is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
 	header.duration_id = cpu_to_le16(0x8000);
 	header.seq_ctl = 0;
 
-	memcpy(header.addr1, priv->CurrentBSSID, 6); 
+	memcpy(header.addr1, priv->CurrentBSSID, 6);
 	memcpy(header.addr2, priv->dev->dev_addr, 6);
-	memcpy(header.addr3, priv->CurrentBSSID, 6); 
+	memcpy(header.addr3, priv->CurrentBSSID, 6);
 
 	body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
 	if (priv->wep_is_on)
@@ -2711,18 +2728,18 @@
 		body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
 
 	body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
-	
+
 	/* current AP address - only in reassoc frame */
 	if (is_reassoc) {
-		memcpy(body.ap,  priv->CurrentBSSID, 6);
+		memcpy(body.ap, priv->CurrentBSSID, 6);
 		ssid_el_p = (u8 *)&body.ssid_el_id;
 		bodysize = 18 + priv->SSID_size;
 	} else {
 		ssid_el_p = (u8 *)&body.ap[0];
 		bodysize = 12 + priv->SSID_size;
 	}
-		
-	ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
+
+	ssid_el_p[0] = C80211_MGMT_ElementID_SSID;
 	ssid_el_p[1] = priv->SSID_size;
 	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
 	ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
@@ -2732,7 +2749,8 @@
 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
 }
 
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv,
+				     struct ieee80211_hdr_4addr *header)
 {
 	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2745,29 +2763,29 @@
 	int i;
 	int max_rssi = -128;
 	int max_index = -1;
-	
+
 	if (priv->BSS_list_entries == 0)
 		return -1;
-			
+
 	if (priv->connect_to_any_BSS) {
-		/* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
-		   and that it is not marked as 'bad' (i.e. we had previously failed to connect to
-		   this BSS with the settings that we currently use) */
+		/* Select a BSS with the max-RSSI but of the same type and of
+		   the same WEP mode and that it is not marked as 'bad' (i.e.
+		   we had previously failed to connect to this BSS with the
+		   settings that we currently use) */
 		priv->current_BSS = 0;
-		for(i=0; i<priv->BSS_list_entries; i++) { 
+		for (i = 0; i < priv->BSS_list_entries; i++) {
 			if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
-			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) || 
+			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
 			     (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
 			    !(priv->BSSinfo[i].channel & 0x80)) {
 				max_rssi = priv->BSSinfo[i].RSSI;
 				priv->current_BSS = max_index = i;
 			}
-			
 		}
 		return max_index;
 	}
-		
-	for(i=0; i<priv->BSS_list_entries; i++) {
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
 		    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
 		    priv->operating_mode == priv->BSSinfo[i].BSStype &&
@@ -2781,19 +2799,19 @@
 	return max_index;
 }
 
-
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
-			   u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
-			   u8 ssid_len, u8 *ssid, int is_beacon)
+static void store_bss_info(struct atmel_private *priv,
+			   struct ieee80211_hdr_4addr *header, u16 capability,
+			   u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
+			   u8 *ssid, int is_beacon)
 {
 	u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
 	int i, index;
-		
-	for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 
-		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 
+
+	for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
+		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
 			index = i;
 
-        /* If we process a probe and an entry from this BSS exists 
+        /* If we process a probe and an entry from this BSS exists
 	   we will update the BSS entry with the info from this BSS.
 	   If we process a beacon we will only update RSSI */
 
@@ -2820,8 +2838,8 @@
 		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
 	else if (capability & C80211_MGMT_CAPABILITY_ESS)
 		priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
-	
-	priv->BSSinfo[index].preamble = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+
+	priv->BSSinfo[index].preamble = capability & C80211_MGMT_CAPABILITY_ShortPreamble ?
 		SHORT_PREAMBLE : LONG_PREAMBLE;
 }
 
@@ -2831,8 +2849,8 @@
 	u16 status = le16_to_cpu(auth->status);
 	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
 	u16 system = le16_to_cpu(auth->alg);
-	
-	if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { 
+
+	if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
 		/* no WEP */
 		if (priv->station_was_associated) {
 			atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2842,20 +2860,20 @@
 			atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
 			send_association_request(priv, 0);
 			return;
-		} 
+		}
 	}
-		
-	if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { 
+
+	if (status == C80211_MGMT_SC_Success && priv->wep_is_on) {
 		/* WEP */
 		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
 			return;
-				
+
 		if (trans_seq_no == 0x0002 &&
 		    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
 			send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
 			return;
 		}
-		
+
 		if (trans_seq_no == 0x0004) {
 			if(priv->station_was_associated) {
 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2865,10 +2883,10 @@
 				atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
 				send_association_request(priv, 0);
 				return;
-			} 
+			}
 		}
-	}			
-	
+	}
+
 	if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
 		/* Do opensystem first, then try sharedkey */
 		if (system ==  C80211_MGMT_AAN_OPENSYSTEM) {
@@ -2876,17 +2894,16 @@
 			send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
 		} else if (priv->connect_to_any_BSS) {
 			int bss_index;
-			
+
 			priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-			
+
 			if ((bss_index  = retrieve_bss(priv)) != -1) {
 				atmel_join_bss(priv, bss_index);
 				return;
 			}
 		}
 	}
-	
-	
+
 	priv->AuthenticationRequestRetryCnt = 0;
 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
 	priv->station_is_associated = 0;
@@ -2902,38 +2919,44 @@
 		u8 length;
 		u8 rates[4];
 	} *ass_resp = (struct ass_resp_format *)priv->rx_buf;
-	
-       	u16 status = le16_to_cpu(ass_resp->status);
+
+	u16 status = le16_to_cpu(ass_resp->status);
 	u16 ass_id = le16_to_cpu(ass_resp->ass_id);
-   	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
-	
+	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
+
 	if (frame_len < 8 + rates_len)
 		return;
-	
+
 	if (status == C80211_MGMT_SC_Success) {
 		if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
 			priv->AssociationRequestRetryCnt = 0;
 		else
 			priv->ReAssociationRequestRetryCnt = 0;
-		
-		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
-		atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
+
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+				MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
+		atmel_set_mib(priv, Phy_Mib_Type,
+			      PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
 		if (priv->power_mode == 0) {
 			priv->listen_interval = 1;
-			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+				       MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
 		} else {
 			priv->listen_interval = 2;
-			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
-			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+				       MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
 		}
-		
+
 		priv->station_is_associated = 1;
 		priv->station_was_associated = 1;
 		atmel_enter_state(priv, STATION_STATE_READY);
 		return;
 	}
-	
+
 	if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
 	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
 	    status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2943,7 +2966,7 @@
 		send_association_request(priv, 0);
 		return;
 	}
-		
+
 	if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
 	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
 	    status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2953,17 +2976,16 @@
 		send_association_request(priv, 1);
 		return;
 	}
-	
+
 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
 	priv->station_is_associated = 0;
-	
-	if(priv->connect_to_any_BSS) {
+
+	if (priv->connect_to_any_BSS) {
 		int bss_index;
 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-		
-		if ((bss_index = retrieve_bss(priv)) != -1) 
+
+		if ((bss_index = retrieve_bss(priv)) != -1)
 			atmel_join_bss(priv, bss_index);
-		
 	}
 }
 
@@ -2977,7 +2999,7 @@
 	/* The WPA stuff cares about the current AP address */
 	if (priv->use_wpa)
 		build_wpa_mib(priv);
-	
+
 	/* When switching to AdHoc turn OFF Power Save if needed */
 
 	if (bss->BSStype == IW_MODE_ADHOC &&
@@ -2985,25 +3007,28 @@
 	    priv->power_mode) {
 		priv->power_mode = 0;
 		priv->listen_interval = 1;
-		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+			       MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+				MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
 	}
-		
+
 	priv->operating_mode = bss->BSStype;
-	priv->channel = bss->channel & 0x7f; 	
+	priv->channel = bss->channel & 0x7f;
 	priv->beacon_period = bss->beacon_period;
-	
+
 	if (priv->preamble != bss->preamble) {
 		priv->preamble = bss->preamble;
-		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
+		atmel_set_mib8(priv, Local_Mib_Type,
+			       LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
 	}
-	
+
 	if (!priv->wep_is_on && bss->UsingWEP) {
 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 		priv->station_is_associated = 0;
 		return;
 	}
-		
+
 	if (priv->wep_is_on && !bss->UsingWEP) {
 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 		priv->station_is_associated = 0;
@@ -3011,30 +3036,28 @@
 	}
 
 	atmel_enter_state(priv, STATION_STATE_JOINNING);
-	
+
 	if (priv->operating_mode == IW_MODE_INFRA)
 		join(priv, BSS_TYPE_INFRASTRUCTURE);
-	else 
+	else
 		join(priv, BSS_TYPE_AD_HOC);
 }
 
-
 static void restart_search(struct atmel_private *priv)
 {
 	int bss_index;
-	
+
 	if (!priv->connect_to_any_BSS) {
 		atmel_scan(priv, 1);
 	} else {
 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-		
-		if ((bss_index = retrieve_bss(priv)) != -1) 
+
+		if ((bss_index = retrieve_bss(priv)) != -1)
 			atmel_join_bss(priv, bss_index);
 		else
 			atmel_scan(priv, 0);
-		
-	} 
-}	
+	}
+}
 
 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
 {
@@ -3050,21 +3073,21 @@
 	}
 
 	rssi = rssi * 100 / max_rssi;
-	if((rssi + old) % 2)
-		priv->wstats.qual.level =  ((rssi + old)/2) + 1;
+	if ((rssi + old) % 2)
+		priv->wstats.qual.level = (rssi + old) / 2 + 1;
 	else
-		priv->wstats.qual.level =  ((rssi + old)/2);		
+		priv->wstats.qual.level = (rssi + old) / 2;
 	priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
 	priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
 }
 
 static void atmel_smooth_qual(struct atmel_private *priv)
 {
-	unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
+	unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
 	while (time_diff--) {
 		priv->last_qual += HZ;
-		priv->wstats.qual.qual = priv->wstats.qual.qual/2;
-		priv->wstats.qual.qual += 
+		priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
+		priv->wstats.qual.qual +=
 			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
 		priv->beacons_this_sec = 0;
 	}
@@ -3073,15 +3096,17 @@
 }
 
 /* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-		      u16 frame_len, u8 rssi)
+static void atmel_management_frame(struct atmel_private *priv,
+				   struct ieee80211_hdr_4addr *header,
+				   u16 frame_len, u8 rssi)
 {
 	u16 subtype;
-	
-	switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
-	case C80211_SUBTYPE_MGMT_BEACON :
+
+	subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE;
+	switch (subtype) {
+	case C80211_SUBTYPE_MGMT_BEACON:
 	case C80211_SUBTYPE_MGMT_ProbeResponse:
-		
+
 		/* beacon frame has multiple variable-length fields -
 		   never let an engineer loose with a data structure design. */
 		{
@@ -3099,7 +3124,7 @@
 				u8 ds_length;
 				/* ds here */
 			} *beacon = (struct beacon_format *)priv->rx_buf;
-			
+
 			u8 channel, rates_length, ssid_length;
 			u64 timestamp = le64_to_cpu(beacon->timestamp);
 			u16 beacon_interval = le16_to_cpu(beacon->interval);
@@ -3107,7 +3132,7 @@
 			u8 *beaconp = priv->rx_buf;
 			ssid_length = beacon->ssid_length;
 			/* this blows chunks. */
-			if (frame_len < 14 || frame_len < ssid_length + 15) 
+			if (frame_len < 14 || frame_len < ssid_length + 15)
 				return;
 			rates_length = beaconp[beacon->ssid_length + 15];
 			if (frame_len < ssid_length + rates_length + 18)
@@ -3115,10 +3140,10 @@
 			if (ssid_length >  MAX_SSID_LENGTH)
 				return;
 			channel = beaconp[ssid_length + rates_length + 18];
-		       
+
 			if (priv->station_state == STATION_STATE_READY) {
 				smooth_rssi(priv, rssi);
-				if (is_frame_from_current_bss(priv, header)) { 
+				if (is_frame_from_current_bss(priv, header)) {
 					priv->beacons_this_sec++;
 					atmel_smooth_qual(priv);
 					if (priv->last_beacon_timestamp) {
@@ -3132,41 +3157,43 @@
 					handle_beacon_probe(priv, capability, channel);
 				}
 			}
-			
-			if (priv->station_state == STATION_STATE_SCANNING ) 
-				store_bss_info(priv, header, capability, beacon_interval, channel,
-					       rssi, ssid_length, &beacon->rates_el_id,
-					       subtype == C80211_SUBTYPE_MGMT_BEACON) ;
+
+			if (priv->station_state == STATION_STATE_SCANNING)
+				store_bss_info(priv, header, capability,
+					       beacon_interval, channel, rssi,
+					       ssid_length,
+					       &beacon->rates_el_id,
+					       subtype == C80211_SUBTYPE_MGMT_BEACON);
 		}
 		break;
-		
+
 	case C80211_SUBTYPE_MGMT_Authentication:
 
 		if (priv->station_state == STATION_STATE_AUTHENTICATING)
 			authenticate(priv, frame_len);
-	
+
 		break;
-		
+
 	case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
 	case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
-		
-		if (priv->station_state == STATION_STATE_ASSOCIATING || 
+
+		if (priv->station_state == STATION_STATE_ASSOCIATING ||
 		    priv->station_state == STATION_STATE_REASSOCIATING)
 			associate(priv, frame_len, subtype);
-		
+
 		break;
 
 	case C80211_SUBTYPE_MGMT_DISASSOSIATION:
-		if (priv->station_is_associated && 
-		    priv->operating_mode == IW_MODE_INFRA && 
+		if (priv->station_is_associated &&
+		    priv->operating_mode == IW_MODE_INFRA &&
 		    is_frame_from_current_bss(priv, header)) {
 			priv->station_was_associated = 0;
 			priv->station_is_associated = 0;
-			
+
 			atmel_enter_state(priv, STATION_STATE_JOINNING);
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
 		}
-		
+
 		break;
 
 	case C80211_SUBTYPE_MGMT_Deauthentication:
@@ -3177,7 +3204,7 @@
 			atmel_enter_state(priv, STATION_STATE_JOINNING);
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
 		}
-		
+
 		break;
 	}
 }
@@ -3185,76 +3212,73 @@
 /* run when timer expires */
 static void atmel_management_timer(u_long a)
 {
-  struct net_device *dev = (struct net_device *) a;
-  struct atmel_private *priv = netdev_priv(dev);
-  unsigned long flags;
-  
-  /* Check if the card has been yanked. */
-  if (priv->card && priv->present_callback && 
-      !(*priv->present_callback)(priv->card))
-	  return;
-  
-  spin_lock_irqsave(&priv->irqlock, flags);
+	struct net_device *dev = (struct net_device *) a;
+	struct atmel_private *priv = netdev_priv(dev);
+	unsigned long flags;
 
-  switch (priv->station_state) {
-	  
-  case STATION_STATE_AUTHENTICATING:
-	  if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->AuthenticationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->AuthenticationRequestRetryCnt++;
-		  priv->CurrentAuthentTransactionSeqNum = 0x0001;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
+	/* Check if the card has been yanked. */
+	if (priv->card && priv->present_callback &&
+		!(*priv->present_callback)(priv->card))
+		return;
+
+	spin_lock_irqsave(&priv->irqlock, flags);
+
+	switch (priv->station_state) {
+
+	case STATION_STATE_AUTHENTICATING:
+		if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->AuthenticationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->AuthenticationRequestRetryCnt++;
+			priv->CurrentAuthentTransactionSeqNum = 0x0001;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
 	  }
-	  
 	  break;
 
-  case STATION_STATE_ASSOCIATING:
-	  if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->AssociationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->AssociationRequestRetryCnt++;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_association_request(priv, 0);
-	  }
+	case STATION_STATE_ASSOCIATING:
+		if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->AssociationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->AssociationRequestRetryCnt++;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_association_request(priv, 0);
+		}
+	  break;
 
-	  break;
-		  
-  case STATION_STATE_REASSOCIATING:	
-	  if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->ReAssociationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->ReAssociationRequestRetryCnt++;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_association_request(priv, 1);
-	  }
+	case STATION_STATE_REASSOCIATING:
+		if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->ReAssociationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->ReAssociationRequestRetryCnt++;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_association_request(priv, 1);
+		}
+		break;
 
-	  break;
-  
-  default:
-	  break;
-  }
-  
-  spin_unlock_irqrestore(&priv->irqlock, flags);
+	default:
+		break;
+	}
+
+	spin_unlock_irqrestore(&priv->irqlock, flags);
 }
-  
+
 static void atmel_command_irq(struct atmel_private *priv)
 {
 	u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
 	u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
 	int fast_scan;
-	
-	if (status == CMD_STATUS_IDLE || 
+
+	if (status == CMD_STATUS_IDLE ||
 	    status == CMD_STATUS_IN_PROGRESS)
 		return;
 
@@ -3266,20 +3290,20 @@
 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
 				      (u8 *)priv->CurrentBSSID, 6);
 			atmel_enter_state(priv, STATION_STATE_READY);
-		}			
+		}
 		break;
-		
+
 	case CMD_Scan:
 		fast_scan = priv->fast_scan;
 		priv->fast_scan = 0;
-		
+
 		if (status != CMD_STATUS_COMPLETE) {
 			atmel_scan(priv, 1);
 		} else {
 			int bss_index = retrieve_bss(priv);
 			if (bss_index != -1) {
 				atmel_join_bss(priv, bss_index);
-			} else if (priv->operating_mode == IW_MODE_ADHOC && 
+			} else if (priv->operating_mode == IW_MODE_ADHOC &&
 				   priv->SSID_size != 0) {
 				start(priv, BSS_TYPE_AD_HOC);
 			} else {
@@ -3289,16 +3313,16 @@
 			priv->site_survey_state = SITE_SURVEY_COMPLETED;
 		}
 		break;
-		
+
 	case CMD_SiteSurvey:
 		priv->fast_scan = 0;
-		
+
 		if (status != CMD_STATUS_COMPLETE)
 			return;
-		
+
 		priv->site_survey_state = SITE_SURVEY_COMPLETED;
 		if (priv->station_is_associated) {
-			atmel_enter_state(priv, STATION_STATE_READY);				
+			atmel_enter_state(priv, STATION_STATE_READY);
 		} else {
 			atmel_scan(priv, 1);
 		}
@@ -3312,16 +3336,15 @@
 			} else {
 				priv->AuthenticationRequestRetryCnt = 0;
 				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
-				
+
 				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
 				priv->CurrentAuthentTransactionSeqNum = 0x0001;
 				send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
 			}
 			return;
 		}
-		
+
 		atmel_scan(priv, 1);
-		
 	}
 }
 
@@ -3333,20 +3356,20 @@
 
 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
 		atmel_set_gcr(priv->dev, GCR_REMAP);
-	
+
 	/* wake up on-board processor */
 	atmel_clear_gcr(priv->dev, 0x0040);
 	atmel_write16(priv->dev, BSR, BSS_SRAM);
-	
+
 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
 		mdelay(100);
 
 	/* and wait for it */
-	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+	for (i = LOOP_RETRY_LIMIT; i; i--) {
 		mr1 = atmel_read16(priv->dev, MR1);
 		mr3 = atmel_read16(priv->dev, MR3);
-		
-		if (mr3 & MAC_BOOT_COMPLETE) 
+
+		if (mr3 & MAC_BOOT_COMPLETE)
 			break;
 		if (mr1 & MAC_BOOT_COMPLETE &&
 		    priv->bus_type == BUS_TYPE_PCCARD)
@@ -3357,35 +3380,36 @@
 		printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
 		return 0;
 	}
-		
+
 	if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
 		printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
 		return 0;
 	}
-	
-	/* now check for completion of MAC initialization through  
-	   the FunCtrl field of the IFACE, poll MR1 to detect completion of	  
-	   MAC initialization, check completion status, set interrupt mask,  
-	   enables interrupts and calls Tx and Rx initialization functions */  
-	
+
+	/* now check for completion of MAC initialization through
+	   the FunCtrl field of the IFACE, poll MR1 to detect completion of
+	   MAC initialization, check completion status, set interrupt mask,
+	   enables interrupts and calls Tx and Rx initialization functions */
+
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
-	
-	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+
+	for (i = LOOP_RETRY_LIMIT; i; i--) {
 		mr1 = atmel_read16(priv->dev, MR1);
 		mr3 = atmel_read16(priv->dev, MR3);
-		
-		if (mr3 & MAC_INIT_COMPLETE) 
+
+		if (mr3 & MAC_INIT_COMPLETE)
 			break;
 		if (mr1 & MAC_INIT_COMPLETE &&
 		    priv->bus_type == BUS_TYPE_PCCARD)
 			break;
 	}
-	
+
 	if (i == 0) {
-		printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
+		printk(KERN_ALERT "%s: MAC failed to initialise.\n",
+				priv->dev->name);
 		return 0;
 	}
-	
+
 	/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
 	if ((mr3 & MAC_INIT_COMPLETE) &&
 	    !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
@@ -3398,9 +3422,9 @@
 		return 0;
 	}
 
-	atmel_copy_to_host(priv->dev, (unsigned char *)iface, 
+	atmel_copy_to_host(priv->dev, (unsigned char *)iface,
 			   priv->host_info_base, sizeof(*iface));
-        
+
 	iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
 	iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
 	iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
@@ -3424,16 +3448,16 @@
 {
 	int rc = 0;
 	struct atmel_private *priv = netdev_priv(dev);
-	 
+
 	/* reset pccard */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
-	
+
 	atmel_write16(dev, GCR, 0x0040);
 	mdelay(500);
-	
+
 	if (atmel_read16(dev, MR2) == 0) {
-		/* No stored firmware so load a small stub which just 
+		/* No stored firmware so load a small stub which just
 		   tells us the MAC address */
 		int i;
 		priv->card_type = CARD_TYPE_EEPROM;
@@ -3442,7 +3466,7 @@
 		atmel_set_gcr(dev, GCR_REMAP);
 		atmel_clear_gcr(priv->dev, 0x0040);
 		atmel_write16(dev, BSR, BSS_SRAM);
-		for (i =  LOOP_RETRY_LIMIT; i; i--) 
+		for (i = LOOP_RETRY_LIMIT; i; i--)
 			if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
 				break;
 		if (i == 0) {
@@ -3451,7 +3475,7 @@
 			atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
 			/* got address, now squash it again until the network
 			   interface is opened */
-			if (priv->bus_type == BUS_TYPE_PCCARD) 
+			if (priv->bus_type == BUS_TYPE_PCCARD)
 				atmel_write16(dev, GCR, 0x0060);
 			atmel_write16(dev, GCR, 0x0040);
 			rc = 1;
@@ -3459,7 +3483,7 @@
 	} else if (atmel_read16(dev, MR4) == 0) {
 		/* Mac address easy in this case. */
 		priv->card_type = CARD_TYPE_PARALLEL_FLASH;
-		atmel_write16(dev,  BSR, 1);	
+		atmel_write16(dev,  BSR, 1);
 		atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
 		atmel_write16(dev,  BSR, 0x200);
 		rc = 1;
@@ -3469,16 +3493,16 @@
 		priv->card_type = CARD_TYPE_SPI_FLASH;
 		if (atmel_wakeup_firmware(priv)) {
 			atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
-			
+
 			/* got address, now squash it again until the network
 			   interface is opened */
-			if (priv->bus_type == BUS_TYPE_PCCARD) 
+			if (priv->bus_type == BUS_TYPE_PCCARD)
 				atmel_write16(dev, GCR, 0x0060);
 			atmel_write16(dev, GCR, 0x0040);
 			rc = 1;
 		}
 	}
-	
+
 	if (rc) {
 		if (dev->dev_addr[0] == 0xFF) {
 			u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
@@ -3486,27 +3510,27 @@
 			memcpy(dev->dev_addr, default_mac, 6);
 		}
 	}
-	
+
 	return rc;
 }
 
-static void build_wep_mib(struct atmel_private *priv)
 /* Move the encyption information on the MIB structure.
    This routine is for the pre-WPA firmware: later firmware has
    a different format MIB and a different routine. */
+static void build_wep_mib(struct atmel_private *priv)
 {
 	struct { /* NB this is matched to the hardware, don't change. */
-		u8 wep_is_on;                 
+		u8 wep_is_on;
 		u8 default_key; /* 0..3 */
 		u8 reserved;
 		u8 exclude_unencrypted;
-		
+
 		u32 WEPICV_error_count;
 		u32 WEP_excluded_count;
-		
+
 		u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
- 		u8 encryption_level; /* 0, 1, 2 */
-		u8 reserved2[3]; 
+		u8 encryption_level; /* 0, 1, 2 */
+		u8 reserved2[3];
 	} mib;
 	int i;
 
@@ -3515,54 +3539,55 @@
 		if (priv->wep_key_len[priv->default_key] > 5)
 			mib.encryption_level = 2;
 		else
-			mib.encryption_level = 1;	
+			mib.encryption_level = 1;
 	} else {
 		mib.encryption_level = 0;
 	}
 
 	mib.default_key = priv->default_key;
 	mib.exclude_unencrypted = priv->exclude_unencrypted;
-	
-	for(i = 0; i < MAX_ENCRYPTION_KEYS;  i++)
+
+	for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
 		memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
-		
+
 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
 
 static void build_wpa_mib(struct atmel_private *priv)
 {
-	/* This is for the later (WPA enabled) firmware. */	   
+	/* This is for the later (WPA enabled) firmware. */
 
 	struct { /* NB this is matched to the hardware, don't change. */
 		u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
 		u8 receiver_address[6];
-		u8 wep_is_on;                 
+		u8 wep_is_on;
 		u8 default_key; /* 0..3 */
 		u8 group_key;
 		u8 exclude_unencrypted;
 		u8 encryption_type;
 		u8 reserved;
-		
+
 		u32 WEPICV_error_count;
 		u32 WEP_excluded_count;
-		
+
 		u8 key_RSC[4][8];
 	} mib;
-	
+
 	int i;
 
 	mib.wep_is_on = priv->wep_is_on;
 	mib.exclude_unencrypted = priv->exclude_unencrypted;
 	memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
-	
+
 	/* zero all the keys before adding in valid ones. */
 	memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
-	
+
 	if (priv->wep_is_on) {
-		/* There's a comment in the Atmel code to the effect that this is only valid
-		   when still using WEP, it may need to be set to something to use WPA */
+		/* There's a comment in the Atmel code to the effect that this
+		   is only valid when still using WEP, it may need to be set to
+		   something to use WPA */
 		memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
-		
+
 		mib.default_key = mib.group_key = 255;
 		for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
 			if (priv->wep_key_len[i] > 0) {
@@ -3570,12 +3595,12 @@
 				if (i == priv->default_key) {
 					mib.default_key = i;
 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
-					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite; 
+					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
 				} else {
 					mib.group_key = i;
 					priv->group_cipher_suite = priv->pairwise_cipher_suite;
 				        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
-					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;	
+					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
 				}
 			}
 		}
@@ -3583,47 +3608,47 @@
 			mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
 		if (mib.group_key == 255)
 			mib.group_key = mib.default_key;
-		
+
 	}
-	
+
 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
-					
-static int reset_atmel_card(struct net_device *dev) 
+
+static int reset_atmel_card(struct net_device *dev)
 {
 	/* do everything necessary to wake up the hardware, including
 	   waiting for the lightning strike and throwing the knife switch....
 
-	   set all the Mib values which matter in the card to match 
+	   set all the Mib values which matter in the card to match
 	   their settings in the atmel_private structure. Some of these
 	   can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
 	   can only be changed by tearing down the world and coming back through
 	   here.
 
-	   This routine is also responsible for initialising some 
-	   hardware-specific fields in the atmel_private structure, 
+	   This routine is also responsible for initialising some
+	   hardware-specific fields in the atmel_private structure,
 	   including a copy of the firmware's hostinfo stucture
 	   which is the route into the rest of the firmare datastructures. */
 
 	struct atmel_private *priv = netdev_priv(dev);
 	u8 configuration;
-	
+
 	/* data to add to the firmware names, in priority order
 	   this implemenents firmware versioning */
-	
+
 	static char *firmware_modifier[] = {
 		"-wpa",
 		"",
 		NULL
 	};
-		
+
 	/* reset pccard */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(priv->dev, GCR, 0x0060);
-		
+
 	/* stop card , disable interrupts */
 	atmel_write16(priv->dev, GCR, 0x0040);
-		
+
 	if (priv->card_type == CARD_TYPE_EEPROM) {
 		/* copy in firmware if needed */
 		const struct firmware *fw_entry = NULL;
@@ -3636,13 +3661,13 @@
 					       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
 					       dev->name);
 					printk(KERN_INFO
-					       "%s: if not, use the firmware= module parameter.\n", 
+					       "%s: if not, use the firmware= module parameter.\n",
 					       dev->name);
 					strcpy(priv->firmware_id, "atmel_at76c502.bin");
 				}
 				if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
-					printk(KERN_ALERT 
-					       "%s: firmware %s is missing, cannot continue.\n", 
+					printk(KERN_ALERT
+					       "%s: firmware %s is missing, cannot continue.\n",
 					       dev->name, priv->firmware_id);
 					return 0;
 				}
@@ -3654,7 +3679,7 @@
 				while (fw_table[fw_index].fw_type != priv->firmware_type
 						&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
 					fw_index++;
-				
+
 				/* construct the actual firmware file name */
 				if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
 					int i;
@@ -3669,24 +3694,24 @@
 					}
 				}
 				if (!success) {
-					printk(KERN_ALERT 
-					       "%s: firmware %s is missing, cannot start.\n", 
+					printk(KERN_ALERT
+					       "%s: firmware %s is missing, cannot start.\n",
 					       dev->name, priv->firmware_id);
 					priv->firmware_id[0] = '\0';
-					return 0;	
+					return 0;
 				}
 			}
-			
+
 			fw = fw_entry->data;
 			len = fw_entry->size;
 		}
-		
+
 	        if (len <= 0x6000) {
 			atmel_write16(priv->dev, BSR, BSS_IRAM);
 			atmel_copy_to_card(priv->dev, 0, fw, len);
 			atmel_set_gcr(priv->dev, GCR_REMAP);
 		} else {
-			/* Remap */ 
+			/* Remap */
 			atmel_set_gcr(priv->dev, GCR_REMAP);
 			atmel_write16(priv->dev, BSR, BSS_IRAM);
 			atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
@@ -3708,45 +3733,45 @@
 	   the 3com broken-ness filter. */
 	priv->use_wpa = (priv->host_info.major_version == 4);
 	priv->radio_on_broken = (priv->host_info.major_version == 5);
-	
+
         /* unmask all irq sources */
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
-	
+
 	/* int Tx system and enable Tx */
 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
 	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
 
-	priv->tx_desc_free = priv->host_info.tx_desc_count;		
-	priv->tx_desc_head = 0;									
-	priv->tx_desc_tail = 0;									
+	priv->tx_desc_free = priv->host_info.tx_desc_count;
+	priv->tx_desc_head = 0;
+	priv->tx_desc_tail = 0;
 	priv->tx_desc_previous = 0;
 	priv->tx_free_mem = priv->host_info.tx_buff_size;
-	priv->tx_buff_head = 0;	
-	priv->tx_buff_tail = 0;	
-		
-	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+	priv->tx_buff_head = 0;
+	priv->tx_buff_tail = 0;
+
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
 				   configuration | FUNC_CTRL_TxENABLE);
 
 	/* init Rx system and enable */
 	priv->rx_desc_head = 0;
-	
-	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
 				   configuration | FUNC_CTRL_RxENABLE);
-			
+
 	if (!priv->radio_on_broken) {
-		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
+		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
 		    CMD_STATUS_REJECTED_RADIO_OFF) {
-			printk(KERN_INFO 
+			printk(KERN_INFO
 			       "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
 			       dev->name);
                         return 0;
 		}
 	}
-	
+
 	/* set up enough MIB values to run. */
 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
 	atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
@@ -3755,7 +3780,7 @@
 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
-	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 
+	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
 		      priv->dev->dev_addr, 6);
 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
@@ -3766,42 +3791,44 @@
 		build_wpa_mib(priv);
 	else
 		build_wep_mib(priv);
-	
+
 	return 1;
 }
 
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+static void atmel_send_command(struct atmel_private *priv, int command,
+			       void *cmd, int cmd_size)
 {
 	if (cmd)
-		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 
+		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
 				   cmd, cmd_size);
-	
+
 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
 }
-	
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+				   void *cmd, int cmd_size)
 {
 	int i, status;
-	
+
 	atmel_send_command(priv, command, cmd, cmd_size);
-	
+
 	for (i = 5000; i; i--) {
 		status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
-		if (status != CMD_STATUS_IDLE && 
+		if (status != CMD_STATUS_IDLE &&
 		    status != CMD_STATUS_IN_PROGRESS)
 			break;
 		udelay(20);
 	}
-	
+
 	if (i == 0) {
 		printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
 		status =  CMD_STATUS_HOST_ERROR;
-	} else { 
+	} else {
 		if (command != CMD_EnableRadio)
 			status = CMD_STATUS_COMPLETE;
 	}
-	
+
 	return status;
 }
 
@@ -3827,7 +3854,8 @@
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
 }
 
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+			    u16 data)
 {
 	struct get_set_mib m;
 	m.type = type;
@@ -3839,7 +3867,8 @@
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
 }
 
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len)
 {
 	struct get_set_mib m;
 	m.type = type;
@@ -3848,23 +3877,24 @@
 
 	if (data_len > MIB_MAX_DATA_BYTES)
 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-	
+
 	memcpy(m.data, data, data_len);
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
 }
 
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len)
 {
 	struct get_set_mib m;
 	m.type = type;
 	m.size = data_len;
 	m.index = index;
-	
+
 	if (data_len > MIB_MAX_DATA_BYTES)
 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-	
+
 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
-	atmel_copy_to_host(priv->dev, data, 
+	atmel_copy_to_host(priv->dev, data,
 			   atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
 }
 
@@ -3873,11 +3903,12 @@
 	int i;
 	outw(data, dev->base_addr + AR);
 	/* Address register appears to need some convincing..... */
-	for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
+	for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
 		outw(data, dev->base_addr + AR);
 }
 
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+			       unsigned char *src, u16 len)
 {
 	int i;
 	atmel_writeAR(dev, dest);
@@ -3894,7 +3925,8 @@
 		atmel_write8(dev, DR, *src);
 }
 
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+			       u16 src, u16 len)
 {
 	int i;
 	atmel_writeAR(dev, src);
@@ -3930,22 +3962,24 @@
 			break;
 		udelay(20);
 	}
-	
-	if (!i) return 0; /* timed out */
-	
+
+	if (!i)
+		return 0; /* timed out */
+
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
 	if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		if (!j--) return 0; /* timed out */
+		if (!j--)
+			return 0; /* timed out */
 		goto retry;
 	}
-	
+
 	return 1;
 }
 
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write16(priv->dev, DR, data); /* card is little-endian */
 	atmel_write16(priv->dev, DR, data >> 16);
 }
@@ -4017,9 +4051,9 @@
 				  serial output, since SO is normally high.  But it
 				  does cause 8 clock cycles and thus 8 bits to be
 				  clocked in to the chip.  See Atmel's SPI
-				  controller (e.g. AT91M55800) timing and 4K 
+				  controller (e.g. AT91M55800) timing and 4K
 				  SPI EEPROM manuals */
-				 
+
 	.set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
 	.set NVRAM_IMAGE, 0x02000200
 	.set NVRAM_LENGTH, 0x0200
@@ -4032,24 +4066,24 @@
 	.set MR4, 0xC
 RESET_VECTOR:
         b RESET_HANDLER
-UNDEF_VECTOR:  
+UNDEF_VECTOR:
         b HALT1
-SWI_VECTOR:            
+SWI_VECTOR:
         b HALT1
-IABORT_VECTOR: 
+IABORT_VECTOR:
         b HALT1
-DABORT_VECTOR:         
-RESERVED_VECTOR:    
+DABORT_VECTOR:
+RESERVED_VECTOR:
         b HALT1
-IRQ_VECTOR:    
+IRQ_VECTOR:
         b HALT1
-FIQ_VECTOR:    
+FIQ_VECTOR:
 	b HALT1
 HALT1:	b HALT1
 RESET_HANDLER:
 	mov     r0, #CPSR_INITIAL
 	msr	CPSR_c, r0	/* This is probably unnecessary */
-			
+
 /* I'm guessing this is initializing clock generator electronics for SPI */
 	ldr	r0, =SPI_CGEN_BASE
 	mov	r1, #0
@@ -4061,7 +4095,7 @@
 	str	r1, [r0, #28]
 	mov	r1, #1
 	str	r1, [r0, #8]
-	
+
 	ldr	r0, =MRBASE
 	mov	r1, #0
 	strh	r1, [r0, #MR1]
@@ -4094,7 +4128,7 @@
 	ldmia	sp!, {lr}
 	bx	lr
 .endfunc
-	
+
 .func Get_MAC_Addr, GET_MAC_ADDR
 GET_MAC_ADDR:
 	stmdb	sp!, {lr}
@@ -4110,13 +4144,13 @@
 .func Delay9, DELAY9
 DELAY9:
 	adds	r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
-DELAYLOOP:	
+DELAYLOOP:
 	beq	DELAY9_done
 	subs	r0, r0, #1
 	b	DELAYLOOP
-DELAY9_done:	
+DELAY9_done:
 	bx	lr
-.endfunc	
+.endfunc
 
 .func SP_Init, SP_INIT
 SP_INIT:
@@ -4145,26 +4179,26 @@
 	ldr	r0, [r0, #SP_RDR]
 	bx	lr
 .endfunc
-.func NVRAM_Init, NVRAM_INIT	
+.func NVRAM_Init, NVRAM_INIT
 NVRAM_INIT:
 	ldr	r1, =SP_BASE
 	ldr	r0, [r1, #SP_RDR]
 	mov	r0, #NVRAM_CMD_RDSR
 	str	r0, [r1, #SP_TDR]
-SP_loop1:	
+SP_loop1:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_TDRE
 	beq	SP_loop1
 
 	mov	r0, #SPI_8CLOCKS
-	str	r0, [r1, #SP_TDR] 
-SP_loop2:	
+	str	r0, [r1, #SP_TDR]
+SP_loop2:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_TDRE
 	beq	SP_loop2
 
 	ldr	r0, [r1, #SP_RDR]
-SP_loop3:	
+SP_loop3:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_RDRF
 	beq	SP_loop3
@@ -4173,7 +4207,7 @@
 	and	r0, r0, #255
 	bx	lr
 .endfunc
-	
+
 .func NVRAM_Xfer, NVRAM_XFER
 	/* r0 = dest address */
 	/* r1 = not used */
@@ -4185,11 +4219,11 @@
 	mov	r4, r3		/* save r3 (length) */
 	mov	r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
 	and	r0, r0, #8
-	add	r0, r0, #NVRAM_CMD_READ 
+	add	r0, r0, #NVRAM_CMD_READ
 	ldr	r1, =NVRAM_SCRATCH
 	strb	r0, [r1, #0]	/* save command in NVRAM_SCRATCH[0] */
 	strb	r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
-_local1:	
+_local1:
 	bl	NVRAM_INIT
 	tst	r0, #NVRAM_SR_RDY
 	bne	_local1
@@ -4211,7 +4245,7 @@
 	cmp	r0, #0
 	bls	_local2
 	ldr	r5, =NVRAM_SCRATCH
-_local4:	
+_local4:
 	ldrb	r6, [r5, r3]
 	str	r6, [r4, #SP_TDR]
 _local3:
@@ -4225,7 +4259,7 @@
 	mov	r3, #SPI_8CLOCKS
 	str	r3, [r4, #SP_TDR]
 	ldr	r0, [r4, #SP_RDR]
-_local5:	
+_local5:
 	ldr	r0, [r4, #SP_SR]
 	tst	r0, #SP_RDRF
 	beq	_local5
@@ -4233,12 +4267,12 @@
 	mov	r0, #0
 	cmp	r2, #0  /* r2 is # of bytes to copy in */
 	bls	_local6
-_local7:	
+_local7:
 	ldr	r5, [r4, #SP_SR]
 	tst	r5, #SP_TDRE
 	beq	_local7
 	str	r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
-_local8:	
+_local8:
 	ldr	r5, [r4, #SP_SR]
 	tst	r5, #SP_RDRF
 	beq	_local8
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
index fc62235..353ccb9 100644
--- a/drivers/net/wireless/hostap/Makefile
+++ b/drivers/net/wireless/hostap/Makefile
@@ -1,3 +1,4 @@
+hostap-y := hostap_main.o
 obj-$(CONFIG_HOSTAP) += hostap.o
 
 obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap_main.c
similarity index 100%
rename from drivers/net/wireless/hostap/hostap.c
rename to drivers/net/wireless/hostap/hostap_main.c
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 77d2a21..44cd3fc 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -175,7 +175,7 @@
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 
 /* Debugging stuff */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define CONFIG_IPW2100_RX_DEBUG	/* Reception debugging */
 #endif
 
@@ -208,7 +208,7 @@
 
 static u32 ipw2100_debug_level = IPW_DL_NONE;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW_DEBUG(level, message...) \
 do { \
 	if (ipw2100_debug_level & (level)) { \
@@ -219,9 +219,9 @@
 } while (0)
 #else
 #define IPW_DEBUG(level, message...) do {} while (0)
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *command_types[] = {
 	"undefined",
 	"unused",		/* HOST_ATTENTION */
@@ -2081,7 +2081,7 @@
 	priv->status &= ~STATUS_SCANNING;
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_HANDLER(v, f) { v, f, # v }
 struct ipw2100_status_indicator {
 	int status;
@@ -2094,7 +2094,7 @@
 	int status;
 	void (*cb) (struct ipw2100_priv * priv, u32 status);
 };
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
 static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
 {
@@ -2149,7 +2149,7 @@
 static void isr_rx_complete_command(struct ipw2100_priv *priv,
 				    struct ipw2100_cmd_header *cmd)
 {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
 		IPW_DEBUG_HC("Command completed '%s (%d)'\n",
 			     command_types[cmd->host_command_reg],
@@ -2167,7 +2167,7 @@
 	wake_up_interruptible(&priv->wait_command_queue);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *frame_types[] = {
 	"COMMAND_STATUS_VAL",
 	"STATUS_CHANGE_VAL",
@@ -2290,7 +2290,7 @@
 
 static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 {
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
 	u32 match, reg;
 	int j;
@@ -2312,7 +2312,7 @@
 	}
 #endif
 
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
 	/* Halt the fimrware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
 		       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
@@ -2716,7 +2716,7 @@
 	list_del(element);
 	DEC_STAT(&priv->fw_pend_stat);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	{
 		int i = txq->oldest;
 		IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
@@ -2782,7 +2782,7 @@
 			       "something else: ids %d=%d.\n",
 			       priv->net_dev->name, txq->oldest, packet->index);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (packet->info.c_struct.cmd->host_command_reg <
 		    sizeof(command_types) / sizeof(*command_types))
 			IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
@@ -2975,7 +2975,7 @@
 
 		IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
 			     packet->index, tbd->host_addr, tbd->buf_length);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (packet->info.d_struct.txb->nr_frags > 1)
 			IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
 				       packet->info.d_struct.txb->nr_frags);
@@ -3827,7 +3827,7 @@
 		       priv->rx_interrupts, priv->inta_other);
 	out += sprintf(out, "firmware resets: %d\n", priv->resets);
 	out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	out += sprintf(out, "packet mismatch image: %s\n",
 		       priv->snapshot[0] ? "YES" : "NO");
 #endif
@@ -3982,7 +3982,7 @@
 
 static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
 	return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
@@ -4011,7 +4011,7 @@
 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
 		   store_debug_level);
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
 static ssize_t show_fatal_error(struct device *d,
 				struct device_attribute *attr, char *buf)
@@ -4937,7 +4937,7 @@
 	};
 	int err;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	if (bssid != NULL)
 		IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
 			     bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
@@ -6858,7 +6858,7 @@
 
 	ret = pci_module_init(&ipw2100_pci_driver);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	ipw2100_debug_level = debug;
 	driver_create_file(&ipw2100_pci_driver.driver,
 			   &driver_attr_debug_level);
@@ -6873,7 +6873,7 @@
 static void __exit ipw2100_exit(void)
 {
 	/* FIXME: IPG: check that we have no instances of the devices open */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	driver_remove_file(&ipw2100_pci_driver.driver,
 			   &driver_attr_debug_level);
 #endif
@@ -8558,7 +8558,7 @@
 
 		quality = min(beacon_qual, min(tx_qual, rssi_qual));
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (beacon_qual == quality)
 			IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
 		else if (tx_qual == quality)
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 7c65b10..f6c5144 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -73,7 +73,7 @@
  * you simply need to add your entry to the ipw2100_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw2100 then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2100_DEBUG defined in your kernel configuration
  *
  */
 
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 5e7c7e9..cdfe502 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -462,7 +462,7 @@
 	ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static char *ipw_error_desc(u32 val)
 {
 	switch (val) {
@@ -1235,7 +1235,7 @@
 			      const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 	struct net_device *dev = priv->net_dev;
 #endif
 	char buffer[] = "00000000";
@@ -1754,7 +1754,7 @@
 		IPW_ERROR("Firmware error detected.  Restarting.\n");
 		if (priv->error) {
 			IPW_ERROR("Sysfs 'error' log already exists.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 			if (ipw_debug_level & IPW_DL_FW_ERRORS) {
 				struct ipw_fw_error *error =
 				    ipw_alloc_error_log(priv);
@@ -1770,7 +1770,7 @@
 			else
 				IPW_ERROR("Error allocating sysfs 'error' "
 					  "log.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 			if (ipw_debug_level & IPW_DL_FW_ERRORS)
 				ipw_dump_error_log(priv, priv->error);
 #endif
@@ -3778,7 +3778,7 @@
 	{0x2E, "Cipher suite is rejected per security policy"},
 };
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static const char *ipw_get_status_code(u16 status)
 {
 	int i;
@@ -4250,7 +4250,7 @@
 					if (priv->
 					    status & (STATUS_ASSOCIATED |
 						      STATUS_AUTH)) {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 						struct notif_authenticate *auth
 						    = &notif->u.auth;
 						IPW_DEBUG(IPW_DL_NOTIF |
@@ -4944,12 +4944,11 @@
 	struct ipw_rx_queue *rxq;
 	int i;
 
-	rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+	rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
 	if (unlikely(!rxq)) {
 		IPW_ERROR("memory allocation failed\n");
 		return NULL;
 	}
-	memset(rxq, 0, sizeof(*rxq));
 	spin_lock_init(&rxq->lock);
 	INIT_LIST_HEAD(&rxq->rx_free);
 	INIT_LIST_HEAD(&rxq->rx_used);
@@ -5828,7 +5827,7 @@
 	up(&priv->sem);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static void ipw_debug_config(struct ipw_priv *priv)
 {
 	IPW_DEBUG_INFO("Scan completed, no valid APs matched "
@@ -7456,8 +7455,7 @@
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
 	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
 	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
-	    ((is_multicast_ether_addr(hdr->addr1) ||
-	      is_broadcast_ether_addr(hdr->addr1)) ?
+	    (is_multicast_ether_addr(hdr->addr1) ?
 	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
@@ -7648,8 +7646,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSSID go through */
-		if (is_multicast_ether_addr(header->addr1) ||
-		    is_broadcast_ether_addr(header->addr1))
+		if (is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -7662,8 +7659,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSS go through */
-		if (is_multicast_ether_addr(header->addr1) ||
-		    is_broadcast_ether_addr(header->addr1))
+		if (is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -7815,7 +7811,7 @@
 
 	while (i != r) {
 		rxb = priv->rxq->queue[i];
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 		if (unlikely(rxb == NULL)) {
 			printk(KERN_CRIT "Queue not allocated!\n");
 			break;
@@ -9657,8 +9653,7 @@
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		hdr_len = IEEE80211_3ADDR_LEN;
-		unicast = !(is_multicast_ether_addr(hdr->addr1) ||
-			    is_broadcast_ether_addr(hdr->addr1));
+		unicast = !is_multicast_ether_addr(hdr->addr1);
 		id = ipw_find_station(priv, hdr->addr1);
 		if (id == IPW_INVALID_STATION) {
 			id = ipw_add_station(priv, hdr->addr1);
@@ -9673,8 +9668,7 @@
 
 	case IW_MODE_INFRA:
 	default:
-		unicast = !(is_multicast_ether_addr(hdr->addr3) ||
-			    is_broadcast_ether_addr(hdr->addr3));
+		unicast = !is_multicast_ether_addr(hdr->addr3);
 		hdr_len = IEEE80211_3ADDR_LEN;
 		id = 0;
 		break;
@@ -10956,7 +10950,7 @@
 
 	priv->net_dev = net_dev;
 	priv->pci_dev = pdev;
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 	ipw_debug_level = debug;
 #endif
 	spin_lock_init(&priv->lock);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 1c98db0..e65620a 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1301,14 +1301,14 @@
 
 /* debug macros */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 #define IPW_DEBUG(level, fmt, args...) \
 do { if (ipw_debug_level & (level)) \
   printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
          in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
 #else
 #define IPW_DEBUG(level, fmt, args...) do {} while (0)
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2200_DEBUG */
 
 /*
  * To use the debug system;
@@ -1332,7 +1332,7 @@
  * you simply need to add your entry to the ipw_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2200_DEBUG defined in your kernel configuration
  *
  */
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 3a4f49f..f28ebdd 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1098,6 +1098,23 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_EESSC,	quirk_alder_ioapic );
 #endif
 
+enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
+/* Defaults to combined */
+static enum ide_combined_type combined_mode;
+
+static int __init combined_setup(char *str)
+{
+	if (!strncmp(str, "ide", 3))
+		combined_mode = IDE;
+	else if (!strncmp(str, "libata", 6))
+		combined_mode = LIBATA;
+	else /* "combined" or anything else defaults to old behavior */
+		combined_mode = COMBINED;
+
+	return 1;
+}
+__setup("combined_mode=", combined_setup);
+
 #ifdef CONFIG_SCSI_SATA_INTEL_COMBINED
 static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
 {
@@ -1164,6 +1181,19 @@
 	if (prog & comb)
 		return;
 
+	/* Don't reserve any so the IDE driver can get them (but only if
+	 * combined_mode=ide).
+	 */
+	if (combined_mode == IDE)
+		return;
+
+	/* Grab them both for libata if combined_mode=libata. */
+	if (combined_mode == LIBATA) {
+		request_region(0x1f0, 8, "libata");	/* port 0 */
+		request_region(0x170, 8, "libata");	/* port 1 */
+		return;
+	}
+
 	/* SATA port is in legacy mode.  Reserve port so that
 	 * IDE driver does not attempt to use it.  If request_region
 	 * fails, it will be obvious at boot time, so we don't bother
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index e7ad269..4ce7438 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -857,7 +857,7 @@
 		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
-		scsi_print_msg(hostdata->msgin);
+		spi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
@@ -887,7 +887,7 @@
 #ifdef NCR_700_DEBUG
 	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
 	       NCR_700_phase[(dsps & 0xf00) >> 8]);
-	scsi_print_msg(hostdata->msgin);
+	spi_print_msg(hostdata->msgin);
 	printk("\n");
 #endif
 
@@ -939,7 +939,7 @@
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-		scsi_print_msg(hostdata->msgin);
+		spi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index 362d784..a8c83bb 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -238,21 +238,23 @@
 #ifdef CONFIG_53C700_LE_ON_BE
 #define bE	(hostdata->force_le_on_be ? 0 : 3)
 #define	bSWAP	(hostdata->force_le_on_be)
-/* This is terrible, but there's no raw version of ioread32.  That means
- * that on a be board we swap twice (once in ioread32 and once again to 
- * get the value correct) */
-#define bS_to_io(x)	((hostdata->force_le_on_be) ? (x) : cpu_to_le32(x))
+#define bEBus	(!hostdata->force_le_on_be)
 #elif defined(__BIG_ENDIAN)
 #define bE	3
 #define bSWAP	0
-#define bS_to_io(x)	(x)
 #elif defined(__LITTLE_ENDIAN)
 #define bE	0
 #define bSWAP	0
-#define bS_to_io(x)	(x)
 #else
 #error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?"
 #endif
+#ifndef bEBus
+#ifdef CONFIG_53C700_BE_BUS
+#define bEBus	1
+#else
+#define bEBus	0
+#endif
+#endif
 #define bS_to_cpu(x)	(bSWAP ? le32_to_cpu(x) : (x))
 #define bS_to_host(x)	(bSWAP ? cpu_to_le32(x) : (x))
 
@@ -466,14 +468,15 @@
 {
 	const struct NCR_700_Host_Parameters *hostdata
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
-	__u32 value = ioread32(hostdata->base + reg);
+	__u32 value = bEBus ? ioread32be(hostdata->base + reg) :
+		ioread32(hostdata->base + reg);
 #if 1
 	/* sanity check the register */
 	if((reg & 0x3) != 0)
 		BUG();
 #endif
 
-	return bS_to_io(value);
+	return value;
 }
 
 static inline void
@@ -497,7 +500,8 @@
 		BUG();
 #endif
 
-	iowrite32(bS_to_io(value), hostdata->base + reg);
+	bEBus ? iowrite32be(value, hostdata->base + reg): 
+		iowrite32(value, hostdata->base + reg);
 }
 
 #endif
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 9cb5dd4..7894b8e 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -282,6 +282,7 @@
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "53c7xx.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
@@ -1724,7 +1725,7 @@
 		printk ("scsi%d : status ", host->host_no);
 		scsi_print_status (status);
 		printk ("\nscsi%d : message ", host->host_no);
-		scsi_print_msg (&msg);
+		spi_print_msg(&msg);
 		printk ("\n");
 	    } else if (hostdata->test_completed == 3) {
 		printk("scsi%d : test 2 no connection with target %d\n",
@@ -2313,7 +2314,7 @@
 	    printk ("scsi%d : received message", host->host_no);
 	    if (c) 
 	    	printk (" from target %d lun %d ", c->device->id, c->device->lun);
-	    scsi_print_msg ((unsigned char *) hostdata->msg_buf);
+	    spi_print_msg((unsigned char *) hostdata->msg_buf);
 	    printk("\n");
 	}
 	
@@ -5540,7 +5541,7 @@
 	    i > 0 && !check_address ((unsigned long) ptr, 1);
 	    ptr += len, i -= len) {
 	    printk("               ");
-	    len = scsi_print_msg (ptr);
+	    len = spi_print_msg(ptr);
 	    printk("\n");
 	    if (!len)
 		break;
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 20dd85a..4c42065 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -336,6 +336,7 @@
 config SCSI_AHA152X
 	tristate "Adaptec AHA152X/2825 support"
 	depends on ISA && SCSI && !64BIT
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
 	  SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
@@ -623,6 +624,7 @@
 config SCSI_DMX3191D
 	tristate "DMX3191D SCSI support"
 	depends on PCI && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is support for Domex DMX3191D SCSI Host Adapters.
 
@@ -632,6 +634,7 @@
 config SCSI_DTC3280
 	tristate "DTC3180/3280 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
 	  the SCSI-HOWTO, available from
@@ -752,6 +755,7 @@
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using PIO. Most boards such as the Trantor T130 fit this
@@ -771,6 +775,7 @@
 config SCSI_GENERIC_NCR5380_MMIO
 	tristate "Generic NCR5380/53c400 SCSI MMIO support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using memory mapped I/O. 
@@ -1254,6 +1259,7 @@
 config SCSI_PAS16
 	tristate "PAS16 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is support for a SCSI host adapter.  It is explained in section
 	  3.10 of the SCSI-HOWTO, available from
@@ -1423,6 +1429,7 @@
 config SCSI_T128
 	tristate "Trantor T128/T128F/T228 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is support for a SCSI host adapter. It is explained in section
 	  3.11 of the SCSI-HOWTO, available from
@@ -1681,6 +1688,7 @@
 config ATARI_SCSI
 	tristate "Atari native SCSI support"
 	depends on ATARI && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	---help---
 	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
 	  Falcon, ...) say Y to get it supported. Of course also, if you have
@@ -1722,6 +1730,7 @@
 config MAC_SCSI
 	bool "Macintosh NCR5380 SCSI"
 	depends on MAC && SCSI=y
+	select SCSI_SPI_ATTRS
 	help
 	  This is the NCR 5380 SCSI controller included on most of the 68030
 	  based Macintoshes.  If you have one of these say Y and read the
@@ -1743,6 +1752,7 @@
 config MVME147_SCSI
 	bool "WD33C93 SCSI driver for MVME147"
 	depends on MVME147 && SCSI=y
+	select SCSI_SPI_ATTRS
 	help
 	  Support for the on-board SCSI controller on the Motorola MVME147
 	  single-board computer.
@@ -1750,6 +1760,7 @@
 config MVME16x_SCSI
 	bool "NCR53C710 SCSI driver for MVME16x"
 	depends on MVME16x && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
 	  SCSI controller chip.  Almost everyone using one of these boards
@@ -1758,6 +1769,7 @@
 config BVME6000_SCSI
 	bool "NCR53C710 SCSI driver for BVME6000"
 	depends on BVME6000 && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
 	  SCSI controller chip.  Almost everyone using one of these boards
@@ -1774,6 +1786,7 @@
 config SUN3_SCSI
 	tristate "Sun3 NCR5380 SCSI"
 	depends on SUN3 && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  This option will enable support for the OBIO (onboard io) NCR5380
 	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index cba9655..9f0ddbe 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -87,6 +87,7 @@
  *      the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #ifndef NDEBUG
 #define NDEBUG 0
@@ -2377,7 +2378,7 @@
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
@@ -2424,7 +2425,7 @@
 				default:
 					if (!tmp) {
 						printk("scsi%d: rejecting message ", instance->host_no);
-						scsi_print_msg(extended_msg);
+						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
 						scmd_printk(KERN_INFO, cmd,
@@ -2560,7 +2561,7 @@
 
 	if (!(msg[0] & 0x80)) {
 		printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
-		scsi_print_msg(msg);
+		spi_print_msg(msg);
 		abort = 1;
 	} else {
 		/* Accept message by clearing ACK */
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 9df23b6..cb2ee25 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -259,6 +259,7 @@
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "aha152x.h"
 
 
@@ -1845,7 +1846,7 @@
 #if defined(AHA152X_DEBUG)
 		if (HOSTDATA(shpnt)->debug & debug_msgi) {
 			printk(INFO_LEAD "inbound message %02x ", CMDINFO(CURRENT_SC), MSGI(0));
-			scsi_print_msg(&MSGI(0));
+			spi_print_msg(&MSGI(0));
 			printk("\n");
 		}
 #endif
@@ -1933,7 +1934,7 @@
 						break;
 
 					printk(INFO_LEAD, CMDINFO(CURRENT_SC));
-					scsi_print_msg(&MSGI(0));
+					spi_print_msg(&MSGI(0));
 					printk("\n");
 
 					ticks = (MSGI(3) * 4 + 49) / 50;
@@ -2031,7 +2032,7 @@
 		int i;
 
 		printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));
-		for (i=0; i<MSGOLEN; i+=scsi_print_msg(&MSGO(i)), printk(" "))
+		for (i=0; i<MSGOLEN; i+=spi_print_msg(&MSGO(i)), printk(" "))
 			;
 		printk(")\n");
 	}
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 83467a0..887eaa2 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -243,7 +243,7 @@
 	.port_stop		= ahci_port_stop,
 };
 
-static struct ata_port_info ahci_port_info[] = {
+static const struct ata_port_info ahci_port_info[] = {
 	/* board_ahci */
 	{
 		.sht		= &ahci_sht,
@@ -643,7 +643,8 @@
 	 	 * not being called from the SCSI EH.
 	 	 */
 		qc->scsidone = scsi_finish_command;
-		ata_qc_complete(qc, AC_ERR_OTHER);
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
 	}
 
 	spin_unlock_irqrestore(&host_set->lock, flags);
@@ -664,7 +665,8 @@
 	ci = readl(port_mmio + PORT_CMD_ISSUE);
 	if (likely((ci & 0x1) == 0)) {
 		if (qc) {
-			ata_qc_complete(qc, 0);
+			assert(qc->err_mask == 0);
+			ata_qc_complete(qc);
 			qc = NULL;
 		}
 	}
@@ -681,8 +683,10 @@
 		/* command processing has stopped due to error; restart */
 		ahci_restart_port(ap, status);
 
-		if (qc)
-			ata_qc_complete(qc, err_mask);
+		if (qc) {
+			qc->err_mask |= AC_ERR_OTHER;
+			ata_qc_complete(qc);
+		}
 	}
 
 	return 1;
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 6aab9da..1c8f872 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1064,6 +1064,7 @@
 	struct	Scsi_Host *host;
 	char	*new_name;
 	u_long	s;
+	int	retval;
 
 	template->name = ahd->description;
 	host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
@@ -1096,9 +1097,15 @@
 
 	host->transportt = ahd_linux_transport_template;
 
-	scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
+	retval = scsi_add_host(host, &ahd->dev_softc->dev);
+	if (retval) {
+		printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
+		scsi_host_put(host);
+		return retval;
+	}
+
 	scsi_scan_host(host);
-	return (0);
+	return 0;
 }
 
 uint64_t
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index d866213..fd389e9 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1061,10 +1061,11 @@
 int
 ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
 {
-	char	 buf[80];
-	struct	 Scsi_Host *host;
+	char	buf[80];
+	struct	Scsi_Host *host;
 	char	*new_name;
-	u_long	 s;
+	u_long	s;
+	int	retval;
 
 	template->name = ahc->description;
 	host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
@@ -1097,9 +1098,16 @@
 
 	host->transportt = ahc_linux_transport_template;
 
-	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
+	retval = scsi_add_host(host,
+			(ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
+	if (retval) {
+		printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
+		scsi_host_put(host);
+		return retval;
+	}
+
 	scsi_scan_host(host);
-	return (0);
+	return 0;
 }
 
 /*
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index 13f2304..06d7601 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -4,6 +4,7 @@
 config SCSI_ACORNSCSI_3
 	tristate "Acorn SCSI card (aka30) support"
 	depends on ARCH_ACORN && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  This enables support for the Acorn SCSI card (aka30). If you have an
 	  Acorn system with one of these, say Y. If unsure, say N.
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index b7b20c6..09ed057 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -152,6 +152,7 @@
 #include "../scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "acornscsi.h"
 #include "msgqueue.h"
 #include "scsi.h"
@@ -1370,7 +1371,7 @@
 
 	host->scsi.last_message = msg->msg[0];
 #if (DEBUG & DEBUG_MESSAGES)
-	scsi_print_msg(msg->msg);
+	spi_print_msg(msg->msg);
 #endif
 	break;
 
@@ -1392,7 +1393,7 @@
 	while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
 	    unsigned int i;
 #if (DEBUG & DEBUG_MESSAGES)
-	    scsi_print_msg(msg);
+	    spi_print_msg(msg);
 #endif
 	    i = 0;
 	    if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
@@ -1488,7 +1489,7 @@
 #if (DEBUG & DEBUG_MESSAGES)
     printk("scsi%d.%c: message in: ",
 	    host->host->host_no, acornscsi_target(host));
-    scsi_print_msg(message);
+    spi_print_msg(message);
     printk("\n");
 #endif
 
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 333d69d..0ea2787 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -37,6 +37,49 @@
  *
  *  Hardware documentation available at http://developer.intel.com/
  *
+ * Documentation
+ *	Publically available from Intel web site. Errata documentation
+ * is also publically available. As an aide to anyone hacking on this
+ * driver the list of errata that are relevant is below.going back to
+ * PIIX4. Older device documentation is now a bit tricky to find.
+ *
+ * The chipsets all follow very much the same design. The orginal Triton
+ * series chipsets do _not_ support independant device timings, but this
+ * is fixed in Triton II. With the odd mobile exception the chips then
+ * change little except in gaining more modes until SATA arrives. This
+ * driver supports only the chips with independant timing (that is those
+ * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix
+ * for the early chip drivers.
+ *
+ * Errata of note:
+ *
+ * Unfixable
+ *	PIIX4    errata #9	- Only on ultra obscure hw
+ *	ICH3	 errata #13     - Not observed to affect real hw
+ *				  by Intel
+ *
+ * Things we must deal with
+ *	PIIX4	errata #10	- BM IDE hang with non UDMA
+ *				  (must stop/start dma to recover)
+ *	440MX   errata #15	- As PIIX4 errata #10
+ *	PIIX4	errata #15	- Must not read control registers
+ * 				  during a PIO transfer
+ *	440MX   errata #13	- As PIIX4 errata #15
+ *	ICH2	errata #21	- DMA mode 0 doesn't work right
+ *	ICH0/1  errata #55	- As ICH2 errata #21
+ *	ICH2	spec c #9	- Extra operations needed to handle
+ *				  drive hotswap [NOT YET SUPPORTED]
+ *	ICH2    spec c #20	- IDE PRD must not cross a 64K boundary
+ *				  and must be dword aligned
+ *	ICH2    spec c #24	- UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ *
+ * Should have been BIOS fixed:
+ *	450NX:	errata #19	- DMA hangs on old 450NX
+ *	450NX:  errata #20	- DMA hangs on old 450NX
+ *	450NX:  errata #25	- Corruption with DMA on old 450NX
+ *	ICH3    errata #15      - IDE deadlock under high load
+ *				  (BIOS must set dev 31 fn 0 bit 23)
+ *	ICH3	errata #18	- Don't use native mode
  */
 
 #include <linux/kernel.h>
@@ -78,9 +121,7 @@
 	ich5_sata		= 1,
 	piix4_pata		= 2,
 	ich6_sata		= 3,
-	ich6_sata_rm		= 4,
-	ich7_sata		= 5,
-	esb2_sata		= 6,
+	ich6_sata_ahci		= 4,
 
 	PIIX_AHCI_DEVICE	= 6,
 };
@@ -111,11 +152,11 @@
 	{ 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
 	{ 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
 	{ 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 },
-	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
+	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 
 	{ }	/* terminate list */
 };
@@ -258,31 +299,7 @@
 		.port_ops	= &piix_sata_ops,
 	},
 
-	/* 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 |
-				  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,
-	},
-
-	/* esb2_sata */
+	/* ich6_sata_ahci */
 	{
 		.sht		= &piix_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
@@ -603,6 +620,40 @@
 }
 
 /**
+ *	piix_check_450nx_errata	-	Check for problem 450NX setup
+ *	
+ *	Check for the present of 450NX errata #19 and errata #25. If
+ *	they are found return an error code so we can turn off DMA
+ */
+
+static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
+{
+	struct pci_dev *pdev = NULL;
+	u16 cfg;
+	u8 rev;
+	int no_piix_dma = 0;
+	
+	while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
+	{
+		/* Look for 450NX PXB. Check for problem configurations
+		   A PCI quirk checks bit 6 already */
+		pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+		pci_read_config_word(pdev, 0x41, &cfg);
+		/* Only on the original revision: IDE DMA can hang */
+		if(rev == 0x00)
+			no_piix_dma = 1;
+		/* On all revisions below 5 PXB bus lock must be disabled for IDE */
+		else if(cfg & (1<<14) && rev < 5)
+			no_piix_dma = 2;
+	}
+	if(no_piix_dma)
+		dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n");
+	if(no_piix_dma == 2)
+		dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n");
+	return no_piix_dma;
+}		
+
+/**
  *	piix_init_one - Register PIIX ATA PCI device with kernel services
  *	@pdev: PCI device to register
  *	@ent: Entry in piix_pci_tbl matching with @pdev
@@ -676,7 +727,15 @@
 			   "combined mode detected (p=%u, s=%u)\n",
 			   pata_chan, sata_chan);
 	}
-
+	if (piix_check_450nx_errata(pdev)) {
+		/* This writes into the master table but it does not
+		   really matter for this errata as we will apply it to
+		   all the PIIX devices on the board */
+		port_info[0]->mwdma_mask = 0;
+		port_info[0]->udma_mask = 0;
+		port_info[1]->mwdma_mask = 0;
+		port_info[1]->udma_mask = 0;
+	}
 	return ata_pci_init_one(pdev, port_info, 2);
 }
 
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 2ae31ce..57295bc 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -74,6 +74,7 @@
  *     the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) \
@@ -2355,7 +2356,7 @@
  * 3..length+1	arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 		    extended_msg[0] = EXTENDED_MESSAGE;
 		    /* Accept first byte by clearing ACK */
@@ -2408,7 +2409,7 @@
 		default:
 		    if (!tmp) {
 			printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-			scsi_print_msg (extended_msg);
+			spi_print_msg(extended_msg);
 			printk("\n");
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2541,7 +2542,7 @@
 
     if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-	scsi_print_msg(msg);
+	spi_print_msg(msg);
 	do_abort(instance);
 	return;
     }
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index ccbbae2..0920220 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -75,7 +75,7 @@
 module_param_array(vendor_firsts, int, NULL, 0444);
 module_param_array(vendor_counts, int, NULL, 0444);
 
-static char *vendor_labels[CH_TYPES-4] = {
+static const char * vendor_labels[CH_TYPES-4] = {
 	"v0", "v1", "v2", "v3"
 };
 // module_param_string_array(vendor_labels, NULL, 0444);
@@ -140,7 +140,7 @@
 #endif
 };
 
-static struct {
+static const struct {
 	unsigned char  sense;
 	unsigned char  asc;
 	unsigned char  ascq;
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 09bc815..30a3353 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1065,7 +1065,7 @@
 	const char * fmt;
 };
 
-static struct error_info2 additional2[] =
+static const struct error_info2 additional2[] =
 {
 	{0x40,0x00,0x7f,"Ram failure (%x)"},
 	{0x40,0x80,0xff,"Diagnostic failure on component (%x)"},
@@ -1077,7 +1077,7 @@
 };
 
 /* description of the sense key values */
-static const char *snstext[] = {
+static const char * const snstext[] = {
 	"No Sense",	    /* 0: There is no sense information */
 	"Recovered Error",  /* 1: The last command completed successfully
 				  but used error correction */
@@ -1278,114 +1278,6 @@
 }
 EXPORT_SYMBOL(scsi_print_req_sense);
 
-#ifdef CONFIG_SCSI_CONSTANTS
-static const char *one_byte_msgs[] = {
-/* 0x00 */ "Command Complete", NULL, "Save Pointers",
-/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
-/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
-/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
-/* 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 *))
-
-
-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) {
-		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 (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 ((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)
 {
 	/* Assume appended output (i.e. not at start of line) */
@@ -1397,7 +1289,7 @@
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * hostbyte_table[]={
+static const char * const 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"};
@@ -1422,12 +1314,12 @@
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * driverbyte_table[]={
+static const char * const driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
 "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",
+static const char * const driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
 "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
 #define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index fa2cb35..b6714da 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5887,7 +5887,12 @@
 	ENTER;
 	spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 	dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg);
-	_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE);
+	if (ioa_cfg->needs_hard_reset) {
+		ioa_cfg->needs_hard_reset = 0;
+		ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+	} else
+		_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
+					IPR_SHUTDOWN_NONE);
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
 	wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
@@ -6264,6 +6269,7 @@
 	unsigned long ipr_regs_pci;
 	void __iomem *ipr_regs;
 	u32 rc = PCIBIOS_SUCCESSFUL;
+	volatile u32 mask, uproc;
 
 	ENTER;
 
@@ -6356,6 +6362,15 @@
 		goto cleanup_nomem;
 	}
 
+	/*
+	 * If HRRQ updated interrupt is not masked, or reset alert is set,
+	 * the card is in an unknown state and needs a hard reset
+	 */
+	mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+	uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+	if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
+		ioa_cfg->needs_hard_reset = 1;
+
 	ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
 	rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg);
 
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 6bec673..b639332 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.0"
-#define IPR_DRIVER_DATE "(October 31, 2005)"
+#define IPR_DRIVER_VERSION "2.1.1"
+#define IPR_DRIVER_DATE "(November 15, 2005)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -922,6 +922,7 @@
 	u8 dump_taken:1;
 	u8 allow_cmds:1;
 	u8 allow_ml_add_del:1;
+	u8 needs_hard_reset:1;
 
 	enum ipr_cache_state cache_state;
 	u16 type; /* CCIN of the card */
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 3d8009f..10bcf42 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -49,7 +49,7 @@
 	      "Alex Aizman <itn780@yahoo.com>");
 MODULE_DESCRIPTION("iSCSI/TCP data-path");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0:4.409");
+MODULE_VERSION("0:4.445");
 /* #define DEBUG_TCP */
 /* #define DEBUG_SCSI */
 #define DEBUG_ASSERT
@@ -581,10 +581,16 @@
 		crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
 		rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
 				     conn->in.ahslen);
+		if (cdgst != rdgst) {
+			printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
+			       "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
+			       cdgst);
+			return ISCSI_ERR_HDR_DGST;
+		}
 	}
 
 	/* save opcode for later */
-	conn->in.opcode = hdr->opcode;
+	conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
 	/* verify itt (itt encoding: age+cid+itt) */
 	if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
@@ -610,13 +616,6 @@
 		  conn->in.ahslen, conn->in.datalen);
 
 	if (conn->in.itt < session->cmds_max) {
-		if (conn->hdrdgst_en && cdgst != rdgst) {
-			printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
-			       "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
-			       cdgst);
-			return ISCSI_ERR_HDR_DGST;
-		}
-
 		ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
 
 		if (!ctask->sc) {
@@ -642,9 +641,7 @@
 		switch(conn->in.opcode) {
 		case ISCSI_OP_SCSI_CMD_RSP:
 			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)
-				rc = iscsi_cmd_rsp(conn, ctask);
-			else if (!conn->in.datalen)
+			if (!conn->in.datalen)
 				rc = iscsi_cmd_rsp(conn, ctask);
 			else
 				/*
@@ -666,8 +663,7 @@
 			break;
 		case ISCSI_OP_R2T:
 			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&
-			    ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+			if (ctask->sc->sc_data_direction == DMA_TO_DEVICE)
 				rc = iscsi_r2t_rsp(conn, ctask);
 			else
 				rc = ISCSI_ERR_PROTO;
@@ -906,11 +902,20 @@
 	crypto_digest_update(conn->data_rx_tfm, &temp, 1);
 }
 
+static void
+iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len)
+{
+	struct scatterlist tmp;
+
+	sg_init_one(&tmp, buf, len);
+	crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
+}
+
 static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 {
 	struct iscsi_cmd_task *ctask = conn->in.ctask;
 	struct scsi_cmnd *sc = ctask->sc;
-	struct scatterlist tmp, *sg;
+	struct scatterlist *sg;
 	int i, offset, rc = 0;
 
 	BUG_ON((void*)ctask != sc->SCp.ptr);
@@ -924,10 +929,8 @@
 				      sc->request_bufflen, ctask->data_offset);
 		if (rc == -EAGAIN)
 			return rc;
-		if (conn->datadgst_en) {
-			sg_init_one(&tmp, sc->request_buffer, i);
-			crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
-		}
+		if (conn->datadgst_en) 
+			iscsi_recv_digest_update(conn, sc->request_buffer, i);
 		rc = 0;
 		goto done;
 	}
@@ -1021,6 +1024,9 @@
 		conn->in.hdr = &conn->hdr;
 		conn->senselen = (conn->data[0] << 8) | conn->data[1];
 		rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+		if (!rc && conn->datadgst_en) 
+			iscsi_recv_digest_update(conn, conn->data,
+						 conn->in.datalen);
 	}
 	break;
 	case ISCSI_OP_TEXT_RSP:
@@ -1045,6 +1051,11 @@
 		rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
 				    conn->data, conn->in.datalen);
 
+		if (!rc && conn->datadgst_en && 
+			conn->in.opcode != ISCSI_OP_LOGIN_RSP)
+			iscsi_recv_digest_update(conn, conn->data,
+			  			conn->in.datalen);
+
 		if (mtask && conn->login_mtask != mtask) {
 			spin_lock(&session->lock);
 			__kfifo_put(session->mgmtpool.queue, (void*)&mtask,
@@ -1053,6 +1064,8 @@
 		}
 	}
 	break;
+	case ISCSI_OP_ASYNC_EVENT:
+	case ISCSI_OP_REJECT:
 	default:
 		BUG_ON(1);
 	}
@@ -1114,8 +1127,7 @@
 		 */
 		rc = iscsi_hdr_recv(conn);
 		if (!rc && conn->in.datalen) {
-			if (conn->datadgst_en &&
-			    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+			if (conn->datadgst_en) {
 				BUG_ON(!conn->data_rx_tfm);
 				crypto_digest_init(conn->data_rx_tfm);
 			}
@@ -1127,26 +1139,24 @@
 	}
 
 	if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+		uint32_t recv_digest;
 		debug_tcp("extra data_recv offset %d copy %d\n",
 			  conn->in.offset, conn->in.copy);
-		if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
-			uint32_t recv_digest;
-			skb_copy_bits(conn->in.skb, conn->in.offset,
-				      &recv_digest, 4);
-			conn->in.offset += 4;
-			conn->in.copy -= 4;
-			if (recv_digest != conn->in.datadgst) {
-				debug_tcp("iscsi_tcp: data digest error!"
-					  "0x%x != 0x%x\n", recv_digest,
-					  conn->in.datadgst);
-				iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
-				return 0;
-			} else {
-				debug_tcp("iscsi_tcp: data digest match!"
-					  "0x%x == 0x%x\n", recv_digest,
-					  conn->in.datadgst);
-				conn->in_progress = IN_PROGRESS_WAIT_HEADER;
-			}
+		skb_copy_bits(conn->in.skb, conn->in.offset,
+				&recv_digest, 4);
+		conn->in.offset += 4;
+		conn->in.copy -= 4;
+		if (recv_digest != conn->in.datadgst) {
+			debug_tcp("iscsi_tcp: data digest error!"
+				  "0x%x != 0x%x\n", recv_digest,
+				  conn->in.datadgst);
+			iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+			return 0;
+		} else {
+			debug_tcp("iscsi_tcp: data digest match!"
+				  "0x%x == 0x%x\n", recv_digest,
+				  conn->in.datadgst);
+			conn->in_progress = IN_PROGRESS_WAIT_HEADER;
 		}
 	}
 
@@ -1167,8 +1177,7 @@
 		}
 		conn->in.copy -= conn->in.padding;
 		conn->in.offset += conn->in.padding;
-		if (conn->datadgst_en &&
-		    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+		if (conn->datadgst_en) {
 			if (conn->in.padding) {
 				debug_tcp("padding -> %d\n", conn->in.padding);
 				memset(pad, 0, conn->in.padding);
@@ -1237,8 +1246,9 @@
 	conn = (struct iscsi_conn*)sk->sk_user_data;
 	session = conn->session;
 
-	if (sk->sk_state == TCP_CLOSE_WAIT ||
-	    sk->sk_state == TCP_CLOSE) {
+	if ((sk->sk_state == TCP_CLOSE_WAIT ||
+	     sk->sk_state == TCP_CLOSE) &&
+	    !atomic_read(&sk->sk_rmem_alloc)) {
 		debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
 	}
@@ -2389,6 +2399,15 @@
 }
 
 static int
+iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+{
+	if (depth > ISCSI_MAX_CMD_PER_LUN)
+		depth = ISCSI_MAX_CMD_PER_LUN;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	return sdev->queue_depth;
+}
+
+static int
 iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
 {
 	int i;
@@ -2853,8 +2872,11 @@
 		 * in hdr_extract() and will be re-negotiated at
 		 * set_param() time.
 		 */
-		if (flag == STOP_CONN_RECOVER)
+		if (flag == STOP_CONN_RECOVER) {
 			conn->hdr_size = sizeof(struct iscsi_hdr);
+			conn->hdrdgst_en = 0;
+			conn->datadgst_en = 0;
+		}
 	}
 	up(&conn->xmitsema);
 }
@@ -3247,13 +3269,14 @@
 static struct scsi_host_template iscsi_sht = {
 	.name			= "iSCSI Initiator over TCP/IP, v."
 				  ISCSI_VERSION_STR,
-        .queuecommand           = iscsi_queuecommand,
+	.queuecommand           = iscsi_queuecommand,
+	.change_queue_depth	= iscsi_change_queue_depth,
 	.can_queue		= ISCSI_XMIT_CMDS_MAX - 1,
 	.sg_tablesize		= ISCSI_SG_TABLESIZE,
-	.cmd_per_lun		= ISCSI_CMD_PER_LUN,
-        .eh_abort_handler       = iscsi_eh_abort,
-        .eh_host_reset_handler	= iscsi_eh_host_reset,
-        .use_clustering         = DISABLE_CLUSTERING,
+	.cmd_per_lun		= ISCSI_DEF_CMD_PER_LUN,
+	.eh_abort_handler       = iscsi_eh_abort,
+	.eh_host_reset_handler	= iscsi_eh_host_reset,
+	.use_clustering         = DISABLE_CLUSTERING,
 	.proc_name		= "iscsi_tcp",
 	.this_id		= -1,
 };
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index d23ae68..855f2df 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -71,7 +71,8 @@
 #define ISCSI_MGMT_CMDS_MAX		32	/* must be power of 2 */
 #define ISCSI_MGMT_ITT_OFFSET		0xa00
 #define ISCSI_SG_TABLESIZE		SG_ALL
-#define ISCSI_CMD_PER_LUN		128
+#define ISCSI_DEF_CMD_PER_LUN		32
+#define ISCSI_MAX_CMD_PER_LUN		128
 #define ISCSI_TCP_MAX_CMD_LEN		16
 
 #define ITT_MASK			(0xfff)
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index d0a0fdb..9ea1025 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -605,7 +605,7 @@
 	tf->command = ata_rw_cmds[index + lba48 + write];
 }
 
-static const char * xfer_mode_str[] = {
+static const char * const xfer_mode_str[] = {
 	"UDMA/16",
 	"UDMA/25",
 	"UDMA/33",
@@ -1046,28 +1046,103 @@
 	return modes;
 }
 
-static int ata_qc_wait_err(struct ata_queued_cmd *qc,
-			   struct completion *wait)
+struct ata_exec_internal_arg {
+	unsigned int err_mask;
+	struct ata_taskfile *tf;
+	struct completion *waiting;
+};
+
+int ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
-	int rc = 0;
+	struct ata_exec_internal_arg *arg = qc->private_data;
+	struct completion *waiting = arg->waiting;
 
-	if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
-		/* timeout handling */
-		unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+	if (!(qc->err_mask & ~AC_ERR_DEV))
+		qc->ap->ops->tf_read(qc->ap, arg->tf);
+	arg->err_mask = qc->err_mask;
+	arg->waiting = NULL;
+	complete(waiting);
 
-		if (!err_mask) {
-			printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
-			       qc->ap->id, qc->tf.command);
-		} else {
-			printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
-			       qc->ap->id, qc->tf.command);
-			rc = -EIO;
-		}
+	return 0;
+}
 
-		ata_qc_complete(qc, err_mask);
+/**
+ *	ata_exec_internal - execute libata internal command
+ *	@ap: Port to which the command is sent
+ *	@dev: Device to which the command is sent
+ *	@tf: Taskfile registers for the command and the result
+ *	@dma_dir: Data tranfer direction of the command
+ *	@buf: Data buffer of the command
+ *	@buflen: Length of data buffer
+ *
+ *	Executes libata internal command with timeout.  @tf contains
+ *	command on entry and result on return.  Timeout and error
+ *	conditions are reported via return value.  No recovery action
+ *	is taken after a command times out.  It's caller's duty to
+ *	clean up after timeout.
+ *
+ *	LOCKING:
+ *	None.  Should be called with kernel context, might sleep.
+ */
+
+static unsigned
+ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+		  struct ata_taskfile *tf,
+		  int dma_dir, void *buf, unsigned int buflen)
+{
+	u8 command = tf->command;
+	struct ata_queued_cmd *qc;
+	DECLARE_COMPLETION(wait);
+	unsigned long flags;
+	struct ata_exec_internal_arg arg;
+
+	spin_lock_irqsave(&ap->host_set->lock, flags);
+
+	qc = ata_qc_new_init(ap, dev);
+	BUG_ON(qc == NULL);
+
+	qc->tf = *tf;
+	qc->dma_dir = dma_dir;
+	if (dma_dir != DMA_NONE) {
+		ata_sg_init_one(qc, buf, buflen);
+		qc->nsect = buflen / ATA_SECT_SIZE;
 	}
 
-	return rc;
+	arg.waiting = &wait;
+	arg.tf = tf;
+	qc->private_data = &arg;
+	qc->complete_fn = ata_qc_complete_internal;
+
+	if (ata_qc_issue(qc))
+		goto issue_fail;
+
+	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+	if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
+		spin_lock_irqsave(&ap->host_set->lock, flags);
+
+		/* We're racing with irq here.  If we lose, the
+		 * following test prevents us from completing the qc
+		 * again.  If completion irq occurs after here but
+		 * before the caller cleans up, it will result in a
+		 * spurious interrupt.  We can live with that.
+		 */
+		if (arg.waiting) {
+			qc->err_mask = AC_ERR_OTHER;
+			ata_qc_complete(qc);
+			printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
+			       ap->id, command);
+		}
+
+		spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	}
+
+	return arg.err_mask;
+
+ issue_fail:
+	ata_qc_free(qc);
+	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	return AC_ERR_OTHER;
 }
 
 /**
@@ -1099,9 +1174,8 @@
 	u16 tmp;
 	unsigned long xfer_modes;
 	unsigned int using_edd;
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
+	struct ata_taskfile tf;
+	unsigned int err_mask;
 	int rc;
 
 	if (!ata_dev_present(dev)) {
@@ -1122,40 +1196,26 @@
 
 	ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
-
-	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-	qc->dma_dir = DMA_FROM_DEVICE;
-	qc->tf.protocol = ATA_PROT_PIO;
-	qc->nsect = 1;
-
 retry:
+	ata_tf_init(ap, &tf, device);
+
 	if (dev->class == ATA_DEV_ATA) {
-		qc->tf.command = ATA_CMD_ID_ATA;
+		tf.command = ATA_CMD_ID_ATA;
 		DPRINTK("do ATA identify\n");
 	} else {
-		qc->tf.command = ATA_CMD_ID_ATAPI;
+		tf.command = ATA_CMD_ID_ATAPI;
 		DPRINTK("do ATAPI identify\n");
 	}
 
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
+	tf.protocol = ATA_PROT_PIO;
 
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+				     dev->id, sizeof(dev->id));
 
-	if (rc)
-		goto err_out;
-	else
-		ata_qc_wait_err(qc, &wait);
+	if (err_mask) {
+		if (err_mask & ~AC_ERR_DEV)
+			goto err_out;
 
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	ap->ops->tf_read(ap, &qc->tf);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (qc->tf.command & ATA_ERR) {
 		/*
 		 * arg!  EDD works for all test cases, but seems to return
 		 * the ATA signature for some ATAPI devices.  Until the
@@ -1168,13 +1228,9 @@
 		 * to have this problem.
 		 */
 		if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
-			u8 err = qc->tf.feature;
+			u8 err = tf.feature;
 			if (err & ATA_ABORTED) {
 				dev->class = ATA_DEV_ATAPI;
-				qc->cursg = 0;
-				qc->cursg_ofs = 0;
-				qc->cursect = 0;
-				qc->nsect = 1;
 				goto retry;
 			}
 		}
@@ -1444,11 +1500,23 @@
 	} while (time_before(jiffies, timeout));
 
 	/* TODO: phy layer with polling, timeouts, etc. */
-	if (sata_dev_present(ap))
+	sstatus = scr_read(ap, SCR_STATUS);
+	if (sata_dev_present(ap)) {
+		const char *speed;
+		u32 tmp;
+
+		tmp = (sstatus >> 4) & 0xf;
+		if (tmp & (1 << 0))
+			speed = "1.5";
+		else if (tmp & (1 << 1))
+			speed = "3.0";
+		else
+			speed = "<unknown>";
+		printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
+		       ap->id, speed, sstatus);
 		ata_port_probe(ap);
-	else {
-		sstatus = scr_read(ap, SCR_STATUS);
-		printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+	} else {
+		printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
 		       ap->id, sstatus);
 		ata_port_disable(ap);
 	}
@@ -2071,7 +2139,7 @@
 		ap->id, dev->devno);
 }
 
-static const char * ata_dma_blacklist [] = {
+static const char * const ata_dma_blacklist [] = {
 	"WDC AC11000H",
 	"WDC AC22100H",
 	"WDC AC32500H",
@@ -2266,34 +2334,23 @@
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	int rc;
-	unsigned long flags;
+	struct ata_taskfile tf;
 
 	/* set up set-features taskfile */
 	DPRINTK("set features - xfer mode\n");
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
+	ata_tf_init(ap, &tf, dev->devno);
+	tf.command = ATA_CMD_SET_FEATURES;
+	tf.feature = SETFEATURES_XFER;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+	tf.nsect = dev->xfer_mode;
 
-	qc->tf.command = ATA_CMD_SET_FEATURES;
-	qc->tf.feature = SETFEATURES_XFER;
-	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_NODATA;
-	qc->tf.nsect = dev->xfer_mode;
-
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+		printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n",
+		       ap->id);
 		ata_port_disable(ap);
-	else
-		ata_qc_wait_err(qc, &wait);
+	}
 
 	DPRINTK("EXIT\n");
 }
@@ -2308,41 +2365,25 @@
 
 static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
-	int rc;
+	struct ata_taskfile tf;
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
-
-	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-	qc->dma_dir = DMA_FROM_DEVICE;
+	ata_tf_init(ap, &tf, dev->devno);
 
 	if (dev->class == ATA_DEV_ATA) {
-		qc->tf.command = ATA_CMD_ID_ATA;
+		tf.command = ATA_CMD_ID_ATA;
 		DPRINTK("do ATA identify\n");
 	} else {
-		qc->tf.command = ATA_CMD_ID_ATAPI;
+		tf.command = ATA_CMD_ID_ATAPI;
 		DPRINTK("do ATAPI identify\n");
 	}
 
-	qc->tf.flags |= ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_PIO;
-	qc->nsect = 1;
+	tf.flags |= ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_PIO;
 
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+			      dev->id, sizeof(dev->id)))
 		goto err_out;
 
-	ata_qc_wait_err(qc, &wait);
-
 	swap_buf_le16(dev->id, ATA_ID_WORDS);
 
 	ata_dump_id(dev);
@@ -2351,6 +2392,7 @@
 
 	return;
 err_out:
+	printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
 	ata_port_disable(ap);
 }
 
@@ -2364,10 +2406,7 @@
 
 static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	int rc;
-	unsigned long flags;
+	struct ata_taskfile tf;
 	u16 sectors = dev->id[6];
 	u16 heads   = dev->id[3];
 
@@ -2378,26 +2417,18 @@
 	/* set up init dev params taskfile */
 	DPRINTK("init dev params \n");
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
+	ata_tf_init(ap, &tf, dev->devno);
+	tf.command = ATA_CMD_INIT_DEV_PARAMS;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+	tf.nsect = sectors;
+	tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-	qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
-	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_NODATA;
-	qc->tf.nsect = sectors;
-	qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
-
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+		printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
+		       ap->id);
 		ata_port_disable(ap);
-	else
-		ata_qc_wait_err(qc, &wait);
+	}
 
 	DPRINTK("EXIT\n");
 }
@@ -2765,7 +2796,7 @@
  *	None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	unsigned long flags;
@@ -2773,7 +2804,7 @@
 	spin_lock_irqsave(&ap->host_set->lock, flags);
 	ap->flags &= ~ATA_FLAG_NOINTR;
 	ata_irq_on(ap);
-	ata_qc_complete(qc, err_mask);
+	ata_qc_complete(qc);
 	spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2790,10 +2821,14 @@
 
 static unsigned long ata_pio_poll(struct ata_port *ap)
 {
+	struct ata_queued_cmd *qc;
 	u8 status;
 	unsigned int poll_state = HSM_ST_UNKNOWN;
 	unsigned int reg_state = HSM_ST_UNKNOWN;
 
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	assert(qc != NULL);
+
 	switch (ap->hsm_task_state) {
 	case HSM_ST:
 	case HSM_ST_POLL:
@@ -2813,6 +2848,7 @@
 	status = ata_chk_status(ap);
 	if (status & ATA_BUSY) {
 		if (time_after(jiffies, ap->pio_task_timeout)) {
+			qc->err_mask |= AC_ERR_ATA_BUS;
 			ap->hsm_task_state = HSM_ST_TMOUT;
 			return 0;
 		}
@@ -2847,29 +2883,31 @@
 	 * msecs, then chk-status again.  If still busy, fall back to
 	 * HSM_ST_POLL state.
 	 */
-	drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-	if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+	drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+	if (drv_stat & ATA_BUSY) {
 		msleep(2);
-		drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-		if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+		drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+		if (drv_stat & ATA_BUSY) {
 			ap->hsm_task_state = HSM_ST_LAST_POLL;
 			ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
 			return 0;
 		}
 	}
 
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	assert(qc != NULL);
+
 	drv_stat = ata_wait_idle(ap);
 	if (!ata_ok(drv_stat)) {
+		qc->err_mask |= __ac_err_mask(drv_stat);
 		ap->hsm_task_state = HSM_ST_ERR;
 		return 0;
 	}
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
-	assert(qc != NULL);
-
 	ap->hsm_task_state = HSM_ST_IDLE;
 
-	ata_poll_qc_complete(qc, 0);
+	assert(qc->err_mask == 0);
+	ata_poll_qc_complete(qc);
 
 	/* another command may start at this point */
 
@@ -3177,6 +3215,7 @@
 err_out:
 	printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
 	      ap->id, dev->devno);
+	qc->err_mask |= AC_ERR_ATA_BUS;
 	ap->hsm_task_state = HSM_ST_ERR;
 }
 
@@ -3215,8 +3254,16 @@
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	assert(qc != NULL);
 
+	/* check error */
+	if (status & (ATA_ERR | ATA_DF)) {
+		qc->err_mask |= AC_ERR_DEV;
+		ap->hsm_task_state = HSM_ST_ERR;
+		return;
+	}
+
+	/* transfer data if any */
 	if (is_atapi_taskfile(&qc->tf)) {
-		/* no more data to transfer or unsupported ATAPI command */
+		/* DRQ=0 means no more data to transfer */
 		if ((status & ATA_DRQ) == 0) {
 			ap->hsm_task_state = HSM_ST_LAST;
 			return;
@@ -3226,6 +3273,7 @@
 	} else {
 		/* handle BSY=0, DRQ=0 as error */
 		if ((status & ATA_DRQ) == 0) {
+			qc->err_mask |= AC_ERR_ATA_BUS;
 			ap->hsm_task_state = HSM_ST_ERR;
 			return;
 		}
@@ -3243,9 +3291,14 @@
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	assert(qc != NULL);
 
+	/* make sure qc->err_mask is available to 
+	 * know what's wrong and recover
+	 */
+	assert(qc->err_mask);
+
 	ap->hsm_task_state = HSM_ST_IDLE;
 
-	ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
+	ata_poll_qc_complete(qc);
 }
 
 static void ata_pio_task(void *_data)
@@ -3347,7 +3400,8 @@
 		       ap->id, qc->tf.command, drv_stat, host_stat);
 
 		/* complete taskfile transaction */
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
@@ -3446,15 +3500,10 @@
 	return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
-{
-	return 0;
-}
-
 static void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	unsigned int tag, do_clear = 0;
+	unsigned int tag;
 
 	qc->flags = 0;
 	tag = qc->tag;
@@ -3462,17 +3511,8 @@
 		if (tag == ap->active_tag)
 			ap->active_tag = ATA_TAG_POISON;
 		qc->tag = ATA_TAG_POISON;
-		do_clear = 1;
-	}
-
-	if (qc->waiting) {
-		struct completion *waiting = qc->waiting;
-		qc->waiting = NULL;
-		complete(waiting);
-	}
-
-	if (likely(do_clear))
 		clear_bit(tag, &ap->qactive);
+	}
 }
 
 /**
@@ -3488,7 +3528,6 @@
 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);
 }
@@ -3505,7 +3544,7 @@
  *	spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_qc_complete(struct ata_queued_cmd *qc)
 {
 	int rc;
 
@@ -3522,7 +3561,7 @@
 	qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
 	/* call completion callback */
-	rc = qc->complete_fn(qc, err_mask);
+	rc = qc->complete_fn(qc);
 
 	/* if callback indicates not to complete command (non-zero),
 	 * return immediately
@@ -3960,7 +3999,8 @@
 		ap->ops->irq_clear(ap);
 
 		/* complete taskfile transaction */
-		ata_qc_complete(qc, ac_err_mask(status));
+		qc->err_mask |= ac_err_mask(status);
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -4054,13 +4094,17 @@
 
 	/* sleep-wait for BSY to clear */
 	DPRINTK("busy wait\n");
-	if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-		goto err_out_status;
+	if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+		qc->err_mask |= AC_ERR_ATA_BUS;
+		goto err_out;
+	}
 
 	/* make sure DRQ is set */
 	status = ata_chk_status(ap);
-	if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
+	if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+		qc->err_mask |= AC_ERR_ATA_BUS;
 		goto err_out;
+	}
 
 	/* send SCSI cdb */
 	DPRINTK("send cdb\n");
@@ -4092,10 +4136,8 @@
 
 	return;
 
-err_out_status:
-	status = ata_chk_status(ap);
 err_out:
-	ata_poll_qc_complete(qc, __ac_err_mask(status));
+	ata_poll_qc_complete(qc);
 }
 
 
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 2282c04..e0439be 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -418,7 +418,7 @@
 	int i;
 
 	/* Based on the 3ware driver translation table */
-	static unsigned char sense_table[][4] = {
+	static const unsigned char sense_table[][4] = {
 		/* BBD|ECC|ID|MAR */
 		{0xd1, 		ABORTED_COMMAND, 0x00, 0x00}, 	// Device busy                  Aborted command
 		/* BBD|ECC|ID */
@@ -449,7 +449,7 @@
 		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		  Medium error, unrecovered read error
 		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
 	};
-	static unsigned char stat_table[][4] = {
+	static const unsigned char stat_table[][4] = {
 		/* Must be first because BUSY means no other bits valid */
 		{0x80, 		ABORTED_COMMAND, 0x47, 0x00},	// Busy, fake parity for now
 		{0x20, 		HARDWARE_ERROR,  0x00, 0x00}, 	// Device fault
@@ -1203,12 +1203,11 @@
 	return 1;
 }
 
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
-				unsigned int err_mask)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
 	u8 *cdb = cmd->cmnd;
- 	int need_sense = (err_mask != 0);
+ 	int need_sense = (qc->err_mask != 0);
 
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	 * user mandated it or if there's an error.  Note that if we
@@ -1532,7 +1531,7 @@
 	return 0;
 }
 
-static const char *inq_83_str = "Linux ATA-SCSI simulator";
+static const char * const inq_83_str = "Linux ATA-SCSI simulator";
 
 /**
  *	ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
@@ -1955,9 +1954,9 @@
 	done(cmd);
 }
 
-static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
+static int atapi_sense_complete(struct ata_queued_cmd *qc)
 {
-	if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+	if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
 		/* FIXME: not quite right; we don't want the
 		 * translation of taskfile registers into
 		 * a sense descriptors, since that's only
@@ -2015,15 +2014,18 @@
 
 	qc->complete_fn = atapi_sense_complete;
 
-	if (ata_qc_issue(qc))
-		ata_qc_complete(qc, AC_ERR_OTHER);
+	if (ata_qc_issue(qc)) {
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
+	}
 
 	DPRINTK("EXIT\n");
 }
 
-static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+static int atapi_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
+	unsigned int err_mask = qc->err_mask;
 
 	VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
 
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 8ebaa69..251e53b 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -39,7 +39,6 @@
 
 /* libata-core.c */
 extern int atapi_enabled;
-extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 				      struct ata_device *dev);
 extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3062b39..38ffa8d 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -29,9 +29,10 @@
 #define LPFC_LC_HBA_Q_DEPTH	1024	/* max cmds per low cost hba */
 #define LPFC_LP101_HBA_Q_DEPTH	128	/* max cmds per low cost hba */
 
-#define LPFC_CMD_PER_LUN	30	/* max outstanding cmds per lun */
+#define LPFC_CMD_PER_LUN	3	/* max outstanding cmds per lun */
 #define LPFC_SG_SEG_CNT		64	/* sg element count per scsi cmnd */
 #define LPFC_IOCB_LIST_CNT	2250	/* list of IOCBs for fast-path usage. */
+#define LPFC_Q_RAMP_UP_INTERVAL 120     /* lun q_depth ramp up interval */
 
 /* Define macros for 64 bit support */
 #define putPaddrLow(addr)    ((uint32_t) (0xffffffff & (u64)(addr)))
@@ -45,6 +46,11 @@
 
 #define MAX_HBAEVT	32
 
+enum lpfc_polling_flags {
+	ENABLE_FCP_RING_POLLING = 0x1,
+	DISABLE_FCP_RING_INT    = 0x2
+};
+
 /* Provide DMA memory definitions the driver uses per port instance. */
 struct lpfc_dmabuf {
 	struct list_head list;
@@ -167,6 +173,7 @@
 	dma_addr_t slim2p_mapping;
 	uint16_t pci_cfg_value;
 
+	struct semaphore hba_can_block;
 	uint32_t hba_state;
 
 #define LPFC_INIT_START           1	/* Initial state after board reset */
@@ -286,6 +293,8 @@
 	uint32_t cfg_fcp_bind_method;
 	uint32_t cfg_discovery_threads;
 	uint32_t cfg_max_luns;
+	uint32_t cfg_poll;
+	uint32_t cfg_poll_tmo;
 	uint32_t cfg_sg_seg_cnt;
 	uint32_t cfg_sg_dma_buf_size;
 
@@ -337,7 +346,9 @@
 #define VPD_PORT            0x8         /* valid vpd port data */
 #define VPD_MASK            0xf         /* mask for any vpd data */
 
+	struct timer_list fcp_poll_timer;
 	struct timer_list els_tmofunc;
+
 	/*
 	 * stat  counters
 	 */
@@ -348,6 +359,7 @@
 	struct lpfc_sysfs_mbox sysfs_mbox;
 
 	/* fastpath list. */
+	spinlock_t scsi_buf_list_lock;
 	struct list_head lpfc_scsi_buf_list;
 	uint32_t total_scsi_bufs;
 	struct list_head lpfc_iocb_list;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 89e8222..5625a8c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -278,6 +278,71 @@
 		return -EIO;
 }
 
+static ssize_t
+lpfc_poll_show(struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(cdev);
+	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+	return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
+}
+
+static ssize_t
+lpfc_poll_store(struct class_device *cdev, const char *buf,
+		size_t count)
+{
+	struct Scsi_Host *host = class_to_shost(cdev);
+	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+	uint32_t creg_val;
+	uint32_t old_val;
+	int val=0;
+
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+
+	if ((val & 0x3) != val)
+		return -EINVAL;
+
+	spin_lock_irq(phba->host->host_lock);
+
+	old_val = phba->cfg_poll;
+
+	if (val & ENABLE_FCP_RING_POLLING) {
+		if ((val & DISABLE_FCP_RING_INT) &&
+		    !(old_val & DISABLE_FCP_RING_INT)) {
+			creg_val = readl(phba->HCregaddr);
+			creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+			writel(creg_val, phba->HCregaddr);
+			readl(phba->HCregaddr); /* flush */
+
+			lpfc_poll_start_timer(phba);
+		}
+	} else if (val != 0x0) {
+		spin_unlock_irq(phba->host->host_lock);
+		return -EINVAL;
+	}
+
+	if (!(val & DISABLE_FCP_RING_INT) &&
+	    (old_val & DISABLE_FCP_RING_INT))
+	{
+		spin_unlock_irq(phba->host->host_lock);
+		del_timer(&phba->fcp_poll_timer);
+		spin_lock_irq(phba->host->host_lock);
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
+	phba->cfg_poll = val;
+
+	spin_unlock_irq(phba->host->host_lock);
+
+	return strlen(buf);
+}
 
 #define lpfc_param_show(attr)	\
 static ssize_t \
@@ -416,6 +481,15 @@
 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
 			 lpfc_board_online_show, lpfc_board_online_store);
 
+static int lpfc_poll = 0;
+module_param(lpfc_poll, int, 0);
+MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
+		 " 0 - none,"
+		 " 1 - poll with interrupts enabled"
+		 " 3 - poll and disable FCP ring interrupts");
+
+static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
+			 lpfc_poll_show, lpfc_poll_store);
 
 /*
 # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
@@ -523,10 +597,10 @@
 # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
 # cr_delay is set to 0.
 */
-LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
+LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
 		"interrupt response is generated");
 
-LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
+LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an"
 		"interrupt response is generated");
 
 /*
@@ -553,6 +627,13 @@
 LPFC_ATTR_R(max_luns, 256, 1, 32768,
 	     "Maximum number of LUNs per target driver will support");
 
+/*
+# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
+# Value range is [1,255], default value is 10.
+*/
+LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
+	     "Milliseconds driver will wait between polling FCP ring");
+
 struct class_device_attribute *lpfc_host_attrs[] = {
 	&class_device_attr_info,
 	&class_device_attr_serialnum,
@@ -575,11 +656,15 @@
 	&class_device_attr_lpfc_topology,
 	&class_device_attr_lpfc_scan_down,
 	&class_device_attr_lpfc_link_speed,
+	&class_device_attr_lpfc_cr_delay,
+	&class_device_attr_lpfc_cr_count,
 	&class_device_attr_lpfc_fdmi_on,
 	&class_device_attr_lpfc_max_luns,
 	&class_device_attr_nport_evt_cnt,
 	&class_device_attr_management_version,
 	&class_device_attr_board_online,
+	&class_device_attr_lpfc_poll,
+	&class_device_attr_lpfc_poll_tmo,
 	NULL,
 };
 
@@ -1292,6 +1377,9 @@
 	lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
 	lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
 	lpfc_max_luns_init(phba, lpfc_max_luns);
+	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
+
+	phba->cfg_poll = lpfc_poll;
 
 	/*
 	 * The total number of segments is the configuration value plus 2
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index d527d05..f1e7089 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -143,6 +143,9 @@
 int lpfc_mem_alloc(struct lpfc_hba *);
 void lpfc_mem_free(struct lpfc_hba *);
 
+void lpfc_poll_timeout(unsigned long ptr);
+void lpfc_poll_start_timer(struct lpfc_hba * phba);
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 084e762..ed6c816 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -73,6 +73,8 @@
 	struct lpfc_hba      *nlp_phba;
 	struct lpfc_work_evt nodev_timeout_evt;
 	struct lpfc_work_evt els_retry_evt;
+	unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
+	unsigned long last_q_full_time;		/* jiffy of last queue full */
 };
 
 /* Defines for nlp_flag (uint32) */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index bcc29ec..20f1a07 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -720,6 +720,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
 		}
@@ -869,6 +870,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		}
@@ -1054,6 +1056,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
 		}
@@ -1205,6 +1208,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		}
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 259eeb1..a1f751e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1017,12 +1017,7 @@
 	rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
 	rport_ids.port_id = ndlp->nlp_DID;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	if (ndlp->nlp_type & NLP_FCP_TARGET)
-		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
-	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
-		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 
-	scsi_block_requests(phba->host);
 	ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
 	if (!rport) {
 		dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1039,7 +1034,16 @@
 	}
 	rdata = rport->dd_data;
 	rdata->pnode = ndlp;
-	scsi_unblock_requests(phba->host);
+
+	if (ndlp->nlp_type & NLP_FCP_TARGET)
+		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
+	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
+		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+
+
+	if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
+		fc_remote_port_rolechg(rport, rport_ids.roles);
+
 
 	return;
 }
@@ -1053,9 +1057,7 @@
 
 	ndlp->rport = NULL;
 	rdata->pnode = NULL;
-	scsi_block_requests(phba->host);
 	fc_remote_port_delete(rport);
-	scsi_unblock_requests(phba->host);
 
 	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 86c4198..1ea565e 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -266,9 +266,11 @@
 		struct {
 #ifdef __BIG_ENDIAN_BITFIELD
 			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
-			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit
+						   8:11 of IEEE ext */
 #else	/*  __LITTLE_ENDIAN_BITFIELD */
-			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit
+						   8:11 of IEEE ext */
 			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
 #endif
 
@@ -278,7 +280,8 @@
 #define NAME_IP_TYPE        0x4	/* IP address */
 #define NAME_CCITT_TYPE     0xC
 #define NAME_CCITT_GR_TYPE  0xE
-			uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE extended Lsb */
+			uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE
+						   extended Lsb */
 			uint8_t IEEE[6];	/* FC IEEE address */
 		} s;
 		uint8_t wwn[8];
@@ -1024,23 +1027,38 @@
 /* Start FireFly Register definitions */
 #define PCI_VENDOR_ID_EMULEX        0x10df
 #define PCI_DEVICE_ID_FIREFLY       0x1ae5
-#define PCI_DEVICE_ID_SUPERFLY      0xf700
-#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_RFLY          0xf095
 #define PCI_DEVICE_ID_PFLY          0xf098
+#define PCI_DEVICE_ID_LP101         0xf0a1
 #define PCI_DEVICE_ID_TFLY          0xf0a5
+#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_BMID          0xf0d5
+#define PCI_DEVICE_ID_ZSMB          0xf0e1
+#define PCI_DEVICE_ID_ZMID          0xf0e5
+#define PCI_DEVICE_ID_NEPTUNE       0xf0f5
+#define PCI_DEVICE_ID_NEPTUNE_SCSP  0xf0f6
+#define PCI_DEVICE_ID_NEPTUNE_DCSP  0xf0f7
+#define PCI_DEVICE_ID_SUPERFLY      0xf700
+#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_CENTAUR       0xf900
 #define PCI_DEVICE_ID_PEGASUS       0xf980
 #define PCI_DEVICE_ID_THOR          0xfa00
 #define PCI_DEVICE_ID_VIPER         0xfb00
+#define PCI_DEVICE_ID_LP10000S      0xfc00
+#define PCI_DEVICE_ID_LP11000S      0xfc10
+#define PCI_DEVICE_ID_LPE11000S     0xfc20
 #define PCI_DEVICE_ID_HELIOS        0xfd00
-#define PCI_DEVICE_ID_BMID          0xf0d5
-#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_HELIOS_SCSP   0xfd11
+#define PCI_DEVICE_ID_HELIOS_DCSP   0xfd12
 #define PCI_DEVICE_ID_ZEPHYR        0xfe00
-#define PCI_DEVICE_ID_ZMID          0xf0e5
-#define PCI_DEVICE_ID_ZSMB          0xf0e1
-#define PCI_DEVICE_ID_LP101	    0xf0a1
-#define PCI_DEVICE_ID_LP10000S	    0xfc00
+#define PCI_DEVICE_ID_ZEPHYR_SCSP   0xfe11
+#define PCI_DEVICE_ID_ZEPHYR_DCSP   0xfe12
+
+#define PCI_SUBSYSTEM_ID_LP11000S      0xfc11
+#define PCI_SUBSYSTEM_ID_LP11002S      0xfc12
+#define PCI_SUBSYSTEM_ID_LPE11000S     0xfc21
+#define PCI_SUBSYSTEM_ID_LPE11002S     0xfc22
+#define PCI_SUBSYSTEM_ID_LPE11010S     0xfc2A
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0749811..b7a603a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -126,34 +126,26 @@
 		return -ERESTART;
 	}
 
-	/* The HBA's current state is provided by the ProgType and rr fields.
-	 * Read and check the value of these fields before continuing to config
-	 * this port.
+	/*
+	 * The value of rr must be 1 since the driver set the cv field to 1.
+	 * This setting requires the FW to set all revision fields.
 	 */
-	if (mb->un.varRdRev.rr == 0 || mb->un.varRdRev.un.b.ProgType != 2) {
-		/* Old firmware */
+	if (mb->un.varRdRev.rr == 0) {
 		vp->rev.rBit = 0;
-		lpfc_printf_log(phba,
-				KERN_ERR,
-				LOG_INIT,
-				"%d:0440 Adapter failed to init, mbxCmd x%x "
-				"READ_REV detected outdated firmware"
-				"Data: x%x\n",
-				phba->brd_no,
-				mb->mbxCommand, 0);
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"%d:0440 Adapter failed to init, READ_REV has "
+				"missing revision information.\n",
+				phba->brd_no);
 		mempool_free(pmb, phba->mbox_mem_pool);
 		return -ERESTART;
-	} else {
-		vp->rev.rBit = 1;
-		vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
-		memcpy(vp->rev.sli1FwName,
-			(char*)mb->un.varRdRev.sli1FwName, 16);
-		vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
-		memcpy(vp->rev.sli2FwName,
-					(char *)mb->un.varRdRev.sli2FwName, 16);
 	}
 
 	/* Save information as VPD data */
+	vp->rev.rBit = 1;
+	vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
+	memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16);
+	vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
+	memcpy(vp->rev.sli2FwName, (char *) mb->un.varRdRev.sli2FwName, 16);
 	vp->rev.biuRev = mb->un.varRdRev.biuRev;
 	vp->rev.smRev = mb->un.varRdRev.smRev;
 	vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev;
@@ -378,6 +370,10 @@
 	if (psli->num_rings > 3)
 		status |= HC_R3INT_ENA;
 
+	if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
+	    (phba->cfg_poll & DISABLE_FCP_RING_INT))
+		status &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+
 	writel(status, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
 	spin_unlock_irq(phba->host->host_lock);
@@ -571,6 +567,8 @@
 
 	rc = -EIO;
 
+	/* Cleanup any outstanding ELS commands */
+	lpfc_els_flush_cmd(phba);
 
 	psli->slistat.link_event++;
 	lpfc_read_la(phba, pmb, mp);
@@ -765,96 +763,139 @@
 lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
 {
 	lpfc_vpd_t *vp;
-	uint32_t id;
-	uint8_t hdrtype;
-	char str[16];
+	uint16_t dev_id = phba->pcidev->device;
+	uint16_t dev_subid = phba->pcidev->subsystem_device;
+	uint8_t hdrtype = phba->pcidev->hdr_type;
+	char *model_str = "";
 
 	vp = &phba->vpd;
-	pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
-	pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
 
-	switch ((id >> 16) & 0xffff) {
+	switch (dev_id) {
 	case PCI_DEVICE_ID_FIREFLY:
-		strcpy(str, "LP6000 1");
+		model_str = "LP6000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_SUPERFLY:
 		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
-			strcpy(str, "LP7000 1");
+			model_str = "LP7000 1Gb PCI";
 		else
-			strcpy(str, "LP7000E 1");
+			model_str = "LP7000E 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_DRAGONFLY:
-		strcpy(str, "LP8000 1");
+		model_str = "LP8000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_CENTAUR:
 		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
-			strcpy(str, "LP9002 2");
+			model_str = "LP9002 2Gb PCI";
 		else
-			strcpy(str, "LP9000 1");
+			model_str = "LP9000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_RFLY:
-		strcpy(str, "LP952 2");
+		model_str = "LP952 2Gb PCI";
 		break;
 	case PCI_DEVICE_ID_PEGASUS:
-		strcpy(str, "LP9802 2");
+		model_str = "LP9802 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_THOR:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP10000DC 2");
+			model_str = "LP10000DC 2Gb 2-port PCI-X";
 		else
-			strcpy(str, "LP10000 2");
+			model_str = "LP10000 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_VIPER:
-		strcpy(str, "LPX1000 10");
+		model_str = "LPX1000 10Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_PFLY:
-		strcpy(str, "LP982 2");
+		model_str = "LP982 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_TFLY:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP1050DC 2");
+			model_str = "LP1050DC 2Gb 2-port PCI-X";
 		else
-			strcpy(str, "LP1050 2");
+			model_str = "LP1050 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_HELIOS:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP11002 4");
+			model_str = "LP11002 4Gb 2-port PCI-X2";
 		else
-			strcpy(str, "LP11000 4");
+			model_str = "LP11000 4Gb PCI-X2";
+		break;
+	case PCI_DEVICE_ID_HELIOS_SCSP:
+		model_str = "LP11000-SP 4Gb PCI-X2";
+		break;
+	case PCI_DEVICE_ID_HELIOS_DCSP:
+		model_str = "LP11002-SP 4Gb 2-port PCI-X2";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE:
+		if (hdrtype == 0x80)
+			model_str = "LPe1002 4Gb 2-port";
+		else
+			model_str = "LPe1000 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE_SCSP:
+		model_str = "LPe1000-SP 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE_DCSP:
+		model_str = "LPe1002-SP 4Gb 2-port PCIe";
 		break;
 	case PCI_DEVICE_ID_BMID:
-		strcpy(str, "LP1150 4");
+		model_str = "LP1150 4Gb PCI-X2";
 		break;
 	case PCI_DEVICE_ID_BSMB:
-		strcpy(str, "LP111 4");
+		model_str = "LP111 4Gb PCI-X2";
 		break;
 	case PCI_DEVICE_ID_ZEPHYR:
 		if (hdrtype == 0x80)
-			strcpy(str, "LPe11002 4");
+			model_str = "LPe11002 4Gb 2-port PCIe";
 		else
-			strcpy(str, "LPe11000 4");
+			model_str = "LPe11000 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_ZEPHYR_SCSP:
+		model_str = "LPe11000-SP 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_ZEPHYR_DCSP:
+		model_str = "LPe11002-SP 4Gb 2-port PCIe";
 		break;
 	case PCI_DEVICE_ID_ZMID:
-		strcpy(str, "LPe1150 4");
+		model_str = "LPe1150 4Gb PCIe";
 		break;
 	case PCI_DEVICE_ID_ZSMB:
-		strcpy(str, "LPe111 4");
+		model_str = "LPe111 4Gb PCIe";
 		break;
 	case PCI_DEVICE_ID_LP101:
-		strcpy(str, "LP101 2");
+		model_str = "LP101 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_LP10000S:
-		strcpy(str, "LP10000-S 2");
+		model_str = "LP10000-S 2Gb PCI";
+		break;
+	case PCI_DEVICE_ID_LP11000S:
+	case PCI_DEVICE_ID_LPE11000S:
+		switch (dev_subid) {
+		case PCI_SUBSYSTEM_ID_LP11000S:
+			model_str = "LP11002-S 4Gb PCI-X2";
+			break;
+		case PCI_SUBSYSTEM_ID_LP11002S:
+			model_str = "LP11000-S 4Gb 2-port PCI-X2";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11000S:
+			model_str = "LPe11002-S 4Gb PCIe";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11002S:
+			model_str = "LPe11002-S 4Gb 2-port PCIe";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11010S:
+			model_str = "LPe11010-S 4Gb 10-port PCIe";
+			break;
+		default:
+			break;
+		}
 		break;
 	default:
-		memset(str, 0, 16);
 		break;
 	}
 	if (mdp)
-		sscanf(str, "%s", mdp);
+		sscanf(model_str, "%s", mdp);
 	if (descp)
-		sprintf(descp, "Emulex LightPulse %s Gigabit PCI Fibre "
-			"Channel Adapter", str);
+		sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str);
 }
 
 /**************************************************/
@@ -1196,6 +1237,7 @@
 		}
 	}
 
+	del_timer_sync(&phba->fcp_poll_timer);
 	del_timer_sync(&phba->fc_estabtmo);
 	del_timer_sync(&phba->fc_disctmo);
 	del_timer_sync(&phba->fc_fdmitmo);
@@ -1351,7 +1393,7 @@
 		goto out_put_host;
 
 	host->unique_id = phba->brd_no;
-
+	init_MUTEX(&phba->hba_can_block);
 	INIT_LIST_HEAD(&phba->ctrspbuflist);
 	INIT_LIST_HEAD(&phba->rnidrspbuflist);
 	INIT_LIST_HEAD(&phba->freebufList);
@@ -1375,6 +1417,10 @@
 	psli->mbox_tmo.function = lpfc_mbox_timeout;
 	psli->mbox_tmo.data = (unsigned long)phba;
 
+	init_timer(&phba->fcp_poll_timer);
+	phba->fcp_poll_timer.function = lpfc_poll_timeout;
+	phba->fcp_poll_timer.data = (unsigned long)phba;
+
 	/*
 	 * Get all the module params for configuring this host and then
 	 * establish the host parameters.
@@ -1489,6 +1535,7 @@
 	host->max_cmd_len = 16;
 
 	/* Initialize the list of scsi buffers used by driver for scsi IO. */
+	spin_lock_init(&phba->scsi_buf_list_lock);
 	INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
 
 	host->transportt = lpfc_transport_template;
@@ -1520,6 +1567,12 @@
 	if (error)
 		goto out_free_irq;
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		spin_lock_irq(phba->host->host_lock);
+		lpfc_poll_start_timer(phba);
+		spin_unlock_irq(phba->host->host_lock);
+	}
+
 	/*
 	 * set fixed host attributes
 	 * Must done after lpfc_sli_hba_setup()
@@ -1679,14 +1732,28 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PFLY,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BMID,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BSMB,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZMID,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZSMB,
@@ -1697,6 +1764,10 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP10000S,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP11000S,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0 }
 };
 
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 507a6af..fbead78 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -55,55 +55,76 @@
 	return (1);
 }
 
-
 int
 lpfc_check_sparm(struct lpfc_hba * phba,
 		 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
 		 uint32_t class)
 {
 	volatile struct serv_parm *hsp = &phba->fc_sparam;
-	/* First check for supported version */
+	uint16_t hsp_value, ssp_value = 0;
 
-	/* Next check for class validity */
+	/*
+	 * The receive data field size and buffer-to-buffer receive data field
+	 * size entries are 16 bits but are represented as two 8-bit fields in
+	 * the driver data structure to account for rsvd bits and other control
+	 * bits.  Reconstruct and compare the fields as a 16-bit values before
+	 * correcting the byte values.
+	 */
 	if (sp->cls1.classValid) {
-
-		if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb)
-			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
-		if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb)
+		hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
+				hsp->cls1.rcvDataSizeLsb;
+		ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
+				sp->cls1.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
+			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS1) {
-		return (0);
+		return 0;
 	}
 
 	if (sp->cls2.classValid) {
-
-		if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb)
-			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
-		if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb)
+		hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
+				hsp->cls2.rcvDataSizeLsb;
+		ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
+				sp->cls2.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
+			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS2) {
-		return (0);
+		return 0;
 	}
 
 	if (sp->cls3.classValid) {
-
-		if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb)
-			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
-		if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb)
+		hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
+				hsp->cls3.rcvDataSizeLsb;
+		ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
+				sp->cls3.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
+			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS3) {
-		return (0);
+		return 0;
 	}
 
-	if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb)
-		sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb;
-	if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb)
+	/*
+	 * Preserve the upper four bits of the MSB from the PLOGI response.
+	 * These bits contain the Buffer-to-Buffer State Change Number
+	 * from the target and need to be passed to the FW.
+	 */
+	hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
+	ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
+	if (ssp_value > hsp_value) {
 		sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
+		sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
+				       (hsp->cmn.bbRcvSizeMsb & 0x0F);
+	}
 
-	/* If check is good, copy wwpn wwnn into ndlp */
 	memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
 	memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
-	return (1);
+	return 1;
 }
 
 static void *
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c63275e..9ee8218 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -41,6 +41,20 @@
 #define LPFC_ABORT_WAIT  2
 
 
+static inline void
+lpfc_block_requests(struct lpfc_hba * phba)
+{
+	down(&phba->hba_can_block);
+	scsi_block_requests(phba->host);
+}
+
+static inline void
+lpfc_unblock_requests(struct lpfc_hba * phba)
+{
+	scsi_unblock_requests(phba->host);
+	up(&phba->hba_can_block);
+}
+
 /*
  * This routine allocates a scsi buffer, which contains all the necessary
  * information needed to initiate a SCSI I/O.  The non-DMAable buffer region
@@ -137,18 +151,22 @@
 }
 
 struct  lpfc_scsi_buf*
-lpfc_sli_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_get_scsi_buf(struct lpfc_hba * phba)
 {
 	struct  lpfc_scsi_buf * lpfc_cmd = NULL;
 	struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+	unsigned long iflag = 0;
 
+	spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
 	list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+	spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
 	return  lpfc_cmd;
 }
 
 static void
 lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 {
+	unsigned long iflag = 0;
 	/*
 	 * There are only two special cases to consider.  (1) the scsi command
 	 * requested scatter-gather usage or (2) the scsi command allocated
@@ -166,8 +184,10 @@
 		 }
 	}
 
+	spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
 	psb->pCmd = NULL;
 	list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
+	spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
 }
 
 static int
@@ -389,7 +409,9 @@
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
-	unsigned long iflag;
+	int result;
+	struct scsi_device *sdev, *tmp_sdev;
+	int depth = 0;
 
 	lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
 	lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@@ -441,11 +463,64 @@
 				*lp, *(lp + 3), cmd->retries, cmd->resid);
 	}
 
+	result = cmd->result;
+	sdev = cmd->device;
 	cmd->scsi_done(cmd);
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	if (!result &&
+	   ((jiffies - pnode->last_ramp_up_time) >
+		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+	   ((jiffies - pnode->last_q_full_time) >
+		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+	   (phba->cfg_lun_queue_depth > sdev->queue_depth)) {
+		shost_for_each_device(tmp_sdev, sdev->host) {
+			if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) {
+				if (tmp_sdev->id != sdev->id)
+					continue;
+				if (tmp_sdev->ordered_tags)
+					scsi_adjust_queue_depth(tmp_sdev,
+						MSG_ORDERED_TAG,
+						tmp_sdev->queue_depth+1);
+				else
+					scsi_adjust_queue_depth(tmp_sdev,
+						MSG_SIMPLE_TAG,
+						tmp_sdev->queue_depth+1);
+
+				pnode->last_ramp_up_time = jiffies;
+			}
+		}
+	}
+
+	/*
+	 * Check for queue full.  If the lun is reporting queue full, then
+	 * back off the lun queue depth to prevent target overloads.
+	 */
+	if (result == SAM_STAT_TASK_SET_FULL) {
+		pnode->last_q_full_time = jiffies;
+
+		shost_for_each_device(tmp_sdev, sdev->host) {
+			if (tmp_sdev->id != sdev->id)
+				continue;
+			depth = scsi_track_queue_full(tmp_sdev,
+					tmp_sdev->queue_depth - 1);
+		}
+		/*
+ 		 * The queue depth cannot be lowered any more.
+		 * Modify the returned error code to store
+		 * the final depth value set by
+		 * scsi_track_queue_full.
+		 */
+		if (depth == -1)
+			depth = sdev->host->cmd_per_lun;
+
+		if (depth) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+				"%d:0711 detected queue full - lun queue depth "
+				" adjusted to %d.\n", phba->brd_no, depth);
+		}
+	}
+
 	lpfc_release_scsi_buf(phba, lpfc_cmd);
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
 }
 
 static void
@@ -693,6 +768,37 @@
 	return lpfcinfobuf;
 }
 
+static __inline__ void lpfc_poll_rearm_timer(struct lpfc_hba * phba)
+{
+	unsigned long  poll_tmo_expires =
+		(jiffies + msecs_to_jiffies(phba->cfg_poll_tmo));
+
+	if (phba->sli.ring[LPFC_FCP_RING].txcmplq_cnt)
+		mod_timer(&phba->fcp_poll_timer,
+			  poll_tmo_expires);
+}
+
+void lpfc_poll_start_timer(struct lpfc_hba * phba)
+{
+	lpfc_poll_rearm_timer(phba);
+}
+
+void lpfc_poll_timeout(unsigned long ptr)
+{
+	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+	unsigned long iflag;
+
+	spin_lock_irqsave(phba->host->host_lock, iflag);
+
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring (phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
+	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+}
+
 static int
 lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
@@ -719,10 +825,11 @@
 		cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
 		goto out_fail_command;
 	}
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_cmd = lpfc_get_scsi_buf (phba);
 	if (lpfc_cmd == NULL) {
-		printk(KERN_WARNING "%s: No buffer available - list empty, "
-		       "total count %d\n", __FUNCTION__, phba->total_scsi_bufs);
+		lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+				"%d:0707 driver's buffer pool is empty, "
+				"IO busied\n", phba->brd_no);
 		goto out_host_busy;
 	}
 
@@ -746,11 +853,17 @@
 				&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
 	if (err)
 		goto out_host_busy_free_buf;
+
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring(phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
 	return 0;
 
  out_host_busy_free_buf:
 	lpfc_release_scsi_buf(phba, lpfc_cmd);
-	cmnd->host_scribble = NULL;
  out_host_busy:
 	return SCSI_MLQUEUE_HOST_BUSY;
 
@@ -759,11 +872,12 @@
 	return 0;
 }
 
+
 static int
-__lpfc_abort_handler(struct scsi_cmnd *cmnd)
+lpfc_abort_handler(struct scsi_cmnd *cmnd)
 {
-	struct lpfc_hba *phba =
-			(struct lpfc_hba *)cmnd->device->host->hostdata[0];
+	struct Scsi_Host *shost = cmnd->device->host;
+	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
 	struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
 	struct lpfc_iocbq *iocb;
 	struct lpfc_iocbq *abtsiocb;
@@ -772,6 +886,8 @@
 	unsigned int loop_count = 0;
 	int ret = SUCCESS;
 
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
 
 	lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
 	BUG_ON(!lpfc_cmd);
@@ -821,9 +937,15 @@
 		goto out;
 	}
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+		lpfc_sli_poll_fcp_ring (phba);
+
 	/* Wait for abort to complete */
 	while (lpfc_cmd->pCmd == cmnd)
 	{
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_sli_poll_fcp_ring (phba);
+
 		spin_unlock_irq(phba->host->host_lock);
 			schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -844,26 +966,19 @@
 
  out:
 	lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
-			"%d:0749 SCSI layer issued abort device: ret %#x, "
-			"ID %d, LUN %d, snum %#lx\n",
+			"%d:0749 SCSI Layer I/O Abort Request "
+			"Status x%x ID %d LUN %d snum %#lx\n",
 			phba->brd_no, ret, cmnd->device->id,
 			cmnd->device->lun, cmnd->serial_number);
 
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
+
 	return ret;
 }
 
 static int
-lpfc_abort_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_abort_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-static int
-__lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -871,9 +986,12 @@
 	struct lpfc_iocbq *iocbq, *iocbqrsp;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
+	uint32_t cmd_result = 0, cmd_status = 0;
 	int ret = FAILED;
 	int cnt, loopcnt;
 
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
 	/*
 	 * If target is not in a MAPPED state, delay the reset until
 	 * target is rediscovered or nodev timeout expires.
@@ -891,7 +1009,7 @@
 			break;
 	}
 
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_cmd = lpfc_get_scsi_buf (phba);
 	if (lpfc_cmd == NULL)
 		goto out;
 
@@ -916,26 +1034,28 @@
 	if (ret == IOCB_SUCCESS)
 		ret = SUCCESS;
 
-	lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4];
-	lpfc_cmd->status = iocbqrsp->iocb.ulpStatus;
-	if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT)
-		if (lpfc_cmd->result & IOERR_DRVR_MASK)
-			lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
+
+	cmd_result = iocbqrsp->iocb.un.ulpWord[4];
+	cmd_status = iocbqrsp->iocb.ulpStatus;
+
+	lpfc_sli_release_iocbq(phba, iocbqrsp);
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
 
 	/*
-	 * All outstanding txcmplq I/Os should have been aborted by the target.
+	 * All outstanding txcmplq I/Os should have been aborted by the device.
 	 * Unfortunately, some targets do not abide by this forcing the driver
 	 * to double check.
 	 */
-	lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
-			    cmnd->device->id, cmnd->device->lun, 0,
-			    LPFC_CTX_LUN);
-
+	cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				cmnd->device->id, cmnd->device->lun,
+				LPFC_CTX_LUN);
+	if (cnt)
+		lpfc_sli_abort_iocb(phba,
+				    &phba->sli.ring[phba->sli.fcp_ring],
+				    cmnd->device->id, cmnd->device->lun,
+				    0, LPFC_CTX_LUN);
 	loopcnt = 0;
-	while((cnt = lpfc_sli_sum_iocb(phba,
-				       &phba->sli.ring[phba->sli.fcp_ring],
-				       cmnd->device->id, cmnd->device->lun,
-				       LPFC_CTX_LUN))) {
+	while(cnt) {
 		spin_unlock_irq(phba->host->host_lock);
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -943,6 +1063,11 @@
 		if (++loopcnt
 		    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
 			break;
+
+		cnt = lpfc_sli_sum_iocb(phba,
+					&phba->sli.ring[phba->sli.fcp_ring],
+					cmnd->device->id, cmnd->device->lun,
+					LPFC_CTX_LUN);
 	}
 
 	if (cnt) {
@@ -952,35 +1077,21 @@
 		ret = FAILED;
 	}
 
-	lpfc_sli_release_iocbq(phba, iocbqrsp);
-
 out_free_scsi_buf:
 	lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 			"%d:0713 SCSI layer issued LUN reset (%d, %d) "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, lpfc_cmd->pCmd->device->id,
-			lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status,
-			lpfc_cmd->result);
-	lpfc_release_scsi_buf(phba, lpfc_cmd);
+			phba->brd_no, cmnd->device->id,cmnd->device->lun,
+			ret, cmd_status, cmd_result);
+
 out:
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
 	return ret;
 }
 
 static int
-lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_reset_lun_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-/*
- * Note: midlayer calls this function with the host_lock held
- */
-static int
-__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -991,7 +1102,10 @@
 	unsigned int midlayer_id = 0;
 	struct lpfc_scsi_buf * lpfc_cmd;
 
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
+
+	lpfc_cmd = lpfc_get_scsi_buf(phba);
 	if (lpfc_cmd == NULL)
 		goto out;
 
@@ -1022,18 +1136,31 @@
 		lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data;
 		ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba);
 		if (ret != SUCCESS) {
-			lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 				"%d:0713 Bus Reset on target %d failed\n",
 				phba->brd_no, i);
 			err_count++;
 		}
 	}
 
+	if (err_count == 0)
+		ret = SUCCESS;
+
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
+
+	/*
+	 * All outstanding txcmplq I/Os should have been aborted by
+	 * the targets.  Unfortunately, some targets do not abide by
+	 * this forcing the driver to double check.
+	 */
 	cmnd->device->id = midlayer_id;
+	cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				0, 0, LPFC_CTX_HOST);
+	if (cnt)
+		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				    0, 0, 0, LPFC_CTX_HOST);
 	loopcnt = 0;
-	while((cnt = lpfc_sli_sum_iocb(phba,
-				&phba->sli.ring[phba->sli.fcp_ring],
-				0, 0, LPFC_CTX_HOST))) {
+	while(cnt) {
 		spin_unlock_irq(phba->host->host_lock);
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -1041,45 +1168,31 @@
 		if (++loopcnt
 		    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
 			break;
+
+		cnt = lpfc_sli_sum_iocb(phba,
+					&phba->sli.ring[phba->sli.fcp_ring],
+					0, 0, LPFC_CTX_HOST);
 	}
 
 	if (cnt) {
-		/* flush all outstanding commands on the host */
-		i = lpfc_sli_abort_iocb(phba,
-				&phba->sli.ring[phba->sli.fcp_ring], 0, 0, 0,
-				LPFC_CTX_HOST);
-
-		lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+		lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 		   "%d:0715 Bus Reset I/O flush failure: cnt x%x left x%x\n",
 		   phba->brd_no, cnt, i);
+		ret = FAILED;
 	}
 
-	if (cnt == 0)
-		ret = SUCCESS;
-	else
-		ret = FAILED;
-
-	lpfc_release_scsi_buf(phba, lpfc_cmd);
 	lpfc_printf_log(phba,
 			KERN_ERR,
 			LOG_FCP,
 			"%d:0714 SCSI layer issued Bus Reset Data: x%x\n",
 			phba->brd_no, ret);
 out:
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
 	return ret;
 }
 
 static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_reset_bus_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
 	struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
@@ -1127,10 +1240,10 @@
 			break;
 		}
 
-		spin_lock_irqsave(phba->host->host_lock, flags);
+		spin_lock_irqsave(&phba->scsi_buf_list_lock, flags);
 		phba->total_scsi_bufs++;
 		list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list);
-		spin_unlock_irqrestore(phba->host->host_lock, flags);
+		spin_unlock_irqrestore(&phba->scsi_buf_list_lock, flags);
 	}
 	return 0;
 }
@@ -1154,6 +1267,12 @@
 	 */
 	rport->dev_loss_tmo = phba->cfg_nodev_tmo + 5;
 
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring(phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e2c08c5..7b785ad 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -886,6 +886,182 @@
 	return rc;
 }
 
+static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
+					struct lpfc_sli_ring * pring)
+{
+	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
+	/*
+	 * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
+	 * rsp ring <portRspMax>
+	 */
+	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+			"%d:0312 Ring %d handler: portRspPut %d "
+			"is bigger then rsp ring %d\n",
+			phba->brd_no, pring->ringno,
+			le32_to_cpu(pgp->rspPutInx),
+			pring->numRiocb);
+
+	phba->hba_state = LPFC_HBA_ERROR;
+
+	/*
+	 * All error attention handlers are posted to
+	 * worker thread
+	 */
+	phba->work_ha |= HA_ERATT;
+	phba->work_hs = HS_FFER3;
+	if (phba->work_wait)
+		wake_up(phba->work_wait);
+
+	return;
+}
+
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
+{
+	struct lpfc_sli      * psli   = &phba->sli;
+	struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING];
+	IOCB_t *irsp = NULL;
+	IOCB_t *entry = NULL;
+	struct lpfc_iocbq *cmdiocbq = NULL;
+	struct lpfc_iocbq rspiocbq;
+	struct lpfc_pgp *pgp;
+	uint32_t status;
+	uint32_t portRspPut, portRspMax;
+	int type;
+	uint32_t rsp_cmpl = 0;
+	void __iomem *to_slim;
+	uint32_t ha_copy;
+
+	pring->stats.iocb_event++;
+
+	/* The driver assumes SLI-2 mode */
+	pgp =  &phba->slim2p->mbx.us.s2.port[pring->ringno];
+
+	/*
+	 * The next available response entry should never exceed the maximum
+	 * entries.  If it does, treat it as an adapter hardware error.
+	 */
+	portRspMax = pring->numRiocb;
+	portRspPut = le32_to_cpu(pgp->rspPutInx);
+	if (unlikely(portRspPut >= portRspMax)) {
+		lpfc_sli_rsp_pointers_error(phba, pring);
+		return;
+	}
+
+	rmb();
+	while (pring->rspidx != portRspPut) {
+
+		entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+		if (++pring->rspidx >= portRspMax)
+			pring->rspidx = 0;
+
+		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
+				      (uint32_t *) &rspiocbq.iocb,
+				      sizeof (IOCB_t));
+		irsp = &rspiocbq.iocb;
+		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
+		pring->stats.iocb_rsp++;
+		rsp_cmpl++;
+
+		if (unlikely(irsp->ulpStatus)) {
+			/* Rsp ring <ringno> error: IOCB */
+			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+					"%d:0326 Rsp Ring %d error: IOCB Data: "
+					"x%x x%x x%x x%x x%x x%x x%x x%x\n",
+					phba->brd_no, pring->ringno,
+					irsp->un.ulpWord[0],
+					irsp->un.ulpWord[1],
+					irsp->un.ulpWord[2],
+					irsp->un.ulpWord[3],
+					irsp->un.ulpWord[4],
+					irsp->un.ulpWord[5],
+					*(((uint32_t *) irsp) + 6),
+					*(((uint32_t *) irsp) + 7));
+		}
+
+		switch (type) {
+		case LPFC_ABORT_IOCB:
+		case LPFC_SOL_IOCB:
+			/*
+			 * Idle exchange closed via ABTS from port.  No iocb
+			 * resources need to be recovered.
+			 */
+			if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
+				printk(KERN_INFO "%s: IOCB cmd 0x%x processed."
+				       " Skipping completion\n", __FUNCTION__,
+				       irsp->ulpCommand);
+				break;
+			}
+
+			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+							 &rspiocbq);
+			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
+				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+						      &rspiocbq);
+			}
+			break;
+		default:
+			if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
+				char adaptermsg[LPFC_MAX_ADPTMSG];
+				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
+				memcpy(&adaptermsg[0], (uint8_t *) irsp,
+				       MAX_MSG_DATA);
+				dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+					 phba->brd_no, adaptermsg);
+			} else {
+				/* Unknown IOCB command */
+				lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+						"%d:0321 Unknown IOCB command "
+						"Data: x%x, x%x x%x x%x x%x\n",
+						phba->brd_no, type,
+						irsp->ulpCommand,
+						irsp->ulpStatus,
+						irsp->ulpIoTag,
+						irsp->ulpContext);
+			}
+			break;
+		}
+
+		/*
+		 * The response IOCB has been processed.  Update the ring
+		 * pointer in SLIM.  If the port response put pointer has not
+		 * been updated, sync the pgp->rspPutInx and fetch the new port
+		 * response put pointer.
+		 */
+		to_slim = phba->MBslimaddr +
+			(SLIMOFF + (pring->ringno * 2) + 1) * 4;
+		writeb(pring->rspidx, to_slim);
+
+		if (pring->rspidx == portRspPut)
+			portRspPut = le32_to_cpu(pgp->rspPutInx);
+	}
+
+	ha_copy = readl(phba->HAregaddr);
+	ha_copy >>= (LPFC_FCP_RING * 4);
+
+	if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
+		pring->stats.iocb_rsp_full++;
+		status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
+		writel(status, phba->CAregaddr);
+		readl(phba->CAregaddr);
+	}
+	if ((ha_copy & HA_R0CE_RSP) &&
+	    (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
+		pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
+		pring->stats.iocb_cmd_empty++;
+
+		/* Force update of the local copy of cmdGetInx */
+		pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+		lpfc_sli_resume_iocb(phba, pring);
+
+		if ((pring->lpfc_sli_cmd_available))
+			(pring->lpfc_sli_cmd_available) (phba, pring);
+
+	}
+
+	return;
+}
+
 /*
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
  * to check it explicitly.
@@ -917,24 +1093,7 @@
 	portRspMax = pring->numRiocb;
 	portRspPut = le32_to_cpu(pgp->rspPutInx);
 	if (unlikely(portRspPut >= portRspMax)) {
-		/*
-		 * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
-		 * rsp ring <portRspMax>
-		 */
-		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-				"%d:0312 Ring %d handler: portRspPut %d "
-				"is bigger then rsp ring %d\n",
-				phba->brd_no, pring->ringno, portRspPut,
-				portRspMax);
-
-		phba->hba_state = LPFC_HBA_ERROR;
-
-		/* All error attention handlers are posted to worker thread */
-		phba->work_ha |= HA_ERATT;
-		phba->work_hs = HS_FFER3;
-		if (phba->work_wait)
-			wake_up(phba->work_wait);
-
+		lpfc_sli_rsp_pointers_error(phba, pring);
 		spin_unlock_irqrestore(phba->host->host_lock, iflag);
 		return 1;
 	}
@@ -947,6 +1106,10 @@
 		 * network byte order and pci byte orders are different.
 		 */
 		entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+		if (++pring->rspidx >= portRspMax)
+			pring->rspidx = 0;
+
 		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
 				      (uint32_t *) &rspiocbq.iocb,
 				      sizeof (IOCB_t));
@@ -1020,9 +1183,6 @@
 		 * been updated, sync the pgp->rspPutInx and fetch the new port
 		 * response put pointer.
 		 */
-		if (++pring->rspidx >= portRspMax)
-			pring->rspidx = 0;
-
 		to_slim = phba->MBslimaddr +
 			(SLIMOFF + (pring->ringno * 2) + 1) * 4;
 		writel(pring->rspidx, to_slim);
@@ -2615,6 +2775,7 @@
 	DECLARE_WAIT_QUEUE_HEAD(done_q);
 	long timeleft, timeout_req = 0;
 	int retval = IOCB_SUCCESS;
+	uint32_t creg_val;
 
 	/*
 	 * If the caller has provided a response iocbq buffer, then context2
@@ -2630,6 +2791,13 @@
 	piocb->context_un.wait_queue = &done_q;
 	piocb->iocb_flag &= ~LPFC_IO_WAKE;
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
 	retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
 	if (retval == IOCB_SUCCESS) {
 		timeout_req = timeout * HZ;
@@ -2663,6 +2831,13 @@
 		retval = IOCB_ERROR;
 	}
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
 	if (prspiocbq)
 		piocb->context2 = NULL;
 
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4f0466f..fa681a9 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.0"
+#define LPFC_DRIVER_VERSION "8.1.1"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 578143e..4a6feb1 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2,7 +2,7 @@
  *
  *			Linux MegaRAID device driver
  *
- * Copyright © 2002  LSI Logic Corporation.
+ * Copyright (c) 2002  LSI Logic Corporation.
  *
  *	   This program is free software; you can redistribute it and/or
  *	   modify it under the terms of the GNU General Public License
@@ -17,7 +17,8 @@
  * Copyright (c) 2003  Christoph Hellwig  <hch@lst.de>
  *	  - new-style, hotplug-aware pci probing and scsi registration
  *
- * Version : v2.00.3 (Feb 19, 2003) - Atul Mukker <Atul.Mukker@lsil.com>
+ * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
+ * 						<Seokmann.Ju@lsil.com>
  *
  * Description: Linux device driver for LSI Logic MegaRAID controller
  *
@@ -51,10 +52,10 @@
 
 #include "megaraid.h"
 
-#define MEGARAID_MODULE_VERSION "2.00.3"
+#define MEGARAID_MODULE_VERSION "2.00.4"
 
-MODULE_AUTHOR ("LSI Logic Corporation");
-MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+MODULE_AUTHOR ("sju@lsil.com");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
 MODULE_LICENSE ("GPL");
 MODULE_VERSION(MEGARAID_MODULE_VERSION);
 
@@ -4553,7 +4554,7 @@
 static struct scsi_host_template megaraid_template = {
 	.module				= THIS_MODULE,
 	.name				= "MegaRAID",
-	.proc_name			= "megaraid",
+	.proc_name			= "megaraid_legacy",
 	.info				= megaraid_info,
 	.queuecommand			= megaraid_queue,	
 	.bios_param			= megaraid_biosparam,
@@ -5037,22 +5038,12 @@
 }
 
 static struct pci_device_id megaraid_pci_tbl[] = {
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
@@ -5095,7 +5086,7 @@
 	 * First argument (major) to register_chrdev implies a dynamic
 	 * major number allocation.
 	 */
-	major = register_chrdev(0, "megadev", &megadev_fops);
+	major = register_chrdev(0, "megadev_legacy", &megadev_fops);
 	if (!major) {
 		printk(KERN_WARNING
 				"megaraid: failed to register char device\n");
@@ -5109,7 +5100,7 @@
 	/*
 	 * Unregister the character device interface to the driver.
 	 */
-	unregister_chrdev(major, "megadev");
+	unregister_chrdev(major, "megadev_legacy");
 
 	pci_unregister_driver(&megaraid_pci_driver);
 
diff --git a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid
index 7363e12..17419e3 100644
--- a/drivers/scsi/megaraid/Kconfig.megaraid
+++ b/drivers/scsi/megaraid/Kconfig.megaraid
@@ -64,7 +64,6 @@
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid_mbox
 
-if MEGARAID_NEWGEN=n
 config MEGARAID_LEGACY
 	tristate "LSI Logic Legacy MegaRAID Driver"
 	depends on PCI && SCSI
@@ -75,7 +74,6 @@
 
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid
-endif
 
 config MEGARAID_SAS
 	tristate "LSI Logic MegaRAID SAS RAID Module"
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 4b5d420..d18a4bc 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -10,12 +10,13 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mbox.c
- * Version	: v2.20.4.6 (Mar 07 2005)
+ * Version	: v2.20.4.7 (Nov 14 2005)
  *
  * Authors:
  * 	Atul Mukker		<Atul.Mukker@lsil.com>
  * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsil.com>
  * 	Manoj Jose		<Manoj.Jose@lsil.com>
+ * 	Seokmann Ju		<Seokmann.Ju@lsil.com>
  *
  * List of supported controllers
  *
@@ -136,7 +137,7 @@
 
 
 
-MODULE_AUTHOR("LSI Logic Corporation");
+MODULE_AUTHOR("sju@lsil.com");
 MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGARAID_VERSION);
@@ -278,68 +279,14 @@
 	{
 		PCI_VENDOR_ID_AMI,
 		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_QC,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
-		PCI_VENDOR_ID_AMI,
+		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_DC,
-	},
-	{
-		PCI_VENDOR_ID_AMI,
-		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_SC,
-	},
-	{
-		PCI_VENDOR_ID_AMI,
-		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_AMI,
-		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,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_0,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_1,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_1,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_2,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_2,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_I4_133_RAID,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_150_4,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_150_4,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_150_6,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_150_6,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
@@ -347,18 +294,6 @@
 		PCI_ANY_ID,
 		PCI_ANY_ID,
 	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCS16,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCS16,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-	},
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, pci_id_table_g);
@@ -2985,6 +2920,7 @@
 
 	for (i = 0; i < 0xFFFFF; i++) {
 		if (mbox->numstatus != 0xFF) break;
+		rmb();
 	}
 
 	if (i == 0xFFFFF) {
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h
index 644b91b..882fb1a 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.h
+++ b/drivers/scsi/megaraid/megaraid_mbox.h
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION	"2.20.4.6"
-#define MEGARAID_EXT_VERSION	"(Release Date: Mon Mar 07 12:27:22 EST 2005)"
+#define MEGARAID_VERSION	"2.20.4.7"
+#define MEGARAID_EXT_VERSION	"(Release Date: Mon Nov 14 12:27:22 EST 2005)"
 
 
 /*
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 2434709..3235070 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -131,7 +131,739 @@
 #define NAME53C			"ncr53c"
 #define NAME53C8XX		"ncr53c8xx"
 
-#include "sym53c8xx_comm.h"
+
+/*==========================================================
+**
+**	Debugging tags
+**
+**==========================================================
+*/
+
+#define DEBUG_ALLOC    (0x0001)
+#define DEBUG_PHASE    (0x0002)
+#define DEBUG_QUEUE    (0x0008)
+#define DEBUG_RESULT   (0x0010)
+#define DEBUG_POINTER  (0x0020)
+#define DEBUG_SCRIPT   (0x0040)
+#define DEBUG_TINY     (0x0080)
+#define DEBUG_TIMING   (0x0100)
+#define DEBUG_NEGO     (0x0200)
+#define DEBUG_TAGS     (0x0400)
+#define DEBUG_SCATTER  (0x0800)
+#define DEBUG_IC        (0x1000)
+
+/*
+**    Enable/Disable debug messages.
+**    Can be changed at runtime too.
+*/
+
+#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
+static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
+	#define DEBUG_FLAGS ncr_debug
+#else
+	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
+#endif
+
+static inline struct list_head *ncr_list_pop(struct list_head *head)
+{
+	if (!list_empty(head)) {
+		struct list_head *elem = head->next;
+
+		list_del(elem);
+		return elem;
+	}
+
+	return NULL;
+}
+
+/*==========================================================
+**
+**	Simple power of two buddy-like allocator.
+**
+**	This simple code is not intended to be fast, but to 
+**	provide power of 2 aligned memory allocations.
+**	Since the SCRIPTS processor only supplies 8 bit 
+**	arithmetic, this allocator allows simple and fast 
+**	address calculations  from the SCRIPTS code.
+**	In addition, cache line alignment is guaranteed for 
+**	power of 2 cache line size.
+**	Enhanced in linux-2.3.44 to provide a memory pool 
+**	per pcidev to support dynamic dma mapping. (I would 
+**	have preferred a real bus astraction, btw).
+**
+**==========================================================
+*/
+
+#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
+#if PAGE_SIZE >= 8192
+#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
+#else
+#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
+#endif
+#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
+#define MEMO_WARN	1
+#define MEMO_GFP_FLAGS	GFP_ATOMIC
+#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
+#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
+#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
+
+typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
+typedef struct device *m_bush_t;	/* Something that addresses DMAable */
+
+typedef struct m_link {		/* Link between free memory chunks */
+	struct m_link *next;
+} m_link_s;
+
+typedef struct m_vtob {		/* Virtual to Bus address translation */
+	struct m_vtob *next;
+	m_addr_t vaddr;
+	m_addr_t baddr;
+} m_vtob_s;
+#define VTOB_HASH_SHIFT		5
+#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
+#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
+#define VTOB_HASH_CODE(m)	\
+	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+
+typedef struct m_pool {		/* Memory pool of a given kind */
+	m_bush_t bush;
+	m_addr_t (*getp)(struct m_pool *);
+	void (*freep)(struct m_pool *, m_addr_t);
+	int nump;
+	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
+	struct m_pool *next;
+	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+} m_pool_s;
+
+static void *___m_alloc(m_pool_s *mp, int size)
+{
+	int i = 0;
+	int s = (1 << MEMO_SHIFT);
+	int j;
+	m_addr_t a;
+	m_link_s *h = mp->h;
+
+	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+		return NULL;
+
+	while (size > s) {
+		s <<= 1;
+		++i;
+	}
+
+	j = i;
+	while (!h[j].next) {
+		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+			h[j].next = (m_link_s *)mp->getp(mp);
+			if (h[j].next)
+				h[j].next->next = NULL;
+			break;
+		}
+		++j;
+		s <<= 1;
+	}
+	a = (m_addr_t) h[j].next;
+	if (a) {
+		h[j].next = h[j].next->next;
+		while (j > i) {
+			j -= 1;
+			s >>= 1;
+			h[j].next = (m_link_s *) (a+s);
+			h[j].next->next = NULL;
+		}
+	}
+#ifdef DEBUG
+	printk("___m_alloc(%d) = %p\n", size, (void *) a);
+#endif
+	return (void *) a;
+}
+
+static void ___m_free(m_pool_s *mp, void *ptr, int size)
+{
+	int i = 0;
+	int s = (1 << MEMO_SHIFT);
+	m_link_s *q;
+	m_addr_t a, b;
+	m_link_s *h = mp->h;
+
+#ifdef DEBUG
+	printk("___m_free(%p, %d)\n", ptr, size);
+#endif
+
+	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+		return;
+
+	while (size > s) {
+		s <<= 1;
+		++i;
+	}
+
+	a = (m_addr_t) ptr;
+
+	while (1) {
+#ifdef MEMO_FREE_UNUSED
+		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+			mp->freep(mp, a);
+			break;
+		}
+#endif
+		b = a ^ s;
+		q = &h[i];
+		while (q->next && q->next != (m_link_s *) b) {
+			q = q->next;
+		}
+		if (!q->next) {
+			((m_link_s *) a)->next = h[i].next;
+			h[i].next = (m_link_s *) a;
+			break;
+		}
+		q->next = q->next->next;
+		a = a & b;
+		s <<= 1;
+		++i;
+	}
+}
+
+static DEFINE_SPINLOCK(ncr53c8xx_lock);
+
+static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
+{
+	void *p;
+
+	p = ___m_alloc(mp, size);
+
+	if (DEBUG_FLAGS & DEBUG_ALLOC)
+		printk ("new %-10s[%4d] @%p.\n", name, size, p);
+
+	if (p)
+		memset(p, 0, size);
+	else if (uflags & MEMO_WARN)
+		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
+
+	return p;
+}
+
+#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
+
+static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
+{
+	if (DEBUG_FLAGS & DEBUG_ALLOC)
+		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+
+	___m_free(mp, ptr, size);
+
+}
+
+/*
+ * With pci bus iommu support, we use a default pool of unmapped memory 
+ * for memory we donnot need to DMA from/to and one pool per pcidev for 
+ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
+ */
+
+static m_addr_t ___mp0_getp(m_pool_s *mp)
+{
+	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
+	if (m)
+		++mp->nump;
+	return m;
+}
+
+static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
+{
+	free_pages(m, MEMO_PAGE_ORDER);
+	--mp->nump;
+}
+
+static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
+
+/*
+ * DMAable pools.
+ */
+
+/*
+ * With pci bus iommu support, we maintain one pool per pcidev and a 
+ * hashed reverse table for virtual to bus physical address translations.
+ */
+static m_addr_t ___dma_getp(m_pool_s *mp)
+{
+	m_addr_t vp;
+	m_vtob_s *vbp;
+
+	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
+	if (vbp) {
+		dma_addr_t daddr;
+		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
+						PAGE_SIZE<<MEMO_PAGE_ORDER,
+						&daddr, GFP_ATOMIC);
+		if (vp) {
+			int hc = VTOB_HASH_CODE(vp);
+			vbp->vaddr = vp;
+			vbp->baddr = daddr;
+			vbp->next = mp->vtob[hc];
+			mp->vtob[hc] = vbp;
+			++mp->nump;
+			return vp;
+		}
+	}
+	if (vbp)
+		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+	return 0;
+}
+
+static void ___dma_freep(m_pool_s *mp, m_addr_t m)
+{
+	m_vtob_s **vbpp, *vbp;
+	int hc = VTOB_HASH_CODE(m);
+
+	vbpp = &mp->vtob[hc];
+	while (*vbpp && (*vbpp)->vaddr != m)
+		vbpp = &(*vbpp)->next;
+	if (*vbpp) {
+		vbp = *vbpp;
+		*vbpp = (*vbpp)->next;
+		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+		--mp->nump;
+	}
+}
+
+static inline m_pool_s *___get_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
+	return mp;
+}
+
+static m_pool_s *___cre_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
+	if (mp) {
+		memset(mp, 0, sizeof(*mp));
+		mp->bush = bush;
+		mp->getp = ___dma_getp;
+		mp->freep = ___dma_freep;
+		mp->next = mp0.next;
+		mp0.next = mp;
+	}
+	return mp;
+}
+
+static void ___del_dma_pool(m_pool_s *p)
+{
+	struct m_pool **pp = &mp0.next;
+
+	while (*pp && *pp != p)
+		pp = &(*pp)->next;
+	if (*pp) {
+		*pp = (*pp)->next;
+		__m_free(&mp0, p, sizeof(*p), "MPOOL");
+	}
+}
+
+static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+	void *m = NULL;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (!mp)
+		mp = ___cre_dma_pool(bush);
+	if (mp)
+		m = __m_calloc(mp, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+
+	return m;
+}
+
+static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (mp)
+		__m_free(mp, m, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+}
+
+static m_addr_t __vtobus(m_bush_t bush, void *m)
+{
+	u_long flags;
+	m_pool_s *mp;
+	int hc = VTOB_HASH_CODE(m);
+	m_vtob_s *vp = NULL;
+	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (mp) {
+		vp = mp->vtob[hc];
+		while (vp && (m_addr_t) vp->vaddr != a)
+			vp = vp->next;
+	}
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
+}
+
+#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
+#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
+#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
+#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
+#define _vtobus(np, p)			__vtobus(np->dev, p)
+#define vtobus(p)			_vtobus(np, p)
+
+/*
+ *  Deal with DMA mapping/unmapping.
+ */
+
+/* To keep track of the dma mapping (sg/single) that has been set */
+#define __data_mapped	SCp.phase
+#define __data_mapping	SCp.have_data_in
+
+static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	switch(cmd->__data_mapped) {
+	case 2:
+		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
+				cmd->sc_data_direction);
+		break;
+	case 1:
+		dma_unmap_single(dev, cmd->__data_mapping,
+				 cmd->request_bufflen,
+				 cmd->sc_data_direction);
+		break;
+	}
+	cmd->__data_mapped = 0;
+}
+
+static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	dma_addr_t mapping;
+
+	if (cmd->request_bufflen == 0)
+		return 0;
+
+	mapping = dma_map_single(dev, cmd->request_buffer,
+				 cmd->request_bufflen,
+				 cmd->sc_data_direction);
+	cmd->__data_mapped = 1;
+	cmd->__data_mapping = mapping;
+
+	return mapping;
+}
+
+static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	int use_sg;
+
+	if (cmd->use_sg == 0)
+		return 0;
+
+	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
+			cmd->sc_data_direction);
+	cmd->__data_mapped = 2;
+	cmd->__data_mapping = use_sg;
+
+	return use_sg;
+}
+
+#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)
+
+/*==========================================================
+**
+**	Driver setup.
+**
+**	This structure is initialized from linux config 
+**	options. It can be overridden at boot-up by the boot 
+**	command line.
+**
+**==========================================================
+*/
+static struct ncr_driver_setup
+	driver_setup			= SCSI_NCR_DRIVER_SETUP;
+
+#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+static struct ncr_driver_setup
+	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
+#endif
+
+#define initverbose (driver_setup.verbose)
+#define bootverbose (np->verbose)
+
+
+/*===================================================================
+**
+**	Driver setup from the boot command line
+**
+**===================================================================
+*/
+
+#ifdef MODULE
+#define	ARG_SEP	' '
+#else
+#define	ARG_SEP	','
+#endif
+
+#define OPT_TAGS		1
+#define OPT_MASTER_PARITY	2
+#define OPT_SCSI_PARITY		3
+#define OPT_DISCONNECTION	4
+#define OPT_SPECIAL_FEATURES	5
+#define OPT_UNUSED_1		6
+#define OPT_FORCE_SYNC_NEGO	7
+#define OPT_REVERSE_PROBE	8
+#define OPT_DEFAULT_SYNC	9
+#define OPT_VERBOSE		10
+#define OPT_DEBUG		11
+#define OPT_BURST_MAX		12
+#define OPT_LED_PIN		13
+#define OPT_MAX_WIDE		14
+#define OPT_SETTLE_DELAY	15
+#define OPT_DIFF_SUPPORT	16
+#define OPT_IRQM		17
+#define OPT_PCI_FIX_UP		18
+#define OPT_BUS_CHECK		19
+#define OPT_OPTIMIZE		20
+#define OPT_RECOVERY		21
+#define OPT_SAFE_SETUP		22
+#define OPT_USE_NVRAM		23
+#define OPT_EXCLUDE		24
+#define OPT_HOST_ID		25
+
+#ifdef SCSI_NCR_IARB_SUPPORT
+#define OPT_IARB		26
+#endif
+
+static char setup_token[] __initdata = 
+	"tags:"   "mpar:"
+	"spar:"   "disc:"
+	"specf:"  "ultra:"
+	"fsn:"    "revprob:"
+	"sync:"   "verb:"
+	"debug:"  "burst:"
+	"led:"    "wide:"
+	"settle:" "diff:"
+	"irqm:"   "pcifix:"
+	"buschk:" "optim:"
+	"recovery:"
+	"safe:"   "nvram:"
+	"excl:"   "hostid:"
+#ifdef SCSI_NCR_IARB_SUPPORT
+	"iarb:"
+#endif
+	;	/* DONNOT REMOVE THIS ';' */
+
+#ifdef MODULE
+#define	ARG_SEP	' '
+#else
+#define	ARG_SEP	','
+#endif
+
+static int __init get_setup_token(char *p)
+{
+	char *cur = setup_token;
+	char *pc;
+	int i = 0;
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		++pc;
+		++i;
+		if (!strncmp(p, cur, pc - cur))
+			return i;
+		cur = pc;
+	}
+	return 0;
+}
+
+
+static int __init sym53c8xx__setup(char *str)
+{
+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+	char *cur = str;
+	char *pc, *pv;
+	int i, val, c;
+	int xi = 0;
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		char *pe;
+
+		val = 0;
+		pv = pc;
+		c = *++pv;
+
+		if	(c == 'n')
+			val = 0;
+		else if	(c == 'y')
+			val = 1;
+		else
+			val = (int) simple_strtoul(pv, &pe, 0);
+
+		switch (get_setup_token(cur)) {
+		case OPT_TAGS:
+			driver_setup.default_tags = val;
+			if (pe && *pe == '/') {
+				i = 0;
+				while (*pe && *pe != ARG_SEP && 
+					i < sizeof(driver_setup.tag_ctrl)-1) {
+					driver_setup.tag_ctrl[i++] = *pe++;
+				}
+				driver_setup.tag_ctrl[i] = '\0';
+			}
+			break;
+		case OPT_MASTER_PARITY:
+			driver_setup.master_parity = val;
+			break;
+		case OPT_SCSI_PARITY:
+			driver_setup.scsi_parity = val;
+			break;
+		case OPT_DISCONNECTION:
+			driver_setup.disconnection = val;
+			break;
+		case OPT_SPECIAL_FEATURES:
+			driver_setup.special_features = val;
+			break;
+		case OPT_FORCE_SYNC_NEGO:
+			driver_setup.force_sync_nego = val;
+			break;
+		case OPT_REVERSE_PROBE:
+			driver_setup.reverse_probe = val;
+			break;
+		case OPT_DEFAULT_SYNC:
+			driver_setup.default_sync = val;
+			break;
+		case OPT_VERBOSE:
+			driver_setup.verbose = val;
+			break;
+		case OPT_DEBUG:
+			driver_setup.debug = val;
+			break;
+		case OPT_BURST_MAX:
+			driver_setup.burst_max = val;
+			break;
+		case OPT_LED_PIN:
+			driver_setup.led_pin = val;
+			break;
+		case OPT_MAX_WIDE:
+			driver_setup.max_wide = val? 1:0;
+			break;
+		case OPT_SETTLE_DELAY:
+			driver_setup.settle_delay = val;
+			break;
+		case OPT_DIFF_SUPPORT:
+			driver_setup.diff_support = val;
+			break;
+		case OPT_IRQM:
+			driver_setup.irqm = val;
+			break;
+		case OPT_PCI_FIX_UP:
+			driver_setup.pci_fix_up	= val;
+			break;
+		case OPT_BUS_CHECK:
+			driver_setup.bus_check = val;
+			break;
+		case OPT_OPTIMIZE:
+			driver_setup.optimize = val;
+			break;
+		case OPT_RECOVERY:
+			driver_setup.recovery = val;
+			break;
+		case OPT_USE_NVRAM:
+			driver_setup.use_nvram = val;
+			break;
+		case OPT_SAFE_SETUP:
+			memcpy(&driver_setup, &driver_safe_setup,
+				sizeof(driver_setup));
+			break;
+		case OPT_EXCLUDE:
+			if (xi < SCSI_NCR_MAX_EXCLUDES)
+				driver_setup.excludes[xi++] = val;
+			break;
+		case OPT_HOST_ID:
+			driver_setup.host_id = val;
+			break;
+#ifdef SCSI_NCR_IARB_SUPPORT
+		case OPT_IARB:
+			driver_setup.iarb = val;
+			break;
+#endif
+		default:
+			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
+			break;
+		}
+
+		if ((cur = strchr(cur, ARG_SEP)) != NULL)
+			++cur;
+	}
+#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
+	return 1;
+}
+
+/*===================================================================
+**
+**	Get device queue depth from boot command line.
+**
+**===================================================================
+*/
+#define DEF_DEPTH	(driver_setup.default_tags)
+#define ALL_TARGETS	-2
+#define NO_TARGET	-1
+#define ALL_LUNS	-2
+#define NO_LUN		-1
+
+static int device_queue_depth(int unit, int target, int lun)
+{
+	int c, h, t, u, v;
+	char *p = driver_setup.tag_ctrl;
+	char *ep;
+
+	h = -1;
+	t = NO_TARGET;
+	u = NO_LUN;
+	while ((c = *p++) != 0) {
+		v = simple_strtoul(p, &ep, 0);
+		switch(c) {
+		case '/':
+			++h;
+			t = ALL_TARGETS;
+			u = ALL_LUNS;
+			break;
+		case 't':
+			if (t != target)
+				t = (target == v) ? v : NO_TARGET;
+			u = ALL_LUNS;
+			break;
+		case 'u':
+			if (u != lun)
+				u = (lun == v) ? v : NO_LUN;
+			break;
+		case 'q':
+			if (h == unit &&
+				(t == ALL_TARGETS || t == target) &&
+				(u == ALL_LUNS    || u == lun))
+				return v;
+			break;
+		case '-':
+			t = ALL_TARGETS;
+			u = ALL_LUNS;
+			break;
+		default:
+			break;
+		}
+		p = ep;
+	}
+	return DEF_DEPTH;
+}
 
 
 /*==========================================================
@@ -2971,21 +3703,10 @@
 
 static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
 {
-	int i;
 	PRINT_ADDR(cp->cmd, "%s: ", label);
 
-	printk ("%x",*msg);
-	if (*msg == M_EXTENDED) {
-		for (i = 1; i < 8; i++) {
-			if (i - 1 > msg[1])
-				break;
-			printk ("-%x",msg[i]);
-		}
-	} else if ((*msg & 0xf0) == 0x20) {
-		printk ("-%x",msg[1]);
-	}
-
-	printk(".\n");
+	spi_print_msg(msg);
+	printk("\n");
 }
 
 /*==========================================================
diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
index 05c7b83..6a7bef2 100644
--- a/drivers/scsi/ncr53c8xx.h
+++ b/drivers/scsi/ncr53c8xx.h
@@ -2,6 +2,7 @@
 **  Device driver for the PCI-SCSI NCR538XX controller family.
 **
 **  Copyright (C) 1994  Wolfgang Stanglmeier
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License as published by
@@ -36,15 +37,1275 @@
 **  And has been ported to NetBSD by
 **          Charles M. Hannum           <mycroft@gnu.ai.mit.edu>
 **
+**  NVRAM detection and reading.
+**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
+**
+**  Added support for MIPS big endian systems.
+**    Carsten Langgaard, carstenl@mips.com
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
+**  Added support for HP PARISC big endian systems.
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
 *******************************************************************************
 */
 
 #ifndef NCR53C8XX_H
 #define NCR53C8XX_H
 
+#include <linux/config.h>
 #include <scsi/scsi_host.h>
 
-#include "sym53c8xx_defs.h"
+/*
+**	If you want a driver as small as possible, do not define the 
+**	following options.
+*/
+#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+#define SCSI_NCR_DEBUG_INFO_SUPPORT
+
+/*
+**	To disable integrity checking, do not define the 
+**	following option.
+*/
+#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
+#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
+#endif
+
+/* ---------------------------------------------------------------------
+** Take into account kernel configured parameters.
+** Most of these options can be overridden at startup by a command line.
+** ---------------------------------------------------------------------
+*/
+
+/*
+ * For Ultra2 and Ultra3 SCSI support option, use special features. 
+ *
+ * Value (default) means:
+ *	bit 0 : all features enabled, except:
+ *		bit 1 : PCI Write And Invalidate.
+ *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
+ *
+ * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
+ * enabled by the driver.
+ */
+#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
+
+#define SCSI_NCR_MAX_SYNC			(80)
+
+/*
+ * Allow tags from 2 to 256, default 8
+ */
+#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
+#define SCSI_NCR_MAX_TAGS	(2)
+#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
+#define SCSI_NCR_MAX_TAGS	(256)
+#else
+#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#endif
+#else
+#define SCSI_NCR_MAX_TAGS	(8)
+#endif
+
+/*
+ * Allow tagged command queuing support if configured with default number 
+ * of tags set to max (see above).
+ */
+#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
+#else
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
+#endif
+
+/*
+ * Immediate arbitration
+ */
+#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
+#define SCSI_NCR_IARB_SUPPORT
+#endif
+
+/*
+ * Sync transfer frequency at startup.
+ * Allow from 5Mhz to 80Mhz default 20 Mhz.
+ */
+#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
+#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
+#undef	CONFIG_SCSI_NCR53C8XX_SYNC
+#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
+#endif
+
+#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
+#else
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
+#endif
+
+/*
+ * Disallow disconnections at boot-up
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+#define SCSI_NCR_SETUP_DISCONNECTION	(0)
+#else
+#define SCSI_NCR_SETUP_DISCONNECTION	(1)
+#endif
+
+/*
+ * Force synchronous negotiation for all targets
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
+#else
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
+#endif
+
+/*
+ * Disable master parity checking (flawed hardwares need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
+#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
+#else
+#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
+#endif
+
+/*
+ * Disable scsi parity checking (flawed devices may need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
+#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
+#else
+#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
+#endif
+
+/*
+ * Settle time after reset at boot-up
+ */
+#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
+
+/*
+**	Bridge quirks work-around option defaulted to 1.
+*/
+#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
+#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
+#endif
+
+/*
+**	Work-around common bridge misbehaviour.
+**
+**	- Do not flush posted writes in the opposite 
+**	  direction on read.
+**	- May reorder DMA writes to memory.
+**
+**	This option should not affect performances 
+**	significantly, so it is the default.
+*/
+#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
+#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+
+/*
+**	Same as option 1, but also deal with 
+**	misconfigured interrupts.
+**
+**	- Edge triggerred instead of level sensitive.
+**	- No interrupt line connected.
+**	- IRQ number misconfigured.
+**	
+**	If no interrupt is delivered, the driver will 
+**	catch the interrupt conditions 10 times per 
+**	second. No need to say that this option is 
+**	not recommended.
+*/
+#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
+#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+#define	SCSI_NCR_PCIQ_BROKEN_INTR
+
+/*
+**	Some bridge designers decided to flush 
+**	everything prior to deliver the interrupt.
+**	This option tries to deal with such a 
+**	behaviour.
+*/
+#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
+#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
+#endif
+
+/*
+**	Other parameters not configurable with "make config"
+**	Avoid to change these constants, unless you know what you are doing.
+*/
+
+#define SCSI_NCR_ALWAYS_SIMPLE_TAG
+#define SCSI_NCR_MAX_SCATTER	(127)
+#define SCSI_NCR_MAX_TARGET	(16)
+
+/*
+**   Compute some desirable value for CAN_QUEUE 
+**   and CMD_PER_LUN.
+**   The driver will use lower values if these 
+**   ones appear to be too large.
+*/
+#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
+#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
+
+#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
+#define SCSI_NCR_TIMER_INTERVAL	(HZ)
+
+#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
+#define SCSI_NCR_MAX_LUN	(16)
+#else
+#define SCSI_NCR_MAX_LUN	(1)
+#endif
+
+/*
+ *  IO functions definition for big/little endian CPU support.
+ *  For now, the NCR is only supported in little endian addressing mode, 
+ */
+
+#ifdef	__BIG_ENDIAN
+
+#define	inw_l2b		inw
+#define	inl_l2b		inl
+#define	outw_b2l	outw
+#define	outl_b2l	outl
+
+#define	readb_raw	readb
+#define	writeb_raw	writeb
+
+#if defined(SCSI_NCR_BIG_ENDIAN)
+#define	readw_l2b	__raw_readw
+#define	readl_l2b	__raw_readl
+#define	writew_b2l	__raw_writew
+#define	writel_b2l	__raw_writel
+#define	readw_raw	__raw_readw
+#define	readl_raw	__raw_readl
+#define	writew_raw	__raw_writew
+#define	writel_raw	__raw_writel
+#else	/* Other big-endian */
+#define	readw_l2b	readw
+#define	readl_l2b	readl
+#define	writew_b2l	writew
+#define	writel_b2l	writel
+#define	readw_raw	readw
+#define	readl_raw	readl
+#define	writew_raw	writew
+#define	writel_raw	writel
+#endif
+
+#else	/* little endian */
+
+#define	inw_raw		inw
+#define	inl_raw		inl
+#define	outw_raw	outw
+#define	outl_raw	outl
+
+#define	readb_raw	readb
+#define	readw_raw	readw
+#define	readl_raw	readl
+#define	writeb_raw	writeb
+#define	writew_raw	writew
+#define	writel_raw	writel
+
+#endif
+
+#if !defined(__hppa__) && !defined(__mips__)
+#ifdef	SCSI_NCR_BIG_ENDIAN
+#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
+#endif
+#endif
+
+#define MEMORY_BARRIER()	mb()
+
+
+/*
+ *  If the NCR uses big endian addressing mode over the 
+ *  PCI, actual io register addresses for byte and word 
+ *  accesses must be changed according to lane routing.
+ *  Btw, ncr_offb() and ncr_offw() macros only apply to 
+ *  constants and so donnot generate bloated code.
+ */
+
+#if	defined(SCSI_NCR_BIG_ENDIAN)
+
+#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
+#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
+
+#else
+
+#define ncr_offb(o)	(o)
+#define ncr_offw(o)	(o)
+
+#endif
+
+/*
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for script patching.
+ *  Macro cpu_to_scr() is to be used for script patching.
+ *  Macro scr_to_cpu() is to be used for getting a DWORD 
+ *  from the script.
+ */
+
+#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw)	cpu_to_le32(dw)
+#define scr_to_cpu(dw)	le32_to_cpu(dw)
+
+#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw)	cpu_to_be32(dw)
+#define scr_to_cpu(dw)	be32_to_cpu(dw)
+
+#else
+
+#define cpu_to_scr(dw)	(dw)
+#define scr_to_cpu(dw)	(dw)
+
+#endif
+
+/*
+ *  Access to the controller chip.
+ *
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for accessing chip io 
+ *  registers. Functions suffixed by '_raw' are assumed 
+ *  to access the chip over the PCI without doing byte 
+ *  reordering. Functions suffixed by '_l2b' are 
+ *  assumed to perform little-endian to big-endian byte 
+ *  reordering, those suffixed by '_b2l' blah, blah,
+ *  blah, ...
+ */
+
+/*
+ *  MEMORY mapped IO input / output
+ */
+
+#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
+#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
+
+#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
+
+#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
+
+#else
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
+#else
+#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
+#else
+#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
+
+#endif
+
+#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
+#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
+#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
+
+#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
+
+/*
+ *  Set bit field ON, OFF 
+ */
+
+#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
+#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
+#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
+#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
+#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
+#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
+
+/*
+ *  We normally want the chip to have a consistent view
+ *  of driver internal data structures when we restart it.
+ *  Thus these macros.
+ */
+#define OUTL_DSP(v)				\
+	do {					\
+		MEMORY_BARRIER();		\
+		OUTL (nc_dsp, (v));		\
+	} while (0)
+
+#define OUTONB_STD()				\
+	do {					\
+		MEMORY_BARRIER();		\
+		OUTONB (nc_dcntl, (STD|NOCOM));	\
+	} while (0)
+
+
+/*
+**   NCR53C8XX devices features table.
+*/
+struct ncr_chip {
+	unsigned short	revision_id;
+	unsigned char	burst_max;	/* log-base-2 of max burst */
+	unsigned char	offset_max;
+	unsigned char	nr_divisor;
+	unsigned int	features;
+#define FE_LED0		(1<<0)
+#define FE_WIDE		(1<<1)    /* Wide data transfers */
+#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
+#define FE_DBLR		(1<<4)	  /* Clock doubler present */
+#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
+#define FE_ERL		(1<<6)    /* Enable read line */
+#define FE_CLSE		(1<<7)    /* Cache line size enable */
+#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
+#define FE_ERMP		(1<<9)    /* Enable read multiple */
+#define FE_BOF		(1<<10)   /* Burst opcode fetch */
+#define FE_DFS		(1<<11)   /* DMA fifo size */
+#define FE_PFEN		(1<<12)   /* Prefetch enable */
+#define FE_LDSTR	(1<<13)   /* Load/Store supported */
+#define FE_RAM		(1<<14)   /* On chip RAM present */
+#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
+#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
+#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
+#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
+#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
+#define FE_LEDC		(1<<20)   /* Hardware control of LED */
+#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
+#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
+#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
+#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
+#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
+#define FE_EHP		(1<<27)   /* 720: Even host parity */
+#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
+#define FE_EA		(1<<29)   /* 720: Enable Ack */
+
+#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
+#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
+#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
+};
+
+
+/*
+**	Driver setup structure.
+**
+**	This structure is initialized from linux config options.
+**	It can be overridden at boot-up by the boot command line.
+*/
+#define SCSI_NCR_MAX_EXCLUDES 8
+struct ncr_driver_setup {
+	u8	master_parity;
+	u8	scsi_parity;
+	u8	disconnection;
+	u8	special_features;
+	u8	force_sync_nego;
+	u8	reverse_probe;
+	u8	pci_fix_up;
+	u8	use_nvram;
+	u8	verbose;
+	u8	default_tags;
+	u16	default_sync;
+	u16	debug;
+	u8	burst_max;
+	u8	led_pin;
+	u8	max_wide;
+	u8	settle_delay;
+	u8	diff_support;
+	u8	irqm;
+	u8	bus_check;
+	u8	optimize;
+	u8	recovery;
+	u8	host_id;
+	u16	iarb;
+	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
+	char	tag_ctrl[100];
+};
+
+/*
+**	Initial setup.
+**	Can be overriden at startup by a command line.
+*/
+#define SCSI_NCR_DRIVER_SETUP			\
+{						\
+	SCSI_NCR_SETUP_MASTER_PARITY,		\
+	SCSI_NCR_SETUP_SCSI_PARITY,		\
+	SCSI_NCR_SETUP_DISCONNECTION,		\
+	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
+	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
+	0,					\
+	0,					\
+	1,					\
+	0,					\
+	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
+	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
+	0x00,					\
+	7,					\
+	0,					\
+	1,					\
+	SCSI_NCR_SETUP_SETTLE_TIME,		\
+	0,					\
+	0,					\
+	1,					\
+	0,					\
+	0,					\
+	255,					\
+	0x00					\
+}
+
+/*
+**	Boot fail safe setup.
+**	Override initial setup from boot command line:
+**	ncr53c8xx=safe:y
+*/
+#define SCSI_NCR_DRIVER_SAFE_SETUP		\
+{						\
+	0,					\
+	1,					\
+	0,					\
+	0,					\
+	0,					\
+	0,					\
+	0,					\
+	1,					\
+	2,					\
+	0,					\
+	255,					\
+	0x00,					\
+	255,					\
+	0,					\
+	0,					\
+	10,					\
+	1,					\
+	1,					\
+	1,					\
+	0,					\
+	0,					\
+	255					\
+}
+
+/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
+
+/*-----------------------------------------------------------------
+**
+**	The ncr 53c810 register structure.
+**
+**-----------------------------------------------------------------
+*/
+
+struct ncr_reg {
+/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
+
+/*01*/  u8	nc_scntl1;    /* no reset                         */
+        #define   ISCON   0x10  /* connected to scsi		    */
+        #define   CRST    0x08  /* force reset                      */
+        #define   IARB    0x02  /* immediate arbitration            */
+
+/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
+	#define   SDU     0x80  /* cmd: disconnect will raise error */
+	#define   CHM     0x40  /* sta: chained mode                */
+	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
+	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
+
+/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
+	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
+	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
+				/* bits 0-2, 7 rsvd for C1010       */
+
+/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
+	#define   RRE     0x40  /* r/w:e enable response to resel.  */
+	#define   SRE     0x20  /* r/w:e enable response to select  */
+
+/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
+				/* bits 6-7 rsvd for C1010          */
+
+/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
+
+/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
+
+/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
+
+/*09*/  u8	nc_socl;
+	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
+	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
+	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
+	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
+	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
+	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
+	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
+	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
+
+/*0a*/  u8	nc_ssid;
+
+/*0b*/  u8	nc_sbcl;
+
+/*0c*/  u8	nc_dstat;
+        #define   DFE     0x80  /* sta: dma fifo empty              */
+        #define   MDPE    0x40  /* int: master data parity error    */
+        #define   BF      0x20  /* int: script: bus fault           */
+        #define   ABRT    0x10  /* int: script: command aborted     */
+        #define   SSI     0x08  /* int: script: single step         */
+        #define   SIR     0x04  /* int: script: interrupt instruct. */
+        #define   IID     0x01  /* int: script: illegal instruct.   */
+
+/*0d*/  u8	nc_sstat0;
+        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
+        #define   ORF     0x40  /* sta: data in SODR register lsb   */
+        #define   OLF     0x20  /* sta: data in SODL register lsb   */
+        #define   AIP     0x10  /* sta: arbitration in progress     */
+        #define   LOA     0x08  /* sta: arbitration lost            */
+        #define   WOA     0x04  /* sta: arbitration won             */
+        #define   IRST    0x02  /* sta: scsi reset signal           */
+        #define   SDP     0x01  /* sta: scsi parity signal          */
+
+/*0e*/  u8	nc_sstat1;
+	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
+
+/*0f*/  u8	nc_sstat2;
+        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
+        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
+        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
+        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
+        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
+
+/*10*/  u8	nc_dsa;	/* --> Base page                    */
+/*11*/  u8	nc_dsa1;
+/*12*/  u8	nc_dsa2;
+/*13*/  u8	nc_dsa3;
+
+/*14*/  u8	nc_istat;	/* --> Main Command and status      */
+        #define   CABRT   0x80  /* cmd: abort current operation     */
+        #define   SRST    0x40  /* mod: reset chip                  */
+        #define   SIGP    0x20  /* r/w: message from host to ncr    */
+        #define   SEM     0x10  /* r/w: message between host + ncr  */
+        #define   CON     0x08  /* sta: connected to scsi           */
+        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
+        #define   SIP     0x02  /* sta: scsi-interrupt              */
+        #define   DIP     0x01  /* sta: host/script interrupt       */
+
+/*15*/  u8	nc_istat1;	/* 896 and later cores only */
+        #define   FLSH    0x04  /* sta: chip is flushing            */
+        #define   SRUN    0x02  /* sta: scripts are running         */
+        #define   SIRQD   0x01  /* r/w: disable INT pin             */
+
+/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
+/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
+
+/*18*/	u8	nc_ctest0;
+	#define   EHP     0x04	/* 720 even host parity             */
+/*19*/  u8	nc_ctest1;
+
+/*1a*/  u8	nc_ctest2;
+	#define   CSIGP   0x40
+				/* bits 0-2,7 rsvd for C1010        */
+
+/*1b*/  u8	nc_ctest3;
+	#define   FLF     0x08  /* cmd: flush dma fifo              */
+	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
+	#define   FM      0x02  /* mod: fetch pin mode              */
+	#define   WRIE    0x01  /* mod: write and invalidate enable */
+				/* bits 4-7 rsvd for C1010          */
+
+/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
+
+/*20*/	u8	nc_dfifo;
+/*21*/  u8	nc_ctest4;
+	#define   MUX     0x80  /* 720 host bus multiplex mode      */
+	#define   BDIS    0x80  /* mod: burst disable               */
+	#define   MPEE    0x08  /* mod: master parity error enable  */
+
+/*22*/  u8	nc_ctest5;
+	#define   DFS     0x20  /* mod: dma fifo size               */
+				/* bits 0-1, 3-7 rsvd for C1010          */
+/*23*/  u8	nc_ctest6;
+
+/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
+/*28*/  u32    nc_dnad;	/* ### Next command register        */
+/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
+/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
+
+/*34*/  u8	nc_scratcha;  /* Temporary register a            */
+/*35*/  u8	nc_scratcha1;
+/*36*/  u8	nc_scratcha2;
+/*37*/  u8	nc_scratcha3;
+
+/*38*/  u8	nc_dmode;
+	#define   BL_2    0x80  /* mod: burst length shift value +2 */
+	#define   BL_1    0x40  /* mod: burst length shift value +1 */
+	#define   ERL     0x08  /* mod: enable read line            */
+	#define   ERMP    0x04  /* mod: enable read multiple        */
+	#define   BOF     0x02  /* mod: burst op code fetch         */
+
+/*39*/  u8	nc_dien;
+/*3a*/  u8	nc_sbr;
+
+/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
+	#define   CLSE    0x80  /* mod: cache line size enable      */
+	#define   PFF     0x40  /* cmd: pre-fetch flush             */
+	#define   PFEN    0x20  /* mod: pre-fetch enable            */
+	#define   EA      0x20  /* mod: 720 enable-ack              */
+	#define   SSM     0x10  /* mod: single step mode            */
+	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
+	#define   STD     0x04  /* cmd: start dma mode              */
+	#define   IRQD    0x02  /* mod: irq disable                 */
+ 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
+				/* bits 0-1 rsvd for C1010          */
+
+/*3c*/  u32	nc_adder;
+
+/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
+/*42*/  u16	nc_sist;	/* <--: interrupt status            */
+        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
+        #define   STO     0x0400/* sta: timeout (select)            */
+        #define   GEN     0x0200/* sta: timeout (general)           */
+        #define   HTH     0x0100/* sta: timeout (handshake)         */
+        #define   MA      0x80  /* sta: phase mismatch              */
+        #define   CMP     0x40  /* sta: arbitration complete        */
+        #define   SEL     0x20  /* sta: selected by another device  */
+        #define   RSL     0x10  /* sta: reselected by another device*/
+        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
+        #define   UDC     0x04  /* sta: unexpected disconnect       */
+        #define   RST     0x02  /* sta: scsi bus reset detected     */
+        #define   PAR     0x01  /* sta: scsi parity error           */
+
+/*44*/  u8	nc_slpar;
+/*45*/  u8	nc_swide;
+/*46*/  u8	nc_macntl;
+/*47*/  u8	nc_gpcntl;
+/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
+/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
+/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
+
+/*4c*/  u8	nc_stest0;
+
+/*4d*/  u8	nc_stest1;
+	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
+	#define   DBLEN   0x08	/* clock doubler running		*/
+	#define   DBLSEL  0x04	/* clock doubler selected		*/
+  
+
+/*4e*/  u8	nc_stest2;
+	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
+	#define   DIF     0x20  /* 720 SCSI differential mode             */
+	#define   EXT     0x02  /* extended filtering                     */
+
+/*4f*/  u8	nc_stest3;
+	#define   TE     0x80	/* c: tolerAnt enable */
+	#define   HSC    0x20	/* c: Halt SCSI Clock */
+	#define   CSF    0x02	/* c: clear scsi fifo */
+
+/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
+/*52*/  u8	nc_stest4;
+	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
+	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
+	#define    SMODE_SE  0x80	/* Single Ended                    */
+	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
+	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
+				/* bits 0-5 rsvd for C1010          */
+
+/*53*/  u8	nc_53_;
+/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
+/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
+	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
+	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
+	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
+	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
+	#define   DILS   0x02	/* Disable Internal Load/Store      */
+	#define   DPR    0x01	/* Disable Pipe Req                 */
+
+/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
+	#define   ZMOD   0x80	/* High Impedance Mode              */
+	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
+	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
+	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
+	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
+	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
+
+/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
+/*5a*/  u16	nc_5a_;
+
+/*5c*/  u8	nc_scr0;	/* Working register B               */
+/*5d*/  u8	nc_scr1;	/*                                  */
+/*5e*/  u8	nc_scr2;	/*                                  */
+/*5f*/  u8	nc_scr3;	/*                                  */
+
+/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
+/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
+/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
+/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
+/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
+/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
+/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
+/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
+/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
+	#define   U3EN   0x80	/* Enable Ultra 3                   */
+	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
+	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
+					transfer edge	            */
+	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
+					transfer edge	            */
+
+/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
+/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
+
+/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
+/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
+/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
+/*c9*/	u8	nc_rbc1;	/*                                  */
+/*ca*/	u8	nc_rbc2;	/*                                  */
+/*cb*/	u8	nc_rbc3;	/*                                  */
+
+/*cc*/	u8	nc_ua;		/* Updated Address                  */
+/*cd*/	u8	nc_ua1;		/*                                  */
+/*ce*/	u8	nc_ua2;		/*                                  */
+/*cf*/	u8	nc_ua3;		/*                                  */
+/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
+/*d4*/	u8	nc_ia;		/* Instruction Address              */
+/*d5*/	u8	nc_ia1;
+/*d6*/	u8	nc_ia2;
+/*d7*/	u8	nc_ia3;
+/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
+/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
+
+				/* Following for C1010 only         */
+/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
+/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
+	#define   SNDCRC  0x10	/* Send CRC Request                 */
+/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
+/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
+/*e8*/  u32	nc_e8_;		/* rsvd 			    */
+/*ec*/  u32	nc_ec_;		/* rsvd 			    */
+/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
+
+};
+
+/*-----------------------------------------------------------
+**
+**	Utility macros for the script.
+**
+**-----------------------------------------------------------
+*/
+
+#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
+#define REG(r) REGJ (nc_, r)
+
+typedef u32 ncrcmd;
+
+/*-----------------------------------------------------------
+**
+**	SCSI phases
+**
+**	DT phases illegal for ncr driver.
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_DATA_OUT	0x00000000
+#define	SCR_DATA_IN	0x01000000
+#define	SCR_COMMAND	0x02000000
+#define	SCR_STATUS	0x03000000
+#define SCR_DT_DATA_OUT	0x04000000
+#define SCR_DT_DATA_IN	0x05000000
+#define SCR_MSG_OUT	0x06000000
+#define SCR_MSG_IN      0x07000000
+
+#define SCR_ILG_OUT	0x04000000
+#define SCR_ILG_IN	0x05000000
+
+/*-----------------------------------------------------------
+**
+**	Data transfer via SCSI.
+**
+**-----------------------------------------------------------
+**
+**	MOVE_ABS (LEN)
+**	<<start address>>
+**
+**	MOVE_IND (LEN)
+**	<<dnad_offset>>
+**
+**	MOVE_TBL
+**	<<dnad_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define OPC_MOVE          0x08000000
+
+#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
+
+#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
+#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
+#define SCR_CHMOV_TBL     (0x10000000)
+
+struct scr_tblmove {
+        u32  size;
+        u32  addr;
+};
+
+/*-----------------------------------------------------------
+**
+**	Selection
+**
+**-----------------------------------------------------------
+**
+**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
+**	<<alternate_address>>
+**
+**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
+**	<<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_SEL_ABS	0x40000000
+#define	SCR_SEL_ABS_ATN	0x41000000
+#define	SCR_SEL_TBL	0x42000000
+#define	SCR_SEL_TBL_ATN	0x43000000
+
+
+#ifdef SCSI_NCR_BIG_ENDIAN
+struct scr_tblsel {
+        u8	sel_scntl3;
+        u8	sel_id;
+        u8	sel_sxfer;
+        u8	sel_scntl4;	
+};
+#else
+struct scr_tblsel {
+        u8	sel_scntl4;	
+        u8	sel_sxfer;
+        u8	sel_id;
+        u8	sel_scntl3;
+};
+#endif
+
+#define SCR_JMP_REL     0x04000000
+#define SCR_ID(id)	(((u32)(id)) << 16)
+
+/*-----------------------------------------------------------
+**
+**	Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**	WAIT_DISC
+**	dummy: <<alternate_address>>
+**
+**	WAIT_RESEL
+**	<<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_WAIT_DISC	0x48000000
+#define SCR_WAIT_RESEL  0x50000000
+
+/*-----------------------------------------------------------
+**
+**	Bit Set / Reset
+**
+**-----------------------------------------------------------
+**
+**	SET (flags {|.. })
+**
+**	CLR (flags {|.. })
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SET(f)     (0x58000000 | (f))
+#define SCR_CLR(f)     (0x60000000 | (f))
+
+#define	SCR_CARRY	0x00000400
+#define	SCR_TRG		0x00000200
+#define	SCR_ACK		0x00000040
+#define	SCR_ATN		0x00000008
+
+
+
+
+/*-----------------------------------------------------------
+**
+**	Memory to memory move
+**
+**-----------------------------------------------------------
+**
+**	COPY (bytecount)
+**	<< source_address >>
+**	<< destination_address >>
+**
+**	SCR_COPY   sets the NO FLUSH option by default.
+**	SCR_COPY_F does not set this option.
+**
+**	For chips which do not support this option,
+**	ncr_copy_and_bind() will remove this bit.
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_FLUSH 0x01000000
+
+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+#define SCR_COPY_F(n) (0xc0000000 | (n))
+
+/*-----------------------------------------------------------
+**
+**	Register move and binary operations
+**
+**-----------------------------------------------------------
+**
+**	SFBR_REG (reg, op, data)        reg  = SFBR op data
+**	<< 0 >>
+**
+**	REG_SFBR (reg, op, data)        SFBR = reg op data
+**	<< 0 >>
+**
+**	REG_REG  (reg, op, data)        reg  = reg op data
+**	<< 0 >>
+**
+**-----------------------------------------------------------
+**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
+**	of SFBR register can be used as data (SCR_SFBR_DATA).
+**	The 896 has additionnal IO registers starting at 
+**	offset 0x80. Bit 7 of register offset is stored in 
+**	bit 7 of the SCRIPTS instruction first DWORD.
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
+
+#define SCR_SFBR_REG(reg,op,data) \
+        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_SFBR(reg,op,data) \
+        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_REG(reg,op,data) \
+        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+
+#define      SCR_LOAD   0x00000000
+#define      SCR_SHL    0x01000000
+#define      SCR_OR     0x02000000
+#define      SCR_XOR    0x03000000
+#define      SCR_AND    0x04000000
+#define      SCR_SHR    0x05000000
+#define      SCR_ADD    0x06000000
+#define      SCR_ADDC   0x07000000
+
+#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
+
+/*-----------------------------------------------------------
+**
+**	FROM_REG (reg)		  SFBR = reg
+**	<< 0 >>
+**
+**	TO_REG	 (reg)		  reg  = SFBR
+**	<< 0 >>
+**
+**	LOAD_REG (reg, data)	  reg  = <data>
+**	<< 0 >>
+**
+**	LOAD_SFBR(data) 	  SFBR = <data>
+**	<< 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_FROM_REG(reg) \
+	SCR_REG_SFBR(reg,SCR_OR,0)
+
+#define	SCR_TO_REG(reg) \
+	SCR_SFBR_REG(reg,SCR_OR,0)
+
+#define	SCR_LOAD_REG(reg,data) \
+	SCR_REG_REG(reg,SCR_LOAD,data)
+
+#define SCR_LOAD_SFBR(data) \
+        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+
+/*-----------------------------------------------------------
+**
+**	LOAD  from memory   to register.
+**	STORE from register to memory.
+**
+**	Only supported by 810A, 860, 825A, 875, 895 and 896.
+**
+**-----------------------------------------------------------
+**
+**	LOAD_ABS (LEN)
+**	<<start address>>
+**
+**	LOAD_REL (LEN)        (DSA relative)
+**	<<dsa_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
+#define SCR_NO_FLUSH2	0x02000000
+#define SCR_DSA_REL2	0x10000000
+
+#define SCR_LOAD_R(reg, how, n) \
+        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_STORE_R(reg, how, n) \
+        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
+#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
+#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
+
+#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
+#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
+#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
+
+
+/*-----------------------------------------------------------
+**
+**	Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<address>>
+**
+**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<distance>>
+**
+**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<address>>
+**
+**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<distance>>
+**
+**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<dummy>>
+**
+**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<ident>>
+**
+**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<ident>>
+**
+**	Conditions:
+**	     WHEN (phase)
+**	     IF   (phase)
+**	     CARRYSET
+**	     DATA (data, mask)
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_OP       0x80000000
+#define SCR_JUMP        0x80080000
+#define SCR_JUMP64      0x80480000
+#define SCR_JUMPR       0x80880000
+#define SCR_CALL        0x88080000
+#define SCR_CALLR       0x88880000
+#define SCR_RETURN      0x90080000
+#define SCR_INT         0x98080000
+#define SCR_INT_FLY     0x98180000
+
+#define IFFALSE(arg)   (0x00080000 | (arg))
+#define IFTRUE(arg)    (0x00000000 | (arg))
+
+#define WHEN(phase)    (0x00030000 | (phase))
+#define IF(phase)      (0x00020000 | (phase))
+
+#define DATA(D)        (0x00040000 | ((D) & 0xff))
+#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+
+#define CARRYSET       (0x00200000)
+
+/*-----------------------------------------------------------
+**
+**	SCSI  constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+**	Messages
+*/
+
+#define	M_COMPLETE	COMMAND_COMPLETE
+#define	M_EXTENDED	EXTENDED_MESSAGE
+#define	M_SAVE_DP	SAVE_POINTERS
+#define	M_RESTORE_DP	RESTORE_POINTERS
+#define	M_DISCONNECT	DISCONNECT
+#define	M_ID_ERROR	INITIATOR_ERROR
+#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		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	IGNORE_WIDE_RESIDUE
+#define	M_IDENTIFY   	(0x80)
+
+#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	EXTENDED_PPR
+
+/*
+**	Status
+*/
+
+#define	S_GOOD		(0x00)
+#define	S_CHECK_COND	(0x02)
+#define	S_COND_MET	(0x04)
+#define	S_BUSY		(0x08)
+#define	S_INT		(0x10)
+#define	S_INT_COND_MET	(0x14)
+#define	S_CONFLICT	(0x18)
+#define	S_TERMINATED	(0x20)
+#define	S_QUEUE_FULL	(0x28)
+#define	S_ILLEGAL	(0xff)
+#define	S_SENSE		(0x80)
+
+/*
+ * End of ncrreg from FreeBSD
+ */
 
 /*
 	Build a scatter/gather entry.
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index f557f17..e8df0c9 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -464,14 +464,12 @@
 			continue;
 		qc = ata_qc_from_tag(ap, ap->active_tag);
 		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
-			unsigned int err_mask = 0;
-
 			if ((status & (aPERR | aPSD | aUIRQ)))
-				err_mask = AC_ERR_OTHER;
+				qc->err_mask |= AC_ERR_OTHER;
 			else if (pp->pkt[0] != cDONE)
-				err_mask = AC_ERR_OTHER;
+				qc->err_mask |= AC_ERR_OTHER;
 
-			ata_qc_complete(qc, err_mask);
+			ata_qc_complete(qc);
 		}
 	}
 	return handled;
@@ -501,7 +499,8 @@
 		
 				/* complete taskfile transaction */
 				pp->state = adma_state_idle;
-				ata_qc_complete(qc, ac_err_mask(status));
+				qc->err_mask |= ac_err_mask(status);
+				ata_qc_complete(qc);
 				handled = 1;
 			}
 		}
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index c1c1c68..5205c4e 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -1,55 +1,70 @@
 config SCSI_QLA2XXX
-	tristate
-	default (SCSI && PCI)
-	depends on SCSI && PCI
+	tristate "QLogic QLA2XXX Fibre Channel Support"
+	depends on PCI && SCSI
+	select SCSI_FC_ATTRS
+	select FW_LOADER
+	---help---
+	This qla2xxx driver supports all QLogic Fibre Channel
+	PCI and PCIe host adapters.
+
+	By default, firmware for the ISP parts will be loaded
+	via the Firmware Loader interface.
+
+	ISP             Firmware Filename
+	----------      -----------------
+	21xx            ql2100_fw.bin
+	22xx            ql2200_fw.bin
+	2300, 2312      ql2300_fw.bin
+	2322            ql2322_fw.bin
+	6312, 6322      ql6312_fw.bin
+	24xx            ql2400_fw.bin
+
+	Upon request, the driver caches the firmware image until
+	the driver is unloaded.
+
+	NOTE: The original method of building firmware-loader
+	modules has been deprecated as the firmware-images will
+	be removed from the kernel sources.
+
+config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
+	bool "  Use firmware-loader modules (DEPRECATED)"
+	depends on SCSI_QLA2XXX
 
 config SCSI_QLA21XX
-	tristate "QLogic ISP2100 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2100 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 21xx (ISP2100) host adapter family.
 
 config SCSI_QLA22XX
-	tristate "QLogic ISP2200 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2200 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 22xx (ISP2200) host adapter family.
 
 config SCSI_QLA2300
-	tristate "QLogic ISP2300 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2300 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
 	adapter family.
 
 config SCSI_QLA2322
-	tristate "QLogic ISP2322 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2322 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
 config SCSI_QLA6312
-	tristate "QLogic ISP63xx host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP63xx firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
 	adapter family.
 
 config SCSI_QLA24XX
-	tristate "QLogic ISP24xx host adapter family support"
-	depends on SCSI_QLA2XXX
-	select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP24xx firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
 	adapter family.
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index b169687..40c0de1 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -3,15 +3,18 @@
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
 		qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o
 
+obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx.o
+
 qla2100-y := ql2100.o ql2100_fw.o
 qla2200-y := ql2200.o ql2200_fw.o
 qla2300-y := ql2300.o ql2300_fw.o
 qla2322-y := ql2322.o ql2322_fw.o
 qla6312-y := ql6312.o ql6312_fw.o
+qla2400-y := ql2400.o ql2400_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_QLA24XX) += qla2xxx.o
+obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c
new file mode 100644
index 0000000..6c7165f
--- /dev/null
+++ b/drivers/scsi/qla2xxx/ql2400.c
@@ -0,0 +1,111 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "qla_def.h"
+
+static char qla_driver_name[] = "qla2400";
+
+extern uint32_t fw2400_version_str[];
+extern uint32_t fw2400_addr01;
+extern uint32_t fw2400_code01[];
+extern uint32_t fw2400_length01;
+extern uint32_t fw2400_addr02;
+extern uint32_t fw2400_code02[];
+extern uint32_t fw2400_length02;
+
+static struct qla_fw_info qla_fw_tbl[] = {
+	{
+		.addressing	= FW_INFO_ADDR_EXTENDED,
+		.fwcode		= (unsigned short *)&fw2400_code01[0],
+		.fwlen		= (unsigned short *)&fw2400_length01,
+		.lfwstart	= (unsigned long *)&fw2400_addr01,
+	},
+	{
+		.addressing	= FW_INFO_ADDR_EXTENDED,
+		.fwcode		= (unsigned short *)&fw2400_code02[0],
+		.fwlen		= (unsigned short *)&fw2400_length02,
+		.lfwstart	= (unsigned long *)&fw2400_addr02,
+	},
+	{ FW_INFO_ADDR_NOMORE, },
+};
+
+static struct qla_board_info qla_board_tbl[] = {
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP2422",
+		.fw_info	= qla_fw_tbl,
+		.fw_fname	= "ql2400_fw.bin",
+	},
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP2432",
+		.fw_info	= qla_fw_tbl,
+		.fw_fname	= "ql2400_fw.bin",
+	},
+};
+
+static struct pci_device_id qla24xx_pci_tbl[] = {
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2422,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[0],
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2432,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[1],
+	},
+	{0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
+
+static int __devinit
+qla24xx_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
+qla24xx_remove_one(struct pci_dev *pdev)
+{
+	qla2x00_remove_one(pdev);
+}
+
+static struct pci_driver qla24xx_pci_driver = {
+	.name		= "qla2400",
+	.id_table	= qla24xx_pci_tbl,
+	.probe		= qla24xx_probe_one,
+	.remove		= __devexit_p(qla24xx_remove_one),
+};
+
+static int __init
+qla24xx_init(void)
+{
+	return pci_module_init(&qla24xx_pci_driver);
+}
+
+static void __exit
+qla24xx_exit(void)
+{
+	pci_unregister_driver(&qla24xx_pci_driver);
+}
+
+module_init(qla24xx_init);
+module_exit(qla24xx_exit);
+
+MODULE_AUTHOR("QLogic Corporation");
+MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(QLA2XXX_VERSION);
diff --git a/drivers/scsi/qla2xxx/ql2400_fw.c b/drivers/scsi/qla2xxx/ql2400_fw.c
new file mode 100644
index 0000000..5977795
--- /dev/null
+++ b/drivers/scsi/qla2xxx/ql2400_fw.c
@@ -0,0 +1,12376 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/types.h>
+
+/*
+ *	Firmware Version 4.00.16 (08:09 Oct 26, 2005)
+ */
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version = 4*1024+0;
+#else
+uint32_t risc_code_version = 4*1024+0;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version_str[] = {4, 0,16};
+#else
+uint32_t firmware_version[] = {4, 0,16};
+#endif
+
+#ifdef UNIQUE_FW_NAME
+#define fw2400_VERSION_STRING "4.00.16"
+#else
+#define FW_VERSION_STRING "4.00.16"
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr01 = 0x00100000 ;
+#else
+uint32_t risc_code_addr01 = 0x00100000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code01[] = {
+#else
+uint32_t risc_code01[] = {
+#endif
+	0x0401f17c, 0x0010e000, 0x00100000, 0x0000ab4a,
+	0x00000004, 0x00000000, 0x00000010, 0x00000002,
+	0x00000003, 0x00000000, 0x20434f50, 0x59524947,
+	0x48542032, 0x30303520, 0x514c4f47, 0x49432043,
+	0x4f52504f, 0x52415449, 0x4f4e2020, 0x20495350,
+	0x32347878, 0x20466972, 0x6d776172, 0x65202020,
+	0x56657273, 0x696f6e20, 0x342e302e, 0x31362020,
+	0x20202024, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x42001800, 0x0010014f, 0x42002000, 0x0010b8fe,
+	0x500c0800, 0x800c1800, 0x500c1000, 0x800c1800,
+	0x54042000, 0x80102000, 0x80040800, 0x80081040,
+	0x040207fc, 0x500c0800, 0x800409c0, 0x040207f6,
+	0x44002000, 0x80102000, 0x40100000, 0x44040000,
+	0x80000000, 0x44080000, 0x80000000, 0x440c0000,
+	0x80000000, 0x44100000, 0x80000000, 0x44140000,
+	0x80000000, 0x44180000, 0x80000000, 0x441c0000,
+	0x80000000, 0x44200000, 0x80000000, 0x44240000,
+	0x80000000, 0x44280000, 0x80000000, 0x442c0000,
+	0x80000000, 0x44300000, 0x80000000, 0x44340000,
+	0x80000000, 0x44380000, 0x80000000, 0x443c0000,
+	0x80000000, 0x44400000, 0x80000000, 0x44440000,
+	0x80000000, 0x44480000, 0x80000000, 0x444c0000,
+	0x80000000, 0x44500000, 0x80000000, 0x44540000,
+	0x80000000, 0x44580000, 0x80000000, 0x445c0000,
+	0x80000000, 0x44600000, 0x80000000, 0x44640000,
+	0x80000000, 0x44680000, 0x80000000, 0x446c0000,
+	0x80000000, 0x44700000, 0x80000000, 0x44740000,
+	0x80000000, 0x44780000, 0x80000000, 0x447c0000,
+	0x80000000, 0x44800000, 0x80000000, 0x44840000,
+	0x80000000, 0x44880000, 0x80000000, 0x448c0000,
+	0x80000000, 0x44900000, 0x80000000, 0x44940000,
+	0x80000000, 0x44980000, 0x80000000, 0x449c0000,
+	0x80000000, 0x44a00000, 0x80000000, 0x44a40000,
+	0x80000000, 0x44a80000, 0x80000000, 0x44ac0000,
+	0x80000000, 0x44b00000, 0x80000000, 0x44b40000,
+	0x80000000, 0x44b80000, 0x80000000, 0x44bc0000,
+	0x80000000, 0x44c00000, 0x80000000, 0x44c40000,
+	0x80000000, 0x44c80000, 0x80000000, 0x44cc0000,
+	0x80000000, 0x44d00000, 0x80000000, 0x44d80000,
+	0x80000000, 0x44d40000, 0x80000000, 0x44dc0000,
+	0x80000000, 0x44e00000, 0x80000000, 0x44e40000,
+	0x80000000, 0x44e80000, 0x80000000, 0x44ec0000,
+	0x80000000, 0x44f00000, 0x80000000, 0x44f40000,
+	0x80000000, 0x44f80000, 0x80000000, 0x44fc0000,
+	0x80000000, 0x45000000, 0x80000000, 0x45040000,
+	0x80000000, 0x45080000, 0x80000000, 0x450c0000,
+	0x80000000, 0x45100000, 0x80000000, 0x45140000,
+	0x80000000, 0x45180000, 0x80000000, 0x451c0000,
+	0x80000000, 0x45200000, 0x80000000, 0x45240000,
+	0x80000000, 0x45280000, 0x80000000, 0x452c0000,
+	0x80000000, 0x45300000, 0x80000000, 0x45340000,
+	0x80000000, 0x45380000, 0x80000000, 0x453c0000,
+	0x80000000, 0x45400000, 0x80000000, 0x45440000,
+	0x80000000, 0x45480000, 0x80000000, 0x454c0000,
+	0x80000000, 0x45500000, 0x80000000, 0x45540000,
+	0x80000000, 0x45580000, 0x80000000, 0x455c0000,
+	0x80000000, 0x45600000, 0x80000000, 0x45640000,
+	0x80000000, 0x45680000, 0x80000000, 0x456c0000,
+	0x80000000, 0x45700000, 0x80000000, 0x45740000,
+	0x80000000, 0x45780000, 0x80000000, 0x457c0000,
+	0x80000000, 0x45800000, 0x80000000, 0x45840000,
+	0x80000000, 0x45880000, 0x80000000, 0x458c0000,
+	0x80000000, 0x45900000, 0x80000000, 0x45940000,
+	0x80000000, 0x45980000, 0x80000000, 0x459c0000,
+	0x80000000, 0x45a00000, 0x80000000, 0x45a40000,
+	0x80000000, 0x45a80000, 0x80000000, 0x45ac0000,
+	0x80000000, 0x45b00000, 0x80000000, 0x45b40000,
+	0x80000000, 0x45b80000, 0x80000000, 0x45bc0000,
+	0x80000000, 0x45c00000, 0x80000000, 0x45c40000,
+	0x80000000, 0x45c80000, 0x80000000, 0x45cc0000,
+	0x80000000, 0x45d00000, 0x80000000, 0x45d40000,
+	0x80000000, 0x45d80000, 0x80000000, 0x45dc0000,
+	0x80000000, 0x45e00000, 0x80000000, 0x45e40000,
+	0x80000000, 0x45e80000, 0x80000000, 0x45ec0000,
+	0x80000000, 0x45f00000, 0x80000000, 0x45f40000,
+	0x80000000, 0x45f80000, 0x80000000, 0x45fc0000,
+	0x4a03c020, 0x00004000, 0x4a03c011, 0x40000010,
+	0x04006000, 0x4203e000, 0x40000000, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+	0x4203e000, 0x30000001, 0x0401f000, 0x0000bf00,
+	0x00000080, 0x0000bfe0, 0x00000020, 0x0000ff00,
+	0x00000080, 0x0000ffd0, 0x00000030, 0x00007100,
+	0x00000010, 0x00007200, 0x00000008, 0x00007209,
+	0x00000007, 0x00007300, 0x00000008, 0x00007309,
+	0x00000007, 0x00007400, 0x00000008, 0x00007409,
+	0x00000007, 0x00007600, 0x000000b0, 0x00007700,
+	0x00000040, 0x00003000, 0x00000070, 0x00004000,
+	0x000000c0, 0x00006000, 0x00000050, 0x00006100,
+	0x00000010, 0x00006130, 0x00000010, 0x00006150,
+	0x00000010, 0x00006170, 0x00000010, 0x00006190,
+	0x00000010, 0x000061b0, 0x00000010, 0x00000000,
+	0x42000000, 0x00000100, 0x4202f000, 0x00000000,
+	0x42000800, 0x00021f00, 0x45780800, 0x80040800,
+	0x80000040, 0x040207fd, 0x4203f000, 0x00021fff,
+	0x40000000, 0x4203e000, 0x90000100, 0x40000000,
+	0x0201f800, 0x001006fd, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24320002, 0x04020015,
+	0x42000800, 0x00000064, 0x80040840, 0x04000007,
+	0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+	0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+	0x00007a17, 0x50040000, 0x8c00050e, 0x04020003,
+	0x8400054e, 0x44000800, 0x4a030000, 0x00000000,
+	0x4a03c020, 0x00000004, 0x4203e000, 0x6000000f,
+	0x59e00023, 0x8c000500, 0x04020039, 0x42000000,
+	0x00100001, 0x50000800, 0x82040c00, 0x00000004,
+	0x58042003, 0x42001000, 0xffffffff, 0x0201f800,
+	0x001006f4, 0x0402004e, 0x58042003, 0x42001000,
+	0xffffffff, 0x0201f800, 0x001006f4, 0x04020048,
+	0x58042003, 0x42001000, 0x00ffffff, 0x0201f800,
+	0x001006f4, 0x04020042, 0x58042003, 0x42001000,
+	0x00ffffff, 0x0201f800, 0x001006f4, 0x0402003c,
+	0x42000000, 0x00100001, 0x5000a000, 0x8250a400,
+	0x00000004, 0x4200a800, 0x00020000, 0x5850b003,
+	0x0201f800, 0x0010ab17, 0x8250a400, 0x00000005,
+	0x4a0370e8, 0x00000003, 0x4200a800, 0x0000c000,
+	0x5850b003, 0x0201f800, 0x0010ab17, 0x4a0378e8,
+	0x00000003, 0x4200a800, 0x00008000, 0x5850b003,
+	0x0201f800, 0x0010ab17, 0x0401f02b, 0x42000800,
+	0x00020000, 0x58042003, 0x42001000, 0xffffffff,
+	0x0201f800, 0x001006f4, 0x04020019, 0x4a0370e8,
+	0x00000003, 0x42000800, 0x0000c000, 0x58042003,
+	0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+	0x0201f800, 0x001006f4, 0x0402000d, 0x4a0378e8,
+	0x00000003, 0x42000800, 0x00008000, 0x58042003,
+	0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+	0x0201f800, 0x001006f4, 0x0400000b, 0x4a03c020,
+	0x00004010, 0x4a03c011, 0x40100011, 0x04006000,
+	0x4203e000, 0x40000000, 0x4203e000, 0x30000001,
+	0x0401f000, 0x0201f800, 0x00100791, 0x42001000,
+	0x0010ab4a, 0x40080000, 0x80140480, 0x82001d00,
+	0xffffff00, 0x04020003, 0x40001800, 0x0401f003,
+	0x42001800, 0x000000ff, 0x480bc840, 0x480fc842,
+	0x04011000, 0x400c0000, 0x80081400, 0x40140000,
+	0x80080580, 0x040207f0, 0x4817500d, 0x45782800,
+	0x59c40000, 0x82000500, 0xffff0000, 0x80000120,
+	0x82000580, 0x00002422, 0x04020005, 0x59a80005,
+	0x8400054e, 0x48035005, 0x0401f008, 0x59e00003,
+	0x82000500, 0x00030000, 0x04000004, 0x59a80005,
+	0x84000554, 0x48035005, 0x42000800, 0x00000040,
+	0x59a80005, 0x8c000514, 0x0402000e, 0x42000800,
+	0x00001000, 0x82141480, 0x0017ffff, 0x04021009,
+	0x80040902, 0x82141480, 0x0013ffff, 0x04021005,
+	0x80040902, 0x82141480, 0x0011ffff, 0x04001b8d,
+	0x4807500e, 0x42001000, 0x00000024, 0x0201f800,
+	0x00106681, 0x82040c00, 0x0010d1c0, 0x4807500b,
+	0x4a03c810, 0x00100000, 0x4a03c811, 0x0010ab4a,
+	0x4a03c829, 0x00000004, 0x59e40001, 0x82000540,
+	0x0003001d, 0x4803c801, 0x4a03c014, 0x001c001c,
+	0x42001000, 0x0000001c, 0x0201f800, 0x001006e2,
+	0x4202c000, 0x0010d1c0, 0x59aab00b, 0x59aaa00b,
+	0x59aaa80b, 0x59aac80e, 0x49675069, 0x59a8000b,
+	0x4803500c, 0x0401fbf5, 0x0201f800, 0x00107903,
+	0x0201f800, 0x001007be, 0x0201f800, 0x00100807,
+	0x0201f800, 0x00101a05, 0x0201f800, 0x00101354,
+	0x0201f800, 0x00100969, 0x0201f800, 0x00101354,
+	0x0201f800, 0x00100f4c, 0x0201f800, 0x001066c1,
+	0x0401fb1a, 0x0201f800, 0x0010220e, 0x0201f800,
+	0x001053bb, 0x0201f800, 0x00104c90, 0x0201f800,
+	0x00106194, 0x0201f800, 0x00105f28, 0x0201f800,
+	0x001013ed, 0x0201f800, 0x0010126f, 0x4203e000,
+	0xf0000001, 0x42000000, 0x00001000, 0x50000000,
+	0x82000480, 0x24220001, 0x04000016, 0x59e00002,
+	0x8c00051e, 0x42000000, 0x7ffe00fe, 0x04020003,
+	0x42000000, 0x7ffe01fe, 0x50000800, 0x48075058,
+	0x80040920, 0x82040580, 0x0000013a, 0x04000004,
+	0x82040580, 0x0000013b, 0x04020006, 0x59a80005,
+	0x84000552, 0x48035005, 0x4a0378e4, 0x000c0000,
+	0x4a03c018, 0x0000000f, 0x4203e000, 0x20000511,
+	0x4203e000, 0x50010000, 0x4a03c020, 0x00000000,
+	0x04027013, 0x59e00020, 0x82000580, 0x00000002,
+	0x0402000f, 0x4a03c020, 0x00004000, 0x4a03c011,
+	0x40000010, 0x04006000, 0x4203e000, 0x40000000,
+	0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+	0x00000000, 0x4203e000, 0x30000001, 0x4202d800,
+	0x00000000, 0x4203e000, 0xb0600000, 0x59a80005,
+	0x42000800, 0x00000002, 0x8c000512, 0x04020007,
+	0x42000800, 0x0000000f, 0x8c000514, 0x04020003,
+	0x42000800, 0x00000001, 0x4007f800, 0x59a80005,
+	0x8c000514, 0x02020000, 0x00020004, 0x59e00003,
+	0x82000500, 0x00030000, 0x82000580, 0x00000000,
+	0x04020af8, 0x0201f000, 0x00020004, 0x4df00000,
+	0x4203e000, 0x50000000, 0x416c0000, 0x82000c80,
+	0x00000008, 0x04021aef, 0x0c01f804, 0x5c03e000,
+	0x0201f000, 0x00020008, 0x001002f7, 0x0010030a,
+	0x001003d7, 0x001002f6, 0x00100452, 0x001002f6,
+	0x001002f6, 0x00100593, 0x0401fae2, 0x42000800,
+	0x0010b4a4, 0x5804001d, 0x4803c857, 0x8c000500,
+	0x0400000d, 0x84000500, 0x4800081d, 0x4202d800,
+	0x00000004, 0x0401fbd3, 0x49f3c857, 0x5c000800,
+	0x5c000000, 0x82000540, 0x00003e00, 0x4c000000,
+	0x4c040000, 0x1c01f000, 0x0401fbbd, 0x0201f800,
+	0x0010513b, 0x04000009, 0x0201f800, 0x00105151,
+	0x0402002e, 0x59c40006, 0x82000540, 0x000000c0,
+	0x48038806, 0x0401f029, 0x0201f800, 0x001050a2,
+	0x836c0580, 0x00000001, 0x040200bc, 0x59a80017,
+	0x82000580, 0x00000009, 0x040200b8, 0x497b5010,
+	0x4a038893, 0x00000001, 0x42001000, 0x000000f0,
+	0x0201f800, 0x0010193d, 0x0201f800, 0x00105149,
+	0x59c41006, 0x04020006, 0x82081540, 0x000000f1,
+	0x82081500, 0xbbffffff, 0x0401f003, 0x82081540,
+	0x440000f1, 0x480b8806, 0x0201f800, 0x0010609e,
+	0x4a0378e4, 0x00002000, 0x42000000, 0x0010b83a,
+	0x0201f800, 0x0010aa47, 0x42001000, 0x00008030,
+	0x497b5013, 0x0401f035, 0x0201f800, 0x00103b38,
+	0x59c400a4, 0x82000500, 0x0000000f, 0x82000480,
+	0x00000007, 0x04021091, 0x0201f800, 0x0010609e,
+	0x59c400a3, 0x82000500, 0xffefffff, 0x480388a3,
+	0x59a8004b, 0x800001c0, 0x04020004, 0x0201f800,
+	0x00104139, 0x0401f085, 0x59a80015, 0x84000546,
+	0x48035015, 0x0201f800, 0x00105141, 0x59c41006,
+	0x04020006, 0x82081540, 0x44000001, 0x82081500,
+	0xffffff0f, 0x0401f003, 0x82081540, 0x440000f1,
+	0x480b8806, 0x497b9005, 0x4a038802, 0x0000ffff,
+	0x4a0378e4, 0x00003000, 0x42000000, 0x0010b80c,
+	0x0201f800, 0x0010aa47, 0x59a81010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x42001000,
+	0x00008010, 0x59a8180a, 0x0201f800, 0x00103a3e,
+	0x0201f800, 0x00101815, 0x59a80805, 0x82040d00,
+	0xffffffdf, 0x48075005, 0x0201f800, 0x0010483d,
+	0x0201f800, 0x0010513b, 0x0400000a, 0x0201f800,
+	0x0010413e, 0x04000007, 0x4a035013, 0x00000001,
+	0x497b5021, 0x0201f800, 0x00103c80, 0x0401f04f,
+	0x0201f800, 0x001048ec, 0x04000005, 0x59c41002,
+	0x8408150c, 0x480b8802, 0x0401f012, 0x0201f800,
+	0x0010513b, 0x04020006, 0x59a8001d, 0x80000540,
+	0x02000800, 0x0010930f, 0x0401f00a, 0x0201f800,
+	0x0010930f, 0x59a80026, 0x8c000506, 0x04020005,
+	0x59a8001d, 0x80000540, 0x02020800, 0x00104245,
+	0x497b5028, 0x497b5027, 0x497b5018, 0x0201f800,
+	0x0010513b, 0x59a81026, 0x0402000a, 0x0201f800,
+	0x0010162a, 0x80001580, 0x59a8002a, 0x82000500,
+	0xffff0000, 0x80040d40, 0x4807502a, 0x0401f005,
+	0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a,
+	0x599c0017, 0x8c00050a, 0x04000002, 0x84081544,
+	0x480b5026, 0x0201f800, 0x0010513b, 0x04000004,
+	0x0201f800, 0x0010162a, 0x48078880, 0x42001000,
+	0x00000005, 0x0201f800, 0x001070b0, 0x497b5028,
+	0x497b501b, 0x4a03501c, 0x0000ffff, 0x4a0378e4,
+	0x000000c0, 0x4202d800, 0x00000002, 0x0201f800,
+	0x0010513b, 0x04000007, 0x59a80026, 0x82000500,
+	0x0000000c, 0x82000580, 0x00000004, 0x04000003,
+	0x0201f800, 0x00101e45, 0x1c01f000, 0x59a8001c,
+	0x82000580, 0x0000ffff, 0x04000004, 0x0201f800,
+	0x00101e45, 0x0401f074, 0x59a80026, 0x8c00050a,
+	0x04020003, 0x8c000506, 0x0400001c, 0x8c000500,
+	0x0400001a, 0x4a038802, 0x0000ffbf, 0x8c000502,
+	0x04000016, 0x599c0018, 0x8c000516, 0x04020010,
+	0x59a80027, 0x82000580, 0x0000ffff, 0x0400000c,
+	0x0201f800, 0x00101f9a, 0x59a80026, 0x8c000504,
+	0x0402005d, 0x42001000, 0x00000003, 0x417a5800,
+	0x0201f800, 0x00101fbf, 0x0401f057, 0x59a80028,
+	0x80000540, 0x04020054, 0x59a80026, 0x8c000508,
+	0x04020005, 0x59a8001b, 0x80000540, 0x0402004e,
+	0x0401f003, 0x8c000516, 0x0400004b, 0x0201f800,
+	0x001048ec, 0x04020048, 0x599c0018, 0x8c000516,
+	0x04020004, 0x0201f800, 0x00104c51, 0x04020042,
+	0x599c0017, 0x8c00050a, 0x0400000d, 0x4200b000,
+	0x000007f0, 0x417a8800, 0x0201f800, 0x00020245,
+	0x04020004, 0x59340200, 0x8c00051a, 0x04020036,
+	0x81468800, 0x8058b040, 0x040207f8, 0x4a038802,
+	0x0000ffff, 0x42001800, 0x0010b4eb, 0x0401fb8c,
+	0x42001800, 0x0010b4f8, 0x0401fb89, 0x59a80005,
+	0x84000502, 0x48035005, 0x4a0378e4, 0x00000080,
+	0x4202d800, 0x00000003, 0x4a03501c, 0x0000ffff,
+	0x0401fa7f, 0x80000580, 0x0201f800, 0x00101590,
+	0x599c0018, 0x8c000516, 0x04000004, 0x0201f800,
+	0x00103b10, 0x0401f009, 0x42001800, 0x0000ffff,
+	0x42002000, 0x00000006, 0x42003000, 0x00000000,
+	0x0201f800, 0x00103aae, 0x0201f800, 0x00105151,
+	0x0400000b, 0x59c40006, 0x0201f800, 0x0010513b,
+	0x04000004, 0x82000500, 0xffffff0f, 0x0401f003,
+	0x82000500, 0xfbffffff, 0x48038806, 0x0201f800,
+	0x00106f36, 0x1c01f000, 0x4c040000, 0x4c080000,
+	0x4c100000, 0x59a8003e, 0x82000c80, 0x00000004,
+	0x04021980, 0x0c01f805, 0x5c002000, 0x5c001000,
+	0x5c000800, 0x1c01f000, 0x00100462, 0x001004ea,
+	0x00100516, 0x00100577, 0x42000000, 0x00000001,
+	0x0201f800, 0x00101590, 0x0201f800, 0x0010609e,
+	0x59c408a3, 0x82040d00, 0xfffffff7, 0x480788a3,
+	0x0201f800, 0x00105141, 0x0400000e, 0x0201f800,
+	0x00105151, 0x0400000b, 0x0201f800, 0x00105149,
+	0x04020964, 0x59c400a3, 0x84000532, 0x84000570,
+	0x480388a3, 0x4a038808, 0x00000008, 0x0401f010,
+	0x59c400a3, 0x84000530, 0x82000500, 0xbf7fffff,
+	0x480388a3, 0x42000800, 0x000000f8, 0x0201f800,
+	0x00104200, 0x59c400a3, 0x82000540, 0x00018000,
+	0x8400051c, 0x480388a3, 0x497b8808, 0x59c40006,
+	0x82000500, 0xfbffff0e, 0x48038806, 0x497b2822,
+	0x497b2823, 0x42000800, 0x000001f4, 0x42001000,
+	0x00100591, 0x0201f800, 0x00105f83, 0x59c40805,
+	0x42001000, 0x00000001, 0x0201f800, 0x0010193d,
+	0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+	0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101821, 0x0401f022,
+	0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f018, 0x0201f800, 0x00101649,
+	0x0402000a, 0x42000000, 0x00000002, 0x0201f800,
+	0x0010188c, 0x42000000, 0x00000002, 0x0201f800,
+	0x00101821, 0x0401f00c, 0x0201f800, 0x00101650,
+	0x04020918, 0x59a80049, 0x800001c0, 0x04000006,
+	0x0201f800, 0x00101656, 0x4a03503e, 0x00000001,
+	0x0401f021, 0x0201f800, 0x00101927, 0x4a03503e,
+	0x00000001, 0x0201f800, 0x00105141, 0x0400000c,
+	0x0201f800, 0x00105151, 0x04000009, 0x0201f800,
+	0x00105149, 0x04020903, 0x4a035033, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f00f, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x04000003, 0x4a038805, 0x04000000, 0x59c400a3,
+	0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+	0x480388a3, 0x1c01f000, 0x0401f8a3, 0x04020004,
+	0x4a03503e, 0x00000003, 0x0401f027, 0x0201f800,
+	0x00101650, 0x04020011, 0x59a80049, 0x800001c0,
+	0x0400000e, 0x0201f800, 0x00101656, 0x59a80048,
+	0x8c00051e, 0x0400001c, 0x0201f800, 0x00105149,
+	0x04020009, 0x4a035033, 0x00000001, 0x0201f800,
+	0x001050a2, 0x0401f004, 0x0201f800, 0x001018d3,
+	0x04020011, 0x0201f800, 0x00101815, 0x4a03503e,
+	0x00000002, 0x497b5049, 0x59c400a3, 0x84000520,
+	0x480388a3, 0x497b2822, 0x497b2823, 0x42000800,
+	0x0000002d, 0x42001000, 0x00100591, 0x0201f800,
+	0x00105f83, 0x1c01f000, 0x0401f877, 0x04020004,
+	0x4a03503e, 0x00000003, 0x0401f05b, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x001018d3, 0x04020050,
+	0x0201f800, 0x00105149, 0x04000044, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x04000020, 0x59c40005, 0x8c000534, 0x0402001d,
+	0x59940022, 0x82000580, 0x00000001, 0x04020046,
+	0x0201f800, 0x00105151, 0x04020043, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00105196, 0x4a035032,
+	0x0000aaaa, 0x4a035033, 0x00000000, 0x59c408a3,
+	0x82040d40, 0x00000008, 0x480788a3, 0x4202d800,
+	0x00000001, 0x4a03503e, 0x00000000, 0x4a038805,
+	0x00000001, 0x497b2822, 0x497b2823, 0x0401f01f,
+	0x0201f800, 0x00105151, 0x04020007, 0x59a80032,
+	0x82000580, 0x0000aaaa, 0x04020003, 0x4a035010,
+	0x00ffffff, 0x497b5032, 0x59c40006, 0x82000540,
+	0x04000001, 0x48038806, 0x59a80805, 0x8c040d06,
+	0x04020005, 0x59c408a3, 0x82040d40, 0x00000008,
+	0x480788a3, 0x4202d800, 0x00000001, 0x4a03503e,
+	0x00000000, 0x4a038805, 0x00000001, 0x497b2822,
+	0x497b2823, 0x0401f010, 0x59c40005, 0x82000500,
+	0x000000c0, 0x0400000c, 0x59c40006, 0x82000540,
+	0x000000f1, 0x48038806, 0x0401f7ef, 0x0201f800,
+	0x00101650, 0x04020004, 0x59a80049, 0x800001c0,
+	0x040207a4, 0x497b8885, 0x1c01f000, 0x4803c856,
+	0x42000000, 0x00000001, 0x0201f800, 0x00101590,
+	0x4a03503e, 0x00000000, 0x0201f800, 0x00101650,
+	0x0402000b, 0x59a80052, 0x800001c0, 0x04000004,
+	0x80000040, 0x48035052, 0x04020005, 0x4a035052,
+	0x0000000a, 0x4a035049, 0x00000001, 0x497b8885,
+	0x0401f0ed, 0x59940022, 0x59940823, 0x80040540,
+	0x1c01f000, 0x497b2823, 0x1c01f000, 0x4c080000,
+	0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+	0x5c001000, 0x1c01f000, 0x4a03505c, 0x00000004,
+	0x4a03505d, 0x00000000, 0x4a03505e, 0x00000010,
+	0x4a03505f, 0x00000002, 0x4a035010, 0x00ffffff,
+	0x0201f800, 0x0010930f, 0x4a03502a, 0x20200000,
+	0x4a03502b, 0x88000200, 0x4a03502c, 0x00ff001f,
+	0x4a03502d, 0x000007d0, 0x4a03502e, 0x80000000,
+	0x4a03502f, 0x00000200, 0x4a035030, 0x00ff0000,
+	0x4a035031, 0x00010000, 0x4a03503a, 0x514c4f47,
+	0x4a03503b, 0x49432020, 0x1c01f000, 0x4d440000,
+	0x417a8800, 0x41780800, 0x0201f800, 0x00020245,
+	0x04020005, 0x0201f800, 0x001049e7, 0x04020002,
+	0x80040800, 0x81468800, 0x83440580, 0x000007f0,
+	0x040207f6, 0x5c028800, 0x1c01f000, 0x4803c857,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x0401f809,
+	0x485fc857, 0x4203e000, 0x50000000, 0x5c000000,
+	0x4d780000, 0x4200b800, 0x00008002, 0x0401f006,
+	0x485fc857, 0x4203e000, 0x50000000, 0x4200b800,
+	0x00008002, 0x04006000, 0x4c000000, 0x4c040000,
+	0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000001, 0x04020005, 0x42000800, 0x00000000,
+	0x0201f800, 0x00106c6c, 0x5c000800, 0x4807c025,
+	0x80040920, 0x4807c026, 0x5c000000, 0x4803c023,
+	0x80000120, 0x4803c024, 0x5c000000, 0x4803c857,
+	0x4803c021, 0x80000120, 0x4803c022, 0x41f80000,
+	0x4803c027, 0x80000120, 0x4803c028, 0x42000000,
+	0x00001000, 0x50000000, 0x82000480, 0x24320001,
+	0x4803c857, 0x0400104f, 0x42000800, 0x00000064,
+	0x80040840, 0x04000007, 0x4a030000, 0x00000001,
+	0x40000000, 0x59800000, 0x8c000500, 0x040007f9,
+	0x04000042, 0x42000800, 0x0010c1a3, 0x46000800,
+	0xfaceface, 0x80040800, 0x42001000, 0x00007a00,
+	0x58080013, 0x44000800, 0x80040800, 0x58080019,
+	0x44000800, 0x80040800, 0x5808001a, 0x44000800,
+	0x80040800, 0x5808001b, 0x44000800, 0x80040800,
+	0x5808001c, 0x44000800, 0x80040800, 0x5808001f,
+	0x44000800, 0x80040800, 0x42001000, 0x00007a40,
+	0x42001800, 0x0000000b, 0x50080000, 0x44000800,
+	0x80081000, 0x80040800, 0x800c1840, 0x040207fb,
+	0x42001800, 0x00000003, 0x42001000, 0x00007b00,
+	0x480c1003, 0x58080005, 0x44000800, 0x80040800,
+	0x800c1840, 0x040217fb, 0x42001000, 0x00007c00,
+	0x58080002, 0x44000800, 0x80040800, 0x58080003,
+	0x44000800, 0x80040800, 0x58080020, 0x44000800,
+	0x80040800, 0x58080021, 0x44000800, 0x80040800,
+	0x58080022, 0x44000800, 0x80040800, 0x58080023,
+	0x44000800, 0x80040800, 0x4a030000, 0x00000000,
+	0x485fc020, 0x905cb9c0, 0x825cbd40, 0x00000012,
+	0x485fc011, 0x4203e000, 0x40000000, 0x4202d800,
+	0x00000005, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+	0x0401f81a, 0x0401f7ff, 0x4a03c850, 0x0010c1bf,
+	0x4a03c851, 0x0010d1be, 0x4a03c853, 0x00000800,
+	0x4a03c855, 0x0001eb5a, 0x59e40001, 0x82000540,
+	0x00003f00, 0x4803c801, 0x4a03b104, 0x70000002,
+	0x4a03a804, 0x70000002, 0x4a03b004, 0x70000002,
+	0x42000000, 0x0010b8ec, 0x49780001, 0x49780002,
+	0x1c01f000, 0x1c01f000, 0x59a8006b, 0x8c000530,
+	0x040207fe, 0x4c080000, 0x42001000, 0x00000004,
+	0x0401f862, 0x5c001000, 0x4201d000, 0x00028b0a,
+	0x0201f800, 0x0010608e, 0x4c080000, 0x42001000,
+	0x00000008, 0x0401f859, 0x5c001000, 0x4201d000,
+	0x00028b0a, 0x0201f800, 0x0010608e, 0x4c080000,
+	0x42001000, 0x00000010, 0x0401f850, 0x5c001000,
+	0x4201d000, 0x00028b0a, 0x0201f800, 0x0010608e,
+	0x0401f7e2, 0x8c00050c, 0x59a8086b, 0x04020003,
+	0x84040d30, 0x0401f006, 0x84040d70, 0x4807506b,
+	0x42001000, 0x00000000, 0x0401f040, 0x4807506b,
+	0x836c0500, 0x00000007, 0x0c01f001, 0x001006e1,
+	0x001006c7, 0x001006c7, 0x001006af, 0x001006d4,
+	0x001006c7, 0x001006c7, 0x001006d4, 0x59a80005,
+	0x8c000514, 0x04020013, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00010000, 0x0400000a,
+	0x82040580, 0x00008000, 0x04000004, 0x42001000,
+	0x42004000, 0x0401f006, 0x42001000, 0x22002000,
+	0x0401f003, 0x42001000, 0x12001000, 0x0401f025,
+	0x42001000, 0x00001004, 0x0401f022, 0x59a80005,
+	0x8c000514, 0x04020008, 0x59a8006b, 0x8c000534,
+	0x04020004, 0x42001000, 0x74057005, 0x0401f819,
+	0x1c01f000, 0x42001000, 0x00002008, 0x0401f7fc,
+	0x59a8006b, 0x8c000534, 0x0402000a, 0x59a80005,
+	0x8c000514, 0x04000004, 0x42001000, 0x24052005,
+	0x0401f00c, 0x42001000, 0x74057005, 0x0401f009,
+	0x1c01f000, 0x1c01f000, 0x82081500, 0x0000001c,
+	0x82081540, 0x001c0000, 0x480bc013, 0x1c01f000,
+	0x59a8006b, 0x8c000530, 0x04000002, 0x84081570,
+	0x480b506b, 0x8c000530, 0x04020005, 0x82081500,
+	0x00007000, 0x80081114, 0x0401fff0, 0x1c01f000,
+	0x41780000, 0x50041800, 0x800c0400, 0x80040800,
+	0x80102040, 0x040207fc, 0x80080500, 0x80000540,
+	0x1c01f000, 0x4202f000, 0x00000000, 0x41780000,
+	0x41780800, 0x41781000, 0x41781800, 0x41782000,
+	0x41782800, 0x41783000, 0x41783800, 0x41784000,
+	0x41784800, 0x41785000, 0x41785800, 0x41786000,
+	0x41786800, 0x41787000, 0x41787800, 0x41788000,
+	0x41788800, 0x41789000, 0x41789800, 0x4178a000,
+	0x4178a800, 0x4178b000, 0x4178b800, 0x4178c000,
+	0x4178c800, 0x4178d000, 0x4178d800, 0x4178e000,
+	0x4178e800, 0x4178f000, 0x4178f800, 0x41790000,
+	0x41790800, 0x41791000, 0x41791800, 0x41792000,
+	0x41792800, 0x41793000, 0x41793800, 0x41794000,
+	0x41794800, 0x41795000, 0x41795800, 0x41796000,
+	0x41796800, 0x41797000, 0x41797800, 0x41798000,
+	0x41798800, 0x42019000, 0x0010b537, 0x42019800,
+	0x0010b50e, 0x4179a000, 0x4179b000, 0x4179a800,
+	0x4179b800, 0x4179c800, 0x4179c000, 0x4179d000,
+	0x4179d800, 0x4179e000, 0x4179e800, 0x4179f000,
+	0x4179f800, 0x417a0000, 0x417a0800, 0x417a1000,
+	0x417a1800, 0x417a2000, 0x42022800, 0x00006100,
+	0x417a3000, 0x417a3800, 0x417a4000, 0x417a4800,
+	0x417a5000, 0x417a5800, 0x417a6000, 0x417a6800,
+	0x417a7000, 0x417a7800, 0x417a8000, 0x417a8800,
+	0x417a9000, 0x417a9800, 0x417ae800, 0x417af800,
+	0x42030000, 0x00007c00, 0x42031000, 0x0010b806,
+	0x42031800, 0x0000bf1d, 0x42032000, 0x0000bf32,
+	0x42032800, 0x0010b7ce, 0x42033000, 0x0010b46e,
+	0x42034000, 0x0010b4a4, 0x42033800, 0x0010b4c3,
+	0x42034800, 0x0010b544, 0x42035000, 0x0010b400,
+	0x42035800, 0x0010ac00, 0x42030800, 0x0010b505,
+	0x417b6000, 0x42036800, 0x00006f00, 0x4203c800,
+	0x00003000, 0x42037000, 0x0000ff00, 0x42037800,
+	0x0000bf00, 0x42038000, 0x00007700, 0x42038800,
+	0x00004000, 0x42039000, 0x00006000, 0x42039800,
+	0x0010bedb, 0x4203a000, 0x00007600, 0x4203a800,
+	0x00007400, 0x4203b000, 0x00007200, 0x4203b800,
+	0x00007100, 0x4203c000, 0x00007000, 0x4203d000,
+	0x00000000, 0x4203e800, 0x00101b95, 0x417bd800,
+	0x1c01f000, 0x42000800, 0x00100000, 0x50040000,
+	0x4c000000, 0x42000000, 0x0000aaaa, 0x44000800,
+	0x42001800, 0x00005555, 0x41782000, 0x82102400,
+	0x00010000, 0x40100000, 0x80042c00, 0x440c2800,
+	0x42003000, 0x0000000a, 0x80183040, 0x040207ff,
+	0x50140000, 0x800c0580, 0x04020004, 0x50040000,
+	0x800c0580, 0x040207f2, 0x5c000000, 0x44000800,
+	0x80142840, 0x4817c861, 0x1c01f000, 0x59a8081f,
+	0x800409c0, 0x04020009, 0x49781c0c, 0x4a001a0c,
+	0x00000200, 0x4a001804, 0x07000000, 0x59a80010,
+	0x9c0001c0, 0x48001805, 0x0401fe01, 0x9c0409c0,
+	0x48041806, 0x1c01f000, 0x59a8080c, 0x4006d000,
+	0x4202b800, 0x00000001, 0x59a8180d, 0x480fc857,
+	0x82041400, 0x00000014, 0x82082400, 0x00000014,
+	0x40100000, 0x800c0480, 0x04001006, 0x44080800,
+	0x40080800, 0x40101000, 0x815eb800, 0x0401f7f7,
+	0x45780800, 0x495f5020, 0x1c01f000, 0x835c0480,
+	0x00000020, 0x04001009, 0x496bc857, 0x815eb840,
+	0x416a5800, 0x592ed000, 0x497a5800, 0x497a5801,
+	0x812e59c0, 0x1c01f000, 0x42000000, 0x0010b853,
+	0x0201f800, 0x0010aa47, 0x417a5800, 0x0401f7f9,
+	0x815eb840, 0x04001008, 0x416a5800, 0x492fc857,
+	0x592ed000, 0x497a5800, 0x497a5801, 0x812e59c0,
+	0x1c01f000, 0x42000000, 0x0010b853, 0x0201f800,
+	0x0010aa47, 0x417ab800, 0x417a5800, 0x0401f7f8,
+	0x492fc857, 0x496a5800, 0x412ed000, 0x815eb800,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x1c01f000, 0x492fc857, 0x812e59c0, 0x04000007,
+	0x592c0001, 0x497a5801, 0x4c000000, 0x0401fff1,
+	0x5c025800, 0x0401f7f9, 0x1c01f000, 0x4807c856,
+	0x42007000, 0x0010b7f8, 0x4a007001, 0x00000000,
+	0x59e00003, 0x82000540, 0x00008080, 0x4803c003,
+	0x4a03b805, 0x90000001, 0x59dc0006, 0x4a03b805,
+	0x70000000, 0x59dc0006, 0x4a03b805, 0x30000000,
+	0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+	0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+	0x4a03b805, 0x60000001, 0x59dc0006, 0x4a03b805,
+	0x70000001, 0x59dc0006, 0x4a03b805, 0x30000002,
+	0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+	0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+	0x4a03b805, 0x60000001, 0x0401ffa1, 0x04000da5,
+	0x42001000, 0x0010b7f6, 0x452c1000, 0x4a025801,
+	0x00000001, 0x4a025802, 0x00000100, 0x4a025809,
+	0x00107149, 0x497a580a, 0x497a580b, 0x497a580c,
+	0x0401ff93, 0x04000d97, 0x42001000, 0x0010b7f7,
+	0x452c1000, 0x4a025801, 0x00000000, 0x4a025802,
+	0x00000100, 0x4a025809, 0x001011bc, 0x497a5803,
+	0x497a5807, 0x497a5808, 0x497a580a, 0x59a80005,
+	0x8c00050e, 0x04000006, 0x4a03b805, 0xe0000001,
+	0x59dc0006, 0x8c000522, 0x040007fc, 0x1c01f000,
+	0x4df00000, 0x4203e000, 0x50000000, 0x4c380000,
+	0x40087000, 0x480bc857, 0x4a007002, 0x00000000,
+	0x42007000, 0x0010b7f8, 0x82080400, 0x00000000,
+	0x45780000, 0x58380005, 0x48087005, 0x80000540,
+	0x04000005, 0x82000400, 0x00000000, 0x44080000,
+	0x0401f003, 0x480bc857, 0x48087006, 0x58380001,
+	0x80000540, 0x0400080c, 0x5c007000, 0x5c03e000,
+	0x1c01f000, 0x4c380000, 0x42007000, 0x0010b7f8,
+	0x58380001, 0x80000540, 0x04000803, 0x5c007000,
+	0x1c01f000, 0x42007000, 0x0010b7f8, 0x58380001,
+	0x82000580, 0x00000000, 0x04020012, 0x58380000,
+	0x0c01f001, 0x0010088e, 0x0010088d, 0x0010088d,
+	0x0010088d, 0x0010088d, 0x0010088d, 0x0010088d,
+	0x0010088d, 0x0401fd4b, 0x58380808, 0x800409c0,
+	0x04020024, 0x58380006, 0x80000540, 0x04020002,
+	0x1c01f000, 0x4803c857, 0x48007002, 0x40006800,
+	0x58340000, 0x80000540, 0x04020002, 0x48007005,
+	0x48007006, 0x4a03b805, 0x20000000, 0x59dc0006,
+	0x4a03b805, 0x30000000, 0x58340007, 0x4803b800,
+	0x58340008, 0x4803b801, 0x58340004, 0x48007003,
+	0x58340003, 0x48007004, 0x4803b803, 0x58340001,
+	0x8c000500, 0x04000004, 0x4a007001, 0x00000001,
+	0x0401f028, 0x4a007001, 0x00000002, 0x0401f03d,
+	0x0201f800, 0x001093ea, 0x0201f800, 0x0010a69d,
+	0x04000017, 0x4a03b805, 0x20000000, 0x59dc0006,
+	0x4a03b805, 0x30000000, 0x4807b800, 0x480bb801,
+	0x4a007003, 0x00000010, 0x480c7009, 0x42001000,
+	0x00100875, 0x0201f800, 0x00105f9a, 0x58380008,
+	0x82000400, 0x00000004, 0x48007004, 0x4803b803,
+	0x4a007001, 0x00000007, 0x0401f022, 0x0201f800,
+	0x00109402, 0x42000800, 0x00000001, 0x42001000,
+	0x00100875, 0x0201f800, 0x00105f76, 0x0401f7ba,
+	0x4c040000, 0x4c080000, 0x58380803, 0x42001000,
+	0x00003fff, 0x82040480, 0x00003fff, 0x04021003,
+	0x40041000, 0x80000580, 0x48007003, 0x800800c4,
+	0x4803b802, 0x4a03b805, 0x30000002, 0x59dc0006,
+	0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805,
+	0x10000000, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x483bc857, 0x4c040000, 0x4c080000, 0x58380803,
+	0x42001000, 0x00003fff, 0x82040480, 0x00003fff,
+	0x04021003, 0x40041000, 0x80000580, 0x48007003,
+	0x800800c4, 0x4803b802, 0x4a03b805, 0x10000002,
+	0x5c001000, 0x5c000800, 0x1c01f000, 0x4c040000,
+	0x4c380000, 0x42007000, 0x0010b7f8, 0x59dc0806,
+	0x4807c857, 0x4a03b805, 0x20000000, 0x8c040d3e,
+	0x04000007, 0x8c040d08, 0x04020cca, 0x58380001,
+	0x82000500, 0x00000007, 0x0c01f804, 0x5c007000,
+	0x5c000800, 0x1c01f000, 0x0010087d, 0x0010091e,
+	0x0010092e, 0x001005d8, 0x001005d8, 0x001005d8,
+	0x001005d8, 0x001011ea, 0x4807c856, 0x82040d00,
+	0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+	0x0400001c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+	0x4803b801, 0x0401f7af, 0x58380802, 0x4a000802,
+	0x00000200, 0x0401f01e, 0x4807c856, 0x82040d00,
+	0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+	0x0400000c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+	0x4803b801, 0x0401f7b7, 0x58380002, 0x82000400,
+	0x00000002, 0x46000000, 0x00000200, 0x0401f00c,
+	0x4c340000, 0x58386802, 0x59dc0000, 0x4803c857,
+	0x48006807, 0x59dc0001, 0x4803c857, 0x48006808,
+	0x4a006802, 0x00000100, 0x5c006800, 0x4a007001,
+	0x00000000, 0x4c300000, 0x58386002, 0x0401f80c,
+	0x04000009, 0x58300009, 0x82000c80, 0x0010ab4a,
+	0x04021c84, 0x82000c80, 0x00020000, 0x04001c81,
+	0x0801f800, 0x5c006000, 0x0401f723, 0x4833c857,
+	0x803061c0, 0x04000009, 0x59a8000c, 0x80300480,
+	0x04001007, 0x59a8000d, 0x80300480, 0x04021004,
+	0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x4dc00000, 0x42007000,
+	0x0010b803, 0x4a007400, 0x00000000, 0x49787001,
+	0x42038000, 0x00007720, 0x4a038006, 0x60000001,
+	0x4a038009, 0xf4f60000, 0x42038000, 0x00007700,
+	0x4a038006, 0x60000001, 0x4a038009, 0xf4f60000,
+	0x4a03c822, 0x00000010, 0x4a0370e8, 0x00000000,
+	0x0401f809, 0x4a0370e9, 0x00003a0f, 0x4a0370e8,
+	0x00000000, 0x4a0370e8, 0x00000001, 0x5c038000,
+	0x1c01f000, 0x4c5c0000, 0x4178b800, 0x0401f80a,
+	0x5c00b800, 0x1c01f000, 0x4803c856, 0x4c5c0000,
+	0x825cbd40, 0x00000001, 0x0401f803, 0x5c00b800,
+	0x1c01f000, 0x4803c856, 0x4dc00000, 0x4c500000,
+	0x4c580000, 0x4c540000, 0x4a0370e8, 0x00000000,
+	0x805cb9c0, 0x04000009, 0x4a038807, 0x00000004,
+	0x59b800ea, 0x8c000510, 0x04000004, 0x59b800e0,
+	0x0401f87b, 0x0401f7fb, 0x42038000, 0x00007720,
+	0x0201f800, 0x00100ec1, 0x59c00007, 0x4a038006,
+	0x20000000, 0x59c00007, 0x4a038006, 0x8000000a,
+	0x59c00007, 0x4a038006, 0x8000000b, 0x59c00007,
+	0x4a038006, 0x40000001, 0x83c00580, 0x00007700,
+	0x04000004, 0x42038000, 0x00007700, 0x0401f7ed,
+	0x42038000, 0x00007720, 0x42000800, 0x00000800,
+	0x59c00007, 0x8c00051e, 0x04000006, 0x4a038006,
+	0x90000001, 0x80040840, 0x040207fa, 0x0401fc11,
+	0x83c00580, 0x00007700, 0x04000004, 0x42038000,
+	0x00007700, 0x0401f7f1, 0x805cb9c0, 0x0402001d,
+	0x4200b000, 0x00000020, 0x83b8ac00, 0x00000020,
+	0x0201f800, 0x0010ab20, 0x4a0370fb, 0x00000001,
+	0x4a037020, 0x001010bd, 0x59a80039, 0x82000500,
+	0x0000ffff, 0x48037021, 0x4a037035, 0x0010bddb,
+	0x4a037030, 0x0010b410, 0x4a037031, 0x0010ac00,
+	0x4a037032, 0x0010b519, 0x4a037036, 0x0010b524,
+	0x59840002, 0x48037034, 0x4a037038, 0x001010b4,
+	0x4a0370fb, 0x00000001, 0x4178a000, 0x4200b000,
+	0x00000020, 0x83b8ac00, 0x00000000, 0x0201f800,
+	0x0010ab20, 0x4200b000, 0x00000040, 0x83b8ac00,
+	0x00000040, 0x0201f800, 0x0010ab20, 0x805cb9c0,
+	0x04020004, 0x4a0370e4, 0xaaaaaaaa, 0x0401f003,
+	0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, 0xaaaaaaaa,
+	0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, 0x00000000,
+	0x4a0370e6, 0xaaaaaaaa, 0x42038000, 0x00007720,
+	0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+	0x02020800, 0x001005d8, 0x42038000, 0x00007700,
+	0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+	0x02020800, 0x001005d8, 0x5c00a800, 0x5c00b000,
+	0x5c00a000, 0x5c038000, 0x1c01f000, 0x4d300000,
+	0x4d380000, 0x40026000, 0x82000500, 0x7f000000,
+	0x82000580, 0x00000003, 0x0402000f, 0x83326500,
+	0x00ffffff, 0x59300203, 0x82000580, 0x00000004,
+	0x04020009, 0x59300c06, 0x82040580, 0x00000009,
+	0x04020005, 0x42027000, 0x00000047, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x5c026000, 0x1c01f000,
+	0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+	0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+	0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+	0x4c640000, 0x4cc80000, 0x4ccc0000, 0x4cf00000,
+	0x4cf40000, 0x4cf80000, 0x4cfc0000, 0x4d000000,
+	0x4d040000, 0x0201f800, 0x00020015, 0x5c020800,
+	0x5c020000, 0x5c01f800, 0x5c01f000, 0x5c01e800,
+	0x5c01e000, 0x5c019800, 0x5c019000, 0x5c00c800,
+	0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+	0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+	0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x493bc857, 0x0201f000, 0x00020044,
+	0x83300500, 0x1f000000, 0x04000008, 0x81326580,
+	0x80000130, 0x82000c80, 0x00000014, 0x02021800,
+	0x001005d8, 0x0c01f013, 0x83300500, 0x000000ff,
+	0x82000c80, 0x00000007, 0x02021800, 0x001005d8,
+	0x0c01f025, 0x1c01f000, 0x82000d00, 0xc0000038,
+	0x02020800, 0x001005d0, 0x0201f800, 0x001005d8,
+	0x00000000, 0x00000048, 0x00000054, 0x00000053,
+	0x00100a9b, 0x00100abf, 0x00100aba, 0x00100adf,
+	0x00100aa6, 0x00100ab2, 0x00100a9b, 0x00100ada,
+	0x00100b1a, 0x00100a9b, 0x00100a9b, 0x00100a9b,
+	0x00100a9b, 0x00100b1d, 0x00100b23, 0x00100b34,
+	0x00100b45, 0x00100a9b, 0x00100b4e, 0x00100b5a,
+	0x00100a9b, 0x00100a9b, 0x00100a9b, 0x0201f800,
+	0x001005d8, 0x00100aa4, 0x00100bff, 0x00100aec,
+	0x00100b0f, 0x00100aa4, 0x00100aa4, 0x00100aa4,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x59300004,
+	0x8c00053e, 0x04020005, 0x42027000, 0x00000055,
+	0x0201f000, 0x000207a1, 0x0201f800, 0x00106f60,
+	0x040007fa, 0x1c01f000, 0x4803c856, 0x0401f8a9,
+	0x40002800, 0x41782000, 0x42027000, 0x00000056,
+	0x0201f000, 0x000207a1, 0x4803c856, 0x42027000,
+	0x00000057, 0x0201f000, 0x000207a1, 0x4803c856,
+	0x59300007, 0x8c00051a, 0x04020010, 0x59325808,
+	0x812e59c0, 0x04000014, 0x592c0408, 0x8c00051c,
+	0x04020003, 0x4a026011, 0xffffffff, 0x59300004,
+	0x8c00053e, 0x04020009, 0x42027000, 0x00000048,
+	0x0201f000, 0x000207a1, 0x59325808, 0x4a025a06,
+	0x00000007, 0x0401f7f4, 0x0201f800, 0x00106f60,
+	0x040007f6, 0x1c01f000, 0x4803c856, 0x83300500,
+	0x00ffffff, 0x0201f000, 0x001064d7, 0x1c01f000,
+	0x4c040000, 0x59b808ea, 0x82040d00, 0x00000007,
+	0x82040580, 0x00000003, 0x04000004, 0x42000000,
+	0x60000000, 0x0401f8ab, 0x5c000800, 0x1c01f000,
+	0x0401f8f9, 0x59325808, 0x812e59c0, 0x04000018,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000d80,
+	0x00000029, 0x04020012, 0x59300203, 0x82000580,
+	0x00000003, 0x0400000b, 0x59300807, 0x84040d26,
+	0x48066007, 0x0201f800, 0x00020086, 0x4a03900d,
+	0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+	0x0201f800, 0x00106f60, 0x040007f4, 0x59880052,
+	0x80000000, 0x48031052, 0x4a03900d, 0x00000040,
+	0x42000000, 0xc0000000, 0x0401f05a, 0x42007800,
+	0x0010bde2, 0x42002000, 0x00003000, 0x42003000,
+	0x00000105, 0x0201f800, 0x00105e04, 0x4a0370e4,
+	0x02000000, 0x1c01f000, 0x4933c857, 0x0201f000,
+	0x0002077d, 0x41300800, 0x800409c0, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001005d0, 0x4933c857,
+	0x813261c0, 0x02000800, 0x001005d8, 0x0401f835,
+	0x40002800, 0x0201f800, 0x0010a99c, 0x0401f8ae,
+	0x04000007, 0x59326809, 0x59340200, 0x8c00050e,
+	0x59300414, 0x02020800, 0x001092ce, 0x1c01f000,
+	0x4933c857, 0x813261c0, 0x02000800, 0x001005d8,
+	0x0401f8a1, 0x0400000b, 0x59325808, 0x0201f800,
+	0x00109037, 0x04000007, 0x592c0208, 0x8400054e,
+	0x48025a08, 0x417a7800, 0x0201f800, 0x00108be3,
+	0x1c01f000, 0x485fc857, 0x5c000000, 0x4d780000,
+	0x4203e000, 0x50000000, 0x4200b800, 0x00008005,
+	0x0201f000, 0x001005dd, 0x4933c857, 0x83300480,
+	0x00000020, 0x02021800, 0x001005d8, 0x83300c00,
+	0x0010b8cc, 0x50040000, 0x80000000, 0x04001002,
+	0x44000800, 0x1c01f000, 0x4933c857, 0x0401f7f4,
+	0x4807c856, 0x59b800ea, 0x8c000510, 0x040007fd,
+	0x59b800e0, 0x4803c857, 0x1c01f000, 0x4803c856,
+	0x42000000, 0x10000000, 0x41300800, 0x0401f02d,
+	0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+	0x80040d40, 0x4807c857, 0x59b800ea, 0x8c000516,
+	0x04020003, 0x480770e1, 0x1c01f000, 0x8c000510,
+	0x040007fa, 0x4c040000, 0x0401f809, 0x5c000800,
+	0x82100480, 0x00000008, 0x040017f4, 0x4c040000,
+	0x0401febc, 0x5c000800, 0x0401f7f0, 0x59b800e2,
+	0x59b820e2, 0x80100580, 0x040207fd, 0x80102114,
+	0x0401f006, 0x59b800e2, 0x59b820e2, 0x80100580,
+	0x040207fd, 0x0401f001, 0x40101800, 0x800c190a,
+	0x82100500, 0x0000001f, 0x820c1d00, 0x0000001f,
+	0x800c2480, 0x82102500, 0x0000001f, 0x1c01f000,
+	0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+	0x80040d40, 0x4807c857, 0x42001000, 0x0010b804,
+	0x50080000, 0x80000540, 0x04020005, 0x4a0370e5,
+	0x00000003, 0x4a0370e4, 0x00000300, 0x80000000,
+	0x44001000, 0x42001000, 0x00000400, 0x59b800ea,
+	0x8c000510, 0x0400000c, 0x0401ffd5, 0x82100480,
+	0x00000008, 0x04001007, 0x4c040000, 0x4c080000,
+	0x0401fe88, 0x5c001000, 0x5c000800, 0x0401f020,
+	0x59b800ea, 0x8c000516, 0x0402001d, 0x4a0370e4,
+	0x00300000, 0x480770e1, 0x42001000, 0x0000ff00,
+	0x80081040, 0x04000012, 0x59b808e4, 0x8c040d28,
+	0x040207fc, 0x42001000, 0x0010b804, 0x50080000,
+	0x80000040, 0x04020005, 0x4a0370e5, 0x00000002,
+	0x4a0370e4, 0x00000200, 0x02001800, 0x001005d8,
+	0x44001000, 0x8c040d2c, 0x1c01f000, 0x41f80000,
+	0x50000000, 0x0201f800, 0x001005d8, 0x80081040,
+	0x040207d3, 0x41f80000, 0x50000000, 0x0201f800,
+	0x001005d8, 0x4d380000, 0x59300c06, 0x82040580,
+	0x00000009, 0x04020006, 0x42027000, 0x00000047,
+	0x0201f800, 0x000207a1, 0x80000580, 0x5c027000,
+	0x1c01f000, 0x4c500000, 0x4a03900d, 0x00000001,
+	0x59c8a020, 0x4a03900d, 0x00000002, 0x59c80820,
+	0x8c50a52e, 0x04000002, 0x900409c0, 0x82040d00,
+	0x0000ffff, 0x0201f800, 0x00105dd7, 0x02000800,
+	0x001005d8, 0x4933c857, 0x8250a500, 0xff000000,
+	0x82500580, 0x05000000, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00a000, 0x1c01f000, 0x0401ffe6,
+	0x4933c857, 0x59300406, 0x82000580, 0x00000000,
+	0x04000040, 0x59c82021, 0x4a03900d, 0x00000001,
+	0x59c82821, 0x82142d00, 0x0000ffff, 0x59325808,
+	0x812e59c0, 0x04000037, 0x59326809, 0x0201f800,
+	0x001048d9, 0x02020800, 0x001092b6, 0x599c0019,
+	0x8c00050c, 0x04020018, 0x0201f800, 0x001048d9,
+	0x04020015, 0x59300811, 0x4807c857, 0x592c0408,
+	0x8c00051c, 0x0402000e, 0x8400055c, 0x48025c08,
+	0x592c0a04, 0x82040d00, 0x000000ff, 0x82040580,
+	0x00000048, 0x04000004, 0x82040580, 0x00000018,
+	0x04020003, 0x59300811, 0x48065803, 0x4a026011,
+	0x7fffffff, 0x48166013, 0x0201f800, 0x001010dd,
+	0x04020014, 0x0401f9fd, 0x40280000, 0x4802600d,
+	0x04000005, 0x4832600b, 0x50200000, 0x4802600a,
+	0x4822600c, 0x59300414, 0x8c00051c, 0x04020004,
+	0x599c0019, 0x8c00050c, 0x0402086e, 0x4a03900d,
+	0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+	0x59880052, 0x80000000, 0x48031052, 0x4a03900d,
+	0x00000040, 0x42000000, 0xc0000000, 0x0401f71d,
+	0x4cf80000, 0x58f40000, 0x8001f540, 0x0401f820,
+	0x41781800, 0x0401f8e4, 0x04020014, 0x44140800,
+	0x0401f82a, 0x04000011, 0x40043800, 0x42001800,
+	0x00000001, 0x40142000, 0x0401f8db, 0x0402000b,
+	0x801c3800, 0x501c0000, 0x44000800, 0x0401f810,
+	0x801c0580, 0x04000004, 0x44103800, 0x801c3840,
+	0x44143800, 0x0401f819, 0x5c01f000, 0x1c01f000,
+	0x80f9f1c0, 0x04020003, 0x58f41202, 0x0401f003,
+	0x42001000, 0x00000007, 0x1c01f000, 0x80f9f1c0,
+	0x04020006, 0x58f40401, 0x82000480, 0x00000002,
+	0x80f40400, 0x0401f005, 0x58f80401, 0x82000480,
+	0x00000002, 0x80f80400, 0x50002800, 0x80000000,
+	0x50002000, 0x1c01f000, 0x80f9f1c0, 0x04020008,
+	0x58f40401, 0x82000480, 0x00000002, 0x02001800,
+	0x001005d8, 0x4801ec01, 0x0401f00b, 0x58f80401,
+	0x82000480, 0x00000002, 0x02001800, 0x001005d8,
+	0x4801f401, 0x82000580, 0x00000002, 0x04020002,
+	0x0401f809, 0x58f40202, 0x80000040, 0x4801ea02,
+	0x02000800, 0x001005d8, 0x82000580, 0x00000001,
+	0x1c01f000, 0x4d2c0000, 0x40fa5800, 0x0201f800,
+	0x001007f4, 0x4979e800, 0x4179f000, 0x5c025800,
+	0x1c01f000, 0x80f5e9c0, 0x04000009, 0x80f9f1c0,
+	0x04020ff5, 0x4d2c0000, 0x40f65800, 0x0201f800,
+	0x001007f4, 0x4179e800, 0x5c025800, 0x1c01f000,
+	0x4cf40000, 0x59300807, 0x82040500, 0x00003100,
+	0x04020032, 0x8c040d22, 0x04000032, 0x5930001f,
+	0x8001ed40, 0x02000800, 0x001005d8, 0x82000580,
+	0xffffffff, 0x04000029, 0x58f40201, 0x82000580,
+	0x0000dcb3, 0x02020800, 0x001005d8, 0x58f40a02,
+	0x82040500, 0x0000fffe, 0x04000003, 0x0401ff89,
+	0x58f40a02, 0x82040480, 0x0000000f, 0x04021059,
+	0x80040800, 0x4805ea02, 0x82040580, 0x00000008,
+	0x0400005d, 0x82040480, 0x00000008, 0x0400100a,
+	0x58f40000, 0x8001ed40, 0x02000800, 0x001005d8,
+	0x58f40201, 0x82000580, 0x0000ddb9, 0x02020800,
+	0x001005d8, 0x58f40401, 0x82000c00, 0x00000002,
+	0x4805ec01, 0x80f40400, 0x59300812, 0x44040000,
+	0x80000000, 0x45780000, 0x5c01e800, 0x1c01f000,
+	0x42001000, 0x00000400, 0x59b800e4, 0x8c000524,
+	0x04020023, 0x4a0370e4, 0x00030000, 0x40000000,
+	0x59b800e4, 0x8c000524, 0x0402001b, 0x59300807,
+	0x84040d62, 0x48066007, 0x4a0370e4, 0x00020000,
+	0x4d2c0000, 0x0201f800, 0x001007d3, 0x04000025,
+	0x492e601f, 0x4a025a01, 0x0000dcb3, 0x59300008,
+	0x80001d40, 0x02000800, 0x001005d8, 0x580c080f,
+	0x48065803, 0x59301811, 0x40040000, 0x800c0580,
+	0x0402000d, 0x497a5a02, 0x4a025c01, 0x00000004,
+	0x0401f011, 0x4a0370e4, 0x00020000, 0x40000000,
+	0x40000000, 0x80081040, 0x02000800, 0x001005d8,
+	0x0401f7d6, 0x4a025a02, 0x00000001, 0x4a025c01,
+	0x00000006, 0x497a5804, 0x400c0000, 0x80040480,
+	0x48025805, 0x412de800, 0x5c025800, 0x0401f7a9,
+	0x5c025800, 0x4a02601f, 0xffffffff, 0x0401f7c3,
+	0x4d2c0000, 0x58f65800, 0x0201f800, 0x001007f4,
+	0x40f65800, 0x0201f800, 0x001007f4, 0x5c025800,
+	0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x001007d3,
+	0x040007f8, 0x4a025a01, 0x0000ddb9, 0x4a025c01,
+	0x00000002, 0x492de800, 0x412de800, 0x5c025800,
+	0x0401f7a5, 0x0401ff33, 0x82f40400, 0x00000004,
+	0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+	0x04000016, 0x82040c00, 0x00000002, 0x80081040,
+	0x040207fa, 0x80f9f1c0, 0x04000011, 0x58f41202,
+	0x82081480, 0x00000007, 0x82f80400, 0x00000002,
+	0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+	0x04000006, 0x82040c00, 0x00000002, 0x80081040,
+	0x040207fa, 0x0401f002, 0x1c01f000, 0x82000540,
+	0x00000001, 0x0401f7fd, 0x4cf40000, 0x4cf80000,
+	0x4001e800, 0x592c0a06, 0x800409c0, 0x0402001d,
+	0x82f40580, 0xffffffff, 0x04000017, 0x58f40201,
+	0x82000580, 0x0000dcb3, 0x02020800, 0x001005d8,
+	0x58f40000, 0x8001f540, 0x04000006, 0x58f80201,
+	0x82000580, 0x0000ddb9, 0x02020800, 0x001005d8,
+	0x41783800, 0x0401f839, 0x04020006, 0x0401ff32,
+	0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+	0x0401ff2d, 0x4a025a06, 0x00000011, 0x0401f7f9,
+	0x82f40580, 0xffffffff, 0x04020f27, 0x0401f7f5,
+	0x4cf40000, 0x4cf80000, 0x4001e800, 0x82040580,
+	0x00000001, 0x0402001f, 0x82f40580, 0xffffffff,
+	0x04000019, 0x58f40201, 0x82000580, 0x0000dcb3,
+	0x02020800, 0x001005d8, 0x58f40000, 0x8001f540,
+	0x04000006, 0x58f80201, 0x82000580, 0x0000ddb9,
+	0x02020800, 0x001005d8, 0x41783800, 0x0401f813,
+	0x04020008, 0x0401ff0c, 0x42000800, 0x00000001,
+	0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+	0x0401ff05, 0x42000800, 0x00000011, 0x0401f7f9,
+	0x4c040000, 0x82f40580, 0xffffffff, 0x04020efe,
+	0x5c000800, 0x0401f7f3, 0x4803c856, 0x401c2000,
+	0x41781800, 0x0401ff8c, 0x0402002c, 0x58f42003,
+	0x42001800, 0x00000001, 0x0401ff87, 0x04020027,
+	0x0401feb8, 0x40082800, 0x82f40400, 0x00000004,
+	0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+	0x04000005, 0x42001800, 0x00000001, 0x0401ff7a,
+	0x0402001a, 0x82183400, 0x00000002, 0x80142840,
+	0x040207f5, 0x80f9f1c0, 0x04000013, 0x58f42a02,
+	0x82142c80, 0x00000007, 0x82f80400, 0x00000003,
+	0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+	0x04000005, 0x42001800, 0x00000001, 0x0401ff66,
+	0x04020006, 0x82183400, 0x00000002, 0x80142840,
+	0x040207f5, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x0201f800, 0x001005d8, 0x58380207,
+	0x8c000502, 0x040007fc, 0x50200000, 0x80387c00,
+	0x583c2800, 0x583c2001, 0x58380404, 0x80001540,
+	0x04020002, 0x58381407, 0x58c83401, 0x58380c08,
+	0x59303807, 0x497a6012, 0x497a6013, 0x0201f000,
+	0x000200be, 0x592c0408, 0x8c000502, 0x040007ea,
+	0x592c0409, 0x80000540, 0x040007e7, 0x82000c80,
+	0x00000002, 0x04001011, 0x58380001, 0x80007540,
+	0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x40040000, 0x800409c0, 0x04000005, 0x82040c80,
+	0x00000005, 0x040217f1, 0x80204400, 0x50200000,
+	0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+	0x592c0a07, 0x592c4c08, 0x592c300d, 0x59303807,
+	0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+	0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+	0x02000000, 0x000200c6, 0x80204000, 0x50201800,
+	0x800c19c0, 0x0402000c, 0x58380001, 0x80007540,
+	0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x50201800, 0x483a600b, 0x480e600a, 0x4822600c,
+	0x0201f000, 0x000200c6, 0x4803c856, 0x592c0208,
+	0x8c00051e, 0x04020017, 0x50200000, 0x80306c00,
+	0x40240000, 0x0c01f001, 0x00100e46, 0x00100e46,
+	0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e46,
+	0x00100e46, 0x00100e46, 0x00100e4f, 0x00100e46,
+	0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e4f,
+	0x00100e46, 0x00100e46, 0x0201f800, 0x001005d8,
+	0x8400051e, 0x48025a08, 0x50200000, 0x80306c00,
+	0x58343801, 0x481e600f, 0x0401f007, 0x58341802,
+	0x58342800, 0x58343801, 0x480e6010, 0x4816600e,
+	0x481e600f, 0x0401f246, 0x4933c857, 0x5931f808,
+	0x59300a06, 0x800409c0, 0x04000005, 0x80040906,
+	0x04020002, 0x80040800, 0x4805fc06, 0x4a026206,
+	0x00000002, 0x592c0409, 0x82000500, 0x00000008,
+	0x0400000b, 0x0401f834, 0x59300203, 0x82000580,
+	0x00000004, 0x04020005, 0x42027000, 0x00000048,
+	0x0201f800, 0x000207a1, 0x1c01f000, 0x4cfc0000,
+	0x58fc0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000048, 0x0402000c, 0x58fc000b, 0x800001c0,
+	0x04000009, 0x58fc0407, 0x800001c0, 0x04000006,
+	0x58fc080b, 0x8c040d16, 0x04000017, 0x58fc0007,
+	0x0401f00a, 0x58fc0408, 0x8c000512, 0x04020014,
+	0x58fc0c09, 0x8c040d16, 0x04020003, 0x5c01f800,
+	0x1c01f000, 0x58fc000a, 0x59300811, 0x80040580,
+	0x04020009, 0x59300007, 0x84000500, 0x48026007,
+	0x42027000, 0x00000048, 0x5c01f800, 0x0201f000,
+	0x000207a1, 0x5c01f800, 0x1c01f000, 0x58fdf809,
+	0x0401f7ec, 0x4933c857, 0x59b808ea, 0x82040d00,
+	0x00000007, 0x82040580, 0x00000000, 0x0400001e,
+	0x82040580, 0x00000003, 0x0400001b, 0x59300406,
+	0x4c000000, 0x4a026406, 0x00000000, 0x42003000,
+	0x00000041, 0x42000000, 0x50000000, 0x41300800,
+	0x4c180000, 0x0401fce7, 0x5c003000, 0x0400000b,
+	0x42000000, 0x0000001e, 0x80000040, 0x040207ff,
+	0x80183040, 0x040207f4, 0x42000000, 0x40000000,
+	0x41300800, 0x0401fcdb, 0x5c000000, 0x48026406,
+	0x1c01f000, 0x59300007, 0x84000500, 0x48026007,
+	0x0401f7fc, 0x59c00007, 0x4a038006, 0x30000000,
+	0x40000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+	0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857,
+	0x4dc00000, 0x4a0370e8, 0x00000000, 0x42038000,
+	0x00007720, 0x0401fff0, 0x42038000, 0x00007700,
+	0x0401ffed, 0x0201f800, 0x0010513b, 0x04020013,
+	0x4a038891, 0x0000ffff, 0x497b8880, 0x497b8892,
+	0x42001000, 0x00000190, 0x40000000, 0x40000000,
+	0x80081040, 0x040207fd, 0x42000000, 0x0010b8a6,
+	0x0201f800, 0x0010aa47, 0x0401f80e, 0x5c038000,
+	0x0201f000, 0x00105258, 0x0401f82d, 0x42000000,
+	0x0010b8a7, 0x0201f800, 0x0010aa47, 0x0401f805,
+	0x48178892, 0x480b8880, 0x5c038000, 0x1c01f000,
+	0x496fc857, 0x836c0580, 0x00000003, 0x0402000b,
+	0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+	0x42001800, 0x0000ffff, 0x0201f800, 0x00103a3e,
+	0x5c001800, 0x5c001000, 0x42000800, 0x0000003c,
+	0x0201f800, 0x00101345, 0x59a8006c, 0x80000540,
+	0x04000006, 0x59a8106d, 0x800811c0, 0x04000003,
+	0x0201f800, 0x00101aaf, 0x4a038891, 0x0000ffff,
+	0x4a03900d, 0x00000040, 0x0201f800, 0x0010098e,
+	0x4a0370e8, 0x00000001, 0x1c01f000, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x59c41080, 0x497b8880,
+	0x59c42892, 0x497b8892, 0x0201f800, 0x0010513b,
+	0x04020002, 0x1c01f000, 0x42002000, 0x00000260,
+	0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0580,
+	0x00000000, 0x04000010, 0x59c41805, 0x820c1d00,
+	0x00000001, 0x0402000e, 0x59c418a4, 0x820c1d00,
+	0x0000000f, 0x820c0480, 0x00000007, 0x04001004,
+	0x820c0480, 0x0000000c, 0x04001003, 0x80102040,
+	0x040207ec, 0x497b8891, 0x1c01f000, 0x4c100000,
+	0x42002000, 0x00000019, 0x46000000, 0x00000001,
+	0x0201f800, 0x00101937, 0x50001800, 0x820c1d00,
+	0x00000001, 0x04000005, 0x80102040, 0x040207f7,
+	0x5c002000, 0x0401f7f0, 0x5c002000, 0x0401f7ec,
+	0x4803c856, 0x1c01f000, 0x4d2c0000, 0x59325808,
+	0x592c0a04, 0x4807c857, 0x82040d00, 0x000000ff,
+	0x82040500, 0x0000000f, 0x0c01f001, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f7f, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f67, 0x00100f67,
+	0x00100f7f, 0x00100f67, 0x00100f69, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f67, 0x0201f800,
+	0x001005d8, 0x82040580, 0x0000003b, 0x02020800,
+	0x001005d8, 0x592c020a, 0x8c000500, 0x0400005f,
+	0x592c1a07, 0x82040500, 0x0000000f, 0x82000400,
+	0x001010bd, 0x50001000, 0x50080000, 0x59302013,
+	0x4802600a, 0x492e600b, 0x480a600c, 0x480e600d,
+	0x48126012, 0x5c025800, 0x1c01f000, 0x82040500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50001000,
+	0x50080000, 0x592c1a07, 0x4802600a, 0x492e600b,
+	0x480a600c, 0x480e600d, 0x497a6012, 0x0401f7f2,
+	0x8c040d00, 0x04020041, 0x82040d00, 0x00000080,
+	0x0400003e, 0x0201f000, 0x000200cf, 0x59300013,
+	0x59301012, 0x80080580, 0x0402000c, 0x42007800,
+	0x80000005, 0x592c1208, 0x82080500, 0xffff7fff,
+	0x48025a08, 0x8c08151e, 0x0402002d, 0x823c7d40,
+	0x00000020, 0x0401f02a, 0x480bc857, 0x42000000,
+	0x0010b851, 0x0201f800, 0x0010aa47, 0x59300414,
+	0x4803c857, 0x8c000514, 0x04020007, 0x599c1819,
+	0x8c0c1d12, 0x04020004, 0x820c1d40, 0x00000001,
+	0x0401f01d, 0x59302013, 0x0401f92b, 0x0402001a,
+	0x42007800, 0x80000005, 0x5930500d, 0x592c0208,
+	0x4803c857, 0x8c00051e, 0x04020005, 0x823c7d40,
+	0x00000020, 0x5930400c, 0x0401f004, 0x8400051e,
+	0x48025a08, 0x0401f8da, 0x50201800, 0x480e600a,
+	0x4832600b, 0x4822600c, 0x482a600d, 0x480fc857,
+	0x4833c857, 0x4823c857, 0x482bc857, 0x80000580,
+	0x483e6004, 0x1c01f000, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x4d2c0000, 0x59900004, 0x81300580,
+	0x02020800, 0x001005d8, 0x0201f800, 0x00109037,
+	0x02000800, 0x001005d8, 0x59325808, 0x4d3c0000,
+	0x4d400000, 0x59300004, 0x4803c857, 0x4c000000,
+	0x0201f800, 0x00106dc3, 0x0201f800, 0x00106b8a,
+	0x5c000000, 0x8c000516, 0x04000010, 0x592c000f,
+	0x4803c857, 0x48025807, 0x41780800, 0x42028000,
+	0x00000002, 0x0201f800, 0x00104e70, 0x4a025c06,
+	0x0000ffff, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00107911, 0x0401f015, 0x4a026203, 0x00000002,
+	0x592c0208, 0x8400054e, 0x48025a08, 0x59300406,
+	0x82000580, 0x00000006, 0x04020009, 0x811800ca,
+	0x81c80c00, 0x58040939, 0x592c000d, 0x80040480,
+	0x592c080f, 0x80040480, 0x4802580b, 0x417a7800,
+	0x0201f800, 0x00108be3, 0x5c028000, 0x5c027800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x59900004, 0x81300580, 0x02020800, 0x001005d8,
+	0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+	0x59325808, 0x592c0208, 0x84000540, 0x48025a08,
+	0x0401f7bf, 0x491bc857, 0x49d3c857, 0x4dd00000,
+	0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600,
+	0x4a03a005, 0x80000002, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020029,
+	0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+	0x00006000, 0x0400002f, 0x82080500, 0x40008000,
+	0x040007f8, 0x800409c0, 0x0402002a, 0x811a31c0,
+	0x04000028, 0x42000000, 0x00001002, 0x50001000,
+	0x46000000, 0x00000512, 0x42001800, 0x0000000a,
+	0x59e00000, 0x8c00051a, 0x040207fc, 0x800c1840,
+	0x040207fc, 0x42000000, 0x00001002, 0x46000000,
+	0x00000514, 0x42001800, 0x0000000a, 0x59e00000,
+	0x8c00053a, 0x040207fc, 0x800c1840, 0x040207fc,
+	0x42000000, 0x00001002, 0x44080000, 0x0401f00d,
+	0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+	0x00006000, 0x04000007, 0x8c08151e, 0x040007f9,
+	0x59d01006, 0x82080500, 0x00006000, 0x040207f5,
+	0x83d3a400, 0x00000020, 0x80040800, 0x82040480,
+	0x00000005, 0x040017bf, 0x5c03a000, 0x1c01f000,
+	0x491bc857, 0x49d3c857, 0x4dd00000, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x4a03a005,
+	0x80000001, 0x59d00006, 0x83d3a400, 0x00000020,
+	0x80040800, 0x82040480, 0x00000005, 0x040017f8,
+	0x5c03a000, 0x1c01f000, 0x59d00006, 0x8c00053e,
+	0x0400001e, 0x59902804, 0x4817c857, 0x801429c0,
+	0x04000013, 0x5990000a, 0x5990080b, 0x5990100c,
+	0x5990180d, 0x4800280a, 0x4804280b, 0x4808280c,
+	0x480c280d, 0x59d00000, 0x59d00801, 0x59d01002,
+	0x59d01803, 0x59d02004, 0x4800280e, 0x4804280f,
+	0x48082810, 0x480c2811, 0x48102812, 0x59900006,
+	0x82000500, 0xffff0000, 0x48032006, 0x4a03a005,
+	0x30000000, 0x59d00006, 0x1c01f000, 0x4803c856,
+	0x80204000, 0x50200000, 0x80000540, 0x04000003,
+	0x80285040, 0x1c01f000, 0x58300001, 0x80000540,
+	0x0400000e, 0x4802600b, 0x40006000, 0x58300204,
+	0x82000500, 0x0000000f, 0x82000400, 0x001010bd,
+	0x50004000, 0x802041c0, 0x02000800, 0x001005d8,
+	0x80285040, 0x1c01f000, 0x40005000, 0x1c01f000,
+	0x00000005, 0x00000008, 0x0000000b, 0x0000000e,
+	0x00000011, 0x00000000, 0x00000000, 0x0000000b,
+	0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+	0x001010b7, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x001010b8, 0x001010b7, 0x001010b4,
+	0x001010b8, 0x001010b7, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x001010b8, 0x001010b8, 0x001010b8,
+	0x00000000, 0x001010b8, 0x00000000, 0x00000000,
+	0x00000000, 0x4813c857, 0x492fc857, 0x4933c857,
+	0x48126012, 0x592c5207, 0x802851c0, 0x0400004a,
+	0x412c6000, 0x0401f84b, 0x04000009, 0x82240580,
+	0x00000002, 0x04020003, 0x5830000d, 0x80102480,
+	0x50200000, 0x80004540, 0x0400003f, 0x50200000,
+	0x80000540, 0x0400000b, 0x80301400, 0x58080002,
+	0x80102480, 0x0400101e, 0x801021c0, 0x04000009,
+	0x80285040, 0x04000034, 0x80204000, 0x0401f7f4,
+	0x58300001, 0x80006540, 0x0400002f, 0x0401f7e6,
+	0x80285040, 0x0400002c, 0x80204000, 0x50200000,
+	0x80000540, 0x0402000a, 0x58300001, 0x80006540,
+	0x04000025, 0x58300204, 0x82004d00, 0x0000000f,
+	0x82244400, 0x001010bd, 0x50204000, 0x592c0208,
+	0x8400051e, 0x48025a08, 0x0401f013, 0x80102080,
+	0x80102000, 0x48126010, 0x4813c857, 0x58080802,
+	0x40100000, 0x80042480, 0x02001800, 0x001005d8,
+	0x58080000, 0x58081801, 0x80102400, 0x4812600e,
+	0x480e600f, 0x4813c857, 0x592c0208, 0x8400055e,
+	0x48025a08, 0x4833c857, 0x4823c857, 0x482bc857,
+	0x4832600b, 0x4822600c, 0x482a600d, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+	0x58300204, 0x82004d00, 0x0000000f, 0x82244400,
+	0x001010bd, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000029, 0x0402001b, 0x50204000, 0x592c0409,
+	0x80000540, 0x02000800, 0x001005d8, 0x82000c80,
+	0x00000002, 0x04001011, 0x58300001, 0x80006540,
+	0x02000800, 0x001005d8, 0x58300204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x40040000, 0x800409c0, 0x04000006, 0x82040c80,
+	0x00000005, 0x040217f1, 0x80204400, 0x80000580,
+	0x1c01f000, 0x59e00004, 0x8c00050e, 0x02020000,
+	0x00100903, 0x1c01f000, 0x4c5c0000, 0x59e4b800,
+	0x485fc857, 0x825c0500, 0x0000001f, 0x04000004,
+	0x59e40862, 0x0201f800, 0x001005d8, 0x825c0500,
+	0x000000e0, 0x02000800, 0x001005d8, 0x8c5cbd0e,
+	0x04020807, 0x8c5cbd0c, 0x04020809, 0x8c5cbd0a,
+	0x04020878, 0x5c00b800, 0x1c01f000, 0x4803c856,
+	0x4a03c800, 0x00000080, 0x1c01f000, 0x4d2c0000,
+	0x42007800, 0x0010b8ec, 0x583c0001, 0x583c0802,
+	0x80040540, 0x0400003f, 0x42000800, 0x0010b7f7,
+	0x50065800, 0x592c0002, 0x82000580, 0x00000000,
+	0x0400000e, 0x59e40850, 0x59e41853, 0x400c0000,
+	0x80040400, 0x59e40852, 0x4807c857, 0x80041480,
+	0x04021008, 0x40001000, 0x480bc857, 0x4a007800,
+	0x00000001, 0x0401f006, 0x4803c857, 0x0401f029,
+	0x59e41050, 0x480bc857, 0x49787800, 0x480bc857,
+	0x480fc857, 0x592c0003, 0x80000540, 0x04000006,
+	0x80080580, 0x04020004, 0x592c0003, 0x4803c857,
+	0x480bc857, 0x480a5803, 0x592c0007, 0x800001c0,
+	0x04000007, 0x592c1007, 0x480bc857, 0x583c0003,
+	0x4803c857, 0x80080480, 0x04001003, 0x583c1001,
+	0x480bc857, 0x583c0802, 0x480bc857, 0x4807c857,
+	0x4a025801, 0x00000000, 0x4a025809, 0x001011bc,
+	0x480a5807, 0x48065808, 0x59e40053, 0x48025804,
+	0x412c1000, 0x492fc857, 0x0201f800, 0x00100858,
+	0x5c025800, 0x4a03c800, 0x00000040, 0x1c01f000,
+	0x42007800, 0x0010b7f7, 0x503c7800, 0x4a007802,
+	0x00000100, 0x42007800, 0x0010b8ec, 0x583c0000,
+	0x4803c857, 0x82000d80, 0x00000001, 0x04000004,
+	0x80000000, 0x48007800, 0x0401f019, 0x49787800,
+	0x583c1806, 0x583c0005, 0x800c1800, 0x480c7806,
+	0x800c0580, 0x04020002, 0x49787806, 0x583c0807,
+	0x800409c0, 0x0400000e, 0x583c0008, 0x80000000,
+	0x48007808, 0x80040580, 0x04020009, 0x49787808,
+	0x583c2006, 0x42001800, 0x00000001, 0x42001000,
+	0x00008028, 0x0201f800, 0x00103a3e, 0x1c01f000,
+	0x4a03c800, 0x00000020, 0x0201f800, 0x0010aa40,
+	0x59e40000, 0x1c01f000, 0x4d2c0000, 0x4a007001,
+	0x00000000, 0x82040d00, 0x43000f80, 0x02020800,
+	0x001005d8, 0x58380009, 0x4803c00f, 0x0201f800,
+	0x00109402, 0x583a5808, 0x592c0000, 0x48007008,
+	0x800001c0, 0x04020002, 0x49787007, 0x0201f800,
+	0x001007f4, 0x5c025800, 0x0201f000, 0x0010087d,
+	0x4803c856, 0x4c3c0000, 0x4d2c0000, 0x4d300000,
+	0x5830000a, 0x80025d40, 0x02000800, 0x001005d8,
+	0x592e6008, 0x4c300000, 0x0201f800, 0x0010941a,
+	0x5c006000, 0x02000800, 0x001005d8, 0x58300002,
+	0x82000580, 0x00000100, 0x04020010, 0x5930780b,
+	0x583c0001, 0x80000540, 0x0400000e, 0x4802600b,
+	0x40007800, 0x82000400, 0x00000002, 0x48006003,
+	0x583c0000, 0x48006004, 0x40301000, 0x0201f800,
+	0x00100858, 0x0401f00c, 0x4a025a06, 0x00000002,
+	0x4c300000, 0x0201f800, 0x000202da, 0x5c006000,
+	0x40325800, 0x0201f800, 0x001007f4, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x5c025800, 0x5c007800,
+	0x1c01f000, 0x4803c856, 0x4d2c0000, 0x4d300000,
+	0x42007000, 0x0010b7f8, 0x58380801, 0x82040580,
+	0x00000002, 0x04020011, 0x58386002, 0x5830000a,
+	0x812c0580, 0x0402000d, 0x59e00004, 0x8c00050e,
+	0x040007fe, 0x59dc0006, 0x4803c857, 0x4a03b805,
+	0x20000000, 0x8c00053e, 0x040007f8, 0x4a007001,
+	0x00000000, 0x0401f019, 0x58386006, 0x40305000,
+	0x803061c0, 0x02000800, 0x001005d8, 0x5830000a,
+	0x812c0580, 0x04000004, 0x40305000, 0x58306000,
+	0x0401f7f8, 0x40280000, 0x80300580, 0x58300000,
+	0x04000006, 0x48005000, 0x800001c0, 0x04020007,
+	0x48287005, 0x0401f005, 0x800001c0, 0x04020002,
+	0x48007005, 0x48007006, 0x40325800, 0x0201f800,
+	0x001007f4, 0x42007000, 0x0010b7f8, 0x58380001,
+	0x82000580, 0x00000000, 0x02000800, 0x0010087d,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x4803c856,
+	0x42000800, 0x0000003c, 0x48079000, 0x59c80000,
+	0x80040500, 0x040207fe, 0x497b9005, 0x4a039035,
+	0x00880200, 0x59a8000e, 0x800000e0, 0x4803900e,
+	0x4a039011, 0x00000024, 0x4a03900f, 0x0010d1c0,
+	0x4a039010, 0x0010d1c0, 0x4a039015, 0x0000007f,
+	0x4a03900d, 0x00000040, 0x4a039000, 0x00001600,
+	0x1c01f000, 0x59c80007, 0x8c000508, 0x040208b7,
+	0x59c80800, 0x8c040d16, 0x04020004, 0x82000500,
+	0x00000006, 0x0c01f005, 0x4807c857, 0x82000500,
+	0x0000000e, 0x0c01f001, 0x001012a8, 0x001012a6,
+	0x00105999, 0x001012a6, 0x001012aa, 0x001012a6,
+	0x001012aa, 0x001012aa, 0x001012a6, 0x001012a6,
+	0x001012a6, 0x001012a6, 0x001012aa, 0x001012a6,
+	0x001012aa, 0x001012a6, 0x0201f800, 0x001005d8,
+	0x4803c857, 0x1c01f000, 0x59c8080c, 0x4807c857,
+	0x82040500, 0x00006000, 0x04000004, 0x0201f800,
+	0x0010aa03, 0x0401f006, 0x82040500, 0x007f0000,
+	0x04000006, 0x0201f800, 0x0010a9d5, 0x0201f800,
+	0x00106eb3, 0x0401f02b, 0x82040500, 0x00000014,
+	0x04000014, 0x0201f800, 0x0010aa32, 0x836c0580,
+	0x00000003, 0x0400000d, 0x0201f800, 0x0010513b,
+	0x04000004, 0x0201f800, 0x0010411d, 0x0401f007,
+	0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f817, 0x0401f015,
+	0x82040500, 0x00001c00, 0x04000005, 0x0201f800,
+	0x0010aa11, 0x0401f810, 0x0401f00e, 0x82040500,
+	0x00000140, 0x04000005, 0x0201f800, 0x0010aa24,
+	0x0401f809, 0x0401f007, 0x82040500, 0x00008000,
+	0x04000004, 0x0201f800, 0x0010a9fc, 0x0401f802,
+	0x1c01f000, 0x4c0c0000, 0x4c100000, 0x4c140000,
+	0x0201f800, 0x00100ec9, 0x5c002800, 0x5c002000,
+	0x5c001800, 0x1c01f000, 0x4803c856, 0x59a80804,
+	0x59a8002b, 0x82000500, 0xfffff000, 0x80040540,
+	0x4803502b, 0x59a8002f, 0x82000500, 0xfffff000,
+	0x80040540, 0x4803502f, 0x48078882, 0x82041c00,
+	0x0000000f, 0x800c1908, 0x820c1c00, 0x00000004,
+	0x400c2000, 0x901029c0, 0x82040480, 0x000001e4,
+	0x04021005, 0x42001000, 0x00000008, 0x801020c6,
+	0x0401f031, 0x82040480, 0x00000230, 0x04021009,
+	0x42001000, 0x00000007, 0x801000c2, 0x800000c2,
+	0x80100400, 0x80100400, 0x80102400, 0x0401f026,
+	0x82040480, 0x00000298, 0x04021008, 0x42001000,
+	0x00000006, 0x801000c2, 0x800000c2, 0x80100400,
+	0x80102400, 0x0401f01c, 0x82040480, 0x00000328,
+	0x04021007, 0x42001000, 0x00000005, 0x801000c2,
+	0x800000c2, 0x80102400, 0x0401f013, 0x82040480,
+	0x00000404, 0x04021005, 0x42001000, 0x00000004,
+	0x801020c4, 0x0401f00c, 0x82040480, 0x0000056c,
+	0x04021006, 0x42001000, 0x00000003, 0x801000c2,
+	0x80102400, 0x0401f004, 0x42001000, 0x00000002,
+	0x801020c2, 0x82100480, 0x00000110, 0x80000080,
+	0x80002000, 0x800800d0, 0x80140540, 0x80100540,
+	0x48039035, 0x1c01f000, 0x59c80815, 0x0201f800,
+	0x001005d0, 0x82040d00, 0x0000007c, 0x48079000,
+	0x59c80000, 0x80040500, 0x040207fe, 0x8c040d04,
+	0x04000003, 0x59c80035, 0x48039035, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+	0x4803c856, 0x497b88a9, 0x4a038807, 0x00000001,
+	0x497b8807, 0x59c40005, 0x48038805, 0x0201f800,
+	0x00101815, 0x4201d000, 0x000001f4, 0x0201f800,
+	0x0010608e, 0x497b880e, 0x4200b000, 0x000001f4,
+	0x42000000, 0x00000001, 0x42000800, 0x00000014,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000014,
+	0x0201f800, 0x0010193f, 0x8c040d00, 0x04000005,
+	0x8058b040, 0x040207f3, 0x0201f800, 0x001005d8,
+	0x4200b000, 0x00000032, 0x42000000, 0x00000001,
+	0x42000800, 0x000000b4, 0x0201f800, 0x00101944,
+	0x42000800, 0x000000b4, 0x0201f800, 0x0010193f,
+	0x8c040d00, 0x04000005, 0x8058b040, 0x040207f3,
+	0x0201f800, 0x001005d8, 0x59c40005, 0x48038805,
+	0x42000000, 0x00000089, 0x800008d0, 0x48075054,
+	0x48075055, 0x48075056, 0x42000800, 0x000000e0,
+	0x0201f800, 0x00101944, 0x42000800, 0x000000f4,
+	0x0201f800, 0x0010193f, 0x82040500, 0xffffffd1,
+	0x82000540, 0x00000002, 0x42000800, 0x000000f4,
+	0x0201f800, 0x00101944, 0x42000800, 0x000000a0,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000001,
+	0x42000800, 0x000000a0, 0x0201f800, 0x00101944,
+	0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+	0x82040540, 0x00000001, 0x42000800, 0x00000000,
+	0x0201f800, 0x00101944, 0x4201d000, 0x0001d4c0,
+	0x0201f800, 0x0010608e, 0x0401fa2b, 0x4a0388a7,
+	0x0000f7f7, 0x4a0388a3, 0x8000403c, 0x4a0388ae,
+	0x000061a8, 0x4a038801, 0x00032063, 0x4a038810,
+	0x00410108, 0x4a038811, 0x00520608, 0x4a038812,
+	0x00450320, 0x4a038813, 0x00440405, 0x4a03881c,
+	0x004132e1, 0x4a038850, 0x80000108, 0x4a038860,
+	0x00000008, 0x4a038870, 0x00000008, 0x4a038851,
+	0x80000508, 0x4a038861, 0x00800000, 0x4a038871,
+	0x00800000, 0x4a038852, 0x80000708, 0x4a038862,
+	0x00800000, 0x4a038872, 0x00800000, 0x4a038853,
+	0x80000608, 0x497b8863, 0x4a038873, 0x00800000,
+	0x4a038882, 0x00000840, 0x4a0388a5, 0x0000001e,
+	0x4a0388a6, 0x0000001e, 0x4a0388b0, 0x00007530,
+	0x4a038802, 0x0000ffff, 0x4a038806, 0xc0e00800,
+	0x1c01f000, 0x497b5022, 0x4a035021, 0x00000001,
+	0x42000800, 0x00000040, 0x0201f800, 0x0010193f,
+	0x82040500, 0xffffffaf, 0x82000540, 0x00000000,
+	0x42000800, 0x00000040, 0x0201f800, 0x00101944,
+	0x42000800, 0x000000f4, 0x0201f800, 0x0010193f,
+	0x4c040000, 0x40040000, 0x84000548, 0x42000800,
+	0x000000f4, 0x0201f800, 0x00101944, 0x42000800,
+	0x00000000, 0x0201f800, 0x0010193f, 0x82040500,
+	0xffffffc1, 0x82000540, 0x00000038, 0x42000800,
+	0x00000000, 0x0201f800, 0x00101944, 0x5c000000,
+	0x42000800, 0x000000f4, 0x0201f000, 0x00101944,
+	0x59c40805, 0x4807c857, 0x59c40006, 0x80040d00,
+	0x02000800, 0x001005d8, 0x82040500, 0x00e00800,
+	0x04020004, 0x8c040d3e, 0x040208c4, 0x0401f007,
+	0x82040500, 0x00800800, 0x02020800, 0x001005d0,
+	0x0201f800, 0x001005d8, 0x4c5c0000, 0x4c600000,
+	0x59c4b805, 0x485fc857, 0x59c40006, 0x8c000500,
+	0x04000003, 0x8c5cbd00, 0x04020079, 0x0201f800,
+	0x0010513b, 0x04000014, 0x59c40005, 0x82000500,
+	0x000000c0, 0x04000036, 0x0201f800, 0x00105151,
+	0x04020033, 0x4a038805, 0x04000000, 0x59c400a3,
+	0x82000500, 0xbf203fff, 0x480388a3, 0x497b5049,
+	0x4a038805, 0x000000c0, 0x0201f800, 0x00105065,
+	0x0401f063, 0x8c5cbd34, 0x04020025, 0x59c40005,
+	0x8c00050c, 0x04020012, 0x8c00050e, 0x04020013,
+	0x8c00050a, 0x04020014, 0x8c000508, 0x0400000b,
+	0x59a80017, 0x82000580, 0x00000009, 0x04020007,
+	0x42000000, 0x0010b844, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00105318, 0x0401f04b, 0x4a035033,
+	0x00000000, 0x0401f00b, 0x4a035033, 0x00000002,
+	0x0401f008, 0x42000000, 0x0010b846, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x001052c2, 0x0401f03e,
+	0x0201f800, 0x00105378, 0x0401f03b, 0x8c5cbd34,
+	0x04000037, 0x59c40005, 0x8c00053a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x0010513b,
+	0x04020010, 0x4a038805, 0x04000000, 0x0201f800,
+	0x00105149, 0x04020008, 0x4a035033, 0x00000001,
+	0x4202d800, 0x00000001, 0x0201f800, 0x001050a2,
+	0x0401f05b, 0x41780000, 0x0201f800, 0x00105113,
+	0x0201f800, 0x001019fe, 0x4000c000, 0x0201f800,
+	0x00101963, 0x836c1580, 0x00000004, 0x0402000d,
+	0x8c5cbd00, 0x04020012, 0x59a81005, 0x8c081506,
+	0x04020005, 0x59c410a3, 0x82081540, 0x00000008,
+	0x480b88a3, 0x59c41006, 0x84081540, 0x480b8806,
+	0x4a038805, 0x04000000, 0x4202d800, 0x00000001,
+	0x497b5014, 0x0201f800, 0x00103b38, 0x8c5cbd3c,
+	0x04020858, 0x8c5cbd00, 0x04000036, 0x42000000,
+	0x0010b8ca, 0x0201f800, 0x0010aa47, 0x4a038805,
+	0x00000001, 0x4200b000, 0x000003e8, 0x4201d000,
+	0x00000064, 0x4c580000, 0x0201f800, 0x0010608e,
+	0x0201f800, 0x001018d3, 0x5c00b000, 0x04000004,
+	0x8058b040, 0x040207f6, 0x0401f004, 0x4a038805,
+	0x00000001, 0x0401f01f, 0x59c40006, 0x84000500,
+	0x48038806, 0x0201f800, 0x00106ede, 0x497b8880,
+	0x0201f800, 0x0010a9c0, 0x59c4000d, 0x8c000500,
+	0x02020800, 0x0010a9ce, 0x59c400a3, 0x82000500,
+	0xfcf8ffff, 0x480388a3, 0x4a03504c, 0x00000002,
+	0x4202d800, 0x00000004, 0x4a038805, 0x00000001,
+	0x0201f800, 0x001006d4, 0x0401fb3b, 0x497b5052,
+	0x4a035049, 0x00000001, 0x0201f800, 0x00100452,
+	0x825cbd00, 0xbbfffffe, 0x485f8805, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x59c41004, 0x480bc857,
+	0x8c081500, 0x04000006, 0x4803c856, 0x497b2807,
+	0x0201f800, 0x00106fa4, 0x0401f00a, 0x82080500,
+	0x000001f0, 0x04000007, 0x4803c856, 0x417a3000,
+	0x0201f800, 0x00106062, 0x0201f800, 0x00106fc6,
+	0x4a038805, 0x80000000, 0x1c01f000, 0x59c408a3,
+	0x4807c857, 0x84040d40, 0x480788a3, 0x1c01f000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x4a038805, 0x40000000, 0x42000000, 0x0010b8c6,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00106c55,
+	0x59c41004, 0x8c081500, 0x04000054, 0x598e600d,
+	0x497b2807, 0x813261c0, 0x04000032, 0x59300403,
+	0x82000580, 0x00000032, 0x0402002e, 0x5930001c,
+	0x48038833, 0x4a038807, 0x00018000, 0x4201d000,
+	0x00000002, 0x0201f800, 0x0010608e, 0x497b8807,
+	0x4201d000, 0x00000002, 0x0201f800, 0x0010608e,
+	0x0201f800, 0x00106e21, 0x4201d000, 0x00007530,
+	0x0201f800, 0x0010608e, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040d80, 0x00000000, 0x04000005,
+	0x42000000, 0x00200000, 0x0201f800, 0x00101949,
+	0x0201f800, 0x00106bbf, 0x59300008, 0x80000540,
+	0x02000800, 0x001005d8, 0x40025800, 0x4a025a04,
+	0x00000103, 0x5931d821, 0x58ef400b, 0x58ec0009,
+	0x0801f800, 0x0201f800, 0x0002077d, 0x0401f047,
+	0x598c000f, 0x82001c80, 0x000000c8, 0x0402100f,
+	0x80000000, 0x4803180f, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x04020004,
+	0x42000000, 0x00200000, 0x0401fbf7, 0x0201f800,
+	0x0010604d, 0x0401f035, 0x4933c857, 0x0201f800,
+	0x00106e21, 0x813261c0, 0x04000030, 0x4a026203,
+	0x00000001, 0x42027000, 0x00000027, 0x0201f800,
+	0x000207a1, 0x0401f029, 0x8c081508, 0x04000027,
+	0x417a3000, 0x0201f800, 0x001070d8, 0x42032000,
+	0x0000bf32, 0x0201f800, 0x00106062, 0x59926004,
+	0x813261c0, 0x04000012, 0x42001800, 0x000000c8,
+	0x0201f800, 0x001070a4, 0x0402000d, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000002,
+	0x04020004, 0x42000000, 0x00200000, 0x0401fbce,
+	0x0201f800, 0x00106052, 0x0401f00c, 0x4933c857,
+	0x0201f800, 0x00106dc3, 0x813261c0, 0x04000007,
+	0x42027000, 0x0000004f, 0x4a026203, 0x00000003,
+	0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x0201f000, 0x00106c4b,
+	0x4803c857, 0x59a80821, 0x48035021, 0x80041580,
+	0x04000045, 0x800409c0, 0x04000023, 0x497b504c,
+	0x42000000, 0x0010b80d, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x0010aaf9, 0x42001000, 0x00008011,
+	0x59c40001, 0x82000500, 0x00018000, 0x82001d80,
+	0x00000000, 0x04000009, 0x82001d80, 0x00008000,
+	0x04000009, 0x82001d80, 0x00010000, 0x04000009,
+	0x0201f800, 0x001005d8, 0x42001800, 0x00000000,
+	0x0401f006, 0x42001800, 0x00000001, 0x0401f003,
+	0x42001800, 0x00000003, 0x0201f800, 0x00103a3e,
+	0x0401f021, 0x59a8084c, 0x800409c0, 0x04020007,
+	0x59c4000d, 0x8c000520, 0x04000004, 0x42001800,
+	0x00000003, 0x0401f002, 0x40041800, 0x0201f800,
+	0x0010aadd, 0x42001000, 0x00008012, 0x0201f800,
+	0x00103a3e, 0x0201f800, 0x001006d4, 0x0201f800,
+	0x0010ab33, 0x0402000c, 0x0401f853, 0x4d400000,
+	0x4d3c0000, 0x42028000, 0x00000028, 0x42027800,
+	0x00000408, 0x0201f800, 0x00101fe5, 0x5c027800,
+	0x5c028000, 0x1c01f000, 0x4803c857, 0x82000400,
+	0x0010210e, 0x50000800, 0x82040d00, 0x000000ff,
+	0x1c01f000, 0x4803c856, 0x4c580000, 0x4200b000,
+	0x00000010, 0x497b88ac, 0x497b88ad, 0x8058b040,
+	0x040207fe, 0x5c00b000, 0x1c01f000, 0x4807c857,
+	0x48075010, 0x80041108, 0x4200b000, 0x00000010,
+	0x497b88ac, 0x80000580, 0x800811c0, 0x04020006,
+	0x82040500, 0x0000000f, 0x82000400, 0x0010ab38,
+	0x50000000, 0x480388ad, 0x80081040, 0x8058b040,
+	0x040207f5, 0x1c01f000, 0x59a80005, 0x04000003,
+	0x84000546, 0x0401f002, 0x84000506, 0x48035005,
+	0x4803c857, 0x1c01f000, 0x4803c857, 0x4c080000,
+	0x4c040000, 0x4c000000, 0x59c40892, 0x4807c857,
+	0x80041580, 0x04000010, 0x80041480, 0x04021007,
+	0x80081080, 0x80081000, 0x4008b000, 0x42000000,
+	0x00000201, 0x0401f004, 0x4008b000, 0x42000000,
+	0x00000210, 0x48038886, 0x8058b040, 0x040207fe,
+	0x497b8886, 0x5c000000, 0x5c000800, 0x5c001000,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x00103b25,
+	0x04000005, 0x42028000, 0x0000002e, 0x0201f000,
+	0x0010a449, 0x1c01f000, 0x42000800, 0x00000002,
+	0x59a80005, 0x8c000514, 0x0402000b, 0x59c80835,
+	0x82040d00, 0x00001f00, 0x80040910, 0x80040800,
+	0x59a8006c, 0x80000540, 0x04000003, 0x42000800,
+	0x0000025a, 0x4807c857, 0x1c01f000, 0x4c000000,
+	0x59a80053, 0x4803c857, 0x82000580, 0x00000000,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59a80053,
+	0x4803c857, 0x82000580, 0x00000001, 0x5c000000,
+	0x1c01f000, 0x4c000000, 0x59a80053, 0x4803c857,
+	0x82000580, 0x00000003, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59a80053, 0x82000580, 0x00000002,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x4c040000,
+	0x4c080000, 0x4c380000, 0x59a80040, 0x82000c80,
+	0x00000007, 0x02021800, 0x001005d8, 0x0c01f806,
+	0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000,
+	0x1c01f000, 0x0010166c, 0x0010167f, 0x00101693,
+	0x00101695, 0x001016bc, 0x001016be, 0x001016c0,
+	0x4803c856, 0x4a035042, 0x00000000, 0x42000000,
+	0x00000002, 0x0401fa1b, 0x42000000, 0x00000002,
+	0x0401f9ad, 0x0401fab2, 0x4803c856, 0x4a035040,
+	0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+	0x001016c1, 0x0201f000, 0x0010606e, 0x497b5045,
+	0x4a035050, 0x00000036, 0x4a03504f, 0x0000002a,
+	0x4803c856, 0x4a035042, 0x00000001, 0x42000000,
+	0x00000002, 0x0401f998, 0x4803c856, 0x4a035040,
+	0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+	0x001016c1, 0x0201f000, 0x0010606e, 0x0201f800,
+	0x001005d8, 0x4a035050, 0x00000036, 0x4803c856,
+	0x4a035042, 0x00000003, 0x42000800, 0x00000000,
+	0x0401faa3, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000090, 0x04000009, 0x82040580, 0x00000010,
+	0x04000009, 0x82040580, 0x00000000, 0x04000008,
+	0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+	0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+	0x00000002, 0x0401f970, 0x497b5046, 0x4803c856,
+	0x4a035040, 0x00000006, 0x42000800, 0x0000001e,
+	0x42001000, 0x001016c1, 0x0201f000, 0x0010606e,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+	0x1c01f000, 0x4c000000, 0x4c040000, 0x4c080000,
+	0x4c380000, 0x59a80042, 0x82000c80, 0x00000007,
+	0x02021800, 0x001005d8, 0x0c01f806, 0x5c007000,
+	0x5c001000, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x001016d7, 0x001016f6, 0x0010174a, 0x00101761,
+	0x00101778, 0x00101781, 0x00101783, 0x0401f9fc,
+	0x0402001b, 0x59a81048, 0x42000800, 0x00000000,
+	0x0401fa63, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000090, 0x04000009, 0x82040580, 0x00000010,
+	0x04000008, 0x82040580, 0x00000000, 0x04000007,
+	0x0201f800, 0x001005d8, 0x84081540, 0x0401f004,
+	0x84081542, 0x0401f002, 0x84081544, 0x480b5048,
+	0x4a035040, 0x00000001, 0x0401f003, 0x0401f8cb,
+	0x0401ff82, 0x1c01f000, 0x0401f88f, 0x04000052,
+	0x0401f9db, 0x0402002a, 0x42000800, 0x00000000,
+	0x0401fa43, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000000, 0x04000044, 0x82040580, 0x00000010,
+	0x04000006, 0x82040580, 0x00000090, 0x04000009,
+	0x0201f800, 0x001005d8, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000036,
+	0x42000800, 0x00000000, 0x0401fa2d, 0x82040d00,
+	0x00000090, 0x82040580, 0x00000010, 0x04000006,
+	0x82040580, 0x00000090, 0x04000006, 0x02020800,
+	0x001005d8, 0x59a80048, 0x84000542, 0x0401f003,
+	0x59a80048, 0x84000540, 0x48035048, 0x59a80045,
+	0x80000000, 0x48035045, 0x82000580, 0x00000005,
+	0x04000003, 0x0401f861, 0x0401f01e, 0x497b5045,
+	0x59c40801, 0x82040d00, 0x00018000, 0x82040580,
+	0x00000000, 0x04000009, 0x82040580, 0x00008000,
+	0x04000009, 0x82040580, 0x00010000, 0x04000008,
+	0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+	0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+	0x00000002, 0x0401f94b, 0x4a035042, 0x00000002,
+	0x0401f004, 0x4a035040, 0x00000003, 0x0401f002,
+	0x0401ff42, 0x1c01f000, 0x0401f83b, 0x04000015,
+	0x59a8004f, 0x80000040, 0x4803504f, 0x0401f984,
+	0x04020005, 0x4a035040, 0x00000003, 0x497b5041,
+	0x0401f00c, 0x59a8004f, 0x80000540, 0x04020003,
+	0x0401f89e, 0x0401f002, 0x0401f84b, 0x0401f82f,
+	0x497b5045, 0x4a035042, 0x00000001, 0x0401ff2b,
+	0x1c01f000, 0x0401f824, 0x04000015, 0x0401f970,
+	0x0402000f, 0x59a80046, 0x80000000, 0x48035046,
+	0x82000580, 0x00000007, 0x0402000c, 0x4a035052,
+	0x0000000a, 0x497b5049, 0x59a80048, 0x8400055e,
+	0x48035048, 0x4803c857, 0x0401f005, 0x0401f817,
+	0x4a035042, 0x00000004, 0x0401ff3d, 0x1c01f000,
+	0x0401f80d, 0x04000007, 0x0401f959, 0x04020003,
+	0x0401ff1b, 0x0401f003, 0x0401f80c, 0x0401ff34,
+	0x1c01f000, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x001005d8, 0x59a80050, 0x80000040, 0x48035050,
+	0x0400088d, 0x1c01f000, 0x4c040000, 0x42000800,
+	0x00000000, 0x0401f9b2, 0x82040d00, 0x00000090,
+	0x82040580, 0x00000090, 0x04000009, 0x82040580,
+	0x00000010, 0x04000009, 0x82040580, 0x00000000,
+	0x04000009, 0x0201f800, 0x001005d8, 0x42000000,
+	0x00000002, 0x0401f005, 0x42000000, 0x00000001,
+	0x0401f002, 0x41780000, 0x0401f8ea, 0x5c000800,
+	0x1c01f000, 0x4c040000, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000009,
+	0x82040580, 0x00008000, 0x04000009, 0x82040580,
+	0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f866,
+	0x5c000800, 0x1c01f000, 0x4c040000, 0x59a80045,
+	0x80000000, 0x48035045, 0x82000580, 0x00000005,
+	0x04020018, 0x497b5045, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000009,
+	0x82040580, 0x00008000, 0x04000009, 0x82040580,
+	0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f846,
+	0x42000800, 0x00000000, 0x0401f961, 0x82040d00,
+	0x00000090, 0x82040580, 0x00000090, 0x04000009,
+	0x82040580, 0x00000010, 0x04000009, 0x82040580,
+	0x00000000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f899,
+	0x5c000800, 0x1c01f000, 0x4c200000, 0x59a80048,
+	0x82000500, 0x00007fff, 0x02000800, 0x001005d8,
+	0x59a84047, 0x80204102, 0x02001800, 0x001005d8,
+	0x48235047, 0x80204500, 0x040007fa, 0x8c000504,
+	0x04020007, 0x8c000502, 0x04020008, 0x8c000500,
+	0x04020008, 0x0201f800, 0x001005d8, 0x42000000,
+	0x00000002, 0x0401f005, 0x41780000, 0x0401f003,
+	0x42000000, 0x00000001, 0x0401f80f, 0x5c004000,
+	0x1c01f000, 0x04011000, 0x4a03c840, 0x0010b440,
+	0x4a03c842, 0x00000009, 0x40000000, 0x040117ff,
+	0x4a035047, 0x00000004, 0x4a03503e, 0x00000000,
+	0x1c01f000, 0x59a80858, 0x82040d80, 0x01391077,
+	0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+	0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+	0x4c000000, 0x0401f9b1, 0x5c000000, 0x800001c0,
+	0x04000040, 0x82000d80, 0x00000001, 0x0402001d,
+	0x42000800, 0x000000a0, 0x0401f909, 0x82040540,
+	0x00000004, 0x42000800, 0x000000a0, 0x0401f909,
+	0x42000800, 0x000000c0, 0x0401f901, 0x82040540,
+	0x00000020, 0x42000800, 0x000000c0, 0x0401f901,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00000000, 0x48038801, 0x59a80054, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8f6, 0x0401f03c,
+	0x82000d80, 0x00000002, 0x02020800, 0x001005d8,
+	0x42000800, 0x000000a0, 0x0401f8e9, 0x82040500,
+	0xfffffffb, 0x42000800, 0x000000a0, 0x0401f8e9,
+	0x42000800, 0x000000c0, 0x0401f8e1, 0x82040500,
+	0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8e1,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00010000, 0x48038801, 0x59a80056, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8d6, 0x0401f01c,
+	0x42000800, 0x000000a0, 0x0401f8cd, 0x82040540,
+	0x00000004, 0x42000800, 0x000000a0, 0x0401f8cd,
+	0x42000800, 0x000000c0, 0x0401f8c5, 0x82040500,
+	0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8c5,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00008000, 0x48038801, 0x59a80055, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8ba, 0x0401f163,
+	0x4803c857, 0x59a80858, 0x82040d80, 0x01391077,
+	0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+	0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+	0x4c000000, 0x0401f94d, 0x5c000000, 0x800001c0,
+	0x04000026, 0x82000d80, 0x00000001, 0x04020010,
+	0x59a8006c, 0x80000540, 0x04000004, 0x42001000,
+	0x00000000, 0x0401fa0a, 0x42000800, 0x00000000,
+	0x0401f897, 0x82040540, 0x00000090, 0x42000800,
+	0x00000000, 0x0401f897, 0x0401f024, 0x82000d80,
+	0x00000002, 0x02020800, 0x001005d8, 0x59a8006c,
+	0x80000540, 0x04000004, 0x42001000, 0x00010000,
+	0x0401f9f7, 0x42000800, 0x00000000, 0x0401f884,
+	0x82040500, 0xffffff6f, 0x42000800, 0x00000000,
+	0x0401f884, 0x0401f011, 0x59a8006c, 0x80000540,
+	0x04000004, 0x42001000, 0x00008000, 0x0401f9e8,
+	0x42000800, 0x00000000, 0x0401f875, 0x82040500,
+	0xffffff6f, 0x82000540, 0x00000010, 0x42000800,
+	0x00000000, 0x0401f873, 0x0401f124, 0x4c580000,
+	0x4200b000, 0x00000014, 0x8058b040, 0x04000043,
+	0x59c4000d, 0x8c000520, 0x040207fc, 0x0401f85c,
+	0x59c4000d, 0x8c000520, 0x040207f8, 0x59c40808,
+	0x84040d50, 0x48078808, 0x4200b000, 0x000000c8,
+	0x8058b040, 0x040207ff, 0x4200b000, 0x00000014,
+	0x8058b040, 0x04000031, 0x59c4000d, 0x8c000520,
+	0x0402002e, 0x42000800, 0x00001000, 0x50040800,
+	0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+	0x040007f4, 0x0401f842, 0x59c4000d, 0x8c000520,
+	0x04020022, 0x42000800, 0x00001000, 0x50040800,
+	0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+	0x040007e8, 0x4200b000, 0x0000000a, 0x8058b040,
+	0x04000003, 0x0401f832, 0x0401f7fd, 0x4200b000,
+	0x00000064, 0x59c4000d, 0x8c00051e, 0x0400000f,
+	0x8058b040, 0x040207fc, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020004,
+	0x59c40808, 0x84040d10, 0x48078808, 0x80000580,
+	0x4803c857, 0x0401f00c, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020004,
+	0x59c40808, 0x84040d10, 0x48078808, 0x82000540,
+	0x00000001, 0x5c00b000, 0x1c01f000, 0x42000800,
+	0x000000a0, 0x0401f816, 0x82040500, 0xfffffffe,
+	0x42000800, 0x000000a0, 0x0401f816, 0x42000800,
+	0x00000000, 0x0401f80e, 0x82040500, 0xfffffffe,
+	0x42000800, 0x00000000, 0x0401f00e, 0x40000000,
+	0x40000000, 0x40000000, 0x40000000, 0x40000000,
+	0x1c01f000, 0x480b8805, 0x1c01f000, 0x4807880e,
+	0x59c4080f, 0x82040d00, 0x000000ff, 0x1c01f000,
+	0x900001c0, 0x80040d40, 0x84040d40, 0x4807880e,
+	0x1c01f000, 0x82000d80, 0x00200000, 0x04000009,
+	0x82000d80, 0x02000000, 0x04000006, 0x82000d80,
+	0x01000000, 0x04000006, 0x59c408a3, 0x0401f006,
+	0x59c408a3, 0x84040d30, 0x0401f003, 0x59c408a3,
+	0x84040d32, 0x80040540, 0x480388a3, 0x480788a3,
+	0x1c01f000, 0x59c400a3, 0x84000556, 0x480388a3,
+	0x84000516, 0x480388a3, 0x1c01f000, 0x485fc857,
+	0x4863c857, 0x4c640000, 0x4d3c0000, 0x4d400000,
+	0x0201f800, 0x00106ede, 0x4863500a, 0x0201f800,
+	0x0010ab33, 0x0402006c, 0x82600d00, 0x0000ff00,
+	0x800409c0, 0x0400000c, 0x4200c800, 0x00000001,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80041110,
+	0x80081580, 0x04000021, 0x82041580, 0x0000ff00,
+	0x0400000a, 0x59c410a3, 0x82081500, 0x00008000,
+	0x04000009, 0x59c410a7, 0x82081500, 0x0000ff00,
+	0x82081580, 0x0000ff00, 0x4200c800, 0x00000000,
+	0x04000012, 0x59a80005, 0x8c000502, 0x04020008,
+	0x8c000500, 0x0402000d, 0x599c1017, 0x8c08151a,
+	0x0400003e, 0x84000542, 0x48035005, 0x4200c800,
+	0x00000002, 0x42028000, 0x00000004, 0x42027800,
+	0x00000008, 0x0401f008, 0x59a80805, 0x84040d40,
+	0x48075005, 0x42028000, 0x00000004, 0x42027800,
+	0x00000400, 0x59a80006, 0x8c000502, 0x04020006,
+	0x59a80805, 0x8c040d0a, 0x04020033, 0x84040d4a,
+	0x48075005, 0x42000000, 0x0010b812, 0x0201f800,
+	0x0010aa47, 0x59a8180a, 0x42001000, 0x00008013,
+	0x0201f800, 0x00103a3e, 0x0201f800, 0x00103b25,
+	0x04000015, 0x4d400000, 0x82600500, 0x000000ff,
+	0x42028800, 0x0000ffff, 0x40643000, 0x42028000,
+	0x0000000e, 0x0201f800, 0x0010a446, 0x42000800,
+	0x00000001, 0x42001000, 0x00000100, 0x0201f800,
+	0x0010618b, 0x5c028000, 0x599c0817, 0x8c040d0a,
+	0x04020011, 0x493fc857, 0x4943c857, 0x0201f800,
+	0x00101fe5, 0x0401f00c, 0x0201f800, 0x00103b25,
+	0x04000009, 0x42028000, 0x0000000f, 0x42028800,
+	0x0000ffff, 0x42003000, 0x00000000, 0x0201f800,
+	0x0010a449, 0x497b8880, 0x5c028000, 0x5c027800,
+	0x5c00c800, 0x1c01f000, 0x42000800, 0x000000a0,
+	0x0401ff5f, 0x82040540, 0x00000002, 0x42000800,
+	0x000000a0, 0x0401f75f, 0x42000800, 0x00000000,
+	0x0401ff57, 0x82040540, 0x00000002, 0x42000800,
+	0x00000000, 0x0401f757, 0x42000800, 0x000000a0,
+	0x0401ff4f, 0x82040500, 0xfffffffd, 0x42000800,
+	0x000000a0, 0x0401f74f, 0x42000800, 0x00000000,
+	0x0401ff47, 0x82040500, 0xfffffffd, 0x42000800,
+	0x00000000, 0x0401f747, 0x59c408a8, 0x0401ff38,
+	0x0401ff37, 0x59c400a8, 0x80040d80, 0x040207fb,
+	0x1c01f000, 0x4803c856, 0x4a038807, 0x00000001,
+	0x497b8807, 0x59c40005, 0x48038805, 0x497b506c,
+	0x497b506d, 0x41785800, 0x42006000, 0x00000001,
+	0x42006800, 0x00000003, 0x0401f824, 0x0401f82f,
+	0x40400000, 0x4803c857, 0x82408580, 0x00000000,
+	0x0402001d, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401f818, 0x0401f823,
+	0x40400000, 0x4803c857, 0x82408580, 0x00000800,
+	0x04020011, 0x42005800, 0x00000001, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401f80b,
+	0x0401f816, 0x40400000, 0x4803c857, 0x82408580,
+	0x0000ffff, 0x04020004, 0x4a03506c, 0x00000001,
+	0x4803c856, 0x1c01f000, 0x41785000, 0x0401f812,
+	0x0401f838, 0x40347000, 0x40340800, 0x0401f03d,
+	0x42005000, 0x00000001, 0x0401f80b, 0x0401f831,
+	0x40340800, 0x0401f037, 0x42005000, 0x00000002,
+	0x0401f805, 0x0401f81d, 0x0401f835, 0x40048000,
+	0x1c01f000, 0x0401f808, 0x0401f814, 0x40280800,
+	0x0401f826, 0x402c0800, 0x0401f827, 0x40300800,
+	0x0401f025, 0x42000800, 0x0000ffff, 0x42001000,
+	0x00000001, 0x0401f829, 0x42001000, 0x00000010,
+	0x0401f826, 0x42000800, 0x0000ffff, 0x42001000,
+	0x00000010, 0x0401f021, 0x41780800, 0x42001000,
+	0x00000002, 0x0401f01d, 0x0401f92e, 0x4a03d000,
+	0x00050004, 0x0401f92b, 0x4a03d000, 0x00050005,
+	0x0401f928, 0x4a03d000, 0x00050004, 0x42000800,
+	0x00000001, 0x42001000, 0x00000001, 0x0401f00f,
+	0x42000800, 0x00000002, 0x42001000, 0x00000002,
+	0x0401f00a, 0x42001000, 0x00000005, 0x0401f007,
+	0x42001000, 0x00000010, 0x0401f004, 0x42001000,
+	0x00000010, 0x0401f01b, 0x0401f912, 0x82082c00,
+	0x0010ab38, 0x50142800, 0x82081500, 0xffffffff,
+	0x04000013, 0x0401f90b, 0x80081040, 0x80142902,
+	0x40040000, 0x80140500, 0x04000007, 0x4a03d000,
+	0x00070006, 0x0401f903, 0x4a03d000, 0x00070007,
+	0x0401f006, 0x4a03d000, 0x00070004, 0x0401f8fd,
+	0x4a03d000, 0x00070005, 0x0401f7ec, 0x1c01f000,
+	0x41780800, 0x82082c00, 0x0010ab38, 0x50142800,
+	0x82081500, 0xffffffff, 0x04000010, 0x0401f8f1,
+	0x4a03d000, 0x00050001, 0x0401f8ee, 0x59e81800,
+	0x80081040, 0x80142902, 0x8c0c1d06, 0x04000004,
+	0x40140000, 0x80040d40, 0x0401f8e6, 0x4a03d000,
+	0x00070000, 0x0401f7ef, 0x1c01f000, 0x480bc857,
+	0x480b506d, 0x59c40001, 0x82000500, 0xffffefff,
+	0x48038801, 0x41781800, 0x0401f8c4, 0x41785800,
+	0x42006000, 0x0000001e, 0x42006800, 0x00000004,
+	0x0401ff7a, 0x42006800, 0x0000003c, 0x0401ff7d,
+	0x41785800, 0x42006000, 0x0000001e, 0x42006800,
+	0x00000004, 0x0401ff71, 0x41786800, 0x0401ff75,
+	0x41785800, 0x42006000, 0x0000001e, 0x41786800,
+	0x0401ff6a, 0x42006800, 0x00000002, 0x0401ff6d,
+	0x42006800, 0x00000001, 0x0401ff64, 0x42006800,
+	0x000000f5, 0x0401ff67, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000004, 0x0401ff5b,
+	0x42006800, 0x00000020, 0x0401ff5e, 0x59a8106d,
+	0x0401f865, 0x42001800, 0x000200f5, 0x0401f897,
+	0x59a8106d, 0x0401f879, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000004, 0x0401ff4b,
+	0x41786800, 0x0401ff4f, 0x59c40001, 0x82000540,
+	0x00001000, 0x48038801, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000015, 0x0401ff3f,
+	0x0401ff4a, 0x40400000, 0x82000540, 0x00000002,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000015, 0x0401ff34, 0x5c000000,
+	0x40006800, 0x0401ff37, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000015, 0x0401ff2b,
+	0x0401ff36, 0x40400000, 0x82000500, 0x0000fffd,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000015, 0x0401ff20, 0x5c000000,
+	0x40006800, 0x0401ff23, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401ff17,
+	0x0401ff22, 0x40400000, 0x82000540, 0x00000040,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401ff0c, 0x5c000000,
+	0x40006800, 0x0401ff0f, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401ff03,
+	0x0401ff0e, 0x40400000, 0x82000500, 0x0000ffbf,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401fef8, 0x5c000000,
+	0x40006800, 0x0401fefb, 0x4a038886, 0x00002020,
+	0x0401f04c, 0x480bc857, 0x82080580, 0x00010000,
+	0x04020007, 0x82040d40, 0x00010000, 0x42001800,
+	0x00000001, 0x0401f82d, 0x0401f00f, 0x82080580,
+	0x00008000, 0x04000007, 0x82040d40, 0x00000000,
+	0x42001800, 0x00900001, 0x0401f824, 0x0401f006,
+	0x82040d40, 0x00008000, 0x42001800, 0x00100001,
+	0x0401f81e, 0x1c01f000, 0x480bc857, 0x82080580,
+	0x00010000, 0x04020008, 0x42001800, 0x000000a1,
+	0x0401f816, 0x42001800, 0x000000c1, 0x0401f813,
+	0x0401f011, 0x82080580, 0x00008000, 0x04000008,
+	0x42001800, 0x000400a1, 0x0401f80c, 0x42001800,
+	0x002000c1, 0x0401f809, 0x0401f007, 0x42001800,
+	0x000400a1, 0x0401f805, 0x42001800, 0x000000c1,
+	0x0401f802, 0x1c01f000, 0x480fc857, 0x41785800,
+	0x42006000, 0x0000001e, 0x41786800, 0x0401feb7,
+	0x400c6800, 0x80346960, 0x0401feba, 0x42006800,
+	0x00000001, 0x0401feb1, 0x400c6800, 0x0401feb5,
+	0x42006800, 0x00000003, 0x0401feac, 0x0401feb7,
+	0x40400000, 0x8c000504, 0x040207fc, 0x1c01f000,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x1c01f000, 0x00020103, 0x00101bd5, 0x00101bdb,
+	0x00101be1, 0x00101be9, 0x00101bef, 0x00101bf7,
+	0x00101bff, 0x00101c09, 0x00101c0f, 0x00101c17,
+	0x00101c1f, 0x00101c29, 0x00101c31, 0x00101c3b,
+	0x00101c45, 0x000200f8, 0x00101c51, 0x00101c59,
+	0x00101c61, 0x00101c6b, 0x00101c73, 0x00101c7d,
+	0x00101c87, 0x00101c93, 0x00101c9b, 0x00101ca5,
+	0x00101caf, 0x00101cbb, 0x00101cc5, 0x00101cd1,
+	0x00101cdd, 0x000200fd, 0x00101ceb, 0x00101cf3,
+	0x00101cfb, 0x00101d05, 0x00101d0d, 0x00101d17,
+	0x00101d21, 0x00101d2d, 0x00101d35, 0x00101d3f,
+	0x00101d49, 0x00101d55, 0x00101d5f, 0x00101d6b,
+	0x00101d77, 0x00101d85, 0x00101d8d, 0x00101d97,
+	0x00101da1, 0x00101dad, 0x00101db7, 0x00101dc3,
+	0x00101dcf, 0x00101ddd, 0x00101de7, 0x00101df3,
+	0x00101dff, 0x00101e0d, 0x00101e19, 0x00101e27,
+	0x00101e35, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c5c0000, 0x4c600000, 0x4178b800,
+	0x0201f800, 0x001048ec, 0x040200fd, 0x59a8c026,
+	0x0201f800, 0x0010513b, 0x04000003, 0x8c60c506,
+	0x0400000e, 0x8c60c500, 0x04020004, 0x8c60c50e,
+	0x040008f6, 0x0401f0f2, 0x0401fab4, 0x040200f0,
+	0x0201f800, 0x0010513b, 0x04020004, 0x4a03501c,
+	0x0000ffff, 0x0401f0ea, 0x8c60c504, 0x04000004,
+	0x4a03501c, 0x0000ffff, 0x0401f0e5, 0x59a8c010,
+	0x8260c500, 0x000000ff, 0x59a81013, 0x8c081500,
+	0x0400005d, 0x8c081502, 0x0402005b, 0x59a8b81c,
+	0x825c0d80, 0x0000ffff, 0x04020003, 0x4200b800,
+	0x00000001, 0x805c1104, 0x82086400, 0x0010be21,
+	0x50300800, 0x825c0500, 0x00000003, 0x0c01f001,
+	0x00101e81, 0x00101e7c, 0x00101e80, 0x00101e7e,
+	0x80040910, 0x0401f004, 0x80040930, 0x0401f002,
+	0x80040920, 0x82040500, 0x000000ff, 0x82000d80,
+	0x000000ff, 0x0400000f, 0x4c000000, 0x82000400,
+	0x0010210e, 0x50000800, 0x80040910, 0x82040580,
+	0x00000080, 0x5c000000, 0x04000030, 0x80600d80,
+	0x0400002e, 0x80000540, 0x0400002c, 0x0401f00b,
+	0x59a81005, 0x82081500, 0x00000003, 0x0402002b,
+	0x59a81013, 0x84081542, 0x480b5013, 0x4a03501c,
+	0x0000ffff, 0x0401f028, 0x4c000000, 0x59a80005,
+	0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+	0x00104c6d, 0x5c000000, 0x0402001c, 0x417a8800,
+	0x0201f800, 0x00105c9a, 0x04020016, 0x0201f800,
+	0x001045e5, 0x04000006, 0x0201f800, 0x00104c62,
+	0x0401f8b1, 0x0400000f, 0x0401f00c, 0x599c0019,
+	0x8c00050e, 0x04020009, 0x0201f800, 0x001045a6,
+	0x04020008, 0x0201f800, 0x00104c62, 0x0401f9e1,
+	0x0401f8be, 0x04000003, 0x805cb800, 0x0401f7b2,
+	0x485f501c, 0x0401f086, 0x4a03501c, 0x0000ffff,
+	0x0401f083, 0x42003000, 0x0000007e, 0x59a8001c,
+	0x82001580, 0x0000ffff, 0x04020005, 0x80000d80,
+	0x4018b000, 0x4803c856, 0x0401f009, 0x8018b480,
+	0x04001004, 0x40000800, 0x4803c856, 0x0401f004,
+	0x4a03501c, 0x0000ffff, 0x0401f071, 0x4c040000,
+	0x4c580000, 0x82040400, 0x0010210e, 0x50000000,
+	0x82000500, 0x000000ff, 0x80604580, 0x0400005c,
+	0x0201f800, 0x00105c9b, 0x04020061, 0x59a80005,
+	0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+	0x00104c6d, 0x5c00b000, 0x5c000800, 0x040207d7,
+	0x4c040000, 0x4c580000, 0x845cbd00, 0x0201f800,
+	0x00020245, 0x04000008, 0x599c0019, 0x8c00050e,
+	0x04020047, 0x0201f800, 0x001045ab, 0x0402004c,
+	0x0401f002, 0x845cbd40, 0x0201f800, 0x00104c62,
+	0x0201f800, 0x001049e7, 0x04020007, 0x59a80005,
+	0x8c000502, 0x04000033, 0x59340200, 0x8c00050e,
+	0x04020030, 0x59a81013, 0x8c081502, 0x04000025,
+	0x0201f800, 0x00104a09, 0x04000031, 0x8c5cbd00,
+	0x04020004, 0x0201f800, 0x001045ff, 0x0401f02c,
+	0x0401f9cd, 0x0400002a, 0x42026000, 0x0010bde9,
+	0x49366009, 0x497a6008, 0x417a7800, 0x0401f925,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00103b25, 0x0400001d, 0x41782800,
+	0x42003000, 0x00000008, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010a446, 0x5c028800, 0x5c028000, 0x0401f010,
+	0x4937c857, 0x599c0019, 0x8c00050e, 0x0402000c,
+	0x0401f96c, 0x0401f849, 0x04000011, 0x0401f008,
+	0x59a80013, 0x8c000500, 0x04000003, 0x0401f9a6,
+	0x04000003, 0x0401f828, 0x04000009, 0x5c00b000,
+	0x5c000800, 0x80040800, 0x8058b040, 0x04020798,
+	0x4a03501c, 0x0000ffff, 0x0401f005, 0x4937c857,
+	0x5c00b000, 0x5c000800, 0x4807501c, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x4803c856, 0x4a03501c,
+	0x00000001, 0x42028800, 0x000007fe, 0x42003000,
+	0x00fffffe, 0x0201f800, 0x001045a6, 0x0402000c,
+	0x0401f948, 0x0401f825, 0x04000009, 0x59a80026,
+	0x8400054e, 0x48035026, 0x0201f800, 0x0010930f,
+	0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+	0x0401f7fe, 0x4937c857, 0x0201f800, 0x00107942,
+	0x04000015, 0x49366009, 0x4a026406, 0x00000001,
+	0x417a7800, 0x0201f800, 0x00104567, 0x59a8001b,
+	0x80000000, 0x4803501b, 0x42027000, 0x00000004,
+	0x599c0019, 0x8c00050e, 0x04000003, 0x42027000,
+	0x00000000, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4937c857, 0x0201f800,
+	0x00107942, 0x0400001c, 0x49366009, 0x59340403,
+	0x82000580, 0x000007fe, 0x04000005, 0x4d3c0000,
+	0x417a7800, 0x0401f8b7, 0x5c027800, 0x4a026406,
+	0x00000001, 0x417a7800, 0x0201f800, 0x00104567,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x59a8001b, 0x80000000, 0x4803501b, 0x42027000,
+	0x00000002, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x42028800,
+	0x000007fc, 0x42003000, 0x00fffffc, 0x0201f800,
+	0x001045a6, 0x04020005, 0x0401f805, 0x04000003,
+	0x4a035027, 0x0000ffff, 0x1c01f000, 0x4937c857,
+	0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+	0x4a026406, 0x00000001, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x59a80028, 0x80000000, 0x48035028,
+	0x42027000, 0x00000002, 0x0201f800, 0x000207a1,
+	0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+	0x492fc857, 0x4c5c0000, 0x4008b800, 0x42028800,
+	0x000007fd, 0x42003000, 0x00fffffd, 0x0201f800,
+	0x001045a6, 0x0402001a, 0x0201f800, 0x0002075a,
+	0x04000017, 0x49366009, 0x5934000a, 0x84000544,
+	0x4802680a, 0x812e59c0, 0x04000005, 0x592c0404,
+	0x8c00051e, 0x04000002, 0x48ee6021, 0x492e6008,
+	0x4a026406, 0x00000001, 0x485e601c, 0x42027000,
+	0x00000022, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x5c00b800, 0x1c01f000, 0x80000580,
+	0x0401f7fd, 0x5c000000, 0x4c000000, 0x4803c857,
+	0x4943c857, 0x493fc857, 0x4d340000, 0x4d440000,
+	0x4c580000, 0x4d2c0000, 0x4c5c0000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x0201f800, 0x001069f1,
+	0x0201f800, 0x00106aac, 0x0201f800, 0x00106737,
+	0x0201f800, 0x0010848a, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x4200b000, 0x000007f0, 0x417a8800,
+	0x0201f800, 0x00020245, 0x0402001f, 0x8d3e7d14,
+	0x04000005, 0x59340212, 0x82000500, 0x0000ff00,
+	0x04000019, 0x8d3e7d06, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04020014, 0x8d3e7d18, 0x0400000f,
+	0x5934b80f, 0x805cb9c0, 0x04000009, 0x49425a06,
+	0x592cb800, 0x0201f800, 0x000202ce, 0x805cb9c0,
+	0x040207fb, 0x497a680f, 0x497a6810, 0x4a026c00,
+	0x00000707, 0x0401f004, 0x4937c857, 0x0201f800,
+	0x001042b4, 0x81468800, 0x8058b040, 0x040207dd,
+	0x8d3e7d02, 0x04000011, 0x497b501d, 0x42028800,
+	0x000007f0, 0x4200b000, 0x00000010, 0x0201f800,
+	0x00020245, 0x04020006, 0x4937c857, 0x4a026c00,
+	0x00000707, 0x0201f800, 0x001042b4, 0x81468800,
+	0x8058b040, 0x040207f6, 0x5c00b800, 0x5c025800,
+	0x5c00b000, 0x5c028800, 0x5c026800, 0x1c01f000,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857,
+	0x493fc857, 0x4d340000, 0x4d400000, 0x4d440000,
+	0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x59326809, 0x813669c0, 0x04000020,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x00106a50, 0x0201f800, 0x00106ab4, 0x0201f800,
+	0x001067fd, 0x0201f800, 0x0010a2ff, 0x4937c857,
+	0x8d3e7d18, 0x04000010, 0x5934b80f, 0x805cb9c0,
+	0x0400000a, 0x405e5800, 0x49425a06, 0x592cb800,
+	0x0201f800, 0x000202ce, 0x805cb9c0, 0x040207fa,
+	0x497a680f, 0x497a6810, 0x4a026c00, 0x00000707,
+	0x0401f003, 0x0201f800, 0x001042b4, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x5c00b800, 0x5c025800,
+	0x5c028800, 0x5c028000, 0x5c026800, 0x1c01f000,
+	0x4933c857, 0x59a80026, 0x8c000508, 0x04020012,
+	0x59305009, 0x482bc857, 0x836c0580, 0x00000002,
+	0x0402000d, 0x0401f813, 0x0402000b, 0x58280403,
+	0x82000580, 0x000007fc, 0x04000008, 0x59a8001b,
+	0x80000040, 0x4803c857, 0x02001800, 0x001005d8,
+	0x4803501b, 0x1c01f000, 0x59a80028, 0x80000040,
+	0x4803c857, 0x040017fc, 0x48035028, 0x1c01f000,
+	0x59300008, 0x800001c0, 0x04020009, 0x59300403,
+	0x82000580, 0x00000001, 0x04020004, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x4937c857, 0x59340200, 0x84000502, 0x48026a00,
+	0x1c01f000, 0x4933c857, 0x493fc857, 0x4947c857,
+	0x4d3c0000, 0x4d400000, 0x4d340000, 0x4d440000,
+	0x4c580000, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x813e79c0, 0x04020004, 0x4200b000, 0x00000001,
+	0x0401f004, 0x4200b000, 0x000007f0, 0x417a8800,
+	0x41440000, 0x81ac0400, 0x50000000, 0x80026d40,
+	0x04000019, 0x42027800, 0x00000001, 0x0201f800,
+	0x001048f6, 0x42028000, 0x00000029, 0x417a7800,
+	0x0201f800, 0x00106a50, 0x0201f800, 0x00106ab4,
+	0x0201f800, 0x001067fd, 0x0201f800, 0x001049e7,
+	0x04020005, 0x4937c857, 0x4a026c00, 0x00000404,
+	0x0401f003, 0x0201f800, 0x00104a14, 0x0201f800,
+	0x0010a2ff, 0x81468800, 0x8058b040, 0x040207e1,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x5c00b000,
+	0x5c028800, 0x5c026800, 0x5c028000, 0x5c027800,
+	0x1c01f000, 0x4937c857, 0x4947c857, 0x4c5c0000,
+	0x4c600000, 0x4c640000, 0x59a80013, 0x8c000500,
+	0x0400001f, 0x599c0017, 0x8c00050a, 0x0402001c,
+	0x5934ba02, 0x825cbd00, 0x000000ff, 0x485fc857,
+	0x4178c000, 0x4178c800, 0x82600400, 0x0010be21,
+	0x50002000, 0x8060c1c0, 0x04000008, 0x82100500,
+	0x000000ff, 0x82002d80, 0x000000ff, 0x0400000c,
+	0x805c0580, 0x0400000d, 0x80102110, 0x8064c800,
+	0x82640580, 0x00000004, 0x040207f5, 0x8060c000,
+	0x82600580, 0x00000020, 0x040207eb, 0x4813c857,
+	0x82000540, 0x00000001, 0x5c00c800, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x59a80026, 0x4803c857,
+	0x8c000512, 0x1c01f000, 0x00007eef, 0x00007de8,
+	0x00007ce4, 0x000080e2, 0x00007be1, 0x000080e0,
+	0x000080dc, 0x000080da, 0x00007ad9, 0x000080d6,
+	0x000080d5, 0x000080d4, 0x000080d3, 0x000080d2,
+	0x000080d1, 0x000079ce, 0x000078cd, 0x000080cc,
+	0x000080cb, 0x000080ca, 0x000080c9, 0x000080c7,
+	0x000080c6, 0x000077c5, 0x000076c3, 0x000080bc,
+	0x000080ba, 0x000075b9, 0x000080b6, 0x000074b5,
+	0x000073b4, 0x000072b3, 0x000080b2, 0x000080b1,
+	0x000080ae, 0x000071ad, 0x000080ac, 0x000070ab,
+	0x00006faa, 0x00006ea9, 0x000080a7, 0x00006da6,
+	0x00006ca5, 0x00006ba3, 0x00006a9f, 0x0000699e,
+	0x0000689d, 0x0000809b, 0x00008098, 0x00006797,
+	0x00006690, 0x0000658f, 0x00006488, 0x00006384,
+	0x00006282, 0x00008081, 0x00008080, 0x0000617c,
+	0x0000607a, 0x00008079, 0x00005f76, 0x00008075,
+	0x00008074, 0x00008073, 0x00008072, 0x00008071,
+	0x0000806e, 0x00005e6d, 0x0000806c, 0x00005d6b,
+	0x00005c6a, 0x00005b69, 0x00008067, 0x00005a66,
+	0x00005965, 0x00005863, 0x0000575c, 0x0000565a,
+	0x00005559, 0x00008056, 0x00008055, 0x00005454,
+	0x00005353, 0x00005252, 0x00005151, 0x0000504e,
+	0x00004f4d, 0x0000804c, 0x0000804b, 0x00004e4a,
+	0x00004d49, 0x00008047, 0x00004c46, 0x00008045,
+	0x00008043, 0x0000803c, 0x0000803a, 0x00008039,
+	0x00008036, 0x00004b35, 0x00008034, 0x00004a33,
+	0x00004932, 0x00004831, 0x0000802e, 0x0000472d,
+	0x0000462c, 0x0000452b, 0x0000442a, 0x00004329,
+	0x00004227, 0x00008026, 0x00008025, 0x00004123,
+	0x0000401f, 0x00003f1e, 0x00003e1d, 0x00003d1b,
+	0x00003c18, 0x00008017, 0x00008010, 0x00003b0f,
+	0x00003a08, 0x00008004, 0x00003902, 0x00008001,
+	0x00008000, 0x00008000, 0x00003800, 0x00003700,
+	0x00003600, 0x00008000, 0x00003500, 0x00008000,
+	0x00008000, 0x00008000, 0x00003400, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00003300, 0x00003200, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00003100, 0x00003000, 0x00008000,
+	0x00008000, 0x00002f00, 0x00008000, 0x00002e00,
+	0x00002d00, 0x00002c00, 0x00008000, 0x00008000,
+	0x00008000, 0x00002b00, 0x00008000, 0x00002a00,
+	0x00002900, 0x00002800, 0x00008000, 0x00002700,
+	0x00002600, 0x00002500, 0x00002400, 0x00002300,
+	0x00002200, 0x00008000, 0x00008000, 0x00002100,
+	0x00002000, 0x00001f00, 0x00001e00, 0x00001d00,
+	0x00001c00, 0x00008000, 0x00008000, 0x00001b00,
+	0x00001a00, 0x00008000, 0x00001900, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00001800, 0x00008000, 0x00001700,
+	0x00001600, 0x00001500, 0x00008000, 0x00001400,
+	0x00001300, 0x00001200, 0x00001100, 0x00001000,
+	0x00000f00, 0x00008000, 0x00008000, 0x00000e00,
+	0x00000d00, 0x00000c00, 0x00000b00, 0x00000a00,
+	0x00000900, 0x00008000, 0x00008000, 0x00000800,
+	0x00000700, 0x00008000, 0x00000600, 0x00008000,
+	0x00008000, 0x00008000, 0x00000500, 0x00000400,
+	0x00000300, 0x00008000, 0x00000200, 0x00008000,
+	0x00008000, 0x00008000, 0x00000100, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00000000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x0201f800, 0x001007d3,
+	0x02000800, 0x001005d8, 0x492f4016, 0x1c01f000,
+	0x83a0ac00, 0x00000006, 0x83a00580, 0x0010b4a4,
+	0x0400000c, 0x492fc857, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x832ca400, 0x00000006, 0x4200b000,
+	0x0000000d, 0x0201f800, 0x0010ab17, 0x0401f00f,
+	0x4200b000, 0x00000010, 0x83e0a400, 0x00000020,
+	0x50500000, 0x8050a000, 0x50500800, 0x900409c0,
+	0x80040540, 0x4400a800, 0x8050a000, 0x8054a800,
+	0x8058b040, 0x040207f7, 0x1c01f000, 0x59a00206,
+	0x4803c857, 0x82000c80, 0x0000007f, 0x040210c9,
+	0x59a80821, 0x0c01f001, 0x001022c0, 0x00102300,
+	0x00102300, 0x0010234b, 0x0010236d, 0x00102300,
+	0x001022c0, 0x0010238f, 0x001023a0, 0x00102300,
+	0x00102300, 0x001023ad, 0x001023c5, 0x001023dd,
+	0x00102300, 0x001023e7, 0x001023f4, 0x00102300,
+	0x0010241d, 0x00102300, 0x0010247a, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102491, 0x00102300,
+	0x001024e3, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x001024e8, 0x00102560, 0x00102300,
+	0x00102567, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102569, 0x001025ea,
+	0x00102727, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102736, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102753, 0x001027a6,
+	0x00102802, 0x00102816, 0x00102835, 0x00102a70,
+	0x00102dff, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102fb4, 0x00103028, 0x00102300,
+	0x00102300, 0x00103094, 0x00102300, 0x00103126,
+	0x001031d8, 0x00102300, 0x00102300, 0x0010320f,
+	0x0010326b, 0x00102300, 0x001032bd, 0x00103419,
+	0x00102300, 0x0010342d, 0x001034b8, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00103522,
+	0x00103526, 0x00103545, 0x00102300, 0x001035e7,
+	0x00102300, 0x00102300, 0x00103615, 0x00102300,
+	0x00103643, 0x00102300, 0x00102300, 0x001036aa,
+	0x001037b7, 0x00103814, 0x00102300, 0x0010387a,
+	0x00102300, 0x00102300, 0x001038d3, 0x00103936,
+	0x00102300, 0x48efc857, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x04000045,
+	0x48efc857, 0x4a034206, 0x00004000, 0x0201f800,
+	0x00103a15, 0x83a00580, 0x0010b4a4, 0x0400000d,
+	0x58ee580a, 0x4d2c0000, 0x0401f856, 0x41a25800,
+	0x0201f800, 0x001007f4, 0x40ee5800, 0x0201f800,
+	0x001007f4, 0x5c025800, 0x0201f000, 0x000202da,
+	0x04026007, 0x59a0001d, 0x84000542, 0x4803401d,
+	0x4a01d809, 0x001022d4, 0x1c01f000, 0x59a00206,
+	0x82000d80, 0x00004000, 0x04000006, 0x900001c0,
+	0x82000540, 0x00000011, 0x4803c011, 0x0401f005,
+	0x900001c0, 0x82000540, 0x00000010, 0x4803c011,
+	0x0401f845, 0x59e00017, 0x8c000508, 0x0402000c,
+	0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+	0x40ee5800, 0x0201f800, 0x001007f4, 0x59a0001d,
+	0x84000504, 0x4803401d, 0x1c01f000, 0x4a03c017,
+	0x00000000, 0x59a00206, 0x82000d80, 0x00004000,
+	0x040007f0, 0x4a03c017, 0x00000001, 0x0401f7ed,
+	0x4803c856, 0x4a034206, 0x00004001, 0x0401f7c0,
+	0x4803c856, 0x4a034206, 0x00004002, 0x0401f7bc,
+	0x4803c856, 0x4a034206, 0x00004003, 0x0401f7b8,
+	0x4803c856, 0x4a034206, 0x00004005, 0x0401f7b4,
+	0x4803c856, 0x4a034206, 0x00004006, 0x0401f7b0,
+	0x4803c856, 0x4a034206, 0x0000400b, 0x0401f7ac,
+	0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a8,
+	0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a4,
+	0x48efc857, 0x58eca80a, 0x8054a9c0, 0x02000800,
+	0x001005d8, 0x83a0a400, 0x00000006, 0x8254ac00,
+	0x00000006, 0x4200b000, 0x0000000d, 0x0201f000,
+	0x0010ab17, 0x59a00206, 0x4803c857, 0x59a00406,
+	0x4803c857, 0x59a00207, 0x4803c857, 0x59a00407,
+	0x4803c857, 0x59a00208, 0x4803c857, 0x59a00408,
+	0x4803c857, 0x59a00209, 0x4803c857, 0x83e0ac00,
+	0x00000020, 0x83a0a400, 0x00000006, 0x4200b000,
+	0x00000010, 0x50500000, 0x4400a800, 0x8054a800,
+	0x900001c0, 0x4400a800, 0x8054a800, 0x8050a000,
+	0x8058b040, 0x040207f8, 0x1c01f000, 0x59a00406,
+	0x800000c2, 0x59a00a07, 0x900409c0, 0x80040540,
+	0x84000540, 0x59a00c07, 0x8c040d00, 0x04000018,
+	0x59a80805, 0x8c040d0e, 0x040207ba, 0x42000800,
+	0x00000064, 0x80040840, 0x04000007, 0x4a030000,
+	0x00000001, 0x40000000, 0x59801000, 0x8c081500,
+	0x040007f9, 0x04000005, 0x48030004, 0x4a030000,
+	0x00000000, 0x0401f75b, 0x4a030000, 0x00000000,
+	0x4a034406, 0x00000004, 0x040007a2, 0x4803880e,
+	0x0401f754, 0x59a00406, 0x800000c2, 0x59a00c07,
+	0x8c040d00, 0x0400001a, 0x59a80805, 0x8c040d0e,
+	0x0402079c, 0x42000800, 0x00000064, 0x80040840,
+	0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+	0x59801000, 0x8c081500, 0x040007f9, 0x04000007,
+	0x48030004, 0x59800805, 0x48074406, 0x4a030000,
+	0x00000000, 0x0401f73b, 0x4a030000, 0x00000000,
+	0x4a034406, 0x00000004, 0x04000782, 0x4803880e,
+	0x59c4080f, 0x48074406, 0x0401f732, 0x59a01c06,
+	0x59a00207, 0x900c19c0, 0x800c1d40, 0x580c0803,
+	0x80000580, 0x500c1000, 0x80080400, 0x800c1800,
+	0x80040840, 0x040207fc, 0x48034406, 0x900001c0,
+	0x48034207, 0x800001c0, 0x04000722, 0x0401f769,
+	0x4a034406, 0x00000004, 0x4a034207, 0x00000000,
+	0x4a034407, 0x00000010, 0x59a8000d, 0x48034208,
+	0x900001c0, 0x48034408, 0x4a034209, 0x00000002,
+	0x0401f714, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+	0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+	0x04001754, 0x59a02406, 0x900001c0, 0x80100540,
+	0x59a8280d, 0x80142480, 0x0400174e, 0x0201f000,
+	0x00103a25, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+	0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+	0x0400173c, 0x59a02406, 0x900001c0, 0x80100540,
+	0x59a8280d, 0x80142480, 0x04001736, 0x0201f000,
+	0x00103a28, 0x59a00a0a, 0x59a00406, 0x900409c0,
+	0x80040d40, 0x59a01407, 0x59a00207, 0x900811c0,
+	0x80081540, 0x44080800, 0x0401f6da, 0x59a00a0a,
+	0x59a00406, 0x900409c0, 0x80040d40, 0x50040000,
+	0x82000d00, 0x0000ffff, 0x48074207, 0x82000d00,
+	0xffff0000, 0x900409c0, 0x48074407, 0x0401f6cd,
+	0x59a00406, 0x8c000500, 0x04000020, 0x59a01207,
+	0x59a01c07, 0x59a02208, 0x480b5054, 0x480f5055,
+	0x48135056, 0x59c40801, 0x82040d00, 0x00018000,
+	0x82040580, 0x00000000, 0x04000009, 0x82040580,
+	0x00008000, 0x04000008, 0x82040580, 0x00010000,
+	0x04000007, 0x0201f800, 0x001005d8, 0x40080000,
+	0x0401f004, 0x400c0000, 0x0401f002, 0x40100000,
+	0x80000110, 0x42000800, 0x000000e0, 0x0201f800,
+	0x00101944, 0x0401f007, 0x59a81054, 0x59a81855,
+	0x59a82056, 0x480b4207, 0x480f4407, 0x48134208,
+	0x0401f6a4, 0x4d2c0000, 0x4d340000, 0x4d300000,
+	0x4d440000, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x04000006, 0x5c028800, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x0401f6e7, 0x59a04407, 0x59a00207,
+	0x900001c0, 0x80204540, 0x0401f81e, 0x04000009,
+	0x4a034208, 0x00000001, 0x4a034406, 0x0000ffff,
+	0x4a034207, 0x0000ffff, 0x497b4407, 0x0401f00b,
+	0x0401f822, 0x0400000e, 0x4a034208, 0x00000002,
+	0x59300402, 0x48034406, 0x59300202, 0x48034207,
+	0x59300206, 0x48034407, 0x5c028800, 0x5c026000,
+	0x5c026800, 0x5c025800, 0x0401f67a, 0x5c028800,
+	0x5c026000, 0x5c026800, 0x5c025800, 0x0401f6c1,
+	0x4937c856, 0x4823c856, 0x4d2c0000, 0x5934000f,
+	0x80025d40, 0x04000007, 0x592c0005, 0x80200580,
+	0x592c0000, 0x040207fb, 0x82000540, 0x00000001,
+	0x5c025800, 0x1c01f000, 0x4823c857, 0x4d2c0000,
+	0x4d300000, 0x42026000, 0x0010d1c0, 0x59300406,
+	0x82000d80, 0x00000003, 0x04000004, 0x82000d80,
+	0x00000006, 0x04020007, 0x59325808, 0x812e59c0,
+	0x04000004, 0x592c0005, 0x80200580, 0x0400000a,
+	0x83326400, 0x00000024, 0x41580000, 0x81300480,
+	0x040017ef, 0x80000580, 0x5c026000, 0x5c025800,
+	0x1c01f000, 0x82000540, 0x00000001, 0x5c026000,
+	0x5c025800, 0x1c01f000, 0x83a00580, 0x0010b4a4,
+	0x04020684, 0x59a80005, 0x8c00050e, 0x04020003,
+	0x4a030000, 0x00000000, 0x4a034206, 0x00004000,
+	0x4a03c011, 0x40000010, 0x0401fea7, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+	0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+	0x0401f000, 0x800409c0, 0x04000004, 0x4a034406,
+	0x00000001, 0x0401f677, 0x836c0580, 0x00000003,
+	0x04020010, 0x59a80010, 0x497b4406, 0x0201f800,
+	0x0010513b, 0x0400000f, 0x82000d00, 0x00ffff00,
+	0x0402000c, 0x82000c00, 0x0010210e, 0x50040800,
+	0x80040910, 0x82041580, 0x00000080, 0x04020004,
+	0x4a034406, 0x00000007, 0x0401f662, 0x48074406,
+	0x82000d00, 0x0000ffff, 0x48074207, 0x80000120,
+	0x48034407, 0x59a80026, 0x82001500, 0x00000100,
+	0x480b4409, 0x8c000502, 0x0400001f, 0x8c000506,
+	0x04000009, 0x82000d00, 0x0000000a, 0x82040d80,
+	0x0000000a, 0x04020004, 0x4a034209, 0x00000001,
+	0x0401f022, 0x8c00050a, 0x04000009, 0x82000d00,
+	0x00000022, 0x82040d80, 0x00000022, 0x04020004,
+	0x4a034209, 0x00000003, 0x0401f018, 0x8c000508,
+	0x04000009, 0x82000d00, 0x00000012, 0x82040d80,
+	0x00000012, 0x04020004, 0x4a034209, 0x00000002,
+	0x0401f00e, 0x0201f800, 0x0010513b, 0x04020004,
+	0x4a034209, 0x00000004, 0x0401f5e6, 0x8c000506,
+	0x04000004, 0x4a034406, 0x00000005, 0x0401f62d,
+	0x4a034209, 0x00000000, 0x0401f5de, 0x59a80037,
+	0x48034407, 0x59a80038, 0x48034209, 0x0401f5d9,
+	0x42007800, 0x0010b8ec, 0x59a00406, 0x4803c857,
+	0x82000c80, 0x00000006, 0x04021622, 0x0c01f001,
+	0x001024f6, 0x001024f7, 0x00102505, 0x00102518,
+	0x00102539, 0x001024f6, 0x0401f61a, 0x836c0580,
+	0x00000000, 0x04000613, 0x59a00a07, 0x59a00407,
+	0x900001c0, 0x80040d40, 0x4807c857, 0x59a00a08,
+	0x59a00408, 0x900001c0, 0x80040d40, 0x4807c857,
+	0x0401f056, 0x836c0580, 0x00000000, 0x04000605,
+	0x59a00407, 0x59a01207, 0x900001c0, 0x80081540,
+	0x59a00408, 0x59a01a08, 0x900001c0, 0x800c1d40,
+	0x42000000, 0x0010c1bf, 0x480fc857, 0x480bc857,
+	0x42000800, 0x00001000, 0x0201f000, 0x00103a28,
+	0x59a00a07, 0x59a00407, 0x900001c0, 0x80041d40,
+	0x820c0c80, 0x0010ab4a, 0x040215f2, 0x820c0c80,
+	0x00100000, 0x040015ef, 0x480fc857, 0x823c7c00,
+	0x00000009, 0x503c0800, 0x800409c0, 0x04000006,
+	0x823c0580, 0x0000000d, 0x040005e6, 0x803c7800,
+	0x0401f7f9, 0x59e41001, 0x82080d00, 0xfffeffcf,
+	0x4807c801, 0x440c7800, 0x46001800, 0x0201f800,
+	0x800c1800, 0x46001800, 0x001005cb, 0x480bc801,
+	0x0401f022, 0x59a01a07, 0x59a00407, 0x900001c0,
+	0x800c1d40, 0x480c7801, 0x59a02208, 0x59a00408,
+	0x900001c0, 0x80102540, 0x48107802, 0x59a00209,
+	0x80000040, 0x040015cb, 0x48007806, 0x80000000,
+	0x48007805, 0x42000800, 0x00004000, 0x40001000,
+	0x0201f800, 0x00106681, 0x80000540, 0x04000003,
+	0x49787801, 0x0401f5bf, 0x40040000, 0x800c1c00,
+	0x040015bc, 0x480c7803, 0x48107804, 0x49787808,
+	0x59a00409, 0x48007807, 0x59e40001, 0x4803c857,
+	0x82000540, 0x00040000, 0x4803c801, 0x0401f561,
+	0x59a80006, 0x48034406, 0x59a80007, 0x48034207,
+	0x59a80008, 0x48034407, 0x0401f55a, 0x0201f800,
+	0x001005d8, 0x4803c856, 0x4a03c013, 0x03800300,
+	0x4a03c014, 0x03800380, 0x59a00c06, 0x82040580,
+	0x000000a0, 0x04000004, 0x82040580, 0x000000a2,
+	0x0402002b, 0x59a0140a, 0x82080480, 0x00000100,
+	0x04021027, 0x59a0020b, 0x8c000500, 0x0402002e,
+	0x59a00a0a, 0x800409c0, 0x04000021, 0x82040480,
+	0x00000041, 0x0402101e, 0x82040c00, 0x00000003,
+	0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x0201f800,
+	0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+	0x4a03c014, 0x03800000, 0x0401f576, 0x832e5c00,
+	0x00000004, 0x412c0000, 0x0201f800, 0x00103a25,
+	0x4a01d809, 0x001025a2, 0x1c01f000, 0x4a03c014,
+	0x03800000, 0x0401f56f, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x0400055c, 0x59a00c06, 0x59a0140a, 0x59a0020b,
+	0x8c000500, 0x04020031, 0x832e5c00, 0x00000004,
+	0x41783800, 0x59a04a0a, 0x401c0000, 0x812c0400,
+	0x50004000, 0x82201d00, 0x000000ff, 0x4c040000,
+	0x0401f8ac, 0x5c000800, 0x0400002d, 0x80244840,
+	0x04000028, 0x80081000, 0x82201d00, 0x0000ff00,
+	0x800c1910, 0x4c040000, 0x0401f8a2, 0x5c000800,
+	0x04000023, 0x80244840, 0x0400001e, 0x80081000,
+	0x82201d00, 0x00ff0000, 0x800c1920, 0x4c040000,
+	0x0401f898, 0x5c000800, 0x04000019, 0x80244840,
+	0x04000014, 0x80081000, 0x82201d00, 0xff000000,
+	0x800c1930, 0x4c040000, 0x0401f88e, 0x5c000800,
+	0x0400000f, 0x80244840, 0x0400000a, 0x80081000,
+	0x801c3800, 0x0401f7d5, 0x59a0020a, 0x82000500,
+	0x000000ff, 0x40001800, 0x0401f882, 0x04000004,
+	0x4a03c014, 0x03800000, 0x0401f4da, 0x4a03c014,
+	0x03800000, 0x0401f523, 0x4803c856, 0x4a03c013,
+	0x03800300, 0x4a03c014, 0x03800380, 0x59a00c06,
+	0x82040580, 0x000000a0, 0x04000004, 0x82040580,
+	0x000000a2, 0x0402006c, 0x59a0140a, 0x82080480,
+	0x00000100, 0x04021068, 0x59a0020b, 0x8c000500,
+	0x0402005c, 0x59a01a0a, 0x800c19c0, 0x04000062,
+	0x820c0480, 0x00000041, 0x0402105f, 0x0201f800,
+	0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+	0x4a03c014, 0x03800000, 0x0401f502, 0x832e5c00,
+	0x00000004, 0x41783800, 0x59a04a0a, 0x401c0000,
+	0x812c0400, 0x40004000, 0x4c040000, 0x4c080000,
+	0x0401f874, 0x5c001000, 0x5c000800, 0x04000047,
+	0x44144000, 0x80244840, 0x0400002b, 0x80081000,
+	0x4c040000, 0x4c080000, 0x0401f86a, 0x5c001000,
+	0x5c000800, 0x0400003d, 0x50200000, 0x801428d0,
+	0x80140540, 0x44004000, 0x80244840, 0x0400001e,
+	0x80081000, 0x4c040000, 0x4c080000, 0x0401f85d,
+	0x5c001000, 0x5c000800, 0x04000030, 0x50200000,
+	0x801428e0, 0x80140540, 0x44004000, 0x80244840,
+	0x04000011, 0x80081000, 0x4c040000, 0x4c080000,
+	0x0401f850, 0x5c001000, 0x5c000800, 0x04000023,
+	0x50200000, 0x801428f0, 0x80140540, 0x44004000,
+	0x80244840, 0x04000004, 0x80081000, 0x801c3800,
+	0x0401f7cb, 0x59a00a0a, 0x82040c00, 0x00000003,
+	0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x4a03c014,
+	0x03800000, 0x412c0000, 0x0201f000, 0x00103a28,
+	0x0401f830, 0x04000005, 0x48174406, 0x4a03c014,
+	0x03800000, 0x0401f463, 0x4a03c014, 0x03800000,
+	0x0401f4ac, 0x4a03c014, 0x03800000, 0x0401f4ad,
+	0x0401f836, 0x04000010, 0x0401f862, 0x0402000f,
+	0x40080800, 0x0401f85f, 0x0402000c, 0x400c0800,
+	0x0401f85c, 0x04020009, 0x0401f84b, 0x42000000,
+	0x00030d40, 0x80000040, 0x040207ff, 0x82000540,
+	0x00000001, 0x1c01f000, 0x0401f843, 0x80000580,
+	0x0401f7fd, 0x0401f821, 0x0400000a, 0x82040d40,
+	0x00000001, 0x0401f84b, 0x04020007, 0x0401f87e,
+	0x0401f898, 0x0401f838, 0x82000540, 0x00000001,
+	0x1c01f000, 0x0401f834, 0x80000580, 0x0401f7fd,
+	0x40041800, 0x0401f811, 0x0400000c, 0x0401f83d,
+	0x0402000b, 0x40080800, 0x0401f83a, 0x04020008,
+	0x400c0800, 0x0401ffe8, 0x04000004, 0x0401f826,
+	0x82000540, 0x00000001, 0x1c01f000, 0x0401f822,
+	0x80000580, 0x0401f7fd, 0x4c040000, 0x42000800,
+	0x00000064, 0x4a03c013, 0x03800300, 0x80040840,
+	0x04000016, 0x59e00013, 0x82000500, 0x00000300,
+	0x82000580, 0x00000300, 0x040207f7, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+	0x01000000, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x02000000, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x5c000800,
+	0x1c01f000, 0x4a03c013, 0x01000000, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+	0x02000200, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x01000100, 0x1c01f000,
+	0x42002000, 0x00000008, 0x82040500, 0x00000080,
+	0x800000c2, 0x82000540, 0x01000000, 0x4803c013,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x4a03c013, 0x02000200, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000000,
+	0x800408c2, 0x80102040, 0x040207ec, 0x4a03c013,
+	0x01000100, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x02000200, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x59e00013,
+	0x82000500, 0x00000100, 0x4a03c013, 0x02000000,
+	0x4c040000, 0x42000800, 0x00000064, 0x59e00013,
+	0x82000500, 0x00000100, 0x80040840, 0x04000003,
+	0x80000540, 0x040207fa, 0x80000540, 0x5c000800,
+	0x1c01f000, 0x4a03c013, 0x01000100, 0x42001000,
+	0x00000008, 0x80000d80, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x59e00013, 0x82000500, 0x00000100, 0x80000110,
+	0x800408c2, 0x80040d40, 0x4a03c013, 0x02000000,
+	0x80081040, 0x040207ed, 0x40042800, 0x1c01f000,
+	0x4a03c013, 0x01000100, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x4a03c013, 0x02000000, 0x1c01f000, 0x59a00407,
+	0x59a80837, 0x48035037, 0x48074407, 0x59a00a09,
+	0x82040480, 0x00000014, 0x04021003, 0x42000800,
+	0x000007d0, 0x59a80038, 0x48075038, 0x48034209,
+	0x0201f000, 0x001022c0, 0x836c0580, 0x00000000,
+	0x0400000e, 0x59a80006, 0x59a00c06, 0x80041580,
+	0x82081500, 0x00000040, 0x02000000, 0x001022c0,
+	0x80080580, 0x48035006, 0x0201f800, 0x00100699,
+	0x0201f000, 0x001022c0, 0x59a00406, 0x59a80806,
+	0x48035006, 0x80040d80, 0x8c040d0c, 0x02020800,
+	0x00100699, 0x59a00207, 0x48035007, 0x59a00407,
+	0x48035008, 0x0201f000, 0x001022c0, 0x800409c0,
+	0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x0010513b, 0x04020005,
+	0x4a034406, 0x00000016, 0x0201f000, 0x0010230c,
+	0x836c0580, 0x00000003, 0x04000005, 0x4a034406,
+	0x00000007, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x82040500, 0xffffff00, 0x02020000, 0x00102310,
+	0x82041580, 0x000000ff, 0x04020007, 0x59a80010,
+	0x82000500, 0x000000ff, 0x82001540, 0x0000ff00,
+	0x0401f011, 0x82040400, 0x0010210e, 0x50000000,
+	0x80000110, 0x82000580, 0x00000080, 0x02000000,
+	0x00102310, 0x59a80010, 0x82000500, 0x000000ff,
+	0x80041580, 0x02000000, 0x00102310, 0x840409c0,
+	0x80041540, 0x0201f800, 0x0002075a, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x48ee6021, 0x480a621c, 0x4a02641c, 0x0000bc09,
+	0x4a026406, 0x00000001, 0x0201f800, 0x00103a00,
+	0x04020007, 0x0201f800, 0x0002077d, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x497a5a04,
+	0x497a5805, 0x4a025c04, 0x00008000, 0x4a01d809,
+	0x001027f9, 0x492e6008, 0x42027000, 0x00000032,
+	0x0201f000, 0x000207a1, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x0201f800, 0x0010513b, 0x04020005, 0x4a034406,
+	0x00000016, 0x0201f000, 0x0010230c, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00c06, 0x82040500,
+	0xffffff00, 0x02020000, 0x00102310, 0x82041580,
+	0x000000ff, 0x04020007, 0x59a80010, 0x82000500,
+	0x000000ff, 0x82001540, 0x0000ff00, 0x0401f011,
+	0x82040400, 0x0010210e, 0x50000000, 0x80000110,
+	0x82000580, 0x00000080, 0x02000000, 0x00102310,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80041580,
+	0x02000000, 0x00102310, 0x840409c0, 0x80041540,
+	0x0201f800, 0x0002075a, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x48ee6021,
+	0x480a621c, 0x4a02641c, 0x0000bc05, 0x4a026406,
+	0x00000001, 0x0201f800, 0x00103a00, 0x04020007,
+	0x0201f800, 0x0002077d, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x497a5a04, 0x497a5805,
+	0x4a025c04, 0x00008000, 0x4a01d809, 0x001027f9,
+	0x492e6008, 0x42027000, 0x00000032, 0x0201f000,
+	0x000207a1, 0x592c0005, 0x82000580, 0x01000000,
+	0x02020000, 0x001022c0, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x497b4406, 0x497b4207,
+	0x0201f800, 0x00103b25, 0x04000008, 0x59a80066,
+	0x59a8086a, 0x80040480, 0x59a80867, 0x48074406,
+	0x80041480, 0x480b4207, 0x49674407, 0x59a8000e,
+	0x48034209, 0x495f4409, 0x59a80020, 0x4803420b,
+	0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a00406, 0x8c000500, 0x0402000f, 0x59a80069,
+	0x81640480, 0x04001008, 0x59a8000b, 0x81500580,
+	0x04000009, 0x59a8006a, 0x59a81066, 0x80080580,
+	0x04000005, 0x4a034406, 0x00000018, 0x0201f000,
+	0x0010230c, 0x82000540, 0x00000001, 0x0201f800,
+	0x001015fe, 0x0201f800, 0x00103c80, 0x0201f000,
+	0x001022c0, 0x4803c856, 0x800409c0, 0x02020000,
+	0x00102314, 0x59a00406, 0x8c00051e, 0x04000008,
+	0x4803c856, 0x59a0020b, 0x82000480, 0x00000800,
+	0x04001015, 0x0201f000, 0x00102310, 0x4803c856,
+	0x59a0020b, 0x599c0a01, 0x80040480, 0x04021003,
+	0x0201f000, 0x00102310, 0x59a8000e, 0x81640580,
+	0x04000009, 0x4a034406, 0x00000018, 0x0201f000,
+	0x0010230c, 0x4a034406, 0x00000005, 0x0201f000,
+	0x0010230c, 0x59a80026, 0x8c00050a, 0x040007fa,
+	0x59a00406, 0x8c00051e, 0x04000036, 0x0201f800,
+	0x0002075a, 0x040007f4, 0x0201f800, 0x00103a00,
+	0x040007f1, 0x497a5a04, 0x59a00406, 0x4802620a,
+	0x59a00209, 0x4802640a, 0x59a00409, 0x4802620b,
+	0x59a0020d, 0x4802620c, 0x59a0040d, 0x4802640c,
+	0x59a0020e, 0x4802620d, 0x59a0040e, 0x4802640d,
+	0x59a00210, 0x4802620e, 0x59a00410, 0x4802640e,
+	0x59a0020b, 0x82000500, 0x0000fffc, 0x80000104,
+	0x4802640b, 0x0401f9d9, 0x040007d7, 0x48ee6021,
+	0x58ee580d, 0x5930020e, 0x59301c0e, 0x900c19c0,
+	0x800c1d40, 0x5930020c, 0x5930140c, 0x900811c0,
+	0x80081540, 0x592c0a05, 0x832c0400, 0x00000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+	0x4a034000, 0x00000001, 0x49334001, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x0201f800, 0x00100ae0,
+	0x0401f86d, 0x497b5057, 0x4201d000, 0x00002710,
+	0x0201f800, 0x001060c6, 0x59c40880, 0x4c040000,
+	0x59c408a3, 0x4c040000, 0x497b4002, 0x0401f876,
+	0x0401f893, 0x4a03a005, 0x10000000, 0x0401f8b4,
+	0x0401f901, 0x04000048, 0x59c80001, 0x800001c0,
+	0x040007fc, 0x59c80018, 0x82000500, 0xf0000000,
+	0x59c00808, 0x82040d00, 0x0fffffff, 0x80040540,
+	0x48038008, 0x0201f800, 0x00100ec1, 0x59c00006,
+	0x4a038006, 0x10000000, 0x59c00009, 0x82000d00,
+	0x00e00000, 0x04020024, 0x4a03900d, 0x00000000,
+	0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+	0x32000000, 0x0402001c, 0x4a03900d, 0x00000001,
+	0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+	0xe1000000, 0x04020014, 0x4a03900d, 0x00000000,
+	0x59c80020, 0x82000500, 0x00ffffff, 0x4a03900d,
+	0x00000000, 0x59c80821, 0x82040d00, 0x00ffffff,
+	0x80040580, 0x04020008, 0x59a80010, 0x80040580,
+	0x04020005, 0x59c40005, 0x82000500, 0x000000f0,
+	0x04000006, 0x4803c856, 0x0401f8d7, 0x4a035057,
+	0x00000001, 0x0401f002, 0x0401f8e1, 0x42000000,
+	0x00000064, 0x80000040, 0x02000800, 0x001005d8,
+	0x59c00807, 0x82040d00, 0x0000000c, 0x040007fa,
+	0x0401f003, 0x4a035057, 0x00000001, 0x0401f8da,
+	0x0201f800, 0x00106f36, 0x0401f818, 0x4201d000,
+	0x000186a0, 0x0201f800, 0x001060c6, 0x5c000800,
+	0x480788a3, 0x5c000800, 0x48078880, 0x59a80057,
+	0x800001c0, 0x02000000, 0x001022c0, 0x0201f000,
+	0x00102318, 0x599c0201, 0x48035059, 0x41780800,
+	0x42001000, 0x00003b10, 0x0201f800, 0x001066a0,
+	0x480b505a, 0x1c01f000, 0x0201f800, 0x00106c4b,
+	0x59b800ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000003, 0x04020003, 0x4a0370e8, 0x00000001,
+	0x1c01f000, 0x42038000, 0x00007700, 0x4a038006,
+	0x30000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+	0x59c00006, 0x59a00209, 0x59a00c09, 0x900409c0,
+	0x80040d40, 0x48078001, 0x59a0020e, 0x59a00c0e,
+	0x900409c0, 0x80040d40, 0x48078000, 0x59a0020b,
+	0x82000500, 0x0000fffc, 0x48038002, 0x48038003,
+	0x48038005, 0x497b9009, 0x59e00003, 0x82000540,
+	0x00008060, 0x4803c003, 0x1c01f000, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+	0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+	0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+	0x040207fe, 0x59d00005, 0x59a00210, 0x59a00c10,
+	0x900409c0, 0x80040d40, 0x4807a001, 0x59a0020d,
+	0x59a00c0d, 0x900409c0, 0x80040d40, 0x4807a000,
+	0x59a0020b, 0x82000500, 0x0000fffc, 0x4803a003,
+	0x4803a002, 0x4803a008, 0x1c01f000, 0x59a00002,
+	0x4803c857, 0x800001c0, 0x0402004a, 0x59a8005a,
+	0x48038880, 0x59c400a3, 0x82000540, 0x00002008,
+	0x8400053a, 0x480388a3, 0x59c40008, 0x8400054e,
+	0x82000500, 0xffffffe1, 0x48038808, 0x59c80040,
+	0x84000534, 0x48039040, 0x0401f902, 0x04020013,
+	0x59a80010, 0x800000d0, 0x82000540, 0x00000011,
+	0x48039120, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x82000540, 0x32000000, 0x48039121, 0x4a039123,
+	0xe1290008, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x48039122, 0x0401f016, 0x59a80010, 0x82000500,
+	0x000000ff, 0x900009c0, 0x840001c0, 0x80040540,
+	0x82000540, 0x00000000, 0x48039120, 0x59a80010,
+	0x82000500, 0x000000ff, 0x82000540, 0x01000000,
+	0x48039121, 0x4a039123, 0x08210008, 0x59a80010,
+	0x82000500, 0x000000ff, 0x48039122, 0x497b9124,
+	0x59a80c5b, 0x80040800, 0x4807545b, 0x900409c0,
+	0x82040540, 0x0000aaaa, 0x48039125, 0x497b9126,
+	0x497b9127, 0x0401f8cf, 0x04020004, 0x4a039100,
+	0x0000e980, 0x0401f003, 0x4a039100, 0x0000e9a0,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0402500d,
+	0x4203e000, 0x80000000, 0x40e81000, 0x41780800,
+	0x42000000, 0x00000064, 0x0201f800, 0x001066a0,
+	0x59940024, 0x80080400, 0x48032824, 0x80000580,
+	0x1c01f000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x417a3000, 0x0201f800, 0x001070d8,
+	0x0201f800, 0x00106dc3, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x1c01f000, 0x59c80007,
+	0x8c000500, 0x04000003, 0x4a03900d, 0x00000030,
+	0x1c01f000, 0x4a038805, 0x00020000, 0x42000800,
+	0x0000003c, 0x0201f800, 0x00101345, 0x4a038891,
+	0x0000ffff, 0x59c80035, 0x48039035, 0x4a03900d,
+	0x00000040, 0x42038000, 0x00007700, 0x0201f800,
+	0x00100ec1, 0x42038000, 0x00007720, 0x0201f800,
+	0x00100ec1, 0x4a03a005, 0x20000000, 0x4a03a005,
+	0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+	0x1c01f000, 0x4d300000, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x5c026000, 0x02000000, 0x00102304, 0x4d300000,
+	0x59a26001, 0x59a00000, 0x4000b000, 0x80000000,
+	0x48034000, 0x592c0001, 0x80000540, 0x0400001e,
+	0x40025800, 0x8058b040, 0x040207fb, 0x58ec1007,
+	0x58ec1808, 0x592c0a05, 0x4d2c0000, 0x58ec000d,
+	0x40025800, 0x592c0204, 0x5c025800, 0x82000580,
+	0x00000103, 0x04000008, 0x832c0400, 0x00000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+	0x0401f007, 0x832c0400, 0x00000006, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x001029e5, 0x5c026000,
+	0x1c01f000, 0x58ec000d, 0x40025800, 0x592c0204,
+	0x82000580, 0x00000103, 0x04020006, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x0201f000, 0x001022c0,
+	0x58ec000d, 0x40025800, 0x592c0404, 0x8400055e,
+	0x48025c04, 0x42028800, 0x000007fd, 0x42003000,
+	0x00fffffd, 0x0201f800, 0x001045a6, 0x04000003,
+	0x80000580, 0x0401f004, 0x59a26001, 0x0201f800,
+	0x0010937d, 0x5c026000, 0x02000000, 0x0010230c,
+	0x4d300000, 0x4a01d809, 0x00102a38, 0x0401f7dc,
+	0x592c0005, 0x82000580, 0x01000000, 0x02000000,
+	0x00102318, 0x4d300000, 0x59a26001, 0x5930020b,
+	0x59301c0a, 0x900001c0, 0x800c1d40, 0x5930040d,
+	0x5930120d, 0x900001c0, 0x80081540, 0x592c0a05,
+	0x832c0400, 0x00000006, 0x0201f800, 0x00103a28,
+	0x4a01d809, 0x001029e5, 0x4a034000, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x4c300000,
+	0x5930040b, 0x82000c80, 0x0000000e, 0x04001004,
+	0x4a025a05, 0x0000000e, 0x0401f003, 0x48025a05,
+	0x0401f00c, 0x800409c0, 0x0400000a, 0x4c040000,
+	0x0201f800, 0x00103a00, 0x5c000800, 0x04000003,
+	0x40040000, 0x0401f7f0, 0x80000580, 0x0401f003,
+	0x82000540, 0x00000001, 0x5c006000, 0x1c01f000,
+	0x59a00206, 0x82000580, 0x00000044, 0x1c01f000,
+	0x4807c857, 0x800409c0, 0x0400000c, 0x0201f800,
+	0x00101650, 0x04020009, 0x42000000, 0x00000002,
+	0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+	0x0201f800, 0x00101821, 0x59a00406, 0x82000500,
+	0x00000007, 0x0c01f001, 0x00102a8c, 0x00102aa1,
+	0x00102ab7, 0x00102a8a, 0x00102a8a, 0x00102a8a,
+	0x00102a8a, 0x00102a8a, 0x0201f000, 0x00102310,
+	0x42000800, 0x000000c0, 0x0201f800, 0x0010193f,
+	0x82040540, 0x00000002, 0x42000800, 0x000000c0,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000008,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x0401f00b, 0x42000800, 0x000000c0, 0x0201f800,
+	0x0010193f, 0x82040540, 0x00000001, 0x42000800,
+	0x000000c0, 0x0201f800, 0x00101944, 0x59c80040,
+	0x4c000000, 0x59a80010, 0x4c000000, 0x59c400a3,
+	0x4c000000, 0x59c40008, 0x4c000000, 0x0401f911,
+	0x04000021, 0x0201f800, 0x001005d8, 0x59a80821,
+	0x800409c0, 0x02020000, 0x00102314, 0x0201f800,
+	0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+	0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+	0x02020000, 0x00102314, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040580, 0x00000000, 0x02020000,
+	0x00102314, 0x59c80040, 0x4c000000, 0x59a80010,
+	0x4c000000, 0x59c400a3, 0x4c000000, 0x59c40008,
+	0x4c000000, 0x59c40080, 0x4c000000, 0x59a0020f,
+	0x59a0bc0f, 0x905cb9c0, 0x805cbd40, 0x41784800,
+	0x41785000, 0x41785800, 0x41789000, 0x41789800,
+	0x0401fe21, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00100ae0, 0x4178c000, 0x497b4002, 0x0401f95c,
+	0x0401f9aa, 0x59a0020c, 0x59a00c0c, 0x80040d40,
+	0x04000002, 0x0401f9fb, 0x0401f9fa, 0x0401fe68,
+	0x8060c1c0, 0x04020014, 0x0401fa98, 0x0401feb2,
+	0x0402000e, 0x0201f800, 0x001018d3, 0x04020008,
+	0x4a034406, 0x00000017, 0x0201f800, 0x0010230c,
+	0x4203e000, 0x50000000, 0x0401f000, 0x42005800,
+	0x0000aaaa, 0x0401f058, 0x59c80001, 0x800001c0,
+	0x040007ee, 0x59c80801, 0x800409c0, 0x04000006,
+	0x0401fa70, 0x40240000, 0x80280540, 0x802c0540,
+	0x0402004d, 0x59a00002, 0x82000580, 0xfeedbeef,
+	0x04000004, 0x42008800, 0x10000000, 0x0401f003,
+	0x42008800, 0x10000004, 0x0401fa19, 0x4a034002,
+	0xfeedbeef, 0x0401fa71, 0x0401fa97, 0x0401fea8,
+	0x59c40005, 0x8c000534, 0x04000004, 0x42005800,
+	0x0000bbbb, 0x0401f038, 0x0401fe83, 0x04020007,
+	0x42005800, 0x0000cccc, 0x485f420f, 0x905cb9c0,
+	0x485f440f, 0x0401f030, 0x59a0040c, 0x800001c0,
+	0x0400000e, 0x59a26000, 0x5930000d, 0x800001c0,
+	0x040207be, 0x59a26001, 0x5930080d, 0x800409c0,
+	0x040207ba, 0x804891c0, 0x040207b8, 0x804c99c0,
+	0x040207b6, 0x0401f87a, 0x805cb840, 0x04000005,
+	0x40240000, 0x80280540, 0x802c0540, 0x0402001a,
+	0x42000000, 0x00030d40, 0x80000040, 0x04020012,
+	0x59c00007, 0x82000500, 0x000501c0, 0x0402000b,
+	0x0201f800, 0x001018d3, 0x04020008, 0x4a034406,
+	0x00000017, 0x0201f800, 0x0010230c, 0x4203e000,
+	0x50000000, 0x0401f000, 0x42005800, 0x0000dddd,
+	0x0401f005, 0x59c00807, 0x82040d00, 0x0000000c,
+	0x040007ea, 0x0401fe5c, 0x59a0040c, 0x800001c0,
+	0x04000002, 0x0401f856, 0x0401fe6b, 0x40240000,
+	0x80280540, 0x802c0540, 0x04020003, 0x805cb9c0,
+	0x04020781, 0x0201f800, 0x00106f36, 0x0401fda3,
+	0x4201d000, 0x000186a0, 0x0201f800, 0x001060c6,
+	0x5c000800, 0x48078880, 0x5c000800, 0x48078808,
+	0x5c000800, 0x480788a3, 0x5c000800, 0x48075010,
+	0x5c000800, 0x48079040, 0x0201f800, 0x00100969,
+	0x59a00406, 0x82000500, 0x00000003, 0x82000580,
+	0x00000002, 0x0400002c, 0x42000800, 0x000000c0,
+	0x0201f800, 0x0010193f, 0x82040500, 0xfffffffc,
+	0x42000800, 0x000000c0, 0x0201f800, 0x00101944,
+	0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+	0x82040500, 0xfffffff7, 0x42000800, 0x00000000,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040500, 0xfffffffb,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x4a0388a7, 0x0000f7f7, 0x42006000, 0xbeffffff,
+	0x42006800, 0x80018000, 0x0201f800, 0x0010427d,
+	0x42006000, 0xfffeffff, 0x41786800, 0x0201f800,
+	0x0010427d, 0x402c0000, 0x80280540, 0x80240540,
+	0x02000000, 0x001022c0, 0x48274406, 0x482b4207,
+	0x482f4407, 0x0201f000, 0x0010231c, 0x59a26000,
+	0x813261c0, 0x0400000e, 0x59325808, 0x812e59c0,
+	0x0400000b, 0x0201f800, 0x0002077d, 0x0201f800,
+	0x001007fd, 0x59a26001, 0x59325808, 0x0201f800,
+	0x0002077d, 0x0201f800, 0x001007fd, 0x1c01f000,
+	0x42000800, 0x000000ef, 0x0201f800, 0x001015eb,
+	0x59c400a3, 0x8400055a, 0x8400053a, 0x480388a3,
+	0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+	0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101821, 0x0401f013,
+	0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f009, 0x42000000, 0x00000002,
+	0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+	0x0201f800, 0x00101821, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000004,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+	0x59c40008, 0x8400054e, 0x82000500, 0xffffffe1,
+	0x48038808, 0x4a0388a7, 0x0000f7f7, 0x42001000,
+	0x04000001, 0x0201f800, 0x0010193d, 0x42006000,
+	0xbe20bfff, 0x42006800, 0x80018000, 0x0201f800,
+	0x0010427d, 0x42006000, 0xfffeffff, 0x41786800,
+	0x0201f800, 0x0010427d, 0x4200b000, 0x00001388,
+	0x4201d000, 0x00000014, 0x4c580000, 0x0201f800,
+	0x0010608e, 0x0201f800, 0x001018d3, 0x5c00b000,
+	0x04000004, 0x8058b040, 0x040207f6, 0x0401f025,
+	0x59c40005, 0x8c000534, 0x04020007, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x0402001c, 0x42006000, 0x00020000, 0x0201f800,
+	0x00104282, 0x4201d000, 0x00000064, 0x0201f800,
+	0x0010608e, 0x42006000, 0xfeffffff, 0x42006800,
+	0x02000000, 0x0201f800, 0x0010427d, 0x42006000,
+	0xfdffffff, 0x41786800, 0x0201f800, 0x0010427d,
+	0x4a038805, 0x04000001, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000000, 0x04000003,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+	0x42038000, 0x00007700, 0x0201f800, 0x00100ec1,
+	0x59c00006, 0x59a0040c, 0x800001c0, 0x0400003f,
+	0x59a03c0c, 0x59a00209, 0x59a01c09, 0x900c19c0,
+	0x800c1d40, 0x59a0020e, 0x59a0240e, 0x901021c0,
+	0x80102540, 0x59a0020b, 0x82000500, 0x0000fffc,
+	0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+	0x0201f800, 0x0002075a, 0x02000800, 0x001005d8,
+	0x49334000, 0x0201f800, 0x001007e4, 0x4a025a04,
+	0x00000018, 0x4a025805, 0x00abcdef, 0x492e6008,
+	0x492e600b, 0x481e600d, 0x4a02600c, 0x00000004,
+	0x832c0400, 0x00000011, 0x4802600a, 0x42001000,
+	0x0000000c, 0x821c0d80, 0x00000001, 0x04000004,
+	0x801c3840, 0x0401f963, 0x0401f004, 0x41783800,
+	0x0401f960, 0x0401f011, 0x821c0c80, 0x00000005,
+	0x04001005, 0x40043800, 0x42001000, 0x0000003c,
+	0x0401f006, 0x80001580, 0x82081400, 0x0000000c,
+	0x801c3840, 0x040207fd, 0x832c0400, 0x00000005,
+	0x0401f950, 0x040207f1, 0x497b9009, 0x59e00003,
+	0x82000540, 0x00008060, 0x4803c003, 0x4a038009,
+	0x00e00000, 0x1c01f000, 0x4803c856, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+	0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+	0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+	0x040207fe, 0x59d00005, 0x59a0020c, 0x800001c0,
+	0x0400003f, 0x59a03a0c, 0x59a00210, 0x59a01c10,
+	0x900c19c0, 0x800c1d40, 0x59a0020d, 0x59a0240d,
+	0x901021c0, 0x80102540, 0x59a0120b, 0x82081500,
+	0x0000fffc, 0x59a0040b, 0x900001c0, 0x80081540,
+	0x480ba003, 0x0201f800, 0x0002075a, 0x02000800,
+	0x001005d8, 0x49334001, 0x0201f800, 0x001007e4,
+	0x4a025a04, 0x00000018, 0x4a025805, 0x00abcdef,
+	0x492e6008, 0x492e600b, 0x481e600d, 0x4a02600c,
+	0x00000004, 0x832c0400, 0x00000011, 0x4802600a,
+	0x42001000, 0x0000000c, 0x821c0d80, 0x00000001,
+	0x04000004, 0x801c3840, 0x0401f906, 0x0401f004,
+	0x41783800, 0x0401f903, 0x0401f011, 0x821c0c80,
+	0x00000005, 0x04001005, 0x40043800, 0x42001000,
+	0x0000003c, 0x0401f006, 0x80001580, 0x82081400,
+	0x0000000c, 0x801c3840, 0x040207fd, 0x832c0400,
+	0x00000005, 0x0401f8f3, 0x040207f1, 0x1c01f000,
+	0x4803c856, 0x59a0020c, 0x800001c0, 0x04000024,
+	0x824c0580, 0x00000002, 0x04000040, 0x59a26001,
+	0x5930380d, 0x801c39c0, 0x0400003c, 0x801c3840,
+	0x481e600d, 0x5932580b, 0x5930080a, 0x50042000,
+	0x58041801, 0x58041002, 0x82081500, 0xfffffffc,
+	0x5930000c, 0x80000000, 0x82000d80, 0x00000005,
+	0x04020009, 0x497a600c, 0x592e5801, 0x812e59c0,
+	0x0400001a, 0x492e600b, 0x832c0c00, 0x00000005,
+	0x0401f005, 0x4802600c, 0x5930080a, 0x82040c00,
+	0x00000003, 0x4806600a, 0x0401f010, 0x59a0120b,
+	0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0,
+	0x80081540, 0x480ba003, 0x59a0020d, 0x59a0240d,
+	0x901021c0, 0x80102540, 0x59a00210, 0x59a01c10,
+	0x900c19c0, 0x800c1d40, 0x4201d000, 0x00003a98,
+	0x0201f800, 0x001060c6, 0x480ba002, 0x59a80059,
+	0x4803a008, 0x4813a000, 0x480fa001, 0x4a03a005,
+	0x10000000, 0x02005800, 0x001005d8, 0x804c9800,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4847c857,
+	0x59a0040c, 0x800001c0, 0x04000024, 0x82480580,
+	0x00000002, 0x04000042, 0x59a26000, 0x5930380d,
+	0x801c39c0, 0x0400003e, 0x801c3840, 0x481e600d,
+	0x5932580b, 0x5930080a, 0x50042000, 0x58041801,
+	0x58041002, 0x82081500, 0xfffffffc, 0x5930000c,
+	0x80000000, 0x82000d80, 0x00000005, 0x04020009,
+	0x497a600c, 0x592e5801, 0x812e59c0, 0x0400001d,
+	0x492e600b, 0x832c0c00, 0x00000005, 0x0401f005,
+	0x4802600c, 0x5930080a, 0x82040c00, 0x00000003,
+	0x4806600a, 0x0401f013, 0x82440580, 0x10000000,
+	0x0402001f, 0x59a0020e, 0x59a0240e, 0x901021c0,
+	0x80102540, 0x59a00209, 0x59a01c09, 0x900c19c0,
+	0x800c1d40, 0x59a0020b, 0x82000500, 0x0000fffc,
+	0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+	0x48138000, 0x480f8001, 0x480b8002, 0x59c80018,
+	0x82000500, 0xf0000000, 0x59c02008, 0x82102500,
+	0x0fffffff, 0x80100540, 0x48038008, 0x48478006,
+	0x80489000, 0x8260c540, 0x00000001, 0x1c01f000,
+	0x59c00009, 0x4803c857, 0x82000d00, 0x00e00000,
+	0x0400000d, 0x485f420f, 0x905cb9c0, 0x485f440f,
+	0x8c00052e, 0x04000002, 0x80285000, 0x8c00052c,
+	0x04000002, 0x80244800, 0x8c00052a, 0x04000002,
+	0x802c5800, 0x1c01f000, 0x59a0020c, 0x800001c0,
+	0x04000024, 0x59d00806, 0x4807c857, 0x8c040d3e,
+	0x04000020, 0x4a03a005, 0x20000000, 0x4a03a005,
+	0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+	0x824c0480, 0x00000003, 0x02021800, 0x001005d8,
+	0x404c0000, 0x0c01f001, 0x00102da1, 0x00102da3,
+	0x00102da9, 0x0201f800, 0x001005d8, 0x80000040,
+	0x40009800, 0x0401ff43, 0x0400000a, 0x0401ff41,
+	0x0401f008, 0x80000040, 0x40009800, 0x59d00806,
+	0x4807c857, 0x8c040d3e, 0x040207e3, 0x0401ff39,
+	0x1c01f000, 0x59a0040c, 0x800001c0, 0x04000024,
+	0x59c00807, 0x4807c857, 0x8c040d3e, 0x04000020,
+	0x59c00807, 0x4a038006, 0x20000000, 0x82480480,
+	0x00000003, 0x02021800, 0x001005d8, 0x40480000,
+	0x0c01f001, 0x00102dc4, 0x00102dc6, 0x00102dce,
+	0x0201f800, 0x001005d8, 0x80000040, 0x40009000,
+	0x42008800, 0x10000004, 0x0401ff65, 0x0400000c,
+	0x0401ff63, 0x0401f00a, 0x80000040, 0x40009000,
+	0x59c00807, 0x4807c857, 0x8c040d3e, 0x040207e5,
+	0x42008800, 0x10000004, 0x0401ff59, 0x1c01f000,
+	0x492fc857, 0x4000a800, 0x4a03b805, 0x20000000,
+	0x59dc0006, 0x4a03b805, 0x30000000, 0x4813b800,
+	0x480fb801, 0x480bb802, 0x4857b803, 0x4a03b805,
+	0x30000002, 0x59dc0006, 0x4a03b805, 0x70000001,
+	0x59dc0006, 0x4a03b805, 0x10000000, 0x59dc0006,
+	0x8c00053e, 0x040007fe, 0x4a03b805, 0x20000000,
+	0x59dc0006, 0x59dc2000, 0x59dc1801, 0x801c39c0,
+	0x0400000a, 0x4d2c0000, 0x0201f800, 0x001007e4,
+	0x5c000800, 0x02000800, 0x001005d8, 0x4a025a04,
+	0x0000000a, 0x492c0801, 0x1c01f000, 0x42006000,
+	0x00102fb2, 0x0201f800, 0x00101345, 0x4a03902c,
+	0x00200000, 0x4200b000, 0x000001f4, 0x59c8002c,
+	0x8c00052c, 0x04000007, 0x8058b040, 0x040207fc,
+	0x42000000, 0x00004003, 0x41781000, 0x0401f196,
+	0x50301000, 0x41784800, 0x4a03902d, 0x00008000,
+	0x4200b000, 0x000001f4, 0x59c8002c, 0x8c000534,
+	0x04000007, 0x8058b040, 0x040207fc, 0x42000000,
+	0x00004003, 0x41781000, 0x0401f187, 0x0401f8f8,
+	0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+	0x040207fb, 0x0401f988, 0x41784800, 0x0401f920,
+	0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+	0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207e0, 0x59a80863, 0x800409c0, 0x04000007,
+	0x42000000, 0x00004004, 0x42001000, 0x00000002,
+	0x59a81862, 0x0401f16c, 0x42006000, 0x00102fb2,
+	0x4a035064, 0x00000004, 0x50301000, 0x41784800,
+	0x4a03902d, 0x00004000, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x8c000532, 0x04000007, 0x8058b040,
+	0x040207fc, 0x42000000, 0x00004003, 0x41781000,
+	0x0401f159, 0x0401f8ca, 0x80244800, 0x40240000,
+	0x82000580, 0x00000154, 0x040207fb, 0x0401f95a,
+	0x41784800, 0x0401f8f2, 0x80244800, 0x40240000,
+	0x82000580, 0x00000154, 0x040207fb, 0x80306000,
+	0x82300580, 0x00102fb4, 0x040207e0, 0x59a80863,
+	0x800409c0, 0x04000007, 0x42000000, 0x00004004,
+	0x42001000, 0x00000004, 0x59a81862, 0x0401f13e,
+	0x42006000, 0x00102fb2, 0x497b5064, 0x50301000,
+	0x41784800, 0x4a03902d, 0x00001000, 0x4200b000,
+	0x000001f4, 0x59c8002c, 0x8c00052e, 0x04000007,
+	0x8058b040, 0x040207fc, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f12c, 0x0401f89d, 0x80244800,
+	0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+	0x0401f92d, 0x41784800, 0x0401f8c5, 0x80244800,
+	0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+	0x80306000, 0x82300580, 0x00102fb4, 0x040207e0,
+	0x59a80863, 0x800409c0, 0x04000007, 0x42000000,
+	0x00004004, 0x42001000, 0x00000001, 0x59a81862,
+	0x0401f111, 0x42006000, 0x00102fb2, 0x50301000,
+	0x41784800, 0x4a03902d, 0x00000800, 0x0401f87c,
+	0x80244800, 0x40240000, 0x82000580, 0x00000018,
+	0x040207fb, 0x0401f90c, 0x41784800, 0x0401f8a4,
+	0x80244800, 0x40240000, 0x82000580, 0x00000018,
+	0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207eb, 0x59a80863, 0x800409c0, 0x04000007,
+	0x42000000, 0x00004004, 0x42001000, 0x00000010,
+	0x59a81862, 0x0401f0f0, 0x42006000, 0x00102fb2,
+	0x50301000, 0x41784800, 0x4a03902d, 0x00000400,
+	0x0401f85b, 0x80244800, 0x40240000, 0x82000580,
+	0x00000088, 0x040207fb, 0x0401f8eb, 0x41784800,
+	0x0401f883, 0x80244800, 0x40240000, 0x82000580,
+	0x00000088, 0x040207fb, 0x80306000, 0x82300580,
+	0x00102fb4, 0x040207eb, 0x59a80863, 0x800409c0,
+	0x04000007, 0x42000000, 0x00004004, 0x42001000,
+	0x00000008, 0x59a81862, 0x0401f0cf, 0x42006000,
+	0x00102fb2, 0x50301000, 0x41784800, 0x4a03902d,
+	0x00002000, 0x4200b000, 0x000001f4, 0x59c8002c,
+	0x8c000530, 0x04000007, 0x8058b040, 0x040207fc,
+	0x42000000, 0x00004003, 0x41781000, 0x0401f0be,
+	0x59c8002c, 0x82000500, 0xffe0ffff, 0x82080d00,
+	0x001f0000, 0x80040540, 0x4803902c, 0x0401f828,
+	0x80244800, 0x40240000, 0x82000580, 0x00000110,
+	0x040207fb, 0x0401f8b8, 0x41784800, 0x0401f850,
+	0x59c80034, 0x82080d00, 0x001f0000, 0x82000500,
+	0x001f0000, 0x80040580, 0x04000006, 0x59a80063,
+	0x80000000, 0x48035063, 0x40240000, 0x48035062,
+	0x80244800, 0x40240000, 0x82000580, 0x00000110,
+	0x040207ef, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207cd, 0x59a80863, 0x800409c0, 0x04000006,
+	0x42000000, 0x00004004, 0x42001000, 0x00000020,
+	0x59a81862, 0x0201f000, 0x001022c0, 0x59c8002c,
+	0x82000500, 0xffff0000, 0x82080d00, 0x0000ffff,
+	0x80040540, 0x4803902c, 0x40080000, 0x48039028,
+	0x48039029, 0x59a80064, 0x82000580, 0x00000004,
+	0x04000004, 0x40080000, 0x4803902a, 0x4803902b,
+	0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+	0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+	0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f06c, 0x4a03902e, 0x00000001,
+	0x4200b000, 0x000001f4, 0x59c8002e, 0x8c000500,
+	0x04000006, 0x8058b040, 0x040207fc, 0x42000000,
+	0x00004003, 0x0401f060, 0x1c01f000, 0x41783800,
+	0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+	0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+	0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f04c, 0x59c80030, 0x59c80830,
+	0x80040580, 0x040207fd, 0x40041800, 0x59c80031,
+	0x59c80831, 0x80040580, 0x040207fd, 0x40042000,
+	0x59c80032, 0x59c80832, 0x80040580, 0x040207fd,
+	0x40042800, 0x59c80033, 0x59c80833, 0x80040580,
+	0x040207fd, 0x40043000, 0x400c0000, 0x80080580,
+	0x04000002, 0x801c3800, 0x40100000, 0x80080580,
+	0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+	0x00000004, 0x04000009, 0x40140000, 0x80080580,
+	0x04000002, 0x801c3800, 0x40180000, 0x80080580,
+	0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+	0x00000004, 0x0400000d, 0x59c80034, 0x59c80834,
+	0x80040580, 0x040207fd, 0x82040500, 0x0000ffff,
+	0x82080d00, 0x0000ffff, 0x80040580, 0x0400000e,
+	0x801c3800, 0x0401f00c, 0x59c80034, 0x59c80834,
+	0x80040580, 0x040207fd, 0x82040500, 0x000000ff,
+	0x82080d00, 0x000000ff, 0x80040580, 0x04000002,
+	0x801c3800, 0x801c39c0, 0x04000006, 0x59a80063,
+	0x801c0400, 0x48035063, 0x40240000, 0x48035062,
+	0x1c01f000, 0x48034206, 0x48074406, 0x480b4207,
+	0x480f4407, 0x48134208, 0x48174408, 0x0201f000,
+	0x001022c3, 0x42000000, 0x00600000, 0x80000040,
+	0x040207ff, 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5,
+	0x59a00c0a, 0x800409c0, 0x02000000, 0x00102310,
+	0x82040480, 0x00000021, 0x02021000, 0x00102310,
+	0x82040480, 0x00000011, 0x04001003, 0x42000800,
+	0x00000010, 0x59a00208, 0x59a01407, 0x900811c0,
+	0x80081540, 0x59a00207, 0x59a01c06, 0x900c19c0,
+	0x800c1d40, 0x0201f800, 0x00103a00, 0x04000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x00102fd5,
+	0x1c01f000, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x4031d800, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x59a00c0a, 0x82040480, 0x00000011, 0x04001003,
+	0x42000800, 0x00000010, 0x59a0040b, 0x59a0120b,
+	0x900811c0, 0x80081540, 0x59a00209, 0x59a01c08,
+	0x900c19c0, 0x800c1d40, 0x58ec0003, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x00102ff0, 0x1c01f000,
+	0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x59a00c0a,
+	0x82040480, 0x00000011, 0x02001000, 0x001022c0,
+	0x82040c80, 0x00000010, 0x59a00208, 0x59a01407,
+	0x900811c0, 0x80081540, 0x59a00207, 0x59a01c06,
+	0x900c19c0, 0x800c1d40, 0x82081400, 0x00000040,
+	0x58ec0003, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x0010300e, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x59a0040a, 0x82000c80, 0x00000010,
+	0x59a0040b, 0x59a0120b, 0x900811c0, 0x80081540,
+	0x59a00209, 0x59a01c08, 0x900c19c0, 0x800c1d40,
+	0x82081400, 0x00000040, 0x58ec0003, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x001022b9, 0x1c01f000,
+	0x48efc857, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x59a00406, 0x48034000, 0x480b4001,
+	0x480f4002, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x42000800, 0x00000010, 0x0201f800, 0x00103a25,
+	0x4a01d809, 0x00103043, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x592c0a04, 0x80040910,
+	0x04020005, 0x4a034406, 0x00000019, 0x0201f000,
+	0x0010230c, 0x4805d80c, 0x0401f00a, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x48efc857, 0x49a3c857,
+	0x48efc857, 0x49a3c857, 0x58ec000c, 0x80000040,
+	0x04000012, 0x4801d80c, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x42000800, 0x00000010, 0x58ec1007,
+	0x58ec1808, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x00103057, 0x1c01f000, 0x58ee580d, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x492f3006, 0x592c0404,
+	0x8400055e, 0x48025c04, 0x4a01d809, 0x00103081,
+	0x1c01f000, 0x58ee580d, 0x48efc857, 0x49a3c857,
+	0x492fc857, 0x592c0404, 0x8400051e, 0x48025c04,
+	0x59a00000, 0x59a01001, 0x59a01802, 0x80081400,
+	0x820c1c40, 0x00000000, 0x832c0400, 0x00000004,
+	0x42000800, 0x00000010, 0x0201f000, 0x00103a28,
+	0x800409c0, 0x04000005, 0x4a034406, 0x00000001,
+	0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+	0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+	0x0010230c, 0x59a0320b, 0x82183500, 0x000000ff,
+	0x59a28c06, 0x0201f800, 0x00020245, 0x02020000,
+	0x00102310, 0x83440580, 0x000007fd, 0x04000008,
+	0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+	0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x801831c0, 0x0400000a,
+	0x412c0800, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x40065800, 0x4a025c04, 0x00008000, 0x497a5a04,
+	0x0201f800, 0x00109100, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x001030d2, 0x1c01f000, 0x592c0005, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x592c0406, 0x82002d00,
+	0x0000ff00, 0x82000500, 0x000000ff, 0x80000904,
+	0x80040800, 0x82040480, 0x00000006, 0x04001003,
+	0x42000800, 0x00000005, 0x832ca400, 0x00000006,
+	0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+	0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+	0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+	0x832c0400, 0x00000006, 0x4c140000, 0x0201f800,
+	0x00103a28, 0x5c002800, 0x801429c0, 0x04000003,
+	0x4a01d809, 0x001030ff, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x592c0006, 0x82000500,
+	0xff000000, 0x80000904, 0x800409c0, 0x02000000,
+	0x00102304, 0x82040480, 0x0000000e, 0x04001003,
+	0x42000800, 0x0000000d, 0x592e5801, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x832ca400, 0x00000005,
+	0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+	0x58ec1007, 0x58ec1808, 0x832c0400, 0x00000005,
+	0x0201f000, 0x00103a28, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x59a00c06, 0x82040500, 0x0000ff00,
+	0x840001c0, 0x82001480, 0x00000007, 0x02021000,
+	0x00102310, 0x0c01f001, 0x0010313d, 0x00103144,
+	0x0010314b, 0x0010314b, 0x0010314b, 0x0010314d,
+	0x00103152, 0x42000800, 0x0000000d, 0x42003800,
+	0x00103166, 0x4a034000, 0x0010b4eb, 0x0401f013,
+	0x42000800, 0x0000000d, 0x42003800, 0x00103166,
+	0x4a034000, 0x0010b4f8, 0x0401f00c, 0x0201f000,
+	0x00102310, 0x42000800, 0x00000008, 0x42003800,
+	0x00103179, 0x0401f005, 0x42000800, 0x00000004,
+	0x42003800, 0x001031c3, 0x59a00207, 0x59a01407,
+	0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09,
+	0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005,
+	0x4c1c0000, 0x0201f800, 0x00103a25, 0x5c003800,
+	0x481dd809, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x4a03501f, 0x00000001,
+	0x4200b000, 0x0000000d, 0x59a0a800, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x0201f000,
+	0x001022c0, 0x4031d800, 0x58ef400b, 0x58ee580d,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x832ca400, 0x00000005, 0x50500000,
+	0x82001500, 0x000c0016, 0x02020000, 0x00102310,
+	0x82500c00, 0x00000003, 0x50040000, 0x82001500,
+	0x00000001, 0x02020000, 0x00102310, 0x50500000,
+	0x82001500, 0x00000028, 0x0400001d, 0x82081580,
+	0x00000028, 0x02020000, 0x00102310, 0x80500800,
+	0x50040000, 0x82001500, 0x00000013, 0x82081580,
+	0x00000013, 0x02020000, 0x00102310, 0x80040800,
+	0x50040000, 0x82001500, 0x00010000, 0x82081580,
+	0x00010000, 0x02020000, 0x00102310, 0x836c0580,
+	0x00000000, 0x04000012, 0x599c0019, 0x8c00050e,
+	0x0402000f, 0x0201f000, 0x00102310, 0x80500800,
+	0x50040000, 0x82001500, 0x00000013, 0x02020000,
+	0x00102310, 0x80040800, 0x50040000, 0x82001500,
+	0x00010000, 0x02020000, 0x00102310, 0x4200b000,
+	0x00000008, 0x4200a800, 0x0010b4e3, 0x0201f800,
+	0x0010ab17, 0x0201f000, 0x001022c0, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x4200b000,
+	0x00000004, 0x4200a800, 0x0010b8fa, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x59a80005,
+	0x84000550, 0x48035005, 0x0201f000, 0x001022c0,
+	0x0201f800, 0x00103a00, 0x04020005, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x82040500, 0x0000ff00, 0x840001c0, 0x82001480,
+	0x00000006, 0x02021000, 0x00102310, 0x0c01f001,
+	0x001031ee, 0x001031f3, 0x001031f8, 0x001031f8,
+	0x001031f8, 0x001031fa, 0x42000800, 0x0000000d,
+	0x4200a000, 0x0010b4eb, 0x0401f00c, 0x42000800,
+	0x0000000d, 0x4200a000, 0x0010b4f8, 0x0401f007,
+	0x0201f000, 0x00102310, 0x42000800, 0x00000008,
+	0x4200a000, 0x0010b4e3, 0x4004b000, 0x832cac00,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x59a00207,
+	0x59a01407, 0x900001c0, 0x80081540, 0x59a00209,
+	0x59a01c09, 0x900001c0, 0x800c1d40, 0x832c0400,
+	0x00000005, 0x0201f000, 0x00103a28, 0x836c0580,
+	0x00000000, 0x04020005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00406, 0x800001c0,
+	0x0400001a, 0x59a80005, 0x8c000514, 0x04000005,
+	0x42000000, 0x00000001, 0x40000800, 0x0401f003,
+	0x59a00207, 0x59a80853, 0x48035053, 0x0201f800,
+	0x0010163b, 0x04000022, 0x0201f800, 0x00101642,
+	0x0400001f, 0x0201f800, 0x00101649, 0x0400001c,
+	0x0201f800, 0x00101650, 0x04000019, 0x48075053,
+	0x0201f000, 0x00102310, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04020004,
+	0x4a034406, 0x00000000, 0x0401f00d, 0x82040580,
+	0x00008000, 0x04020004, 0x4a034406, 0x00000001,
+	0x0401f007, 0x82040580, 0x00010000, 0x02020800,
+	0x001005d8, 0x4a034406, 0x00000003, 0x59a00406,
+	0x82000580, 0x00000002, 0x0402001f, 0x59c40006,
+	0x84000500, 0x48038806, 0x0201f800, 0x00106ede,
+	0x497b8880, 0x0201f800, 0x0010a9c0, 0x0201f800,
+	0x0010a9ce, 0x42000000, 0x0010b8ca, 0x0201f800,
+	0x0010aa47, 0x82000540, 0x00000001, 0x0201f800,
+	0x0010518c, 0x4a038808, 0x00000000, 0x4202d800,
+	0x00000004, 0x42001000, 0x00000001, 0x0201f800,
+	0x0010193d, 0x4a035049, 0x00000001, 0x0201f800,
+	0x001006d4, 0x0201f000, 0x001022c0, 0x800409c0,
+	0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+	0x0010230c, 0x836c0580, 0x00000003, 0x04000005,
+	0x4a034406, 0x00000007, 0x0201f000, 0x0010230c,
+	0x59a28c06, 0x59a0320b, 0x82183500, 0x000000ff,
+	0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+	0x83440580, 0x000007fd, 0x04000008, 0x0201f800,
+	0x001049e7, 0x04000005, 0x42000800, 0x00000009,
+	0x0201f000, 0x0010230c, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+	0x0201f800, 0x00109115, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x0010329e, 0x1c01f000, 0x592c0005, 0x82000d00,
+	0x0000ffff, 0x82000500, 0xffff0000, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x80040904, 0x832ca400,
+	0x00000005, 0x4050a800, 0x4004b000, 0x0201f800,
+	0x0010ab28, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0201f000,
+	0x00103a28, 0x496fc857, 0x836c0580, 0x00000000,
+	0x04000005, 0x4a034406, 0x0000001a, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x0010513b, 0x02020800,
+	0x00104142, 0x42000800, 0x00000020, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x419c0000,
+	0x49a3c857, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x001032da, 0x1c01f000, 0x4833c857, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x599c0200, 0x800001c0,
+	0x02000000, 0x00102310, 0x59a80005, 0x8c000512,
+	0x04000004, 0x599c0019, 0x8400050c, 0x48033819,
+	0x0201f800, 0x001097d7, 0x59a80005, 0x8c000514,
+	0x04000004, 0x599c0017, 0x84000508, 0x48033817,
+	0x0201f800, 0x00103b25, 0x04020004, 0x8c00050a,
+	0x02020000, 0x00102310, 0x4803c857, 0x8c000504,
+	0x04020004, 0x59c408a3, 0x84040d7a, 0x480788a3,
+	0x8c000502, 0x04020004, 0x59c408a3, 0x84040d08,
+	0x480788a3, 0x599c0c02, 0x8c000500, 0x04020004,
+	0x8c000516, 0x04000012, 0x0401f001, 0x82041480,
+	0x0000007f, 0x02021000, 0x00102310, 0x82041400,
+	0x0010210e, 0x50081000, 0x82081500, 0x000000ff,
+	0x8c000500, 0x04020006, 0x480b5010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x599c0019,
+	0x8c00050e, 0x0402000b, 0x59a80806, 0x8c040d14,
+	0x04000008, 0x42000800, 0x0010b4e3, 0x50040800,
+	0x82040d00, 0x00000028, 0x02020000, 0x00102310,
+	0x82000500, 0x00000030, 0x04000003, 0x80000108,
+	0x0401f003, 0x42000000, 0x00000002, 0x48039040,
+	0x42000800, 0x00000002, 0x82000400, 0x00103415,
+	0x50001000, 0x0201f800, 0x00106c78, 0x599c0201,
+	0x82000c80, 0x00000100, 0x02001000, 0x00102310,
+	0x82000c80, 0x00000841, 0x02021000, 0x00102310,
+	0x82000500, 0x00000007, 0x02020000, 0x00102310,
+	0x599c0401, 0x80000540, 0x02000000, 0x00102310,
+	0x599c0409, 0x599c0c07, 0x80040c80, 0x02021000,
+	0x00102310, 0x80000040, 0x02000000, 0x00102310,
+	0x599c0209, 0x599c0a07, 0x80040c80, 0x02021000,
+	0x00102310, 0x80000040, 0x02000000, 0x00102310,
+	0x0201f800, 0x001053cd, 0x0201f800, 0x00104cb6,
+	0x599c0201, 0x48035004, 0x0201f800, 0x001012ee,
+	0x599c020a, 0x800001c0, 0x04000003, 0x4803504d,
+	0x0401f003, 0x4a03504d, 0x000000c8, 0x0201f800,
+	0x00103b25, 0x04000004, 0x0201f800, 0x001060df,
+	0x417a5000, 0x836c0580, 0x00000000, 0x04020098,
+	0x599c0003, 0x599c0804, 0x9c0001c0, 0x9c0409c0,
+	0x48035002, 0x48075003, 0x599c1017, 0x8c08151c,
+	0x04000006, 0x599c0005, 0x599c0806, 0x9c0001c0,
+	0x9c0409c0, 0x0401f003, 0x82000500, 0xf0ffffff,
+	0x48035000, 0x48075001, 0x42001000, 0x0010b4eb,
+	0x48001000, 0x48041001, 0x42001000, 0x0010b4f8,
+	0x48001000, 0x48041001, 0x59a80005, 0x8c000514,
+	0x04020015, 0x599c1019, 0x82081500, 0x0000e000,
+	0x82080580, 0x00000000, 0x0402000c, 0x4a035053,
+	0x00000000, 0x42000000, 0x00000001, 0x0201f800,
+	0x0010188c, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101821, 0x0401f02b, 0x82080580, 0x00002000,
+	0x0402000a, 0x4a035053, 0x00000001, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f01f, 0x82080580, 0x00004000,
+	0x04020006, 0x4a035053, 0x00000002, 0x4a035049,
+	0x00000001, 0x0401f017, 0x82080580, 0x00006000,
+	0x02020000, 0x00102310, 0x59a80858, 0x82040d80,
+	0x01391077, 0x04020005, 0x59e00813, 0x8c040d00,
+	0x02020000, 0x00102310, 0x4a035053, 0x00000003,
+	0x42000000, 0x00000002, 0x0201f800, 0x0010188c,
+	0x42000000, 0x00000002, 0x0201f800, 0x00101821,
+	0x599c0019, 0x8c000520, 0x0400000d, 0x42000000,
+	0x00000004, 0x42000800, 0x00000040, 0x0201f800,
+	0x00101944, 0x42000000, 0x00000010, 0x42000800,
+	0x000000c0, 0x0201f800, 0x00101944, 0x4a035032,
+	0x0000aaaa, 0x599c1018, 0x82081500, 0x00000030,
+	0x59a8006c, 0x80000540, 0x0400000c, 0x82080580,
+	0x00000000, 0x02000000, 0x00102310, 0x599c1018,
+	0x82081500, 0xffffffcf, 0x82081540, 0x00000010,
+	0x480b3818, 0x0401f010, 0x82080d80, 0x00000000,
+	0x04000007, 0x82080d80, 0x00000010, 0x0400000a,
+	0x82080d80, 0x00000020, 0x04020002, 0x48075032,
+	0x0201f800, 0x00103aba, 0x04000008, 0x0201f800,
+	0x001015fe, 0x0201f800, 0x0010162a, 0x59a8002a,
+	0x80040540, 0x4803502a, 0x49f3c857, 0x42001000,
+	0x00105065, 0x0201f800, 0x00105f90, 0x42001000,
+	0x00105058, 0x0201f800, 0x00106084, 0x4a038805,
+	0xffffffff, 0x4a03c014, 0x00400040, 0x4a03c013,
+	0x00400000, 0x0201f800, 0x001048c7, 0x59a0001d,
+	0x84000540, 0x4803401d, 0x49f3c857, 0x0201f000,
+	0x001022c0, 0x00000018, 0x0000000c, 0x00000018,
+	0x00000020, 0x836c0580, 0x00000000, 0x04020005,
+	0x42000800, 0x00000007, 0x0201f000, 0x0010230c,
+	0x42000800, 0x00000020, 0x59a00407, 0x59a01207,
+	0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09,
+	0x900c19c0, 0x800c1d40, 0x419c0000, 0x0201f000,
+	0x00103a28, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+	0x0201f000, 0x0010230c, 0x59a80013, 0x8c000500,
+	0x04000011, 0x4a034406, 0x00000000, 0x42000800,
+	0x00000020, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x42000000, 0x0010be21, 0x0201f000,
+	0x00103a28, 0x4a034406, 0x00000001, 0x4200b000,
+	0x00000020, 0x4200a800, 0x0010be21, 0x4200a000,
+	0xffffffff, 0x4450a800, 0x8054a800, 0x8058b040,
+	0x040207fd, 0x4d440000, 0x4d340000, 0x42028800,
+	0xffffffff, 0x42002000, 0xffffffff, 0x42003000,
+	0x00000001, 0x42003800, 0x00000001, 0x42001800,
+	0x0010be21, 0x59a81010, 0x82081500, 0x000000ff,
+	0x40180000, 0x0c01f001, 0x0010346e, 0x00103471,
+	0x00103475, 0x00103479, 0x82102500, 0xffffff00,
+	0x0401f014, 0x82102500, 0xffff00ff, 0x840811c0,
+	0x0401f010, 0x82102500, 0xff00ffff, 0x900811c0,
+	0x0401f00c, 0x82102500, 0x00ffffff, 0x9c0801c0,
+	0x80102540, 0x44101800, 0x42003000, 0xffffffff,
+	0x42002000, 0xffffffff, 0x800c1800, 0x0401f003,
+	0x40080000, 0x80102540, 0x81468800, 0x83442c80,
+	0x0000007f, 0x04021014, 0x4c080000, 0x4c0c0000,
+	0x4c180000, 0x4c1c0000, 0x0201f800, 0x00020245,
+	0x5c003800, 0x5c003000, 0x5c001800, 0x5c001000,
+	0x040207f2, 0x0201f800, 0x001049f3, 0x040207ef,
+	0x80183000, 0x801c3800, 0x59341202, 0x40180000,
+	0x0c01f7ce, 0x82100580, 0xffffffff, 0x04000002,
+	0x44101800, 0x42001800, 0x0010be21, 0x500c0000,
+	0x82000500, 0xffffff00, 0x801c0540, 0x44001800,
+	0x5c026800, 0x5c028800, 0x42000800, 0x00000020,
+	0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+	0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+	0x42000000, 0x0010be21, 0x0201f000, 0x00103a28,
+	0x59a28c06, 0x59a0020b, 0x8c000500, 0x0400000e,
+	0x59a01208, 0x59a00408, 0x82000500, 0x000000ff,
+	0x900001c0, 0x80081540, 0x41784000, 0x0201f800,
+	0x00104919, 0x04000008, 0x48034406, 0x0201f000,
+	0x00102310, 0x0201f800, 0x00020245, 0x02020000,
+	0x00102310, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x59a0020b, 0x8c000500, 0x04000005, 0x0201f800,
+	0x001049f3, 0x02020000, 0x00103ac4, 0x59a0020b,
+	0x8c000502, 0x04000019, 0x83440480, 0x000007f0,
+	0x04021016, 0x0201f800, 0x001049fc, 0x04020013,
+	0x497a5a04, 0x4a025c04, 0x00008000, 0x0201f800,
+	0x001090e6, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x001034f1,
+	0x1c01f000, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x4200b000, 0x0000000a,
+	0x4134a000, 0x832e5c00, 0x00000002, 0x412ca800,
+	0x0201f800, 0x0010ab17, 0x832cac00, 0x00000006,
+	0x4054a000, 0x4200b000, 0x00000004, 0x0201f800,
+	0x0010ab28, 0x592c0802, 0x82040500, 0x00ff00ff,
+	0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+	0x48025802, 0x592c0801, 0x82040500, 0x00ff00ff,
+	0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+	0x48025801, 0x42000800, 0x0000000a, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x412c0000,
+	0x0201f000, 0x00103a28, 0x496fc857, 0x496f4406,
+	0x0201f000, 0x001022c0, 0x59a28c06, 0x0201f800,
+	0x00020245, 0x02020000, 0x00102310, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x83340c00, 0x00000006,
+	0x59a0020b, 0x8c000500, 0x04000003, 0x83340c00,
+	0x00000008, 0x58040001, 0x48034409, 0x900001c0,
+	0x48034209, 0x50040000, 0x48034407, 0x900001c0,
+	0x48034207, 0x59340200, 0x48034406, 0x0201f000,
+	0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x59a0220b,
+	0x8c102500, 0x0402002e, 0x8c102506, 0x04020006,
+	0x59a03208, 0x82180480, 0x00000003, 0x02021000,
+	0x00102310, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x0201f800, 0x001049e7,
+	0x04000005, 0x4a034406, 0x00000009, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x59a0220b, 0x8c102506, 0x04000004, 0x59343002,
+	0x82183500, 0x00ffffff, 0x497a5a04, 0x4a025c04,
+	0x00008000, 0x0201f800, 0x001090a8, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x4a01d809, 0x001035d1, 0x1c01f000, 0x59a28c06,
+	0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+	0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+	0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x497a5a04, 0x4a025c04,
+	0x00008000, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x592e5800, 0x0201f800, 0x001090bd, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x4a01d809, 0x001035a3, 0x1c01f000, 0x592c2805,
+	0x82140d80, 0x01000000, 0x04020005, 0x4a034406,
+	0x00000004, 0x0201f000, 0x0010230c, 0x42000800,
+	0x00000008, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0201f800,
+	0x00103a28, 0x8c142d00, 0x04000003, 0x4a01d809,
+	0x001035be, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ee580e, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x42000800, 0x00000008, 0x832c0400,
+	0x00000005, 0x58ec1007, 0x58ec1808, 0x0201f000,
+	0x00103a28, 0x592c0005, 0x82000580, 0x01000000,
+	0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+	0x0010230c, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x42000800, 0x00000006, 0x832c0400,
+	0x00000006, 0x0201f000, 0x00103a28, 0x59a00a0a,
+	0x800409c0, 0x02000000, 0x00102310, 0x82040480,
+	0x000000e7, 0x04001003, 0x42000800, 0x000000e6,
+	0x59a00207, 0x59a01407, 0x900001c0, 0x80081540,
+	0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40,
+	0x83880400, 0x00000000, 0x0201f800, 0x00103a28,
+	0x4a01d809, 0x001035ff, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x58ef400b, 0x59a0020b,
+	0x8c000500, 0x04000008, 0x83880400, 0x00000000,
+	0x4803c840, 0x4a03c842, 0x00000006, 0x04011000,
+	0x497b8885, 0x4a034207, 0x000000e6, 0x0201f000,
+	0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x0401fbe5,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+	0x59a00406, 0x800001c0, 0x02000000, 0x00102310,
+	0x82001580, 0x000000ff, 0x04000005, 0x82001480,
+	0x00000004, 0x02021000, 0x00102310, 0x40001000,
+	0x0201f800, 0x00101fbf, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x0010363a, 0x1c01f000, 0x592c0005, 0x82000580,
+	0x01000000, 0x02020000, 0x001022c0, 0x4a034406,
+	0x00000004, 0x0201f000, 0x0010230c, 0x59a01406,
+	0x8c081508, 0x04020007, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a01c07, 0x820c0480, 0x00001000, 0x02021000,
+	0x00102310, 0x497b2804, 0x497b2805, 0x497b281c,
+	0x497b281d, 0x497b281f, 0x497b2820, 0x497b2822,
+	0x497b2823, 0x80000580, 0x0201f800, 0x001015fe,
+	0x59a80805, 0x8c081500, 0x04000004, 0x82040d40,
+	0x00000011, 0x0401f004, 0x8c081506, 0x04000002,
+	0x84040d42, 0x84040d0a, 0x48075005, 0x4202d800,
+	0x00000001, 0x82081500, 0x000000e0, 0x8008010a,
+	0x0c020036, 0x0201f800, 0x0010513b, 0x04020009,
+	0x4a035033, 0x00000001, 0x0201f800, 0x001050a2,
+	0x0401f01f, 0x4a035033, 0x00000000, 0x0401f7fb,
+	0x497b5032, 0x0201f800, 0x00104142, 0x0201f800,
+	0x00106c55, 0x0201f800, 0x00106ede, 0x0201f800,
+	0x00106c4b, 0x59a00a07, 0x480788a7, 0x59c400a3,
+	0x82000500, 0xfeffffff, 0x82000540, 0x80018000,
+	0x40000800, 0x84040d20, 0x480388a3, 0x480788a3,
+	0x497b504e, 0x42000800, 0x0000002d, 0x42001000,
+	0x001041bc, 0x0201f800, 0x00105f69, 0x59a00407,
+	0x800000c2, 0x800008c4, 0x8005d400, 0x42000000,
+	0x0000ffff, 0x0201f800, 0x0010513b, 0x04000003,
+	0x59a00207, 0x80000110, 0x0201f800, 0x00103afc,
+	0x0201f000, 0x001022c0, 0x0010366d, 0x00103670,
+	0x00103678, 0x00102310, 0x00103675, 0x00102310,
+	0x00102310, 0x00102310, 0x836c0580, 0x00000003,
+	0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+	0x0010230c, 0x59a03c06, 0x59a00407, 0x59a04a07,
+	0x902449c0, 0x80244d40, 0x59a00409, 0x59a05209,
+	0x902851c0, 0x80285540, 0x0401fb46, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x417a8800, 0x41783000, 0x497b4001, 0x497b4004,
+	0x832c4400, 0x00000005, 0x48234002, 0x8c1c3d04,
+	0x04020078, 0x0201f800, 0x00020245, 0x0402002a,
+	0x0201f800, 0x001049e7, 0x04000004, 0x0201f800,
+	0x001048e3, 0x04020024, 0x8c1c3d00, 0x04000008,
+	0x59340009, 0x44004000, 0x59340008, 0x80204000,
+	0x44004000, 0x80204000, 0x0401f007, 0x59340007,
+	0x44004000, 0x59340006, 0x80204000, 0x44004000,
+	0x80204000, 0x83440580, 0x000007fe, 0x0400000d,
+	0x83440580, 0x000007fc, 0x0400000a, 0x0201f800,
+	0x001049f3, 0x04000003, 0x85468d5e, 0x0401f005,
+	0x0201f800, 0x00104838, 0x04020002, 0x85468d5e,
+	0x45444000, 0x85468d1e, 0x80204000, 0x82183400,
+	0x00000003, 0x81468800, 0x83440480, 0x000007f0,
+	0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+	0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+	0x42028800, 0x000007fc, 0x82180580, 0x0000000f,
+	0x0400000b, 0x0401f7c0, 0x801831c0, 0x04020006,
+	0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+	0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+	0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+	0x4801d803, 0x4825d807, 0x4829d808, 0x4000a800,
+	0x4000a000, 0x4018b000, 0x0201f800, 0x0010ab17,
+	0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+	0x0010372a, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x59a00004, 0x80000540, 0x04020008,
+	0x59a28800, 0x59a04002, 0x59a03803, 0x41783000,
+	0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801,
+	0x800408c4, 0x48074406, 0x0201f000, 0x001022c0,
+	0x0201f800, 0x00020245, 0x0402002f, 0x0201f800,
+	0x001049e7, 0x04000004, 0x0201f800, 0x001048e3,
+	0x04020029, 0x83440580, 0x000007fe, 0x04000011,
+	0x83440580, 0x000007fc, 0x0400000e, 0x0201f800,
+	0x001049f3, 0x04000005, 0x59340403, 0x8400055e,
+	0x48026c03, 0x0401f007, 0x0201f800, 0x00104838,
+	0x04020004, 0x59340403, 0x8400055e, 0x48026c03,
+	0x4134a000, 0x4020a800, 0x4200b000, 0x00000006,
+	0x0201f800, 0x0010ab17, 0x59340007, 0x4400a800,
+	0x59340006, 0x4800a801, 0x59340009, 0x4800a802,
+	0x59340008, 0x4800a803, 0x59340403, 0x8400051e,
+	0x48026c03, 0x82204400, 0x0000000a, 0x82183400,
+	0x0000000a, 0x81468800, 0x83440480, 0x000007f0,
+	0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+	0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+	0x42028800, 0x000007fc, 0x82180580, 0x0000000a,
+	0x0400000b, 0x0401f7bb, 0x801831c0, 0x04020006,
+	0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+	0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+	0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+	0x4801d803, 0x4825d807, 0x4829d808, 0x40ec1000,
+	0x0201f800, 0x00100858, 0x4a01d809, 0x001037a1,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x59a00004, 0x80000540, 0x04020008, 0x59a28800,
+	0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807,
+	0x58ec5008, 0x0401f78f, 0x59a00801, 0x800408c4,
+	0x48074406, 0x0201f000, 0x001022c0, 0x42002800,
+	0x0000007e, 0x59a00c06, 0x59a01207, 0x59a01c07,
+	0x59a02209, 0x82040500, 0x0000ff00, 0x840001c0,
+	0x82003480, 0x00000020, 0x02001000, 0x00102310,
+	0x80140480, 0x02001000, 0x00102310, 0x82040500,
+	0x000000ff, 0x82003480, 0x00000020, 0x02001000,
+	0x00102310, 0x80140480, 0x02001000, 0x00102310,
+	0x82080500, 0x0000ff00, 0x840001c0, 0x82003480,
+	0x00000020, 0x02001000, 0x00102310, 0x80140480,
+	0x02001000, 0x00102310, 0x82080500, 0x000000ff,
+	0x82003480, 0x00000020, 0x02001000, 0x00102310,
+	0x80140480, 0x02001000, 0x00102310, 0x820c0500,
+	0x0000ff00, 0x840001c0, 0x82003480, 0x00000020,
+	0x02001000, 0x00102310, 0x80140480, 0x02001000,
+	0x00102310, 0x820c0500, 0x000000ff, 0x82003480,
+	0x00000020, 0x02001000, 0x00102310, 0x80140480,
+	0x02001000, 0x00102310, 0x82100500, 0x0000ff00,
+	0x840001c0, 0x82003480, 0x00000020, 0x02001000,
+	0x00102310, 0x80140480, 0x02001000, 0x00102310,
+	0x82100500, 0x000000ff, 0x82003480, 0x00000020,
+	0x02001000, 0x00102310, 0x80140480, 0x02001000,
+	0x00102310, 0x900401c0, 0x80080d40, 0x900c01c0,
+	0x80101d40, 0x83a83400, 0x0000003a, 0x44043000,
+	0x80183000, 0x440c3000, 0x0201f000, 0x001022c0,
+	0x0401f9ec, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x42000800, 0x0000000c,
+	0x0401f853, 0x4a01d809, 0x00103820, 0x1c01f000,
+	0x4031d800, 0x58ee580d, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x832ca400, 0x00000004, 0x4200b000, 0x0000000c,
+	0x40c8a800, 0x0201f800, 0x0010ab17, 0x58c80200,
+	0x80000540, 0x04000034, 0x58c80400, 0x82000500,
+	0xfffffffb, 0x04020030, 0x58c80401, 0x80000540,
+	0x0400002d, 0x82000480, 0x0000ff01, 0x0402102a,
+	0x58c80202, 0x82000480, 0x0000005c, 0x04001026,
+	0x0201f800, 0x001063a3, 0x58c80c08, 0x58c80204,
+	0x80040480, 0x04001020, 0x58c80204, 0x82000480,
+	0x00000005, 0x0402101c, 0x58c80205, 0x58c80c08,
+	0x80040902, 0x80040480, 0x04001017, 0x58c80c08,
+	0x0201f800, 0x001062f1, 0x0400001b, 0x0201f800,
+	0x001061b9, 0x04020012, 0x4979940b, 0x59c408a3,
+	0x82040d40, 0x00000002, 0x480788a3, 0x4a038830,
+	0x00000001, 0x4a038832, 0x01ffffff, 0x58c80202,
+	0x48030804, 0x0201f800, 0x0010619b, 0x0201f000,
+	0x001022c0, 0x0201f000, 0x00102310, 0x0201f800,
+	0x001063f5, 0x0201f800, 0x00106402, 0x0201f800,
+	0x001062e4, 0x0201f000, 0x0010230c, 0x4c000000,
+	0x59a01207, 0x59a00407, 0x900811c0, 0x80081540,
+	0x59a01a09, 0x59a00409, 0x900c19c0, 0x800c1d40,
+	0x5c000000, 0x0401f1ac, 0x59840000, 0x82000580,
+	0x00000000, 0x04000054, 0x59840002, 0x8c000504,
+	0x04000051, 0x84000546, 0x48030802, 0x0201f800,
+	0x001062e4, 0x59c408a3, 0x82040d00, 0xfffffffd,
+	0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010ac00,
+	0x505e6800, 0x813669c0, 0x04000008, 0x5936600e,
+	0x813261c0, 0x04000005, 0x0201f800, 0x001062d5,
+	0x02000800, 0x001064ad, 0x805cb800, 0x825c0580,
+	0x0010b3f0, 0x040207f3, 0x59866003, 0x813261c0,
+	0x0400000b, 0x59300406, 0x82000580, 0x00000009,
+	0x02020800, 0x001005d8, 0x5930b800, 0x0201f800,
+	0x001062c1, 0x405e6000, 0x0401f7f5, 0x497b0803,
+	0x4200b800, 0x0010b51b, 0x505e6000, 0x813261c0,
+	0x04000011, 0x59300406, 0x82000580, 0x00000009,
+	0x0402000d, 0x59300203, 0x82000580, 0x00000004,
+	0x04020009, 0x59326809, 0x813669c0, 0x02020800,
+	0x001005d8, 0x0201f800, 0x00100e99, 0x0201f800,
+	0x001062c1, 0x4578b800, 0x805cb800, 0x825c0580,
+	0x0010b523, 0x040207e9, 0x42000800, 0x0010b519,
+	0x49780801, 0x49780800, 0x59a80069, 0x82000400,
+	0x00000007, 0x48035069, 0x0201f800, 0x001063f5,
+	0x0201f800, 0x00106402, 0x5c00b800, 0x0201f800,
+	0x001061b4, 0x0201f000, 0x001022c0, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00407, 0x59a02207,
+	0x901021c0, 0x80102540, 0x59a00409, 0x59a02a09,
+	0x901429c0, 0x80142d40, 0x0401f91e, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x417a8800, 0x41781800, 0x497b4001, 0x497b4003,
+	0x832c3400, 0x00000004, 0x481b4002, 0x41440000,
+	0x81ac0400, 0x50026800, 0x813669c0, 0x0400000b,
+	0x0201f800, 0x001049e7, 0x04020008, 0x59340002,
+	0x48003000, 0x49443001, 0x82183400, 0x00000002,
+	0x820c1c00, 0x00000002, 0x81468800, 0x83440480,
+	0x00000800, 0x04000005, 0x820c0480, 0x00000010,
+	0x0402100b, 0x0401f7ea, 0x800c19c0, 0x04020006,
+	0x59a00801, 0x80040902, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034003, 0x00000001, 0x49474000,
+	0x59a00001, 0x800c0400, 0x48034001, 0x40ec1000,
+	0x4a001001, 0x00000000, 0x480c1004, 0x59a00002,
+	0x48001003, 0x48101007, 0x48141008, 0x0201f800,
+	0x00100858, 0x4a01d809, 0x00103920, 0x1c01f000,
+	0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x59a00003,
+	0x80000540, 0x04020008, 0x59a28800, 0x59a03002,
+	0x41781800, 0x40ec1000, 0x58082007, 0x58082808,
+	0x0401f7bf, 0x59a00801, 0x80040902, 0x48074406,
+	0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a80026, 0x8c00050a, 0x04020007, 0x8c000506,
+	0x04020005, 0x4a034406, 0x00000016, 0x0201f000,
+	0x0010230c, 0x0401f8bb, 0x04020005, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x80040902, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8ce,
+	0x4a01d809, 0x0010395b, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x592c0009,
+	0x0201f800, 0x00105c9a, 0x02000800, 0x001045a6,
+	0x02020000, 0x00102310, 0x49474001, 0x481a6802,
+	0x592c000a, 0x82001d80, 0x70000000, 0x04020007,
+	0x0401f890, 0x04020011, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x82001d80, 0x72000000,
+	0x02020000, 0x00102310, 0x0401f886, 0x04020885,
+	0x04020884, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x58ee580d, 0x4a025c04,
+	0x00008000, 0x497a5a04, 0x592c3208, 0x80183102,
+	0x592c1801, 0x4a001805, 0x01000000, 0x0201f800,
+	0x001090d1, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x00103995,
+	0x1c01f000, 0x592c4000, 0x592c0005, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x832c3c00, 0x00000005,
+	0x401ca000, 0x401ca800, 0x5820280a, 0x4200b000,
+	0x00000002, 0x82143580, 0x70000000, 0x04000003,
+	0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab28,
+	0x401c0000, 0x58201006, 0x58201807, 0x58202205,
+	0x80102102, 0x82143580, 0x70000000, 0x04020008,
+	0x82103480, 0x00000002, 0x02001000, 0x00102310,
+	0x42000800, 0x00000002, 0x0401f06e, 0x82143580,
+	0x72000000, 0x02020000, 0x00102310, 0x82103480,
+	0x0000002a, 0x02001000, 0x00102310, 0x42000800,
+	0x0000000f, 0x0401f863, 0x4a01d809, 0x001039c9,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x592e5800, 0x832c0c00, 0x00000005,
+	0x4004a000, 0x4004a800, 0x4200b000, 0x0000000f,
+	0x0201f800, 0x0010ab28, 0x40ec1000, 0x4a001001,
+	0x00000000, 0x4a001004, 0x0000000f, 0x48041003,
+	0x0201f800, 0x00100858, 0x4a01d809, 0x001039e5,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x832c0c00, 0x00000005, 0x4004a000,
+	0x4004a800, 0x4200b000, 0x0000000c, 0x0201f800,
+	0x0010ab28, 0x40ec1000, 0x4a001001, 0x00000000,
+	0x4a001004, 0x0000000c, 0x48041003, 0x0201f800,
+	0x00100858, 0x4a01d809, 0x001022b9, 0x1c01f000,
+	0x0201f800, 0x001007e4, 0x04000010, 0x497a5800,
+	0x58ec000d, 0x80000540, 0x04020004, 0x492dd80d,
+	0x492dd80e, 0x0401f007, 0x58ec000e, 0x48025800,
+	0x82000400, 0x00000001, 0x452c0000, 0x492dd80e,
+	0x832c0400, 0x00000004, 0x492fc857, 0x4803c857,
+	0x1c01f000, 0x4d2c0000, 0x48efc857, 0x58ec400d,
+	0x4823c857, 0x802041c0, 0x04000007, 0x40225800,
+	0x592c4001, 0x497a5801, 0x0201f800, 0x001007f4,
+	0x0401f7f8, 0x4979d80d, 0x4979d80e, 0x5c025800,
+	0x1c01f000, 0x42003000, 0x00000001, 0x0401f003,
+	0x42003000, 0x00000000, 0x4803c857, 0x4807c857,
+	0x480bc857, 0x480fc857, 0x481bc857, 0x48efc857,
+	0x4819d801, 0x800409c0, 0x02000800, 0x001005d8,
+	0x4805d804, 0x4801d803, 0x4809d807, 0x480dd808,
+	0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+	0x001022b9, 0x1c01f000, 0x80002d80, 0x480bc857,
+	0x480fc857, 0x4813c857, 0x4817c857, 0x4d2c0000,
+	0x4da00000, 0x42034000, 0x0010b4a4, 0x59a00017,
+	0x800001c0, 0x04020013, 0x04006012, 0x480bc020,
+	0x480fc021, 0x4813c022, 0x4817c023, 0x900811c0,
+	0x82081540, 0x00000012, 0x480bc011, 0x59e00017,
+	0x8c000508, 0x04020004, 0x4203e000, 0x30000001,
+	0x0401f053, 0x4a03c017, 0x00000002, 0x0401f7fb,
+	0x4c040000, 0x4c1c0000, 0x80000800, 0x48074017,
+	0x59a0381a, 0x481fc857, 0x801c39c0, 0x04020027,
+	0x82000480, 0x0000000a, 0x04021010, 0x59a00018,
+	0x80000000, 0x48034018, 0x59a00219, 0x82000400,
+	0x00000002, 0x82000c80, 0x00000013, 0x48034219,
+	0x04001003, 0x497b4219, 0x41780000, 0x59a03816,
+	0x801c3c00, 0x0401f030, 0x4803c856, 0x0201f800,
+	0x001007e4, 0x04000007, 0x492f401a, 0x492f401b,
+	0x412c3800, 0x497b421c, 0x497a5813, 0x0401f026,
+	0x59880051, 0x80000000, 0x48031051, 0x59a00017,
+	0x80000040, 0x48034017, 0x59a00219, 0x59a03816,
+	0x801c3c00, 0x0401f01c, 0x59a0021c, 0x82000400,
+	0x00000002, 0x82000c80, 0x00000012, 0x04021004,
+	0x4803421c, 0x801c3c00, 0x0401f013, 0x0201f800,
+	0x001007e4, 0x0402000b, 0x59880051, 0x80000000,
+	0x48031051, 0x59a00017, 0x80000040, 0x48034017,
+	0x4803c856, 0x59a0021c, 0x801c3c00, 0x0401f006,
+	0x492f401a, 0x492c3813, 0x412c3800, 0x497b421c,
+	0x497a5813, 0x48083c00, 0x480c3a00, 0x48103c01,
+	0x48143a01, 0x5c003800, 0x5c000800, 0x5c034000,
+	0x5c025800, 0x1c01f000, 0x480fc857, 0x4813c857,
+	0x481bc857, 0x42000000, 0x0010b813, 0x0201f800,
+	0x0010aa47, 0x801800d0, 0x40002800, 0x42001000,
+	0x00008014, 0x0401f786, 0x4c000000, 0x599c0017,
+	0x8c000512, 0x5c000000, 0x1c01f000, 0x4c000000,
+	0x599c0018, 0x8c00050e, 0x5c000000, 0x1c01f000,
+	0x59a80821, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x599c0017, 0x8c00050a,
+	0x04000005, 0x4a034406, 0x00000008, 0x0201f000,
+	0x0010230c, 0x59340405, 0x8c000508, 0x04020004,
+	0x8c00050a, 0x02020000, 0x001034db, 0x497a5a04,
+	0x497a5805, 0x4a025c04, 0x00008000, 0x0201f800,
+	0x00109176, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x00103aed,
+	0x1c01f000, 0x592c0005, 0x82000580, 0x01000000,
+	0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+	0x0010230c, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x0201f000, 0x001034db,
+	0x82001580, 0x0000ffff, 0x04000009, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x00020245, 0x0402000c,
+	0x0201f800, 0x00105fae, 0x0401f009, 0x42028800,
+	0x000007ef, 0x0201f800, 0x00020245, 0x02000800,
+	0x00105fae, 0x81468840, 0x040217fb, 0x1c01f000,
+	0x4803c856, 0x4c0c0000, 0x4d340000, 0x4d440000,
+	0x42028800, 0x000007fe, 0x0201f800, 0x00020245,
+	0x04020009, 0x5934180a, 0x820c1d00, 0x00000001,
+	0x820c1d80, 0x00000001, 0x42001000, 0x0000801b,
+	0x0401ff1e, 0x5c028800, 0x5c026800, 0x5c001800,
+	0x1c01f000, 0x599c0017, 0x8c000508, 0x1c01f000,
+	0x48efc857, 0x04011000, 0x48efc840, 0x4a03c842,
+	0x00000011, 0x40000000, 0x040117ff, 0x4a01d80f,
+	0xbeefbeef, 0x1c01f000, 0x497b4000, 0x497b4001,
+	0x497b4002, 0x497b4003, 0x497b4004, 0x1c01f000,
+	0x59c400a4, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x82000500, 0x0000000f, 0x82000480, 0x00000007,
+	0x0400100a, 0x82006c80, 0x00000006, 0x02021800,
+	0x001005d8, 0x0c01f807, 0x5c00a800, 0x5c00a000,
+	0x5c00b000, 0x1c01f000, 0x0401f906, 0x0401f7fb,
+	0x00103b51, 0x00103b57, 0x00103b7c, 0x00103b9e,
+	0x00103c59, 0x59c40806, 0x8c040d00, 0x04020003,
+	0x84040d40, 0x48078806, 0x1c01f000, 0x59c40005,
+	0x8c000534, 0x02020000, 0x0010429e, 0x4a038805,
+	0xffffffff, 0x42006000, 0x00020000, 0x0201f800,
+	0x00104282, 0x59a80015, 0x82000500, 0xfffffffa,
+	0x84000542, 0x48035015, 0x497b5026, 0x42000800,
+	0x0010be21, 0x45780800, 0x497b5013, 0x42006000,
+	0xffefffff, 0x42006800, 0x40000000, 0x0201f800,
+	0x0010427d, 0x59c40006, 0x82000500, 0xffffff0f,
+	0x48038806, 0x42000800, 0x00000010, 0x42001000,
+	0x001041f3, 0x0201f800, 0x00105f83, 0x0401f001,
+	0x42006000, 0xffffffff, 0x42006800, 0x00800000,
+	0x0201f800, 0x0010427d, 0x4200b000, 0x000000c8,
+	0x59c400a4, 0x82000500, 0x0000000f, 0x82000580,
+	0x0000000a, 0x0400000f, 0x8058b040, 0x040207f9,
+	0x497b5014, 0x42006000, 0xbf7fffff, 0x42006800,
+	0x00018000, 0x0201f800, 0x0010427d, 0x42006000,
+	0xfffeffff, 0x41786800, 0x0201f000, 0x0010427d,
+	0x497b5014, 0x4a035012, 0x00000000, 0x80000580,
+	0x0201f000, 0x00104289, 0x4a038805, 0xffffffff,
+	0x59a80012, 0x82000c80, 0x00000004, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00103ba9, 0x00103bd6,
+	0x00103c4f, 0x4803c856, 0x59c400a3, 0x8400051e,
+	0x480388a3, 0x4a035012, 0x00000001, 0x59c40008,
+	0x8400054e, 0x48038808, 0x0201f800, 0x00104263,
+	0x42007800, 0x0010b54c, 0x4a007806, 0x11010000,
+	0x4200a000, 0x0010b402, 0x4200a800, 0x0010b553,
+	0x4200b000, 0x00000002, 0x0201f800, 0x0010ab17,
+	0x497b8802, 0x42000800, 0x00000003, 0x497b504a,
+	0x0201f800, 0x0010416e, 0x4a03504a, 0x00000001,
+	0x497b5016, 0x0201f800, 0x00104290, 0x42006000,
+	0xffffffff, 0x42006800, 0x00080000, 0x0201f800,
+	0x0010427d, 0x42006000, 0xfff7ffff, 0x41786800,
+	0x0201f000, 0x0010427d, 0x59a80016, 0x497b5016,
+	0x80002540, 0x04000066, 0x59c40004, 0x82000500,
+	0x00000003, 0x04020071, 0x59a80815, 0x8c040d02,
+	0x0400004b, 0x82100580, 0x0000000c, 0x0402004f,
+	0x82100400, 0x00000018, 0x8000b104, 0x41cc1000,
+	0x42001800, 0x0010b54c, 0x50080800, 0x500c0000,
+	0x80040580, 0x0402001a, 0x80081000, 0x800c1800,
+	0x8058b040, 0x040207f9, 0x0201f800, 0x00104290,
+	0x42006000, 0xffffffff, 0x42006800, 0x00500000,
+	0x0201f800, 0x0010427d, 0x4a035012, 0x00000002,
+	0x4a035014, 0x00000002, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f800, 0x0010606e,
+	0x0201f800, 0x00104263, 0x0401f048, 0x59cc0806,
+	0x82040d80, 0x11010000, 0x04020028, 0x59cc0800,
+	0x82040500, 0x00ffffff, 0x0400001a, 0x82000580,
+	0x000000ef, 0x04020017, 0x59cc0801, 0x82040500,
+	0x00ffffff, 0x82000580, 0x000000ef, 0x04020011,
+	0x83cca400, 0x00000007, 0x4200a800, 0x0010b402,
+	0x4200b000, 0x00000002, 0x50500800, 0x50540000,
+	0x80040480, 0x04001007, 0x04020010, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207f8, 0x0401f00b,
+	0x59a80015, 0x84000502, 0x48035015, 0x41cca000,
+	0x4200a800, 0x0010b54c, 0x4200b000, 0x00000009,
+	0x0201f800, 0x0010ab17, 0x0201f800, 0x00104290,
+	0x42006000, 0xffffffff, 0x42006800, 0x00080000,
+	0x0201f800, 0x0010427d, 0x42006000, 0xfff7ffff,
+	0x41786800, 0x0201f800, 0x0010427d, 0x42006000,
+	0xffffffff, 0x42006800, 0x00004000, 0x0201f800,
+	0x0010427d, 0x59c40004, 0x82000500, 0x00000003,
+	0x04020006, 0x497b5016, 0x42000800, 0x00000003,
+	0x0201f000, 0x0010416e, 0x1c01f000, 0x1c01f000,
+	0x59a80014, 0x82006d80, 0x0000000f, 0x04000005,
+	0x82000580, 0x0000001b, 0x02020800, 0x00104139,
+	0x1c01f000, 0x59a80015, 0x84000506, 0x48035015,
+	0x497b504a, 0x59a80014, 0x82000c80, 0x0000001e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00103c97,
+	0x00103cac, 0x00103cd5, 0x00103cf0, 0x00103d14,
+	0x00103d45, 0x00103d68, 0x00103d9b, 0x00103dbe,
+	0x00103de4, 0x00103e21, 0x00103e48, 0x00103e5f,
+	0x00103e71, 0x00103e8a, 0x00103ea0, 0x00103ea5,
+	0x00103ecd, 0x00103ef0, 0x00103f16, 0x00103f39,
+	0x00103f6c, 0x00103fae, 0x00103fd8, 0x00103ff0,
+	0x00104030, 0x00104049, 0x0010405c, 0x0010405d,
+	0x4803c856, 0x4202d800, 0x00000007, 0x0201f800,
+	0x0010513b, 0x04000007, 0x42006000, 0xffffffd7,
+	0x41786800, 0x0201f800, 0x0010427d, 0x0401f00b,
+	0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+	0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+	0x0201f800, 0x00105098, 0x1c01f000, 0x4803c856,
+	0x42006000, 0xbf7fffff, 0x42006800, 0x00400000,
+	0x0201f800, 0x0010427d, 0x4a035014, 0x00000001,
+	0x42001000, 0x001041f3, 0x0201f800, 0x00105fa4,
+	0x0201f800, 0x001041f8, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f000, 0x0010606e,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020025,
+	0x4803c857, 0x42006000, 0xffbfffff, 0x41786800,
+	0x0201f800, 0x0010427d, 0x59c40004, 0x82000500,
+	0x00000003, 0x0402001b, 0x59cc1006, 0x82081580,
+	0x11020000, 0x04020016, 0x59cc1007, 0x8c08153e,
+	0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+	0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+	0x59a80015, 0x84000544, 0x48035015, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x4a035014,
+	0x00000010, 0x0401f9d4, 0x0401f002, 0x497b5016,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000003,
+	0x42006000, 0xbf3fffff, 0x42006800, 0x00100000,
+	0x0201f800, 0x0010427d, 0x42001000, 0x001041f3,
+	0x0201f800, 0x00105fa4, 0x0201f800, 0x001041f8,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x42007800, 0x0010b552, 0x46007800, 0x11020000,
+	0x42000800, 0x00000005, 0x0201f000, 0x0010416e,
+	0x59a80016, 0x80000540, 0x04000021, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020016,
+	0x59cc1006, 0x82081580, 0x11020000, 0x04020012,
+	0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+	0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+	0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+	0x48035015, 0x4a035014, 0x00000004, 0x0401f805,
+	0x0401f003, 0x0201f800, 0x00104139, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000005, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+	0x0010b552, 0x46007800, 0x11030000, 0x0201f800,
+	0x0010413e, 0x04020014, 0x59a80015, 0x8c000500,
+	0x04020011, 0x59a80810, 0x82040580, 0x00ffffff,
+	0x0400000d, 0x82040d00, 0x000000ff, 0x82040400,
+	0x0010210e, 0x50000800, 0x80040910, 0x42001000,
+	0x00000004, 0x0401fb9b, 0x0400000b, 0x0201f800,
+	0x0010420d, 0x4200b000, 0x00000004, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010b553, 0x0201f800,
+	0x0010ab17, 0x42000800, 0x00000005, 0x0201f000,
+	0x0010416e, 0x59a80016, 0x80000540, 0x04000020,
+	0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+	0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+	0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x4a035014, 0x00000006,
+	0x0401f804, 0x0401f002, 0x0401fbd3, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000007, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+	0x0010b552, 0x46007800, 0x11040000, 0x0401fbc7,
+	0x04020020, 0x59a80015, 0x8c000500, 0x0402001d,
+	0x599c0017, 0x8c000500, 0x0400001a, 0x599c1402,
+	0x82080480, 0x0000007f, 0x02021800, 0x001005d8,
+	0x4c080000, 0x82081400, 0x0010210e, 0x50081000,
+	0x82081500, 0x000000ff, 0x480b5010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x5c000800,
+	0x42001000, 0x00000004, 0x0401fb3e, 0x04000005,
+	0x0401fd2b, 0x04000003, 0x0201f800, 0x001015fe,
+	0x42000800, 0x00000005, 0x0401f3d4, 0x59a80016,
+	0x80000540, 0x04000020, 0x4803c857, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x59a80016,
+	0x82000580, 0x00000014, 0x04020016, 0x59cc1006,
+	0x82081580, 0x11040000, 0x04020012, 0x59cc1007,
+	0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+	0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+	0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+	0x4a035014, 0x00000008, 0x0401f804, 0x0401f002,
+	0x0401fb7d, 0x1c01f000, 0x4803c856, 0x4a035014,
+	0x00000009, 0x83cca400, 0x00000006, 0x4200a800,
+	0x0010b552, 0x4200b000, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x42007800, 0x0010b552, 0x46007800,
+	0x11050100, 0x0401fb71, 0x0402000a, 0x59a80015,
+	0x8c000500, 0x04020007, 0x0401fa8c, 0x04020005,
+	0x82000540, 0x00000001, 0x0201f800, 0x001015fe,
+	0x42000800, 0x00000005, 0x0401fb94, 0x0401fb63,
+	0x04020ea4, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x0400003a, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020030,
+	0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+	0x11050000, 0x0402002a, 0x8c081510, 0x04000014,
+	0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+	0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+	0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+	0x48035015, 0x4a035013, 0x00000001, 0x4a035014,
+	0x0000000a, 0x0401f818, 0x0401f016, 0x80000540,
+	0x04020013, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x497b5013, 0x4a035014,
+	0x0000000e, 0x0401f86d, 0x0401f002, 0x0401fb1a,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x0000000b,
+	0x42001000, 0x0010b553, 0x4008a800, 0x4200b000,
+	0x00000020, 0x4600a800, 0xffffffff, 0x8054a800,
+	0x8058b040, 0x040207fc, 0x42007800, 0x0010b552,
+	0x46007800, 0x11060000, 0x42001000, 0x0010b553,
+	0x0401fb0a, 0x04000005, 0x50080000, 0x46001000,
+	0x00ffffff, 0x0401f00c, 0x50080800, 0x82040d00,
+	0x0000ffff, 0x59a80010, 0x82000500, 0x000000ff,
+	0x82000540, 0x00000100, 0x800000e0, 0x80040d40,
+	0x44041000, 0x42000800, 0x00000021, 0x0401f327,
+	0x59a80016, 0x80000540, 0x04000014, 0x4803c857,
+	0x59a80016, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000084,
+	0x04020009, 0x59cc1006, 0x82081580, 0x11060000,
+	0x04020005, 0x4a035014, 0x0000000c, 0x0401f804,
+	0x0401f002, 0x0401fadc, 0x1c01f000, 0x4803c856,
+	0x4a035014, 0x0000000d, 0x83cca400, 0x00000006,
+	0x4200a800, 0x0010b552, 0x4200b000, 0x00000021,
+	0x0201f800, 0x0010ab17, 0x42007800, 0x0010b552,
+	0x46007800, 0x11070000, 0x42000800, 0x00000021,
+	0x0401f2fe, 0x59a80016, 0x80000540, 0x04000016,
+	0x4803c857, 0x59a80016, 0x42001000, 0x00104148,
+	0x0201f800, 0x00105f90, 0x82000580, 0x00000084,
+	0x0402000c, 0x59cc1006, 0x82081580, 0x11070000,
+	0x04020008, 0x4a035013, 0x00000001, 0x0401fa91,
+	0x4a035014, 0x0000000e, 0x0401f804, 0x0401f002,
+	0x0401fab1, 0x1c01f000, 0x4803c856, 0x82040d40,
+	0x00000001, 0x0401fbfc, 0x4a035014, 0x0000000f,
+	0x497b5016, 0x42006000, 0xffffffff, 0x42006800,
+	0x00300000, 0x0401fbe8, 0x42006000, 0xffdfffff,
+	0x41786800, 0x0401fbe4, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f000, 0x00105f69,
+	0x4803c856, 0x59a80016, 0x80000540, 0x04020296,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000011,
+	0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x4200a800, 0x0010b552, 0x4600a800, 0x11020000,
+	0x0401fa8a, 0x04020015, 0x59a80010, 0x82000d00,
+	0xffff0000, 0x04000011, 0x82000500, 0x000000ff,
+	0x0400000e, 0x82000c00, 0x0010210e, 0x50040800,
+	0x80040910, 0x82040580, 0x0000007e, 0x04000007,
+	0x82040580, 0x00000080, 0x04000004, 0x42001000,
+	0x00000004, 0x0401fa07, 0x42000800, 0x00000005,
+	0x0401f2a2, 0x59a80016, 0x80000540, 0x04000020,
+	0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+	0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+	0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x4a035014, 0x00000012,
+	0x0401f804, 0x0401f002, 0x0401fa4b, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000013, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x4200a800,
+	0x0010b552, 0x4600a800, 0x11030000, 0x0401fa3f,
+	0x04020013, 0x59a80015, 0x8c000500, 0x04020010,
+	0x59a80810, 0x82040580, 0x00ffffff, 0x0400000c,
+	0x82040d00, 0x000000ff, 0x82040400, 0x0010210e,
+	0x50000800, 0x80040910, 0x42001000, 0x00000004,
+	0x0401f9c0, 0x04000002, 0x0401fafb, 0x42000800,
+	0x00000005, 0x0401f259, 0x59a80016, 0x80000540,
+	0x04000020, 0x4803c857, 0x42001000, 0x00104148,
+	0x0201f800, 0x00105f90, 0x59a80016, 0x82000580,
+	0x00000014, 0x04020016, 0x59cc1006, 0x82081580,
+	0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e,
+	0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+	0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+	0x59a80015, 0x84000544, 0x48035015, 0x4a035014,
+	0x00000014, 0x0401f804, 0x0401f002, 0x0401fa02,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000015,
+	0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x4200a800, 0x0010b552, 0x4600a800, 0x11040000,
+	0x0401f9f6, 0x04020020, 0x59a80015, 0x8c000500,
+	0x0402001d, 0x599c0017, 0x8c000500, 0x0400001a,
+	0x599c1402, 0x82080480, 0x0000007f, 0x02021800,
+	0x001005d8, 0x4c080000, 0x82081400, 0x0010210e,
+	0x50081000, 0x82081500, 0x000000ff, 0x480b5010,
+	0x42000800, 0x00000003, 0x0201f800, 0x00106c78,
+	0x5c000800, 0x42001000, 0x00000004, 0x0401f96d,
+	0x04000005, 0x0201f800, 0x00103abf, 0x02020800,
+	0x001015fe, 0x42000800, 0x00000005, 0x0401f203,
+	0x59a80016, 0x80000540, 0x0400003f, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020035,
+	0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+	0x11050000, 0x0402002f, 0x8c081510, 0x04000010,
+	0x0401fb09, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x0401f013, 0x59cc1007,
+	0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+	0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+	0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+	0x82000540, 0x00000001, 0x0401faeb, 0x497b5013,
+	0x0401f003, 0x4a035013, 0x00000001, 0x59cc1007,
+	0x8c08153c, 0x04000003, 0x4a035026, 0x00000008,
+	0x4a035014, 0x00000016, 0x0401f804, 0x0401f002,
+	0x0401f98d, 0x1c01f000, 0x4803c856, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x4a035014,
+	0x00000017, 0x59a80013, 0x8c000500, 0x04000006,
+	0x42001000, 0x0010b552, 0x46001000, 0x11050100,
+	0x0401f003, 0x4a035014, 0x0000001b, 0x0401f97b,
+	0x0402000a, 0x59a80015, 0x8c000500, 0x04020007,
+	0x0401f896, 0x04020005, 0x82000540, 0x00000001,
+	0x0201f800, 0x001015fe, 0x42000800, 0x00000005,
+	0x0401f99e, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x04000015, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000084, 0x0402000b,
+	0x59cc1006, 0x82081580, 0x11060000, 0x04020007,
+	0x80000580, 0x0401faa0, 0x4a035014, 0x00000018,
+	0x0401f804, 0x0401f002, 0x0401f94b, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000019, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000021, 0x0201f800, 0x0010ab17, 0x42003800,
+	0x0010b553, 0x0401f941, 0x04020018, 0x401c2800,
+	0x50141000, 0x80080130, 0x80000000, 0x40001800,
+	0x82081500, 0x00ffffff, 0x800000f0, 0x80080540,
+	0x44002800, 0x59a80810, 0x82040d00, 0x000000ff,
+	0x400c1000, 0x80081104, 0x82082400, 0x0010b553,
+	0x50101000, 0x820c0500, 0x00000003, 0x0c01f806,
+	0x80081540, 0x44082000, 0x42000800, 0x00000021,
+	0x0401f156, 0x0010401d, 0x00104022, 0x00104027,
+	0x0010402c, 0x800408f0, 0x40040000, 0x82081500,
+	0x00ffffff, 0x1c01f000, 0x800408e0, 0x40040000,
+	0x82081500, 0xff00ffff, 0x1c01f000, 0x800408d0,
+	0x40040000, 0x82081500, 0xffff00ff, 0x1c01f000,
+	0x40040000, 0x82081500, 0xffffff00, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x04000016, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000084, 0x0402000c,
+	0x59cc1006, 0x82081580, 0x11070000, 0x04020008,
+	0x4a035013, 0x00000001, 0x0401f8d2, 0x4a035014,
+	0x0000001a, 0x0401f804, 0x0401f002, 0x0401f8f2,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0401fa3e,
+	0x4a035014, 0x0000001b, 0x83cca400, 0x00000006,
+	0x4200a800, 0x0010b552, 0x59a82016, 0x40100000,
+	0x8000b104, 0x40580800, 0x5450a800, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207fc, 0x0401f113,
+	0x1c01f000, 0x1c01f000, 0x4803c856, 0x42003000,
+	0x00000004, 0x42004000, 0x0010b553, 0x599c2817,
+	0x8c142d14, 0x0402001f, 0x42001000, 0x00000003,
+	0x40200000, 0x80080400, 0x50000800, 0x82042580,
+	0xffffffff, 0x04020005, 0x80081040, 0x80183040,
+	0x040207f8, 0x0401f05e, 0x800811c0, 0x04020006,
+	0x82042580, 0x3fffffff, 0x04000058, 0x82040d40,
+	0xc0000000, 0x4200b000, 0x00000020, 0x42001800,
+	0x00000001, 0x40042000, 0x80102102, 0x04021021,
+	0x800c18c2, 0x8058b040, 0x040207fc, 0x0401f04b,
+	0x41781000, 0x40200000, 0x80080400, 0x50000800,
+	0x82042580, 0xffffffff, 0x04020005, 0x80081000,
+	0x80183040, 0x040207f8, 0x0401f040, 0x800811c0,
+	0x04020003, 0x82040d40, 0xc0000000, 0x4200b000,
+	0x00000001, 0x42001800, 0x80000000, 0x40042000,
+	0x801020c2, 0x04021007, 0x800c1902, 0x8058b000,
+	0x82580480, 0x00000021, 0x040017fa, 0x0401f02f,
+	0x40200000, 0x80082400, 0x50100000, 0x800c0540,
+	0x44002000, 0x59a80015, 0x84000540, 0x48035015,
+	0x40580000, 0x42002800, 0x00000020, 0x80142c80,
+	0x40080000, 0x42003800, 0x00000003, 0x801c0480,
+	0x800000ca, 0x80142d40, 0x82144c00, 0x0010210e,
+	0x50242800, 0x82142d00, 0x000000ff, 0x48175010,
+	0x4c040000, 0x40140800, 0x0201f800, 0x001015eb,
+	0x5c000800, 0x40001800, 0x500c0000, 0x80100540,
+	0x44001800, 0x59a80015, 0x84000540, 0x48035015,
+	0x4200a800, 0x0010b553, 0x4020a000, 0x4200b000,
+	0x00000004, 0x0201f800, 0x0010ab17, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x4807c857, 0x480bc857, 0x4008b000, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010b553, 0x40541000,
+	0x0201f800, 0x0010ab17, 0x40041800, 0x41782000,
+	0x42000000, 0x00000003, 0x820c1c80, 0x00000020,
+	0x04001004, 0x80102000, 0x80000040, 0x0401f7fb,
+	0x40041800, 0x801021c0, 0x04000005, 0x820c1c80,
+	0x00000020, 0x80102040, 0x040207fd, 0x42002000,
+	0x00000001, 0x800c19c0, 0x04000004, 0x801020c2,
+	0x800c1840, 0x040207fe, 0x80083c00, 0x83cc2c00,
+	0x00000007, 0x80142c00, 0x50140000, 0x80102d00,
+	0x04020012, 0x80100540, 0x44003800, 0x82042400,
+	0x0010210e, 0x50102800, 0x82142d00, 0x000000ff,
+	0x48175010, 0x4c040000, 0x40140800, 0x0201f800,
+	0x001015eb, 0x5c000800, 0x59a80015, 0x84000540,
+	0x48035015, 0x80000580, 0x1c01f000, 0x4807c856,
+	0x42001000, 0x00008017, 0x59a8184e, 0x0201f800,
+	0x0010aa4f, 0x0201f800, 0x00103a3e, 0x1c01f000,
+	0x4807c856, 0x4200b000, 0x00000020, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010be21, 0x0201f000,
+	0x0010ab28, 0x4807c856, 0x0201f800, 0x00106ede,
+	0x42000800, 0x000000f7, 0x0401f8de, 0x497b2804,
+	0x497b2805, 0x497b281c, 0x497b281d, 0x4202d800,
+	0x00000001, 0x42006000, 0xbf7fffff, 0x42006800,
+	0x00018000, 0x0401f950, 0x42006000, 0xfffeffff,
+	0x41786800, 0x0401f94c, 0x497b504e, 0x42000800,
+	0x0000002d, 0x42001000, 0x001041bc, 0x0201f000,
+	0x00105f69, 0x4807c856, 0x0401ffe3, 0x497b5014,
+	0x497b5016, 0x1c01f000, 0x4807c856, 0x59a80005,
+	0x8c000506, 0x1c01f000, 0x4807c856, 0x42006000,
+	0xffffffff, 0x42006800, 0x00000028, 0x0401f136,
+	0x4807c856, 0x0401ffc2, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+	0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+	0x0401f921, 0x42006000, 0xffdfffff, 0x41786800,
+	0x0401f91d, 0x497b5014, 0x42000800, 0x000000f7,
+	0x0401f89c, 0x59c400a3, 0x82000500, 0xbf20bfff,
+	0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+	0x480388a3, 0x1c01f000, 0x497b5016, 0x59b400f5,
+	0x8c000500, 0x04020004, 0x82000540, 0x00000001,
+	0x480368f5, 0x800400c4, 0x82000400, 0x00002000,
+	0x4803910a, 0x59b400f6, 0x82000500, 0x00000018,
+	0x040207fd, 0x4a0368f0, 0x0010b54b, 0x42000000,
+	0x0010b552, 0x480368f1, 0x82040400, 0x0000dc00,
+	0x480368f3, 0x59c400a4, 0x82000500, 0x0000000f,
+	0x82000580, 0x00000008, 0x04020017, 0x4c5c0000,
+	0x4c600000, 0x59c4b805, 0x8c5cbd3a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+	0x4000c000, 0x0201f800, 0x00101963, 0x4202d800,
+	0x00000001, 0x497b5014, 0x5c00c000, 0x5c00b800,
+	0x1c01f000, 0x59c8010b, 0x8c000502, 0x040007e2,
+	0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80,
+	0x0000000b, 0x04020005, 0x59a80814, 0x82040d40,
+	0x00002000, 0x0401f004, 0x59a80812, 0x82040d40,
+	0x00001000, 0x4807504e, 0x59a8084a, 0x800409c0,
+	0x04020007, 0x42000800, 0x000007d0, 0x42001000,
+	0x00104148, 0x0201f800, 0x0010606e, 0x1c01f000,
+	0x4807c856, 0x0401ff4e, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+	0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+	0x0401f8ad, 0x42006000, 0xffdfffff, 0x41786800,
+	0x0401f8a9, 0x0201f800, 0x00105141, 0x04000014,
+	0x0201f800, 0x00105151, 0x04020011, 0x4a035032,
+	0x0000aaaa, 0x4c040000, 0x0201f800, 0x0010162a,
+	0x59a8002a, 0x82000500, 0xffff0000, 0x80040540,
+	0x4803502a, 0x5c000800, 0x4a035033, 0x00000000,
+	0x0201f800, 0x001050a2, 0x0401f008, 0x4a03504c,
+	0x00000005, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101590, 0x0401ff2c, 0x1c01f000, 0x0401f805,
+	0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f086,
+	0x0201f800, 0x00105151, 0x04020005, 0x59c40006,
+	0x82000540, 0x000000f0, 0x48038806, 0x1c01f000,
+	0x800408d0, 0x59a80015, 0x8c000506, 0x04000006,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80040540,
+	0x0401f003, 0x82040540, 0x000000f7, 0x480388a7,
+	0x1c01f000, 0x4807c856, 0x42000000, 0x0010b83b,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000005,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000d,
+	0x42027800, 0x00000002, 0x0401f038, 0x4807c856,
+	0x42000000, 0x0010b86b, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000000, 0x4d3c0000, 0x4c180000,
+	0x42003000, 0x0000000f, 0x42027800, 0x00000002,
+	0x0401f02a, 0x4807c856, 0x42000000, 0x0010b86a,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000003,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000e,
+	0x42027800, 0x00000202, 0x0401f01c, 0x4807c856,
+	0x42000000, 0x0010b869, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000004, 0x4d3c0000, 0x4c180000,
+	0x42003000, 0x00000010, 0x42027800, 0x00000202,
+	0x0401f00e, 0x4807c856, 0x42000000, 0x0010b83e,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000001,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000c,
+	0x42027800, 0x00000202, 0x42001800, 0x0000ffff,
+	0x42002000, 0x00000007, 0x0201f800, 0x00103aae,
+	0x5c003000, 0x4d400000, 0x0201f800, 0x0010a95d,
+	0x42028000, 0x0000002a, 0x0201f800, 0x00101fe5,
+	0x5c028000, 0x5c027800, 0x1c01f000, 0x4807c856,
+	0x04011000, 0x4a03c840, 0x0010b54b, 0x4a03c842,
+	0x00000040, 0x40000000, 0x040117ff, 0x42007800,
+	0x0010b54b, 0x46007800, 0x00000011, 0x803c7800,
+	0x4a007800, 0x220000ef, 0x4a007801, 0x000000ef,
+	0x4a007802, 0x01380000, 0x4a007803, 0x00000000,
+	0x4a007804, 0xffffffff, 0x4a007805, 0x00000000,
+	0x1c01f000, 0x59c400a3, 0x80300500, 0x80340540,
+	0x480388a3, 0x1c01f000, 0x4833c857, 0x59c400a3,
+	0x80300540, 0x480388a3, 0x80300580, 0x480388a3,
+	0x1c01f000, 0x4803c856, 0x04000004, 0x4a03504b,
+	0x00000001, 0x0401f002, 0x497b504b, 0x1c01f000,
+	0x4803c856, 0x59c80002, 0x80000540, 0x0400000a,
+	0x80000040, 0x04000008, 0x4a039005, 0x00000140,
+	0x42000000, 0x00000006, 0x80000040, 0x040207ff,
+	0x0401f7f4, 0x1c01f000, 0x4c5c0000, 0x4c600000,
+	0x59c4b805, 0x485fc856, 0x8c5cbd3a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+	0x4000c000, 0x0201f800, 0x00101963, 0x4a038805,
+	0x04000000, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x497a6a00, 0x4937c857, 0x4a026c00, 0x00000707,
+	0x497a6801, 0x497a6808, 0x497a6809, 0x497a6806,
+	0x497a6807, 0x497a6c0b, 0x497a680c, 0x0201f800,
+	0x00103b25, 0x04020006, 0x5934080f, 0x59340010,
+	0x80040540, 0x02020800, 0x001005d8, 0x4a026a04,
+	0x00000100, 0x497a6a03, 0x59340402, 0x82000500,
+	0x000000ff, 0x48026c02, 0x497a6c04, 0x497a6a05,
+	0x497a6c05, 0x497a6811, 0x4d2c0000, 0x5934000d,
+	0x49466c03, 0x80025d40, 0x04000004, 0x0201f800,
+	0x001007fd, 0x497a680d, 0x5c025800, 0x599c0401,
+	0x48026a0b, 0x599c0208, 0x48026c12, 0x497a680a,
+	0x0201f000, 0x00104c62, 0x42000000, 0x00000005,
+	0x80000d80, 0x0401f02d, 0x0201f800, 0x00104a09,
+	0x04020017, 0x59a80026, 0x8c00050a, 0x04020010,
+	0x59340212, 0x82000500, 0x0000ff00, 0x4803c857,
+	0x0400000b, 0x59340a00, 0x8c040d1e, 0x02000000,
+	0x000201c4, 0x42000000, 0x00000029, 0x42000800,
+	0x00001000, 0x492fc857, 0x0401f018, 0x492fc857,
+	0x42000000, 0x00000028, 0x0401f012, 0x59a80805,
+	0x8c040d02, 0x04020003, 0x8c040d00, 0x04000004,
+	0x42000000, 0x00000004, 0x0401f00a, 0x42000000,
+	0x00000029, 0x59340a00, 0x8c040d1e, 0x04000005,
+	0x492fc857, 0x42000800, 0x00001000, 0x0401f003,
+	0x492fc857, 0x80000d80, 0x4803c857, 0x80028540,
+	0x1c01f000, 0x4803c857, 0x59a80005, 0x8c000500,
+	0x040207ec, 0x0201f800, 0x001049e7, 0x040207e4,
+	0x59340200, 0x8c00050e, 0x040007e1, 0x0201f000,
+	0x000201c4, 0x0201f800, 0x001047eb, 0x040007bf,
+	0x0201f000, 0x000201c8, 0x592c0206, 0x492fc857,
+	0x82000d80, 0x000007ff, 0x04020006, 0x4a025c0a,
+	0x00000030, 0x42026800, 0x0010b524, 0x0401f021,
+	0x82000c80, 0x000007f0, 0x04021046, 0x81ac0400,
+	0x50000000, 0x80026d40, 0x04000038, 0x0201f800,
+	0x001048e3, 0x04020038, 0x592c040a, 0x8c00050a,
+	0x04020014, 0x592e6009, 0x83300480, 0x0010d1c0,
+	0x0400103b, 0x41580000, 0x81300480, 0x04021038,
+	0x59300c06, 0x82040580, 0x00000009, 0x04020037,
+	0x4a025a06, 0x00000000, 0x497a5800, 0x59300008,
+	0x80000540, 0x04020018, 0x492e6008, 0x0401f010,
+	0x0201f800, 0x0002075a, 0x04000019, 0x592c0206,
+	0x49366009, 0x492e6008, 0x4a026406, 0x00000009,
+	0x497a6015, 0x49325809, 0x82000d80, 0x000007ff,
+	0x04020003, 0x4a026015, 0x00008000, 0x42027000,
+	0x00000043, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f020, 0x40000800, 0x58040000, 0x80000d40,
+	0x040207fd, 0x492c0800, 0x0401f01a, 0x42000000,
+	0x0000002c, 0x0401f016, 0x42000000, 0x00000028,
+	0x0401f013, 0x59a80805, 0x82040500, 0x00000003,
+	0x04000004, 0x42000000, 0x00000004, 0x0401f00c,
+	0x42000000, 0x00000029, 0x0401f009, 0x42000000,
+	0x00000008, 0x0401f006, 0x82040580, 0x00000007,
+	0x040207fb, 0x42000000, 0x00000005, 0x80000540,
+	0x1c01f000, 0x492fc857, 0x592e8c06, 0x83440d80,
+	0x000007fc, 0x04000004, 0x83440480, 0x000007f0,
+	0x04021014, 0x0201f800, 0x00020245, 0x04020011,
+	0x0201f800, 0x001049f3, 0x04020011, 0x0201f800,
+	0x0002075a, 0x0400001c, 0x49366009, 0x492e6008,
+	0x4a026406, 0x0000000a, 0x42027000, 0x00000040,
+	0x0201f800, 0x000207a1, 0x80000580, 0x0401f011,
+	0x42000000, 0x00000028, 0x0401f00d, 0x0201f800,
+	0x00104a09, 0x040007fb, 0x59a80805, 0x82040d00,
+	0x00000003, 0x04000004, 0x42000000, 0x00000004,
+	0x0401f003, 0x42000000, 0x00000029, 0x80000540,
+	0x1c01f000, 0x42000000, 0x0000002c, 0x0401f7fc,
+	0x492fc857, 0x592e8c06, 0x4947c857, 0x83440c80,
+	0x00000800, 0x42000000, 0x0000000a, 0x04021176,
+	0x592c4207, 0x4823c857, 0x82200500, 0x0000000f,
+	0x0c01f001, 0x001043d5, 0x0010445d, 0x001044a9,
+	0x001044b4, 0x001044bf, 0x001043d1, 0x001043d1,
+	0x001043d1, 0x001044cf, 0x00104513, 0x00104530,
+	0x001043d1, 0x001043d1, 0x001043d1, 0x001043d1,
+	0x001043d1, 0x4803c857, 0x42000000, 0x0000000c,
+	0x0401f15d, 0x592c1008, 0x82081500, 0x00ffffff,
+	0x59a80010, 0x80084d80, 0x42000000, 0x00000010,
+	0x04000155, 0x0201f800, 0x00104919, 0x04000036,
+	0x4803c857, 0x82004d80, 0x0000001d, 0x0402001a,
+	0x0201f800, 0x00105755, 0x59340405, 0x4c000000,
+	0x0201f800, 0x001049e7, 0x5c000000, 0x04000004,
+	0x8c20450a, 0x04000028, 0x80000580, 0x44002800,
+	0x59340008, 0x48002802, 0x59340009, 0x48002801,
+	0x59340006, 0x48002804, 0x59340007, 0x48002803,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010955f,
+	0x0401f166, 0x4803c857, 0x82004d80, 0x0000001a,
+	0x04020003, 0x40101000, 0x0401f136, 0x4803c857,
+	0x82004d80, 0x0000001b, 0x04020003, 0x40181000,
+	0x0401f130, 0x4803c857, 0x82004d80, 0x0000001c,
+	0x04000131, 0x82004d80, 0x00000019, 0x42000000,
+	0x0000000a, 0x04000120, 0x42000000, 0x0000000a,
+	0x04020137, 0x59a80005, 0x8c000514, 0x0400001b,
+	0x0201f800, 0x001049e7, 0x04000018, 0x59340212,
+	0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+	0x0402000c, 0x42001000, 0x00000008, 0x59a80026,
+	0x8c000506, 0x04020009, 0x59340002, 0x82000500,
+	0x00ff0000, 0x82000580, 0x00ff0000, 0x04000007,
+	0x0201f800, 0x00104c6d, 0x42000000, 0x0000001c,
+	0x40181000, 0x04020107, 0x0201f800, 0x0002075a,
+	0x04000111, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000001, 0x8c20450a, 0x04000004, 0x592c0404,
+	0x8400055c, 0x48025c04, 0x4c200000, 0x4d3c0000,
+	0x42027800, 0x00001000, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x5c004000, 0x8c204512, 0x0400000b,
+	0x599c0018, 0x8c000518, 0x04000008, 0x592c0009,
+	0x82000500, 0x00000380, 0x5934080a, 0x80040d40,
+	0x84040d54, 0x4806680a, 0x417a7800, 0x0401f914,
+	0x42000800, 0x00000003, 0x0401f91b, 0x42027000,
+	0x00000002, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f10a, 0x0201f800, 0x00020245, 0x040200ec,
+	0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+	0x001049e7, 0x040200ec, 0x417a7800, 0x417a6000,
+	0x0201f800, 0x001020a1, 0x59a80005, 0x8c000514,
+	0x0400001b, 0x0201f800, 0x001049e7, 0x04000018,
+	0x59340212, 0x82000500, 0x0000ff00, 0x42001000,
+	0x00000010, 0x0402000c, 0x42001000, 0x00000008,
+	0x59a80026, 0x8c000506, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x04000007, 0x0201f800, 0x00104c6d, 0x42000000,
+	0x0000001c, 0x40181000, 0x040200b2, 0x0201f800,
+	0x0002075a, 0x040000bc, 0x5934080a, 0x8c204512,
+	0x0400000c, 0x599c0018, 0x8c000518, 0x04000009,
+	0x592c0009, 0x82000500, 0x00000380, 0x82041500,
+	0xfffffc7f, 0x80080d40, 0x84040d54, 0x0401f002,
+	0x84040d14, 0x4806680a, 0x49366009, 0x492e6008,
+	0x4a026406, 0x00000001, 0x417a7800, 0x0401f8c8,
+	0x42000800, 0x00000005, 0x0401f8cf, 0x42027000,
+	0x00000003, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f0be, 0x0201f800, 0x00020245, 0x040200a0,
+	0x0201f800, 0x001049fc, 0x040200a3, 0x0201f800,
+	0x00109517, 0x04000094, 0x80000580, 0x0401f0b3,
+	0x0201f800, 0x00020245, 0x04020095, 0x0201f800,
+	0x001049fc, 0x04020098, 0x0201f800, 0x001090e6,
+	0x04000089, 0x80000580, 0x0401f0a8, 0x0201f800,
+	0x00020245, 0x0402008a, 0x83444d80, 0x000007fe,
+	0x42000000, 0x0000000a, 0x0402006b, 0x0201f800,
+	0x001049e7, 0x04020088, 0x0201f800, 0x0010952f,
+	0x04000079, 0x80000580, 0x0401f098, 0x82200500,
+	0x00000070, 0x04020005, 0x8c20450e, 0x42000000,
+	0x0000000c, 0x0402005c, 0x8c20450a, 0x0400000d,
+	0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e,
+	0x04020002, 0x853e7d56, 0x82200500, 0x000000a0,
+	0x0201f800, 0x001049d3, 0x5c027800, 0x0401f07f,
+	0x0201f800, 0x00020245, 0x04020065, 0x8c204508,
+	0x04000010, 0x4d3c0000, 0x42027800, 0x00001000,
+	0x8c20450e, 0x04020002, 0x853e7d56, 0x82200500,
+	0x00000090, 0x0201f800, 0x001049bb, 0x5c027800,
+	0x42000000, 0x0000000a, 0x0402003b, 0x0401f06b,
+	0x836c0580, 0x00000003, 0x42000800, 0x00000007,
+	0x0402000f, 0x0201f800, 0x001049f3, 0x04000007,
+	0x4c000000, 0x0201f800, 0x00104a1f, 0x5c000000,
+	0x0400004d, 0x0401f05d, 0x0201f800, 0x001094c5,
+	0x04000007, 0x80000580, 0x0401f05c, 0x0201f800,
+	0x00104a1f, 0x04000051, 0x0401f054, 0x0201f800,
+	0x00104a1f, 0x04000034, 0x0401f050, 0x0201f800,
+	0x00020245, 0x04020036, 0x836c0580, 0x00000003,
+	0x04020040, 0x8c204508, 0x04000006, 0x417a7800,
+	0x417a6000, 0x0201f800, 0x001020a1, 0x0401f043,
+	0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+	0x001049e7, 0x0402002c, 0x417a7800, 0x417a6000,
+	0x0201f800, 0x001020a1, 0x480bc856, 0x0201f800,
+	0x00109332, 0x04000018, 0x80000580, 0x0401f037,
+	0x0401f7e3, 0x480bc857, 0x42000800, 0x00000019,
+	0x40001000, 0x4200b000, 0x00000002, 0x0401f00a,
+	0x480bc857, 0x40000800, 0x4200b000, 0x00000002,
+	0x0401f005, 0x480bc857, 0x40000800, 0x4200b000,
+	0x00000001, 0x480bc857, 0x42028000, 0x00000031,
+	0x0401f020, 0x480bc857, 0x42000800, 0x00000003,
+	0x4200b000, 0x00000001, 0x0401f7f7, 0x480bc857,
+	0x42000800, 0x0000000a, 0x4200b000, 0x00000001,
+	0x0401f7f1, 0x480bc857, 0x42000800, 0x00000009,
+	0x40001000, 0x4200b000, 0x00000002, 0x0401f7ea,
+	0x480bc857, 0x42000800, 0x00000007, 0x4200b000,
+	0x00000001, 0x0401f7e4, 0x480bc857, 0x4200b000,
+	0x00000001, 0x0401f7e0, 0x80028580, 0x4178b000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4937c857,
+	0x59326809, 0x59341200, 0x813e79c0, 0x04000003,
+	0x84081540, 0x0401f002, 0x84081500, 0x480a6a00,
+	0x1c01f000, 0x59326809, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4937c857, 0x82040580, 0x00000006,
+	0x04020004, 0x42000000, 0x00000606, 0x0401f021,
+	0x82040580, 0x00000004, 0x04020004, 0x42000000,
+	0x00000404, 0x0401f01b, 0x82040580, 0x00000007,
+	0x42000000, 0x00000707, 0x04000016, 0x82040580,
+	0x00000003, 0x42000000, 0x00000703, 0x04000011,
+	0x82040580, 0x00000005, 0x42000000, 0x00000405,
+	0x0400000c, 0x82040580, 0x00000009, 0x42000000,
+	0x00000409, 0x04000007, 0x82040580, 0x0000000b,
+	0x42000000, 0x0000070b, 0x02020800, 0x001005d8,
+	0x4803c857, 0x48026c00, 0x82040d80, 0x00000006,
+	0x04020005, 0x59341404, 0x800811c0, 0x02000800,
+	0x001005d8, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4947c857, 0x481bc857, 0x83440480,
+	0x00000800, 0x04021034, 0x83441400, 0x0010ac00,
+	0x50080000, 0x80026d40, 0x04020011, 0x4c180000,
+	0x4d2c0000, 0x0201f800, 0x001007d3, 0x412e6800,
+	0x5c025800, 0x5c003000, 0x04000027, 0x45341000,
+	0x497a680d, 0x497a6810, 0x497a680f, 0x497a680e,
+	0x4c180000, 0x0401fcf3, 0x5c003000, 0x59340a12,
+	0x4c040000, 0x0201f800, 0x0010513b, 0x5c000800,
+	0x04000009, 0x82180500, 0x00ffff00, 0x04000008,
+	0x59a81010, 0x82081500, 0x00ffff00, 0x80080580,
+	0x04000003, 0x80000580, 0x0401f004, 0x82180500,
+	0x000000ff, 0x800000d0, 0x80040d80, 0x04000003,
+	0x4803c857, 0x48026a12, 0x59340002, 0x80180580,
+	0x04000003, 0x481bc857, 0x481a6802, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x82000540, 0x00000001,
+	0x0401f7fc, 0x4947c857, 0x83440480, 0x00000800,
+	0x04021011, 0x83441400, 0x0010ac00, 0x50080000,
+	0x80026d40, 0x0400000b, 0x0401fbf9, 0x0402000a,
+	0x59a80005, 0x8c000502, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04000004, 0x82000540, 0x00000001,
+	0x1c01f000, 0x80000580, 0x0401f7fe, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x4947c857, 0x4d2c0000,
+	0x4d300000, 0x83440480, 0x00000800, 0x04021024,
+	0x83441400, 0x0010ac00, 0x50080000, 0x80026d40,
+	0x0400001b, 0x45781000, 0x5934000d, 0x80025d40,
+	0x02020800, 0x001007fd, 0x59366011, 0x813261c0,
+	0x0400000e, 0x4c640000, 0x5930c800, 0x59325808,
+	0x0201f800, 0x00109037, 0x02020800, 0x001007fd,
+	0x0201f800, 0x0002077d, 0x82666540, 0x00000000,
+	0x040207f6, 0x5c00c800, 0x0201f800, 0x00104c62,
+	0x41365800, 0x0201f800, 0x001007f5, 0x80000580,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x0401f7fb, 0x4937c857, 0x4c580000,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x48026802,
+	0x497a6c01, 0x497a6a01, 0x59340200, 0x84000502,
+	0x48026a00, 0x0201f800, 0x0010513b, 0x04020017,
+	0x59340403, 0x82000580, 0x000007fe, 0x04000005,
+	0x59a80026, 0x8c00050a, 0x04020010, 0x0401f008,
+	0x59cc0408, 0x8c000518, 0x0400000c, 0x59cc0009,
+	0x48035035, 0x59cc000a, 0x48035036, 0x59cc0207,
+	0x80000540, 0x04020003, 0x42000000, 0x00000001,
+	0x48038893, 0x4803501e, 0x59cc0a09, 0x82040d00,
+	0x00000010, 0x59cc0408, 0x82000500, 0x00000020,
+	0x04000002, 0x84040d40, 0x5934000a, 0x82000500,
+	0xffffffee, 0x80040540, 0x4802680a, 0x83cca400,
+	0x0000000b, 0x8334ac00, 0x00000006, 0x4200b000,
+	0x00000002, 0x0201f800, 0x0010ab17, 0x83cca400,
+	0x0000000d, 0x8334ac00, 0x00000008, 0x4200b000,
+	0x00000002, 0x0201f800, 0x0010ab17, 0x59cc0a18,
+	0x82040480, 0x00000800, 0x0402100c, 0x82040480,
+	0x00000400, 0x04001004, 0x42000800, 0x00000400,
+	0x0401f006, 0x82040480, 0x00000200, 0x04001003,
+	0x42000800, 0x00000200, 0x48066a04, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020003, 0x59cc0a08,
+	0x48066a04, 0x42000800, 0x00000004, 0x59cc1207,
+	0x800811c0, 0x04000005, 0x82080480, 0x00000004,
+	0x04021002, 0x40080800, 0x48066c04, 0x5c00b000,
+	0x1c01f000, 0x4937c857, 0x59a80026, 0x8c000508,
+	0x04000004, 0x84000556, 0x4803c857, 0x48035026,
+	0x59cc0207, 0x4803c857, 0x48026a05, 0x59cc020a,
+	0x4803c857, 0x48026c05, 0x59341200, 0x599c0818,
+	0x5934180a, 0x4807c857, 0x480bc857, 0x480fc857,
+	0x59cc2006, 0x82102500, 0xff000000, 0x82102580,
+	0x02000000, 0x04000007, 0x8c00050e, 0x04000009,
+	0x8c0c1d14, 0x04000003, 0x8c0c1d0e, 0x04000005,
+	0x8c040d18, 0x04000003, 0x8408154a, 0x0401f002,
+	0x8408150a, 0x8c000510, 0x04000009, 0x8c0c1d14,
+	0x04000003, 0x8c0c1d10, 0x04000005, 0x8c040d18,
+	0x04000003, 0x8408154e, 0x0401f002, 0x8408150e,
+	0x8c000512, 0x04000009, 0x8c0c1d14, 0x04000003,
+	0x8c0c1d12, 0x04000005, 0x8c040d18, 0x04000003,
+	0x8408155c, 0x0401f002, 0x8408151c, 0x480a6a00,
+	0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+	0x4c580000, 0x5934000d, 0x80025d40, 0x04000029,
+	0x592c0003, 0x82000480, 0x00000008, 0x0400100b,
+	0x412cb800, 0x592c0001, 0x80025d40, 0x040207f9,
+	0x0201f800, 0x001007e4, 0x04000037, 0x492fc857,
+	0x492cb801, 0x0401f020, 0x832c0c00, 0x00000004,
+	0x4200b000, 0x00000008, 0x50040000, 0x82000580,
+	0xffffffff, 0x04020006, 0x80041000, 0x50080000,
+	0x82000580, 0xffffffff, 0x04000007, 0x82040c00,
+	0x00000002, 0x8058b040, 0x040207f4, 0x0201f800,
+	0x001005d8, 0x45480800, 0x454c1000, 0x592c1803,
+	0x800c1800, 0x480e5803, 0x480fc857, 0x0401f014,
+	0x0201f800, 0x001007e4, 0x04000017, 0x492fc857,
+	0x492e680d, 0x497a5802, 0x4a025803, 0x00000001,
+	0x494a5804, 0x494e5805, 0x832c0c00, 0x00000006,
+	0x4200b000, 0x0000000e, 0x46000800, 0xffffffff,
+	0x80040800, 0x8058b040, 0x040207fc, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c025800, 0x5c00b800,
+	0x1c01f000, 0x80000580, 0x0401f7fb, 0x4803c856,
+	0x4d3c0000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+	0x0400001f, 0x592c0002, 0x80000540, 0x0402001f,
+	0x412e7800, 0x0401f8ce, 0x0402001c, 0x46000800,
+	0xffffffff, 0x46001000, 0xffffffff, 0x4813c857,
+	0x480fc857, 0x580c0003, 0x82000c80, 0x00000002,
+	0x04021014, 0x480fc857, 0x400c0000, 0x812c0580,
+	0x04020004, 0x580c0001, 0x4802680d, 0x0401f003,
+	0x580c0001, 0x48002001, 0x400e5800, 0x0201f800,
+	0x001007f4, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c027800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+	0x80000040, 0x48001803, 0x4803c857, 0x0401f7f6,
+	0x0201f800, 0x00020086, 0x59300007, 0x8400054e,
+	0x48026007, 0x592c1a04, 0x820c1d00, 0x000000ff,
+	0x820c0580, 0x00000048, 0x04000013, 0x0201f000,
+	0x0002028e, 0x8c000500, 0x02020800, 0x000200e5,
+	0x4a026203, 0x00000002, 0x592c1a04, 0x820c1d00,
+	0x000000ff, 0x820c0580, 0x00000018, 0x02000000,
+	0x0002028e, 0x820c0580, 0x00000048, 0x02020000,
+	0x0002028e, 0x42000800, 0x80000804, 0x0201f800,
+	0x00106721, 0x0201f000, 0x00020297, 0x4a025a06,
+	0x00000008, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x00000029, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x0000002a, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x00000028, 0x0201f000, 0x000202da, 0x4943c857,
+	0x4d440000, 0x4d340000, 0x4d2c0000, 0x4c580000,
+	0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+	0x00020245, 0x0402000d, 0x8d3e7d14, 0x04000005,
+	0x59340212, 0x82000500, 0x0000ff00, 0x04000007,
+	0x8d3e7d06, 0x04000004, 0x59340200, 0x8c00050e,
+	0x04020002, 0x0401f813, 0x81468800, 0x8058b040,
+	0x040207ef, 0x83440480, 0x00000800, 0x04021008,
+	0x8d3e7d02, 0x04000006, 0x42028800, 0x000007f0,
+	0x4200b000, 0x00000010, 0x0401f7e5, 0x5c00b000,
+	0x5c025800, 0x5c026800, 0x5c028800, 0x1c01f000,
+	0x4d2c0000, 0x41783000, 0x5936580f, 0x812e59c0,
+	0x04000029, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000012, 0x04000020, 0x8d3e7d00,
+	0x04000003, 0x0401f83c, 0x0402001c, 0x592c2000,
+	0x497a5800, 0x801831c0, 0x04020009, 0x59340010,
+	0x812c0580, 0x04020004, 0x497a680f, 0x497a6810,
+	0x0401f008, 0x4812680f, 0x0401f006, 0x48103000,
+	0x59340010, 0x812c0580, 0x04020002, 0x481a6810,
+	0x4a025a04, 0x00000103, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+	0x40125800, 0x0401f7da, 0x412c3000, 0x592e5800,
+	0x0401f7d7, 0x5c025800, 0x1c01f000, 0x4803c856,
+	0x41781800, 0x5934000f, 0x80025d40, 0x04000010,
+	0x592c0005, 0x80200580, 0x592c0000, 0x04000003,
+	0x412c1800, 0x0401f7f9, 0x497a5800, 0x800c19c0,
+	0x04000008, 0x48001800, 0x80000540, 0x04020004,
+	0x480e6810, 0x82000540, 0x00000001, 0x1c01f000,
+	0x4802680f, 0x80000540, 0x040207fd, 0x497a6810,
+	0x0401f7f9, 0x592c0008, 0x81480580, 0x04020003,
+	0x592c0009, 0x814c0580, 0x1c01f000, 0x4803c856,
+	0x4c580000, 0x413c1800, 0x400c2000, 0x593c0002,
+	0x80000540, 0x04020018, 0x4200b000, 0x00000008,
+	0x820c0c00, 0x00000004, 0x50040000, 0x81480580,
+	0x04020005, 0x80041000, 0x50080000, 0x814c0580,
+	0x0400000d, 0x82040c00, 0x00000002, 0x8058b040,
+	0x040207f6, 0x400c2000, 0x580c0001, 0x80001d40,
+	0x040207ee, 0x82000540, 0x00000001, 0x5c00b000,
+	0x1c01f000, 0x80000580, 0x0401f7fd, 0x4937c857,
+	0x4c580000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+	0x04020016, 0x0201f800, 0x001007e4, 0x04000010,
+	0x492e680d, 0x4a025802, 0x00000001, 0x497a5803,
+	0x832c0c00, 0x00000004, 0x4200b000, 0x00000010,
+	0x46000800, 0xffffffff, 0x80040800, 0x8058b040,
+	0x040207fc, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c00b000, 0x1c01f000, 0x4d2c0000, 0x592e5801,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x0401f7ea,
+	0x4d2c0000, 0x5936580d, 0x812e59c0, 0x04000007,
+	0x4937c857, 0x497a680d, 0x0201f800, 0x001007fd,
+	0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+	0x59340405, 0x4937c857, 0x4803c857, 0x8c000508,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x0010513b,
+	0x04000011, 0x59a80815, 0x8c040d04, 0x0402000e,
+	0x59a80826, 0x8c040d06, 0x0400000b, 0x83ac0400,
+	0x000007fe, 0x50000000, 0x80026d40, 0x04000006,
+	0x0401f9a7, 0x04020004, 0x59340200, 0x8400055a,
+	0x48026a00, 0x599c0017, 0x8c000508, 0x04000015,
+	0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+	0x00020245, 0x0402000c, 0x0401f999, 0x0402000a,
+	0x59a80010, 0x59340802, 0x80040580, 0x82000500,
+	0x00ffff00, 0x04020004, 0x59340200, 0x8400055a,
+	0x48026a00, 0x81468800, 0x8058b040, 0x040207f0,
+	0x0401f884, 0x04000003, 0x59a80836, 0x0401f006,
+	0x599c0017, 0x8c000508, 0x04000007, 0x42000800,
+	0x000007d0, 0x42001000, 0x00104876, 0x0201f800,
+	0x0010606e, 0x1c01f000, 0x4803c856, 0x4d340000,
+	0x4d440000, 0x4d3c0000, 0x4c580000, 0x42001000,
+	0x00104876, 0x0201f800, 0x00105f90, 0x59a80826,
+	0x8c040d06, 0x04000015, 0x0401f86a, 0x04000013,
+	0x83ae6c00, 0x000007fe, 0x51366800, 0x59340200,
+	0x8400051a, 0x48026a00, 0x599c0017, 0x8c000508,
+	0x04000007, 0x42000800, 0x000007d0, 0x42001000,
+	0x00104876, 0x0201f800, 0x0010606e, 0x0201f800,
+	0x00101e45, 0x0401f027, 0x4200b000, 0x000007f0,
+	0x80028d80, 0x0201f800, 0x00020245, 0x0402001e,
+	0x59340200, 0x8c00051a, 0x0400001b, 0x59368c03,
+	0x417a7800, 0x42028000, 0x00000029, 0x41783000,
+	0x0201f800, 0x0010a446, 0x59340200, 0x84000558,
+	0x8400051a, 0x48026a00, 0x4937c857, 0x4a026c00,
+	0x00000707, 0x42028000, 0x00000029, 0x0201f800,
+	0x00106ab4, 0x417a7800, 0x0201f800, 0x001067fd,
+	0x80000d80, 0x0201f800, 0x0010a2ff, 0x0201f800,
+	0x00106c4b, 0x81468800, 0x8058b040, 0x040207de,
+	0x5c00b000, 0x5c027800, 0x5c028800, 0x5c026800,
+	0x1c01f000, 0x4933c857, 0x59303809, 0x581c0200,
+	0x8400051a, 0x48003a00, 0x1c01f000, 0x4803c856,
+	0x42026800, 0x0010b524, 0x497a680e, 0x42028800,
+	0x000007ff, 0x0201f800, 0x001042b4, 0x4937c857,
+	0x4a026c00, 0x00000606, 0x4a026802, 0x00ffffff,
+	0x4a026a04, 0x00000200, 0x4a026c04, 0x00000002,
+	0x1c01f000, 0x59300009, 0x50000000, 0x4933c857,
+	0x4803c857, 0x8c00050e, 0x1c01f000, 0x59300009,
+	0x50000000, 0x8c00050a, 0x1c01f000, 0x4933c856,
+	0x0401f90f, 0x04000006, 0x59340400, 0x82000d00,
+	0x000000ff, 0x82041580, 0x00000005, 0x1c01f000,
+	0x4d340000, 0x83ac0400, 0x000007fe, 0x50000000,
+	0x80026d40, 0x04000003, 0x59340200, 0x8c00051a,
+	0x5c026800, 0x1c01f000, 0x4937c857, 0x493fc857,
+	0x59340403, 0x81ac0400, 0x50000000, 0x81340580,
+	0x02020800, 0x001005d8, 0x59341200, 0x813e79c0,
+	0x04000003, 0x8408155e, 0x0401f002, 0x8408151e,
+	0x480a6a00, 0x1c01f000, 0x4937c857, 0x0201f800,
+	0x0010210a, 0x04000006, 0x59a80835, 0x42001000,
+	0x00104910, 0x0201f800, 0x0010606e, 0x1c01f000,
+	0x4937c857, 0x42001000, 0x00104910, 0x0201f800,
+	0x00105f90, 0x59a81026, 0x84081512, 0x480b5026,
+	0x1c01f000, 0x4c380000, 0x4c340000, 0x4c240000,
+	0x4c600000, 0x4008c000, 0x83440480, 0x00000800,
+	0x04021045, 0x80002d80, 0x41442000, 0x83447400,
+	0x0010ac00, 0x4200b000, 0x000007f0, 0x83444c80,
+	0x000007f0, 0x04001003, 0x4200b000, 0x00000010,
+	0x50380000, 0x80000540, 0x0402001e, 0x41440000,
+	0x80100580, 0x04020043, 0x40102800, 0x82104c80,
+	0x000007f0, 0x04001015, 0x82104d80, 0x000007fc,
+	0x04020005, 0x82604d80, 0x00fffffc, 0x0402002a,
+	0x0401f00e, 0x82104d80, 0x000007fd, 0x04020005,
+	0x82604d80, 0x00fffffd, 0x04020023, 0x0401f007,
+	0x82104d80, 0x000007ff, 0x0402001f, 0x82604d80,
+	0x00ffffff, 0x0402001c, 0x84142d5e, 0x0401f029,
+	0x40006800, 0x58343002, 0x82183500, 0x00ffffff,
+	0x40180000, 0x80600580, 0x04020019, 0x40100000,
+	0x81440580, 0x0402000a, 0x40366800, 0x8c204508,
+	0x04000053, 0x0401ff8a, 0x04020051, 0x4947c857,
+	0x42000000, 0x0000001d, 0x0401f04e, 0x4947c857,
+	0x480bc857, 0x4823c857, 0x42000000, 0x0000001a,
+	0x0401f048, 0x4947c857, 0x4863c857, 0x4813c857,
+	0x42000000, 0x00000019, 0x0401f042, 0x40100000,
+	0x81440580, 0x04020007, 0x58343002, 0x4947c857,
+	0x481bc857, 0x42000000, 0x0000001b, 0x0401f039,
+	0x80102000, 0x80387000, 0x83444c80, 0x000007f0,
+	0x04001009, 0x82104d80, 0x00000800, 0x0402000c,
+	0x42002000, 0x000007f0, 0x42007000, 0x0010b3f0,
+	0x0401f007, 0x82104d80, 0x000007f0, 0x04020004,
+	0x41782000, 0x42007000, 0x0010ac00, 0x8058b040,
+	0x040207a4, 0x801429c0, 0x04020007, 0x0201f800,
+	0x001005d8, 0x4947c857, 0x42000000, 0x0000000a,
+	0x0401f01c, 0x4d2c0000, 0x4c180000, 0x40603000,
+	0x0401fc12, 0x4947c857, 0x4937c857, 0x5c003000,
+	0x5c025800, 0x040207f4, 0x497a6a12, 0x59a80026,
+	0x8c00050a, 0x0402000d, 0x82600500, 0x00ffff00,
+	0x04000006, 0x59a84810, 0x82244d00, 0x00ffff00,
+	0x80240580, 0x04020005, 0x82600500, 0x000000ff,
+	0x800000d0, 0x48026a12, 0x48626802, 0x80000580,
+	0x80000540, 0x5c00c000, 0x5c004800, 0x5c006800,
+	0x5c007000, 0x1c01f000, 0x5934000f, 0x5934140b,
+	0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+	0x02020800, 0x00020253, 0x1c01f000, 0x4803c857,
+	0x4947c857, 0x4c300000, 0x82006500, 0x00000030,
+	0x04000006, 0x4c000000, 0x0201f800, 0x0010942a,
+	0x5c000000, 0x0402000b, 0x8c00050e, 0x04000006,
+	0x0201f800, 0x00020245, 0x04020006, 0x4937c857,
+	0x0401fc2f, 0x80000580, 0x5c006000, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fc, 0x4803c857,
+	0x4c580000, 0x4d440000, 0x40001000, 0x80000d80,
+	0x4200b000, 0x000007f0, 0x4c040000, 0x40068800,
+	0x4c080000, 0x40080000, 0x0401ffdd, 0x5c001000,
+	0x5c000800, 0x80040800, 0x8058b040, 0x040207f7,
+	0x5c028800, 0x5c00b000, 0x1c01f000, 0x4c5c0000,
+	0x59340400, 0x8200bd80, 0x00000606, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x59340400, 0x8200bd80,
+	0x00000404, 0x5c00b800, 0x1c01f000, 0x4c5c0000,
+	0x59340400, 0x8200bd80, 0x00000404, 0x04000003,
+	0x8200bd80, 0x00000606, 0x5c00b800, 0x1c01f000,
+	0x4c5c0000, 0x4c600000, 0x59340400, 0x8200bd00,
+	0x0000ff00, 0x825cc580, 0x00000400, 0x04000003,
+	0x825cc580, 0x00000600, 0x5c00c000, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x59340400, 0x82000500,
+	0x000000ff, 0x8200bd80, 0x00000003, 0x04000003,
+	0x8200bd80, 0x00000005, 0x5c00b800, 0x1c01f000,
+	0x4c5c0000, 0x59340400, 0x82000500, 0x0000ff00,
+	0x8400b9c0, 0x805c0580, 0x4937c857, 0x4803c857,
+	0x48026c00, 0x5c00b800, 0x1c01f000, 0x4c040000,
+	0x4c080000, 0x592c0207, 0x8c00050c, 0x0400000f,
+	0x592e8c06, 0x82000500, 0x00000080, 0x84000548,
+	0x4d3c0000, 0x42027800, 0x00001000, 0x0401ff90,
+	0x5c027800, 0x82000540, 0x00000001, 0x5c001000,
+	0x5c000800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+	0x592c040b, 0x82000500, 0x0000e000, 0x82000580,
+	0x00006000, 0x04000019, 0x836c0580, 0x00000003,
+	0x04000016, 0x836c0580, 0x00000002, 0x040200ff,
+	0x59a80026, 0x82000d00, 0x00000038, 0x04020005,
+	0x59a80832, 0x800409c0, 0x0400000c, 0x0401f0f7,
+	0x82000d00, 0x00000003, 0x82040d80, 0x00000003,
+	0x040200f2, 0x82000d00, 0x00000028, 0x04020003,
+	0x8c00050c, 0x040000ed, 0x592c100a, 0x82080500,
+	0xff000000, 0x040200ce, 0x59a80010, 0x80080580,
+	0x040000c8, 0x592c0c0b, 0x82040d00, 0x0000e000,
+	0x82040480, 0x00008000, 0x040210c8, 0x592e8c06,
+	0x83440480, 0x00000800, 0x04001007, 0x83440580,
+	0x0000ffff, 0x040200af, 0x800409c0, 0x040200f7,
+	0x0401f0ac, 0x800409c0, 0x040200f4, 0x41784000,
+	0x0401fead, 0x040200db, 0x42027000, 0x00000053,
+	0x592c2409, 0x82100500, 0xffffff00, 0x040200aa,
+	0x4813c857, 0x592c000c, 0x800001c0, 0x04000083,
+	0x82100580, 0x00000004, 0x040000a0, 0x82100580,
+	0x00000051, 0x0400009d, 0x82100580, 0x00000003,
+	0x04000016, 0x82100580, 0x00000020, 0x0400004b,
+	0x82100580, 0x00000024, 0x04000042, 0x82100580,
+	0x00000021, 0x04000042, 0x82100580, 0x00000050,
+	0x04000037, 0x82100580, 0x00000052, 0x04000031,
+	0x82100580, 0x00000005, 0x0402006b, 0x42027000,
+	0x00000001, 0x0401f01b, 0x42027000, 0x00000002,
+	0x59a80005, 0x8c000514, 0x04000016, 0x0401ff4c,
+	0x04000014, 0x59340212, 0x82000500, 0x0000ff00,
+	0x42001000, 0x00000010, 0x0402000c, 0x59a80026,
+	0x8c000506, 0x0402006f, 0x42001000, 0x00000008,
+	0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+	0x00ff0000, 0x04000003, 0x0401f9bf, 0x04020065,
+	0x0201f800, 0x0002075a, 0x0400007e, 0x4a026406,
+	0x00000010, 0x49366009, 0x42000800, 0x00000003,
+	0x83380580, 0x00000002, 0x04000003, 0x42000800,
+	0x0000000b, 0x0201f800, 0x00104571, 0x0401f044,
+	0x42027000, 0x00000000, 0x0401f003, 0x42027000,
+	0x00000004, 0x0401ff37, 0x04020071, 0x0401f036,
+	0x42027000, 0x00000033, 0x0401f006, 0x42027000,
+	0x00000005, 0x0401f003, 0x42027000, 0x00000003,
+	0x0401ff23, 0x04020066, 0x59a80005, 0x8c000514,
+	0x04000016, 0x0401ff12, 0x04000014, 0x59340212,
+	0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+	0x0402000c, 0x59a80026, 0x8c000506, 0x04020035,
+	0x42001000, 0x00000008, 0x59340002, 0x82000500,
+	0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003,
+	0x0401f985, 0x0402002b, 0x0201f800, 0x0002075a,
+	0x04000044, 0x4a026406, 0x00000010, 0x49366009,
+	0x42000800, 0x00000005, 0x83380580, 0x00000003,
+	0x04000003, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x0401f00a, 0x82102580, 0x00000011,
+	0x0402002d, 0x0201f800, 0x0002075a, 0x04000031,
+	0x4a026406, 0x00000010, 0x49366009, 0x492e6008,
+	0x49325808, 0x813669c0, 0x04000007, 0x592c0c0b,
+	0x8c040d18, 0x04000004, 0x59340200, 0x84000514,
+	0x48026a00, 0x0201f800, 0x000207a1, 0x80000580,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd,
+	0x42001000, 0x0000000a, 0x0401f015, 0x42001000,
+	0x00000010, 0x0401f012, 0x42001000, 0x00000016,
+	0x0401f00f, 0x42001000, 0x00000017, 0x0401f00c,
+	0x42001000, 0x00000018, 0x0401f009, 0x42001000,
+	0x0000001b, 0x0401f006, 0x42001000, 0x0000001e,
+	0x0401f003, 0x42001000, 0x00000020, 0x42000800,
+	0x00000019, 0x42028000, 0x00000031, 0x0401f7e2,
+	0x42000800, 0x00000003, 0x0401f003, 0x42000800,
+	0x0000000a, 0x41781000, 0x0401f7f7, 0x42000800,
+	0x00000009, 0x59341400, 0x0401f7f3, 0x42028000,
+	0x00000008, 0x0401f005, 0x42000800, 0x00000007,
+	0x416c1000, 0x0401f7ec, 0x41780800, 0x41781000,
+	0x0401f7cd, 0x42028000, 0x00000000, 0x0401f7fb,
+	0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+	0x82004d80, 0x0000001a, 0x04020004, 0x40101000,
+	0x40000800, 0x0401f7dc, 0x82004d80, 0x0000001b,
+	0x04020003, 0x40181000, 0x0401f7fa, 0x82004d80,
+	0x0000001c, 0x040007f7, 0x82004d80, 0x00000019,
+	0x040007b8, 0x0401f7d6, 0x592e6008, 0x0201f800,
+	0x0010941a, 0x040007b6, 0x59300c06, 0x82040580,
+	0x00000011, 0x040207d6, 0x83440580, 0x0000ffff,
+	0x04020005, 0x59326809, 0x813669c0, 0x0400000e,
+	0x0401f7cf, 0x592c100a, 0x82081500, 0x00ffffff,
+	0x41784000, 0x0401fda8, 0x040207d6, 0x59300009,
+	0x800001c0, 0x04000003, 0x81340580, 0x040207c4,
+	0x49366009, 0x592c0c0b, 0x82041500, 0x0000e000,
+	0x82080580, 0x00006000, 0x04000009, 0x59300a03,
+	0x82040580, 0x00000007, 0x040207b9, 0x492e6008,
+	0x42027000, 0x00000054, 0x0401f77f, 0x0201f800,
+	0x0010a8d4, 0x040007bc, 0x0401f7b1, 0x492fc857,
+	0x59a80021, 0x800001c0, 0x04020073, 0x592e6008,
+	0x4933c857, 0x0201f800, 0x0010941a, 0x04000041,
+	0x59301406, 0x82080580, 0x00000005, 0x0402005b,
+	0x59301203, 0x82080580, 0x00000007, 0x04020057,
+	0x592e8c06, 0x83440480, 0x00000800, 0x04021032,
+	0x41784000, 0x592c1009, 0x82081500, 0x00ffffff,
+	0x0401fd75, 0x0402005f, 0x59300009, 0x800001c0,
+	0x04000003, 0x81340580, 0x04020048, 0x4d300000,
+	0x592e6013, 0x4933c857, 0x83300580, 0xffffffff,
+	0x0400000d, 0x0201f800, 0x0010941a, 0x5c026000,
+	0x04000029, 0x591c1406, 0x82080580, 0x00000006,
+	0x04000046, 0x82080580, 0x00000011, 0x04000043,
+	0x0401f002, 0x5c026000, 0x59a80010, 0x592c100a,
+	0x82081500, 0x00ffffff, 0x80081580, 0x04020017,
+	0x592c1009, 0x82081500, 0x00ffffff, 0x80081580,
+	0x0400000f, 0x49366009, 0x492e6008, 0x42027000,
+	0x00000092, 0x0201f800, 0x000207a1, 0x80000580,
+	0x1c01f000, 0x42001000, 0x0000000a, 0x0401f00c,
+	0x42001000, 0x00000010, 0x0401f009, 0x42001000,
+	0x00000014, 0x0401f006, 0x42001000, 0x00000018,
+	0x0401f003, 0x42001000, 0x0000003c, 0x492fc857,
+	0x480bc857, 0x42000800, 0x00000019, 0x42028000,
+	0x00000031, 0x82000540, 0x00000001, 0x0401f7e9,
+	0x492fc857, 0x4803c857, 0x480bc857, 0x40000800,
+	0x0401f7f7, 0x492fc857, 0x42000800, 0x0000000a,
+	0x41781000, 0x0401f7f2, 0x4933c857, 0x59300406,
+	0x4803c857, 0x59300203, 0x4803c857, 0x59300009,
+	0x4803c857, 0x42028000, 0x00000008, 0x41780800,
+	0x41781000, 0x0401f7e8, 0x42000800, 0x0000001e,
+	0x0401f7f0, 0x42000800, 0x00000001, 0x0401f7ed,
+	0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+	0x82004d80, 0x0000001a, 0x04020003, 0x40101000,
+	0x0401f7dc, 0x82004d80, 0x0000001b, 0x04020003,
+	0x40181000, 0x0401f7d7, 0x82004d80, 0x0000001c,
+	0x040007d4, 0x82004d80, 0x00000019, 0x040007d1,
+	0x0401f7d5, 0x59302009, 0x801021c0, 0x04000035,
+	0x58101400, 0x82081d00, 0x000000ff, 0x59300c03,
+	0x82040580, 0x00000008, 0x04000022, 0x82040580,
+	0x0000000a, 0x04000017, 0x82040580, 0x0000000c,
+	0x04000010, 0x82040580, 0x00000002, 0x04000019,
+	0x82040580, 0x00000001, 0x04000012, 0x82040580,
+	0x00000003, 0x0400000b, 0x82040580, 0x00000005,
+	0x04000004, 0x82040580, 0x00000033, 0x04020019,
+	0x820c0580, 0x00000009, 0x0400000d, 0x0401f015,
+	0x820c0580, 0x00000005, 0x04000009, 0x0401f011,
+	0x820c0580, 0x0000000b, 0x04000005, 0x0401f00d,
+	0x820c0580, 0x00000003, 0x0402000a, 0x82081d00,
+	0xffffff00, 0x840c01c0, 0x800c0540, 0x4813c857,
+	0x480bc857, 0x4807c857, 0x4803c857, 0x48002400,
+	0x1c01f000, 0x599c0017, 0x8c00050a, 0x04000003,
+	0x80000580, 0x1c01f000, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000008, 0x42028800, 0x000007fd,
+	0x0201f800, 0x00020245, 0x04020003, 0x5934000a,
+	0x8c000504, 0x1c01f000, 0x4d300000, 0x5934000e,
+	0x80026540, 0x04000006, 0x0201f800, 0x001062d5,
+	0x02000800, 0x001064ad, 0x497a680e, 0x5c026000,
+	0x1c01f000, 0x4d440000, 0x4d340000, 0x80000580,
+	0x40001800, 0x40028800, 0x82080580, 0x00000008,
+	0x04020003, 0x42001800, 0x00000001, 0x0201f800,
+	0x00020245, 0x0402000a, 0x0401fd6d, 0x04020008,
+	0x800c19c0, 0x04000004, 0x59340405, 0x8c000508,
+	0x04000003, 0x80081040, 0x04000009, 0x81468800,
+	0x83440480, 0x00000800, 0x040017f1, 0x80000580,
+	0x5c026800, 0x5c028800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x5c026800, 0x5c028800, 0x1c01f000,
+	0x4a033020, 0x00000000, 0x497b3026, 0x497b3027,
+	0x497b3028, 0x497b3029, 0x497b302b, 0x497b3021,
+	0x4a03b104, 0x60000001, 0x1c01f000, 0x4803c856,
+	0x599c0018, 0x497b3024, 0x497b3025, 0x82000500,
+	0x0000000f, 0x82000d80, 0x00000005, 0x04000006,
+	0x82000580, 0x00000006, 0x0400000d, 0x497b3022,
+	0x1c01f000, 0x4a033022, 0x00000005, 0x599c0216,
+	0x82000500, 0x0000ffff, 0x04020003, 0x42000000,
+	0x00000002, 0x48033023, 0x1c01f000, 0x4a033022,
+	0x00000006, 0x0401f7f6, 0x0401ffe5, 0x4a03c826,
+	0x00000004, 0x599c0209, 0x80000540, 0x0400001f,
+	0x599c0207, 0x80000540, 0x04000007, 0x800000cc,
+	0x599c080d, 0x80040400, 0x4803b100, 0x497bb102,
+	0x59d80101, 0x599c000d, 0x4803b100, 0x599c000e,
+	0x4803b101, 0x599c0207, 0x80000540, 0x04020002,
+	0x497bb102, 0x599c0a09, 0x82040540, 0x00400000,
+	0x59980822, 0x4803b103, 0x4a03b109, 0x00000004,
+	0x4a03b104, 0x10000001, 0x800409c0, 0x04020004,
+	0x4a033020, 0x00000001, 0x1c01f000, 0x4a033020,
+	0x00000002, 0x0401f7fd, 0x59980022, 0x4803c856,
+	0x80000540, 0x02000000, 0x000202de, 0x0401f017,
+	0x42034000, 0x0010b4a4, 0x59a1d81e, 0x80edd9c0,
+	0x02000800, 0x001005d8, 0x58ec0009, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x4803c857, 0x800001c0,
+	0x08020000, 0x0201f800, 0x001005d8, 0x5931d821,
+	0x58ef400b, 0x58ec0009, 0x800001c0, 0x08020000,
+	0x0201f800, 0x001005d8, 0x497a5800, 0x59980026,
+	0x80000540, 0x0402008c, 0x59d80105, 0x82000d00,
+	0x00018780, 0x040201da, 0x80000106, 0x82000500,
+	0x00000003, 0x0c01f001, 0x00104d0a, 0x00104d89,
+	0x00104d22, 0x00104d50, 0x592c0001, 0x492fc857,
+	0x492fb107, 0x80000d40, 0x04020007, 0x59940019,
+	0x80000540, 0x04022003, 0x59980023, 0x48032819,
+	0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+	0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+	0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7ee, 0x492fc857, 0x492fb107,
+	0x592c0001, 0x80000d40, 0x04020012, 0x59da5908,
+	0x835c0480, 0x00000020, 0x0400101c, 0x0402b01a,
+	0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+	0x00018780, 0x040201aa, 0x59940019, 0x80000540,
+	0x04022003, 0x59980023, 0x48032819, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0401f7e3, 0x0400f009, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7e0, 0x492fa807, 0x0401f7de,
+	0x492fc857, 0x59d81108, 0x45681000, 0x400ad000,
+	0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+	0x00001200, 0x48039000, 0x0402d00c, 0x592c0001,
+	0x492fc857, 0x492fb107, 0x80000d40, 0x0402001d,
+	0x59940019, 0x80000540, 0x04022003, 0x59980023,
+	0x48032819, 0x1c01f000, 0x59d80105, 0x82000500,
+	0x00018780, 0x04020172, 0x42000000, 0x0010b855,
+	0x0201f800, 0x0010aa47, 0x59980026, 0x59980828,
+	0x80000000, 0x48033026, 0x492fc857, 0x800409c0,
+	0x492f3028, 0x04000003, 0x492c0800, 0x0401f002,
+	0x492f3029, 0x592c0001, 0x80000d40, 0x040007e5,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0401f7d8, 0x59980026, 0x59980828, 0x80000000,
+	0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020027, 0x0402d00e,
+	0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+	0x80000040, 0x48033026, 0x04020002, 0x48033028,
+	0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+	0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0402e00a, 0x59da5908, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x59d80105,
+	0x82000500, 0x00018780, 0x04020125, 0x59940019,
+	0x80000540, 0x04022003, 0x59980023, 0x48032819,
+	0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+	0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+	0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7ce, 0x592c0204, 0x4803c856,
+	0x04000008, 0x42034000, 0x0010b4a4, 0x59a1d81e,
+	0x80edd9c0, 0x02000800, 0x001005d8, 0x0401f003,
+	0x5931d821, 0x58ef400b, 0x58ec0009, 0x800001c0,
+	0x08020000, 0x0201f800, 0x001005d8, 0x497a5801,
+	0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0200e000, 0x000202fb, 0x0201f000, 0x00020302,
+	0x5998002b, 0x84000540, 0x4803302b, 0x0201f000,
+	0x0002035e, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x492fc857, 0x59980026, 0x59980828,
+	0x80000000, 0x48033026, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020002, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x1c01f000, 0x59980026, 0x59980828, 0x80000000,
+	0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020039, 0x0402d00e,
+	0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+	0x80000040, 0x48033026, 0x04020002, 0x48033028,
+	0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+	0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0402e01d, 0x59da5908, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x04006018,
+	0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+	0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+	0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+	0x00018780, 0x0402007e, 0x1c01f000, 0x5998002b,
+	0x84000540, 0x4803302b, 0x0401f7f8, 0x497a5801,
+	0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x0401f7bc,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x492fc857,
+	0x4943c857, 0x4807c857, 0x4a025a04, 0x00000103,
+	0x49425a06, 0x48065a08, 0x4a025c06, 0x0000ffff,
+	0x813261c0, 0x04000003, 0x59300402, 0x48025c06,
+	0x832c0400, 0x00000009, 0x04011000, 0x4803c840,
+	0x4a03c842, 0x0000000b, 0x04011000, 0x1c01f000,
+	0x4df00000, 0x4203e000, 0x50000000, 0x599cb817,
+	0x59940019, 0x80000540, 0x04002023, 0x0400000e,
+	0x59980022, 0x82000580, 0x00000005, 0x0400001e,
+	0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08,
+	0x04000005, 0x59a8006a, 0x59a80866, 0x80040580,
+	0x04020015, 0x8c5cbd08, 0x04020030, 0x59d8090b,
+	0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e,
+	0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040,
+	0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+	0x00000002, 0x4203e000, 0x30000001, 0x4a032819,
+	0xffff0000, 0x04026835, 0x04006003, 0x8c5cbd08,
+	0x04020860, 0x59980029, 0x80025d40, 0x04000010,
+	0x59d80105, 0x82000500, 0x00018780, 0x04020020,
+	0x0402d00d, 0x59980026, 0x492fc857, 0x80000040,
+	0x48033026, 0x592c0000, 0x492fb107, 0x48033029,
+	0x04020003, 0x4803c856, 0x48033028, 0x5c03e000,
+	0x1c01f000, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0401f7fa, 0x59e0000f, 0x59e0080f,
+	0x80040580, 0x040207fd, 0x59e00010, 0x59e01010,
+	0x80081580, 0x040207fd, 0x40065000, 0x80041580,
+	0x040007c7, 0x040067dc, 0x0401f7ca, 0x4803c857,
+	0x485fc857, 0x8c00050e, 0x02020800, 0x001005d0,
+	0x4203e000, 0x50000000, 0x4200b800, 0x00008004,
+	0x0201f000, 0x001005dd, 0x5998002b, 0x8c000500,
+	0x04000013, 0x84000500, 0x4803302b, 0x59d8010a,
+	0x59d8090a, 0x80040580, 0x040207fd, 0x800408e0,
+	0x82040d40, 0x00000013, 0x4807c011, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x1c01f000, 0x0402e014,
+	0x59da5908, 0x496a5800, 0x412ed000, 0x815eb800,
+	0x0400e7fc, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x59d8090b, 0x59980024, 0x48073024,
+	0x80040480, 0x04020004, 0x59940019, 0x80000540,
+	0x04022003, 0x59980823, 0x48072819, 0x59d80105,
+	0x82000500, 0x00018780, 0x040207c9, 0x1c01f000,
+	0x59981025, 0x59e00010, 0x59e00810, 0x80041d80,
+	0x040207fd, 0x80080580, 0x04000013, 0x48073025,
+	0x59e0000f, 0x59e0100f, 0x80081d80, 0x040207fd,
+	0x81280580, 0x04000008, 0x400a5000, 0x40080000,
+	0x80040580, 0x04000003, 0x59980823, 0x48072819,
+	0x1c01f000, 0x59940019, 0x80000540, 0x040227f8,
+	0x0401f7fc, 0x59e0000f, 0x59e0100f, 0x80081d80,
+	0x040207fd, 0x81280580, 0x040007f6, 0x400a5000,
+	0x59940019, 0x80000540, 0x040027ed, 0x0401f7f1,
+	0x59a80017, 0x82000c80, 0x0000000a, 0x02021800,
+	0x001005d8, 0x0c01f809, 0x4a038805, 0x000000f0,
+	0x59c400a3, 0x82000500, 0x02870000, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x00104fc5, 0x00104f51,
+	0x00104f6c, 0x00104f95, 0x00104fb8, 0x00104ff2,
+	0x00105004, 0x00104f6c, 0x00104fd6, 0x00104f50,
+	0x1c01f000, 0x4a038808, 0x00000004, 0x0401f8f9,
+	0x0201f800, 0x001053ab, 0x59c40805, 0x8c040d0e,
+	0x04020013, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+	0x04020006, 0x8c040d08, 0x0400000d, 0x4a035017,
+	0x00000003, 0x0401f00a, 0x4a035017, 0x00000000,
+	0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+	0x0010aa47, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000002, 0x0401f8de, 0x59c40805,
+	0x8c040d08, 0x04020021, 0x8c040d0c, 0x0402001c,
+	0x8c040d0e, 0x04020017, 0x82040500, 0x000000f0,
+	0x0402001c, 0x0201f800, 0x001053ab, 0x4a038808,
+	0x00000080, 0x59c40002, 0x8400050c, 0x48038802,
+	0x0401f9d9, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x4a038808,
+	0x00000080, 0x4a035017, 0x00000009, 0x0401f009,
+	0x4a035017, 0x00000001, 0x0401f006, 0x4a035017,
+	0x00000000, 0x0401f003, 0x4a035017, 0x00000003,
+	0x1c01f000, 0x0401f8b7, 0x4a038808, 0x00000080,
+	0x59c40805, 0x8c040d0a, 0x0402001b, 0x8c040d0c,
+	0x04020016, 0x8c040d0e, 0x04020011, 0x82040500,
+	0x000000f0, 0x04020016, 0x59c40002, 0x8400050c,
+	0x48038802, 0x0401f9b4, 0x4d3c0000, 0x42027800,
+	0x00000001, 0x0201f800, 0x00109874, 0x5c027800,
+	0x4a035017, 0x00000009, 0x0401f009, 0x4a035017,
+	0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000008, 0x59c40805, 0x8c040d0c,
+	0x04020006, 0x8c040d0e, 0x04000006, 0x4a035017,
+	0x00000001, 0x0401f003, 0x4a035017, 0x00000000,
+	0x1c01f000, 0x0401f8d3, 0x59c40805, 0x8c040d0c,
+	0x0402000d, 0x4c040000, 0x0401f882, 0x5c000800,
+	0x8c040d0a, 0x04020006, 0x8c040d0e, 0x04000006,
+	0x4a035017, 0x00000001, 0x0401f003, 0x4a035017,
+	0x00000002, 0x1c01f000, 0x4a038808, 0x00000008,
+	0x42001000, 0x00105058, 0x0201f800, 0x00106084,
+	0x59c40805, 0x8c040d0a, 0x0402000d, 0x8c040d08,
+	0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e,
+	0x0400000d, 0x4a035017, 0x00000001, 0x0401f00a,
+	0x4a035017, 0x00000000, 0x0401f007, 0x42000000,
+	0x0010b844, 0x0201f800, 0x0010aa47, 0x4a035017,
+	0x00000004, 0x1c01f000, 0x0401f8a6, 0x0401f859,
+	0x59c40805, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+	0x04020006, 0x8c040d0e, 0x04000009, 0x4a035017,
+	0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000004, 0x0401f846, 0x59c40805,
+	0x8c040d0a, 0x04020010, 0x8c040d08, 0x0402000b,
+	0x8c040d0c, 0x04020006, 0x8c040d0e, 0x0400000c,
+	0x4a035017, 0x00000001, 0x0401f009, 0x4a035017,
+	0x00000000, 0x0401f006, 0x4a035017, 0x00000003,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x0401f91f, 0x02020800, 0x001005d8, 0x59a80805,
+	0x8c040d0c, 0x04000015, 0x84040d0c, 0x48075005,
+	0x4a038805, 0x00000010, 0x0201f800, 0x00101937,
+	0x59c40005, 0x8c000508, 0x04000008, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0401f01a, 0x59c40006, 0x84000548,
+	0x48038806, 0x0401f016, 0x59a80017, 0x82000580,
+	0x00000001, 0x0400000c, 0x59a80017, 0x82000580,
+	0x00000005, 0x0402000c, 0x42000000, 0x0010b844,
+	0x0201f800, 0x0010aa47, 0x4a035017, 0x00000008,
+	0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+	0x0010aa47, 0x4a035017, 0x00000004, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x4c080000, 0x42000800,
+	0x00000064, 0x42001000, 0x00105058, 0x0201f800,
+	0x00106079, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401ffba, 0x5c000800,
+	0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+	0x00106e21, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x59c40006, 0x84000500, 0x48038806, 0x0201f800,
+	0x00106ede, 0x497b8880, 0x0201f800, 0x0010a9c0,
+	0x0201f800, 0x0010a9ce, 0x0201f800, 0x00101815,
+	0x4a03504c, 0x00000004, 0x4202d800, 0x00000004,
+	0x4a038805, 0x00000001, 0x42001000, 0x00105058,
+	0x0201f800, 0x00106084, 0x0201f800, 0x001006d4,
+	0x0401f8c1, 0x04000006, 0x42006000, 0xfeffffff,
+	0x41786800, 0x0201f800, 0x0010427d, 0x0201f800,
+	0x00100452, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101590, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x59c40008, 0x8c000508, 0x04020007, 0x4a038808,
+	0x00000010, 0x4201d000, 0x00001388, 0x0201f800,
+	0x0010608e, 0x1c01f000, 0x4c040000, 0x59a80833,
+	0x82040580, 0x00000000, 0x0400000b, 0x82040580,
+	0x00000001, 0x0400000b, 0x82040580, 0x00000002,
+	0x0400000b, 0x82040580, 0x00000003, 0x0400000b,
+	0x0401f057, 0x4a035017, 0x00000000, 0x0401f009,
+	0x4a035017, 0x00000004, 0x0401f006, 0x4a035017,
+	0x00000001, 0x0401f003, 0x4a035017, 0x00000007,
+	0x497b8880, 0x4a038893, 0x00000001, 0x41780000,
+	0x0201f800, 0x00101606, 0x0201f800, 0x00106ede,
+	0x836c0d80, 0x00000004, 0x04000008, 0x59c40006,
+	0x82000500, 0xffffff0f, 0x82000540, 0x04000001,
+	0x48038806, 0x0401f007, 0x59c40006, 0x82000500,
+	0xffffff0f, 0x82000540, 0x04000000, 0x48038806,
+	0x0401f875, 0x04020005, 0x59c40806, 0x82040d00,
+	0xfbffff0f, 0x48078806, 0x4200b000, 0x00000005,
+	0x59c40005, 0x8c000534, 0x04020033, 0x42006000,
+	0xfc18ffff, 0x42006800, 0x01000000, 0x0201f800,
+	0x0010427d, 0x0201f800, 0x00101937, 0x59c408a4,
+	0x82040d00, 0x0000000f, 0x82040d80, 0x0000000c,
+	0x0400000a, 0x42006000, 0xfeffffff, 0x42006800,
+	0x02000000, 0x0201f800, 0x0010427d, 0x8058b040,
+	0x040207e8, 0x0401f8a1, 0x0401f853, 0x04000006,
+	0x42006000, 0xfeffffff, 0x41786800, 0x0201f800,
+	0x0010427d, 0x836c0d80, 0x00000004, 0x04000006,
+	0x59a8084d, 0x42001000, 0x00105065, 0x0201f800,
+	0x0010606e, 0x4a035033, 0x00000004, 0x0401fe31,
+	0x0401f841, 0x04020008, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040580, 0x0000000c, 0x02020800,
+	0x001005d8, 0x5c000800, 0x1c01f000, 0x4803c856,
+	0x4c000000, 0x0201f800, 0x0010609e, 0x4a035010,
+	0x00ffffff, 0x497b5032, 0x59a8002a, 0x82000500,
+	0xffff0000, 0x4803502a, 0x497b8880, 0x497b8893,
+	0x41780000, 0x0201f800, 0x00101606, 0x59c40001,
+	0x82000500, 0xfffffcff, 0x48038801, 0x42006000,
+	0xfc18ffff, 0x41786800, 0x0201f800, 0x0010427d,
+	0x4a038808, 0x00000000, 0x5c000000, 0x800001c0,
+	0x02020800, 0x0010411d, 0x4a038805, 0x040000f0,
+	0x59c40006, 0x82000500, 0xffffffcf, 0x82000540,
+	0x440000c1, 0x48038806, 0x1c01f000, 0x4c5c0000,
+	0x59a8b832, 0x825cbd80, 0x0000aaaa, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000000, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000010, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000020, 0x5c00b800,
+	0x1c01f000, 0x59a80005, 0x4803c857, 0x82000d00,
+	0x00000013, 0x04000025, 0x599c1017, 0x4d3c0000,
+	0x82000500, 0x00000011, 0x04000007, 0x42027800,
+	0x00000400, 0x0201f800, 0x00103b25, 0x0402000a,
+	0x0401f012, 0x42027800, 0x00000408, 0x0201f800,
+	0x00103b25, 0x0400000d, 0x42003000, 0x00000003,
+	0x0401f003, 0x42003000, 0x00000004, 0x42028000,
+	0x0000000e, 0x0201f800, 0x0010a449, 0x599c1017,
+	0x8c08150a, 0x04020007, 0x42028000, 0x00000004,
+	0x0201f800, 0x00101fe5, 0x80000580, 0x0401f80d,
+	0x5c027800, 0x0401f00a, 0x0201f800, 0x00103b25,
+	0x04000007, 0x42028000, 0x0000000f, 0x42003000,
+	0x00000001, 0x0201f800, 0x0010a449, 0x1c01f000,
+	0x59a80005, 0x04000004, 0x82000540, 0x00000010,
+	0x0401f003, 0x82000500, 0xffffffef, 0x48035005,
+	0x4803c857, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x42000000, 0x0010b8cb, 0x0201f800, 0x0010aa47,
+	0x42000800, 0x0010c0f1, 0x59c40003, 0x44000800,
+	0x59c40004, 0x48000801, 0x59c4000b, 0x48000802,
+	0x59c4008e, 0x48000803, 0x59c4008f, 0x48000804,
+	0x59c40090, 0x48000805, 0x59c40091, 0x48000806,
+	0x59c40092, 0x48000807, 0x59c40093, 0x48000808,
+	0x59c40099, 0x48000809, 0x59c4009e, 0x4800080a,
+	0x59c400aa, 0x4800080b, 0x59c400af, 0x4800080c,
+	0x59c400b2, 0x4800080d, 0x59c400b1, 0x4800080e,
+	0x82040c00, 0x0000000f, 0x41c41800, 0x4200b000,
+	0x00000030, 0x580c0050, 0x44000800, 0x80040800,
+	0x800c1800, 0x8058b040, 0x040207fb, 0x41c41800,
+	0x4200b000, 0x00000020, 0x580c0010, 0x44000800,
+	0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+	0x497b8830, 0x4200b000, 0x00000040, 0x59c40031,
+	0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+	0x497b88ac, 0x4200b000, 0x00000010, 0x59c400ad,
+	0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+	0x59c41001, 0x4c080000, 0x8408150c, 0x480b8801,
+	0x4a0370e4, 0x00000300, 0x4a0370e5, 0xb0000000,
+	0x42000800, 0x00000800, 0x80040840, 0x02000800,
+	0x001005d8, 0x59b800e5, 0x8c000538, 0x040207fb,
+	0x4a0370e4, 0x00000200, 0x42006000, 0xffffffff,
+	0x42006800, 0x80000000, 0x0201f800, 0x0010427d,
+	0x4a038807, 0x00000001, 0x497b8807, 0x4a038808,
+	0x00000010, 0x42006000, 0xfcf8ffff, 0x42006800,
+	0x01000000, 0x0201f800, 0x0010427d, 0x5c001000,
+	0x480b8801, 0x42000800, 0x0010c0f1, 0x50040000,
+	0x48038803, 0x58040001, 0x48038804, 0x58040002,
+	0x4803880b, 0x58040003, 0x4803888e, 0x58040004,
+	0x4803888f, 0x58040005, 0x48038890, 0x58040006,
+	0x48038891, 0x58040007, 0x48038892, 0x58040008,
+	0x48038893, 0x58040009, 0x48038899, 0x5804000a,
+	0x4803889e, 0x5804000b, 0x480388aa, 0x5804000c,
+	0x480388af, 0x5804000d, 0x480388b2, 0x5804000e,
+	0x480388b1, 0x82040c00, 0x0000000f, 0x41c41800,
+	0x4200b000, 0x00000030, 0x50040000, 0x48001850,
+	0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+	0x41c41800, 0x4200b000, 0x00000020, 0x50040000,
+	0x48001810, 0x80040800, 0x800c1800, 0x8058b040,
+	0x040207fb, 0x497b8830, 0x4200b000, 0x00000040,
+	0x50040000, 0x48038831, 0x80040800, 0x8058b040,
+	0x040207fc, 0x497b88ac, 0x4200b000, 0x00000010,
+	0x50040000, 0x480388ad, 0x80040800, 0x8058b040,
+	0x040207fc, 0x497b8880, 0x41780000, 0x0201f800,
+	0x00101606, 0x59c408a4, 0x82040d00, 0x0000000f,
+	0x82040580, 0x0000000c, 0x02020800, 0x001005d8,
+	0x4a038805, 0x04000000, 0x5c00b000, 0x1c01f000,
+	0x4803c856, 0x4c580000, 0x4ce80000, 0x42000000,
+	0x0010b845, 0x0201f800, 0x0010aa47, 0x59c41008,
+	0x4c080000, 0x82080500, 0xffffff7f, 0x48038808,
+	0x59c40004, 0x82000500, 0x00003e02, 0x04000005,
+	0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+	0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+	0x4a038805, 0x00000010, 0x4a038808, 0x00000004,
+	0x4200b000, 0x00000065, 0x59c40005, 0x8c000508,
+	0x04020012, 0x4201d000, 0x000003e8, 0x0201f800,
+	0x0010608e, 0x8058b040, 0x040207f8, 0x0201f800,
+	0x00106ede, 0x4a038808, 0x00000008, 0x4a035033,
+	0x00000001, 0x4202d800, 0x00000001, 0x82000540,
+	0x00000001, 0x0401f030, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8a8, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x497b8880, 0x59a8002a,
+	0x82000500, 0x0000ffff, 0x4c000000, 0x0201f800,
+	0x00101606, 0x5c000000, 0x48038880, 0x4a038808,
+	0x00000000, 0x4200b000, 0x00000065, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x04000008,
+	0x4201d000, 0x000003e8, 0x0201f800, 0x0010608e,
+	0x8058b040, 0x040207f2, 0x0401f7d1, 0x59c40006,
+	0x82000540, 0x000000f0, 0x48038806, 0x59a8001e,
+	0x80000540, 0x04020002, 0x80000000, 0x48038893,
+	0x80000580, 0x5c001000, 0x4df00000, 0x0201f800,
+	0x0010195d, 0x5c03e000, 0x480b8808, 0x5c01d000,
+	0x5c00b000, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x4ce80000, 0x59c41008, 0x82080500, 0xffffff7f,
+	0x48038808, 0x4c080000, 0x59c40004, 0x82000500,
+	0x00003e02, 0x04000005, 0x4201d000, 0x00000014,
+	0x0201f800, 0x0010608e, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8a9, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x4a038808, 0x00000002,
+	0x80000580, 0x48038880, 0x48038893, 0x0201f800,
+	0x00101606, 0x4200b000, 0x00000384, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x04000015,
+	0x82000500, 0x000000d0, 0x04020012, 0x4201d000,
+	0x00000067, 0x0201f800, 0x0010608e, 0x8058b040,
+	0x040207ef, 0x0201f800, 0x00106ede, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x82000540, 0x00000001, 0x0401f010,
+	0x497b8880, 0x59a8001e, 0x80000540, 0x04020002,
+	0x80000000, 0x48038893, 0x59a8002a, 0x82000500,
+	0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+	0x5c000000, 0x48038880, 0x80000580, 0x5c001000,
+	0x4df00000, 0x0201f800, 0x0010195d, 0x5c03e000,
+	0x480b8808, 0x5c01d000, 0x5c00b000, 0x1c01f000,
+	0x4803c856, 0x59c40004, 0x82000500, 0x00003e02,
+	0x0400000a, 0x0201f800, 0x00106ede, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0401f052, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8aa, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x59c40006, 0x84000508,
+	0x48038806, 0x4a038805, 0x00000010, 0x59a80805,
+	0x84040d4c, 0x48075005, 0x42000800, 0x00000064,
+	0x42001000, 0x00105058, 0x0201f800, 0x0010606e,
+	0x4a038808, 0x00000000, 0x497b8880, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x0400000e,
+	0x82000500, 0x000000e0, 0x0402000b, 0x4201d000,
+	0x000003e8, 0x0201f800, 0x0010608e, 0x0201f800,
+	0x00105f48, 0x59940004, 0x80000540, 0x040207ec,
+	0x0401f023, 0x4c080000, 0x42001000, 0x00105065,
+	0x0201f800, 0x00105f90, 0x42001000, 0x00105058,
+	0x0201f800, 0x00106084, 0x5c001000, 0x497b8880,
+	0x59a8001e, 0x80000540, 0x04020002, 0x80000000,
+	0x48038893, 0x59a8002a, 0x82000500, 0x0000ffff,
+	0x4c000000, 0x0201f800, 0x00101606, 0x5c000000,
+	0x48038880, 0x59a80805, 0x84040d0c, 0x48075005,
+	0x59c40006, 0x84000548, 0x48038806, 0x0201f800,
+	0x0010195d, 0x4a038808, 0x00000080, 0x1c01f000,
+	0x4803c856, 0x4d400000, 0x4d3c0000, 0x0201f800,
+	0x00106ede, 0x0201f800, 0x0010ab33, 0x04020025,
+	0x599c1017, 0x59a80805, 0x8c040d00, 0x0402000c,
+	0x8c08151a, 0x0400001f, 0x84040d42, 0x48075005,
+	0x42028000, 0x00000004, 0x42027800, 0x0000000c,
+	0x8c081508, 0x04020008, 0x0401f012, 0x42028000,
+	0x00000004, 0x42027800, 0x00000004, 0x8c081508,
+	0x0400000c, 0x4d400000, 0x42028000, 0x0000000e,
+	0x42028800, 0x0000ffff, 0x0201f800, 0x0010a446,
+	0x5c028000, 0x599c0817, 0x8c040d0a, 0x04020005,
+	0x4943c857, 0x493fc857, 0x0201f800, 0x00101fe5,
+	0x497b8880, 0x4202d800, 0x00000001, 0x0401fcfb,
+	0x5c027800, 0x5c028000, 0x1c01f000, 0x0201f800,
+	0x00100ae0, 0x42000000, 0x0010b8ab, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x00100ef4, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101606, 0x4a038880,
+	0x00000001, 0x0201f000, 0x0010195d, 0x4202e000,
+	0x00000000, 0x4a033015, 0x00000001, 0x497b301d,
+	0x497b3006, 0x4a03b004, 0x60000001, 0x59d80005,
+	0x4a03b004, 0x90000001, 0x4a03a804, 0x60000001,
+	0x59d40005, 0x4a03a804, 0x90000001, 0x0201f000,
+	0x00105983, 0x4a03c825, 0x00000004, 0x4a03c827,
+	0x00000004, 0x599c0409, 0x80000d40, 0x04000020,
+	0x599c0407, 0x80000540, 0x04000007, 0x800000cc,
+	0x599c100b, 0x80080400, 0x4803b000, 0x497bb002,
+	0x59d80001, 0x599c000b, 0x4803b000, 0x599c000c,
+	0x4803b001, 0x599c0407, 0x80000540, 0x04020002,
+	0x497bb002, 0x599c0c09, 0x82040540, 0x00400000,
+	0x4803b003, 0x4a03b009, 0x00000004, 0x4a03b004,
+	0x10000001, 0x59e00803, 0x82040d00, 0xfffffeff,
+	0x82040d40, 0x00008000, 0x4807c003, 0x599c040a,
+	0x80000540, 0x04000020, 0x599c0408, 0x80000540,
+	0x04000007, 0x800000cc, 0x599c100f, 0x80080400,
+	0x4803a800, 0x497ba802, 0x59d40001, 0x599c000f,
+	0x4803a800, 0x599c0010, 0x4803a801, 0x599c0408,
+	0x80000540, 0x04020002, 0x497ba802, 0x599c0c0a,
+	0x82040540, 0x00400000, 0x4803a803, 0x4a03a809,
+	0x00000004, 0x4a03a804, 0x10000001, 0x59e00803,
+	0x82040d00, 0xfffffbff, 0x82040d40, 0x00008000,
+	0x4807c003, 0x800409c0, 0x04000007, 0x4202e000,
+	0x00000001, 0x0200b800, 0x00020551, 0x0200f000,
+	0x00020566, 0x1c01f000, 0x0201f800, 0x001005d8,
+	0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+	0x59981005, 0x800811c0, 0x0400001e, 0x58080005,
+	0x82000d00, 0x43018780, 0x02020000, 0x00105846,
+	0x8c000508, 0x04000015, 0x580a5808, 0x592c0204,
+	0x497a5800, 0x497a5801, 0x82000500, 0x000000ff,
+	0x82000c80, 0x0000004b, 0x0402100b, 0x0c01f80f,
+	0x5c03e000, 0x83700580, 0x00000003, 0x040007e6,
+	0x0200f800, 0x00020566, 0x0200b000, 0x00020551,
+	0x1c01f000, 0x0401f850, 0x5c03e000, 0x0401f7f9,
+	0x0401f8de, 0x0401f7fd, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x001054a1, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105519, 0x00105491, 0x00105491, 0x001054a1,
+	0x001054a1, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x492fc857, 0x42000000, 0x0010b85e,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00000400,
+	0x0401f019, 0x492fc857, 0x42000000, 0x0010b85d,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00001000,
+	0x0401f011, 0x492fc857, 0x42000000, 0x0010b85c,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00002000,
+	0x0401f009, 0x492fc857, 0x42000000, 0x0010b85f,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00000800,
+	0x0401f001, 0x4803c857, 0x4202e000, 0x00000001,
+	0x592c0c04, 0x82040d00, 0xffff80ff, 0x80040540,
+	0x48025c04, 0x0201f000, 0x000202da, 0x592c0204,
+	0x492fc857, 0x80000110, 0x040007db, 0x80000040,
+	0x04000025, 0x48033002, 0x492f3003, 0x492f3004,
+	0x4a033008, 0x001054e5, 0x4202e000, 0x00000003,
+	0x1c01f000, 0x592c0204, 0x492fc857, 0x80000110,
+	0x040007cd, 0x80000040, 0x04000033, 0x48033002,
+	0x492f3003, 0x492f3004, 0x4a033008, 0x00105501,
+	0x4202e000, 0x00000003, 0x1c01f000, 0x0201f800,
+	0x0010ab33, 0x02020000, 0x000204d9, 0x42028000,
+	0x00000028, 0x41780800, 0x417a6000, 0x0201f800,
+	0x00104e70, 0x0201f800, 0x001091c6, 0x0201f000,
+	0x000202da, 0x592c0a0a, 0x8c040d02, 0x04020016,
+	0x59a80021, 0x492fc857, 0x80000540, 0x0402000f,
+	0x592c0207, 0x80000540, 0x04000005, 0x0201f800,
+	0x00104326, 0x04020004, 0x1c01f000, 0x42000000,
+	0x00000000, 0x592c0a06, 0x48065c06, 0x48025a06,
+	0x0201f000, 0x000202da, 0x42000000, 0x00000028,
+	0x0401f7f9, 0x42000800, 0x00000009, 0x0201f000,
+	0x0010665b, 0x592c0208, 0x492fc857, 0x82000c80,
+	0x0000199a, 0x040217a4, 0x592c0408, 0x80000540,
+	0x040207a1, 0x59a80821, 0x800409c0, 0x04020009,
+	0x592c0207, 0x80000540, 0x0400079b, 0x497a5a06,
+	0x0201f800, 0x00104385, 0x04020004, 0x1c01f000,
+	0x42000000, 0x00000028, 0x48025a06, 0x0201f000,
+	0x000202da, 0x59980804, 0x59980002, 0x48065800,
+	0x492c0801, 0x492f3004, 0x80000040, 0x48033002,
+	0x04000002, 0x1c01f000, 0x599a5803, 0x59980008,
+	0x4202e000, 0x00000001, 0x0801f000, 0x592e8a06,
+	0x592c0406, 0x4803c856, 0x82000500, 0x000000ff,
+	0x4200b800, 0x00000001, 0x82000d80, 0x00000001,
+	0x04000015, 0x417a8800, 0x4200b800, 0x000007f0,
+	0x82000d80, 0x00000002, 0x0400000f, 0x80000540,
+	0x02020000, 0x000202da, 0x592e8a06, 0x0201f800,
+	0x00020245, 0x02020000, 0x000202da, 0x592e9008,
+	0x592e9809, 0x0201f800, 0x00104713, 0x0201f000,
+	0x000202da, 0x59a80805, 0x84040d00, 0x48075005,
+	0x0201f800, 0x00020245, 0x02000800, 0x0010482c,
+	0x81468800, 0x805cb840, 0x040207fa, 0x0201f000,
+	0x000202da, 0x592c0a08, 0x4807c857, 0x82040580,
+	0x0000000e, 0x04000045, 0x82040580, 0x00000046,
+	0x04000046, 0x82040580, 0x00000045, 0x04000020,
+	0x82040580, 0x00000029, 0x04000010, 0x82040580,
+	0x0000002a, 0x04000009, 0x82040580, 0x0000000f,
+	0x040001fc, 0x82040580, 0x0000002e, 0x040001f9,
+	0x4807c856, 0x0401f1f2, 0x59a80805, 0x84040d04,
+	0x48075005, 0x0401f1f3, 0x592e8a06, 0x0201f800,
+	0x00020245, 0x040201ef, 0x59340200, 0x84000518,
+	0x48026a00, 0x592e6009, 0x4933c857, 0x83300580,
+	0xffffffff, 0x0402002a, 0x0401f1e6, 0x592c1407,
+	0x480bc857, 0x0201f800, 0x00109410, 0x411e6000,
+	0x04020003, 0x4803c856, 0x0401f1d9, 0x592e3809,
+	0x591c1414, 0x84081516, 0x84081554, 0x480a3c14,
+	0x4a026403, 0x0000003a, 0x592c040b, 0x80000540,
+	0x04000007, 0x4a026403, 0x0000003b, 0x592c020c,
+	0x4802641a, 0x592c040c, 0x4802621a, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x0401f1c7, 0x59a80068, 0x84000510,
+	0x48035068, 0x0401f1c3, 0x592c1207, 0x8c081500,
+	0x040201c0, 0x592e8a06, 0x592e6009, 0x0201f800,
+	0x0010941a, 0x04020003, 0x4803c856, 0x0401f1b4,
+	0x59300c06, 0x82040580, 0x00000004, 0x04000003,
+	0x4803c856, 0x0401f1ae, 0x59300a03, 0x82040580,
+	0x00000007, 0x04000003, 0x4803c856, 0x0401f1a8,
+	0x59300c03, 0x82040580, 0x00000001, 0x04000021,
+	0x82040580, 0x00000003, 0x04000016, 0x82040580,
+	0x00000006, 0x04000020, 0x82040580, 0x00000008,
+	0x04000015, 0x82040580, 0x0000000a, 0x0400000a,
+	0x82040580, 0x0000000c, 0x04000004, 0x82040580,
+	0x0000002e, 0x04020018, 0x42000800, 0x00000009,
+	0x0401f013, 0x42000800, 0x00000005, 0x0401f010,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+	0x00000001, 0x42000800, 0x00000003, 0x0401f008,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+	0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x0201f800,
+	0x0010672b, 0x0401f17b, 0x40000800, 0x58040000,
+	0x80000540, 0x040207fd, 0x492c0800, 0x1c01f000,
+	0x492fc857, 0x59300c06, 0x82040580, 0x00000006,
+	0x04020094, 0x0201f800, 0x001049e7, 0x04020005,
+	0x59340200, 0x8c00051a, 0x02000000, 0x00020533,
+	0x59340200, 0x8c00050e, 0x0400008a, 0x59300203,
+	0x42027800, 0x00000001, 0x82000580, 0x00000007,
+	0x02020000, 0x00020533, 0x4a026203, 0x00000002,
+	0x0201f000, 0x00020533, 0x42028000, 0x00000002,
+	0x4a026206, 0x00000014, 0x4d2c0000, 0x0201f800,
+	0x0010a1d1, 0x5c025800, 0x59300c06, 0x4807c857,
+	0x82040580, 0x00000007, 0x04020063, 0x492fc857,
+	0x4a025a06, 0x00000001, 0x0201f000, 0x000202da,
+	0x592c240a, 0x492fc857, 0x4813c857, 0x8c10251c,
+	0x04020016, 0x8c10251a, 0x04000003, 0x8c10250a,
+	0x04000069, 0x59340a00, 0x8c040d0e, 0x04000003,
+	0x8c10251e, 0x04000064, 0x0201f800, 0x0002075a,
+	0x0400006b, 0x592c240a, 0x49366009, 0x49325809,
+	0x4a026406, 0x00000006, 0x4a026203, 0x00000007,
+	0x0201f000, 0x0002052f, 0x592c0a0c, 0x5934000f,
+	0x41784000, 0x80001540, 0x0400006d, 0x58080204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+	0x04020004, 0x5808020c, 0x80040580, 0x04000004,
+	0x58080000, 0x40084000, 0x0401f7f3, 0x58080000,
+	0x49781000, 0x802041c0, 0x04000006, 0x48004000,
+	0x80000540, 0x04020007, 0x48226810, 0x0401f005,
+	0x4802680f, 0x80000540, 0x04020002, 0x497a6810,
+	0x4d2c0000, 0x400a5800, 0x4a025a06, 0x00000002,
+	0x0201f800, 0x000202da, 0x5c025800, 0x0401f7bc,
+	0x592c040a, 0x8c00051c, 0x04000016, 0x592c0206,
+	0x82000580, 0x0000ffff, 0x04020012, 0x592e6009,
+	0x83300580, 0xffffffff, 0x040007b1, 0x83300480,
+	0x0010d1c0, 0x04001010, 0x59a8000b, 0x81300480,
+	0x0402100d, 0x59300008, 0x800001c0, 0x04020005,
+	0x59300203, 0x82000580, 0x00000007, 0x04000797,
+	0x492fc857, 0x4a025a06, 0x00000029, 0x0201f000,
+	0x000202da, 0x492fc857, 0x4a025a06, 0x00000008,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+	0x00000045, 0x0201f000, 0x000202da, 0x492fc857,
+	0x4a025a06, 0x0000002a, 0x0201f000, 0x000202da,
+	0x492fc857, 0x4a025a06, 0x00000028, 0x0201f000,
+	0x000202da, 0x492fc857, 0x4a025a06, 0x00000006,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+	0x0000000e, 0x0201f000, 0x000202da, 0x59340010,
+	0x492e6810, 0x492fc857, 0x80000d40, 0x04000003,
+	0x492c0800, 0x1c01f000, 0x5934040b, 0x492e680f,
+	0x492fc857, 0x4803c857, 0x80000540, 0x04020003,
+	0x4a026a03, 0x00000001, 0x1c01f000, 0x59a8000e,
+	0x81640480, 0x0402176e, 0x42026000, 0x0010d1c0,
+	0x59300009, 0x81340580, 0x04020004, 0x59300202,
+	0x80040580, 0x04000759, 0x83326400, 0x00000024,
+	0x41580000, 0x81300480, 0x040017f6, 0x0401f760,
+	0x492fc857, 0x592c0407, 0x82000c80, 0x0000199a,
+	0x040215f1, 0x592c0204, 0x80000112, 0x040205de,
+	0x592e8a06, 0x0201f800, 0x00020245, 0x04020059,
+	0x0201f800, 0x001049e7, 0x04020059, 0x592e780a,
+	0x493fc857, 0x8d3e7d3e, 0x04020007, 0x59a80021,
+	0x80000540, 0x0402004f, 0x0201f800, 0x00104838,
+	0x040005dd, 0x833c1d00, 0x0000001f, 0x040005da,
+	0x592c0207, 0x82000c80, 0x00001000, 0x040215d6,
+	0x800000c2, 0x800008c4, 0x8005d400, 0x592e9008,
+	0x592e9809, 0x5934080d, 0x800409c0, 0x0402002e,
+	0x833c1d00, 0x0000001f, 0x81780040, 0x80000000,
+	0x800c1902, 0x040217fe, 0x040205c7, 0x0c01f001,
+	0x001056e9, 0x001056ec, 0x001056f9, 0x001056fc,
+	0x001056ff, 0x0201f800, 0x0010903e, 0x0401f01a,
+	0x0201f800, 0x0010480b, 0x04000027, 0x80e9d1c0,
+	0x02020800, 0x00105fae, 0x42028000, 0x00000005,
+	0x417a9000, 0x417a9800, 0x0201f800, 0x0010904e,
+	0x0401f00d, 0x42027000, 0x0000004d, 0x0401f006,
+	0x42027000, 0x0000004e, 0x0401f003, 0x42027000,
+	0x00000052, 0x0201f800, 0x001046c9, 0x02020800,
+	0x0010907e, 0x04000010, 0x8d3e7d3e, 0x04020017,
+	0x1c01f000, 0x58040002, 0x80000540, 0x04020007,
+	0x4d3c0000, 0x40067800, 0x0201f800, 0x001047eb,
+	0x5c027800, 0x040207cb, 0x4a025a06, 0x00000030,
+	0x0401f00d, 0x4a025a06, 0x0000002c, 0x0401f00a,
+	0x4a025a06, 0x00000028, 0x0401f007, 0x4a025a06,
+	0x00000029, 0x0401f004, 0x497a5c09, 0x4a025a06,
+	0x00000000, 0x4a025a04, 0x00000103, 0x0201f000,
+	0x000202da, 0x492fc857, 0x592c0204, 0x80000110,
+	0x80000040, 0x04000002, 0x0401f56f, 0x592c0207,
+	0x82000500, 0x000003ff, 0x48025a07, 0x8c000506,
+	0x04000004, 0x82000500, 0x00000070, 0x04020004,
+	0x59a80821, 0x800409c0, 0x04020018, 0x4a025a06,
+	0x0000dead, 0x592c0408, 0x82000500, 0x0000f0ff,
+	0x48025c08, 0x0201f800, 0x001043b4, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x8058b1c0, 0x04000009,
+	0x0201f800, 0x0010955f, 0x0401f80f, 0x44042800,
+	0x82580580, 0x00000002, 0x04020002, 0x48082801,
+	0x0201f000, 0x000202da, 0x42028000, 0x00000031,
+	0x42000800, 0x00000001, 0x4200b000, 0x00000001,
+	0x0401f7ed, 0x592c0408, 0x80000118, 0x832c2c00,
+	0x00000009, 0x80142c00, 0x1c01f000, 0x492fc857,
+	0x4a025a08, 0x00000006, 0x0201f000, 0x000202da,
+	0x492fc857, 0x4a025a08, 0x00000001, 0x0201f000,
+	0x000202da, 0x492fc857, 0x592c040a, 0x82000500,
+	0x00000003, 0x04000020, 0x0201f800, 0x0002075a,
+	0x04000021, 0x592c0204, 0x492e6008, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000045, 0x0400000e,
+	0x592c000b, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x04020018, 0x42027000, 0x00000041,
+	0x49366009, 0x4a026406, 0x00000001, 0x0201f000,
+	0x000207a1, 0x59300015, 0x8400055e, 0x48026015,
+	0x42026800, 0x0010b524, 0x42027000, 0x00000040,
+	0x0401f7f4, 0x4a025a06, 0x00000101, 0x0201f000,
+	0x000202da, 0x4a025a06, 0x0000002c, 0x0201f000,
+	0x000202da, 0x4a025a06, 0x00000028, 0x0201f800,
+	0x000202da, 0x0201f000, 0x0002077d, 0x492fc857,
+	0x0201f800, 0x001062e1, 0x0400000b, 0x592c0204,
+	0x80000110, 0x80000040, 0x040204fb, 0x592c0c06,
+	0x800409c0, 0x04000009, 0x42000000, 0x00000102,
+	0x0401f003, 0x42000000, 0x00000104, 0x48025a06,
+	0x0201f000, 0x000202da, 0x592c0c07, 0x800409c0,
+	0x04000024, 0x82040480, 0x00000005, 0x04021021,
+	0x4c040000, 0x80040800, 0x0201f800, 0x00106306,
+	0x5c001000, 0x04020018, 0x832c0400, 0x00000008,
+	0x4000a000, 0x0201f800, 0x0010632f, 0x04020012,
+	0x592c1207, 0x82cc0580, 0x0010b50e, 0x04020009,
+	0x58c80c0b, 0x84040d00, 0x84040d02, 0x8c081500,
+	0x04000002, 0x84040d5e, 0x4805940b, 0x0401f001,
+	0x42000000, 0x00000000, 0x48025a06, 0x0201f000,
+	0x000202da, 0x42000000, 0x00000103, 0x0401f7fb,
+	0x42000000, 0x00000102, 0x0401f7f8, 0x492fc857,
+	0x592e7c06, 0x833c0500, 0xfffffffe, 0x04020043,
+	0x592c4007, 0x42026000, 0x0010d1c0, 0x41581800,
+	0x400c0000, 0x81300480, 0x04021023, 0x59300203,
+	0x82000580, 0x00000000, 0x04000007, 0x59300008,
+	0x80000d40, 0x04000004, 0x58040005, 0x80200580,
+	0x04000004, 0x83326400, 0x00000024, 0x0401f7f1,
+	0x58040204, 0x82000500, 0x000000ff, 0x82000d80,
+	0x00000053, 0x04000007, 0x82000d80, 0x00000048,
+	0x04000004, 0x82000580, 0x00000018, 0x04020023,
+	0x4d2c0000, 0x0201f800, 0x00108be3, 0x5c025800,
+	0x0400001e, 0x4a025a06, 0x00000000, 0x0201f000,
+	0x000202da, 0x592e8a06, 0x83440480, 0x000007f0,
+	0x04021016, 0x83440400, 0x0010ac00, 0x50000000,
+	0x80026d40, 0x04000011, 0x4d2c0000, 0x0201f800,
+	0x001047cb, 0x0400000c, 0x42028000, 0x00000005,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x001091cc, 0x0201f800, 0x000202da, 0x5c025800,
+	0x0401f7e5, 0x5c025800, 0x4a025a06, 0x00000031,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4d2c0000,
+	0x0201f800, 0x001007e4, 0x04000016, 0x492fc857,
+	0x412f4000, 0x0201f800, 0x001007e4, 0x0400000e,
+	0x492fc857, 0x412dd800, 0x0201f800, 0x00103b28,
+	0x0201f800, 0x00103b32, 0x49a1d80b, 0x5c025800,
+	0x492dd80a, 0x0201f800, 0x00102214, 0x0201f000,
+	0x00102233, 0x41a25800, 0x0201f800, 0x001007f4,
+	0x5c025800, 0x4a025a06, 0x00004005, 0x4a025c06,
+	0x00000002, 0x0201f000, 0x000202da, 0x4807c857,
+	0x485fc857, 0x4200b800, 0x00000001, 0x5c000800,
+	0x4c5c0000, 0x0401f005, 0x4807c857, 0x485fc857,
+	0x5c000800, 0x4d780000, 0x4803c857, 0x492fc857,
+	0x8c00050e, 0x02020800, 0x001005d0, 0x4203e000,
+	0x50000000, 0x4200b800, 0x00008003, 0x0201f000,
+	0x001005dd, 0x592c0204, 0x80000110, 0x80000040,
+	0x04020441, 0x0201f800, 0x00104a34, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x4806580d, 0x480a580e,
+	0x4943c857, 0x4807c857, 0x480bc857, 0x0201f000,
+	0x000202da, 0x592c0204, 0x80000110, 0x80000040,
+	0x04020431, 0x0201f800, 0x00104b8b, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x48065811, 0x480a5812,
+	0x0201f000, 0x000202da, 0x592c0204, 0x80000110,
+	0x04000425, 0x80000040, 0x0402000c, 0x4202e000,
+	0x00000001, 0x592c020a, 0x8c000504, 0x02000000,
+	0x000204d0, 0x592c0207, 0x82000c80, 0x00001001,
+	0x04021429, 0x0401f009, 0x4202e000, 0x00000003,
+	0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+	0x000204d0, 0x1c01f000, 0x4202e000, 0x00000002,
+	0x42000000, 0x0010beda, 0x50007000, 0x492c700b,
+	0x4978700e, 0x4978700c, 0x592c0011, 0x592c0812,
+	0x48007007, 0x48047008, 0x592c1013, 0x82080500,
+	0xffff0000, 0x04000003, 0x0201f800, 0x001005d8,
+	0x4978700d, 0x82080480, 0x00000180, 0x4803c857,
+	0x04001007, 0x4800700f, 0x4a007005, 0x00000180,
+	0x4a007004, 0x00000060, 0x0401f005, 0x4978700f,
+	0x48087005, 0x80081104, 0x48087004, 0x5838000a,
+	0x48007003, 0x40381000, 0x0201f000, 0x00100858,
+	0x0201f800, 0x001007d3, 0x04000003, 0x59980007,
+	0x0801f000, 0x1c01f000, 0x40307000, 0x5838000b,
+	0x80025d40, 0x0400001b, 0x58380002, 0x82000580,
+	0x00000100, 0x0400001d, 0x4c380000, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+	0x0400000b, 0x592c0208, 0x8400054e, 0x48025a08,
+	0x4a025a06, 0x00000002, 0x4a025a04, 0x00000103,
+	0x0201f800, 0x000202c1, 0x0401f005, 0x4a025a06,
+	0x00000010, 0x0201f800, 0x000202da, 0x5c007000,
+	0x4202e000, 0x00000001, 0x4a007002, 0x00000100,
+	0x49787010, 0x1c01f000, 0x58380004, 0x82000480,
+	0x00000003, 0x04000087, 0x58380010, 0x8c000500,
+	0x04020019, 0x4200b000, 0x00000003, 0x832cac00,
+	0x00000011, 0x5838000a, 0x5838100d, 0x8008a400,
+	0x4c380000, 0x0201f800, 0x0010ab17, 0x5c007000,
+	0x5838000d, 0x82000400, 0x00000003, 0x4800700d,
+	0x4a007010, 0x00000001, 0x58380004, 0x82000480,
+	0x00000003, 0x48007004, 0x82000580, 0x00000003,
+	0x0400006c, 0x5838000e, 0x80001d40, 0x04020020,
+	0x4c380000, 0x0201f800, 0x001007d3, 0x5c007000,
+	0x04000010, 0x4a025a04, 0x0000010a, 0x42001800,
+	0x00000005, 0x480c700e, 0x5838000c, 0x80000540,
+	0x04020002, 0x5838000b, 0x40000800, 0x492c0801,
+	0x492c700c, 0x42000800, 0x0000000f, 0x0401f011,
+	0x4202e000, 0x00000008, 0x4a033007, 0x00105915,
+	0x1c01f000, 0x4202e000, 0x00000002, 0x42000000,
+	0x0010beda, 0x50007000, 0x0401f7e7, 0x583a580c,
+	0x400c0000, 0x42000800, 0x00000014, 0x80040c80,
+	0x58381004, 0x5838000f, 0x41783000, 0x80000540,
+	0x04020005, 0x84183540, 0x82081480, 0x00000003,
+	0x0400003c, 0x40080000, 0x80040480, 0x04001002,
+	0x40080800, 0x4004b000, 0x412c0000, 0x800c0400,
+	0x4000a800, 0x5838000a, 0x5838100d, 0x8008a400,
+	0x4c080000, 0x4c040000, 0x4c0c0000, 0x4c380000,
+	0x0201f800, 0x0010ab17, 0x5c007000, 0x5c001800,
+	0x5c000800, 0x40040000, 0x58381004, 0x80080480,
+	0x48007004, 0x82000580, 0x00000003, 0x04000002,
+	0x84183500, 0x5c000000, 0x80041400, 0x82080480,
+	0x00000060, 0x04020003, 0x84183542, 0x41781000,
+	0x400c0000, 0x80041c00, 0x820c0480, 0x00000014,
+	0x04020003, 0x84183544, 0x40001800, 0x40080800,
+	0x4804700d, 0x480c700e, 0x40180000, 0x0c01f001,
+	0x00105960, 0x00105964, 0x00105962, 0x00105960,
+	0x001058fc, 0x00105964, 0x00105962, 0x00105960,
+	0x0201f800, 0x001005d8, 0x5838100f, 0x0401f739,
+	0x5838080d, 0x82040400, 0x00000002, 0x5838100a,
+	0x80080400, 0x50001000, 0x800811c0, 0x0402000f,
+	0x4202e000, 0x00000001, 0x583a580b, 0x4978700b,
+	0x49787010, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000012, 0x02000000, 0x00020507,
+	0x0201f000, 0x000204d0, 0x5838000a, 0x80040c00,
+	0x82381c00, 0x00000007, 0x54041800, 0x80040800,
+	0x800c1800, 0x54041800, 0x0401f71a, 0x0201f800,
+	0x001007d3, 0x02000800, 0x001005d8, 0x4a02580a,
+	0x0010be79, 0x42000800, 0x0010beda, 0x452c0800,
+	0x497a580b, 0x497a580c, 0x497a580d, 0x497a580e,
+	0x497a580f, 0x4a025809, 0x001058b6, 0x497a5810,
+	0x4a025802, 0x00000100, 0x4a025801, 0x00000001,
+	0x1c01f000, 0x59c80007, 0x8c000502, 0x04000070,
+	0x835c2c80, 0x00000005, 0x02001000, 0x00105f23,
+	0x59c82817, 0x497b9005, 0x82140500, 0x00e00000,
+	0x0402004f, 0x82140500, 0x000003ff, 0x82001c00,
+	0x00000006, 0x41cc2000, 0x42003000, 0x00006080,
+	0x820c0480, 0x00000040, 0x04001006, 0x42001000,
+	0x00000040, 0x820c1c80, 0x00000040, 0x0401f003,
+	0x400c1000, 0x41781800, 0x54182000, 0x80102000,
+	0x80183000, 0x80081040, 0x040207fc, 0x800c19c0,
+	0x04000005, 0x59c80005, 0x80000000, 0x48039005,
+	0x0401f7ea, 0x82140500, 0x01f60000, 0x04020029,
+	0x82140500, 0x0000f000, 0x0400000b, 0x82000c80,
+	0x00002000, 0x0402100f, 0x82140500, 0x0e000000,
+	0x80000132, 0x0c01f840, 0x4a039005, 0x00000140,
+	0x1c01f000, 0x59cc0400, 0x82000500, 0x0000ff00,
+	0x82000580, 0x00008100, 0x040007f4, 0x0401f01c,
+	0x4817c857, 0x82140500, 0x000003ff, 0x04020007,
+	0x59cc0400, 0x82000500, 0x0000ff00, 0x82000580,
+	0x00008100, 0x04020012, 0x42000000, 0x0010b8bd,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00105dfa,
+	0x4803c856, 0x4a039005, 0x00000140, 0x0401f020,
+	0x4817c857, 0x82140500, 0x00f60000, 0x04020004,
+	0x0201f800, 0x00105e35, 0x040207d2, 0x0201f800,
+	0x0010513b, 0x04000010, 0x59c400a4, 0x4803c857,
+	0x82000500, 0x0000000f, 0x82000580, 0x0000000a,
+	0x04020009, 0x497b5016, 0x59c400a3, 0x82000540,
+	0x00080000, 0x480388a3, 0x82000500, 0xfff7ffff,
+	0x480388a3, 0x4817c856, 0x0201f800, 0x0010a978,
+	0x4a039005, 0x00000140, 0x0401f842, 0x4803c856,
+	0x1c01f000, 0x00105a1d, 0x00105cf4, 0x00105a15,
+	0x00105a15, 0x00105a15, 0x00105a15, 0x00105a15,
+	0x00105a15, 0x4803c857, 0x42000000, 0x0010b85a,
+	0x0201f800, 0x0010aa47, 0x4a039005, 0x00000140,
+	0x1c01f000, 0x4817c857, 0x59cc0400, 0x4803c857,
+	0x82000d00, 0x0000ff00, 0x82041500, 0x0000f000,
+	0x840409c0, 0x82140500, 0x000003ff, 0x800018c4,
+	0x8c142d14, 0x04000005, 0x59cc0002, 0x82000500,
+	0x00000003, 0x800c1c80, 0x480f5016, 0x82080580,
+	0x00002000, 0x04020011, 0x836c0580, 0x00000001,
+	0x0402000c, 0x59cc0006, 0x82000500, 0xff000000,
+	0x82000580, 0x11000000, 0x04020011, 0x0201f800,
+	0x00103b38, 0x0201f800, 0x00105f48, 0x0401f00c,
+	0x0401f81f, 0x0401f00a, 0x82080580, 0x00003000,
+	0x04020003, 0x0401fa06, 0x0401f005, 0x82080580,
+	0x00008000, 0x04020002, 0x0401fafc, 0x1c01f000,
+	0x4817c857, 0x42000000, 0x0010b859, 0x0201f800,
+	0x0010aa47, 0x836c0580, 0x00000003, 0x0402000b,
+	0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+	0x40141800, 0x80142120, 0x0201f800, 0x00103a3e,
+	0x5c001800, 0x5c001000, 0x1c01f000, 0x4807c857,
+	0x59cc0002, 0x82000500, 0xff000000, 0x82001580,
+	0x01000000, 0x04000004, 0x82001580, 0x23000000,
+	0x04020192, 0x82040580, 0x00000023, 0x0402003f,
+	0x0401fb6a, 0x0400018d, 0x59300c06, 0x82040580,
+	0x00000010, 0x04000013, 0x82040580, 0x00000011,
+	0x04000010, 0x82040580, 0x00000001, 0x0400000d,
+	0x82040580, 0x00000004, 0x0400000a, 0x82040580,
+	0x00000008, 0x04000007, 0x82040580, 0x0000000a,
+	0x04000004, 0x4933c857, 0x4807c857, 0x0401f177,
+	0x59300004, 0x82000500, 0x80010000, 0x04000004,
+	0x0201f800, 0x00106f60, 0x04020170, 0x59cc0a04,
+	0x48066202, 0x59cc0006, 0x82000500, 0xffff0000,
+	0x82000d80, 0x02000000, 0x04020005, 0x42027000,
+	0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+	0x02140000, 0x040007fa, 0x82000d80, 0x02100000,
+	0x040007f7, 0x82000d80, 0x02100000, 0x040007f4,
+	0x82000d80, 0x01000000, 0x04020158, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x04020154, 0x42027000,
+	0x00000016, 0x0401f7ec, 0x82040580, 0x00000022,
+	0x0402014e, 0x59a80806, 0x8c040d14, 0x04000011,
+	0x0401f967, 0x0402000f, 0x0401f97d, 0x0400000d,
+	0x42027000, 0x0000004c, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x0201f800, 0x00105eec, 0x0400012a,
+	0x42028800, 0x0000ffff, 0x417a6800, 0x0401f126,
+	0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+	0x03000000, 0x04020021, 0x59a80026, 0x8c000508,
+	0x04000017, 0x8400054c, 0x48035026, 0x59cc0800,
+	0x82040d00, 0x00ffffff, 0x48075010, 0x497b8830,
+	0x84040d70, 0x48078832, 0x59c40802, 0x84040d4c,
+	0x48078802, 0x59cc0007, 0x82000500, 0x0000ffff,
+	0x48038893, 0x4803501e, 0x42000800, 0x00000003,
+	0x59a81010, 0x0201f800, 0x00106c78, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x04020118, 0x42027000,
+	0x00000017, 0x0401f0d9, 0x82000d80, 0x04000000,
+	0x04020011, 0x59cc0006, 0x82000500, 0x0000ffff,
+	0x0402010e, 0x0201f800, 0x0010513b, 0x04000004,
+	0x42027000, 0x0000001d, 0x0401f0cc, 0x59a80026,
+	0x84000548, 0x48035026, 0x42027000, 0x00000030,
+	0x0401f0c6, 0x82000d80, 0x05000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200fb,
+	0x42027000, 0x00000018, 0x0401f0bc, 0x82000d80,
+	0x20100000, 0x04020004, 0x42027000, 0x00000019,
+	0x0401f0b6, 0x82000d80, 0x21100000, 0x04020004,
+	0x42027000, 0x0000001a, 0x0401f0b0, 0x82000d80,
+	0x52000000, 0x04020008, 0x59cc0006, 0x82000500,
+	0x0000ffff, 0x040200e5, 0x42027000, 0x0000001b,
+	0x0401f0a6, 0x82000d80, 0x50000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200db,
+	0x42027000, 0x0000001c, 0x0401f09c, 0x82000d80,
+	0x13000000, 0x04020004, 0x42027000, 0x00000034,
+	0x0401f096, 0x82000d80, 0x12000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200cb,
+	0x42027000, 0x00000024, 0x0401f08c, 0x82000d00,
+	0xff000000, 0x82040d80, 0x24000000, 0x04020004,
+	0x42027000, 0x0000002d, 0x0401f084, 0x82000d00,
+	0xff000000, 0x82040d80, 0x53000000, 0x04020004,
+	0x42027000, 0x0000002a, 0x0401f07c, 0x82000d80,
+	0x0f000000, 0x04020004, 0x42027000, 0x00000020,
+	0x0401f076, 0x82000d80, 0x61040000, 0x04020036,
+	0x83cc1400, 0x00000006, 0x80080800, 0x50080000,
+	0x82000500, 0x0000ffff, 0x82000480, 0x00000004,
+	0x4c580000, 0x8000b104, 0x8058b1c0, 0x04000026,
+	0x4c100000, 0x50041800, 0x820c1500, 0x03000000,
+	0x80081130, 0x42000000, 0x0010b817, 0x82082580,
+	0x00000000, 0x04020004, 0x42000000, 0x0010b814,
+	0x0401f00c, 0x82082580, 0x00000001, 0x04020004,
+	0x42000000, 0x0010b815, 0x0401f006, 0x82082580,
+	0x00000002, 0x04020003, 0x42000000, 0x0010b816,
+	0x0201f800, 0x0010aa47, 0x42001000, 0x00008015,
+	0x820c2500, 0x0000ffff, 0x800c1920, 0x0201f800,
+	0x00103a3e, 0x5c002000, 0x80040800, 0x8058b040,
+	0x040207da, 0x5c00b000, 0x42027000, 0x00000023,
+	0x0401f03e, 0x82000d80, 0x60000000, 0x04020004,
+	0x42027000, 0x0000003f, 0x0401f038, 0x82000d80,
+	0x54000000, 0x04020006, 0x0401fb12, 0x0402006f,
+	0x42027000, 0x00000046, 0x0401f030, 0x82000d80,
+	0x55000000, 0x04020009, 0x0401fb32, 0x04020004,
+	0x42027000, 0x00000041, 0x0401f028, 0x42027000,
+	0x00000042, 0x0401f025, 0x82000d80, 0x78000000,
+	0x04020004, 0x42027000, 0x00000045, 0x0401f01f,
+	0x82000d80, 0x10000000, 0x04020004, 0x42027000,
+	0x0000004e, 0x0401f019, 0x82000d80, 0x63000000,
+	0x04020004, 0x42027000, 0x0000004a, 0x0401f013,
+	0x82000d00, 0xff000000, 0x82040d80, 0x56000000,
+	0x04020004, 0x42027000, 0x0000004f, 0x0401f00b,
+	0x82000d00, 0xff000000, 0x82040d80, 0x57000000,
+	0x04020004, 0x42027000, 0x00000050, 0x0401f003,
+	0x42027000, 0x0000001d, 0x59cc3800, 0x821c3d00,
+	0x00ffffff, 0x821c0580, 0x00fffffe, 0x59cc0001,
+	0x04020005, 0x40003000, 0x42028800, 0x000007fe,
+	0x0401f003, 0x0401f8d1, 0x04020030, 0x0201f800,
+	0x001045a6, 0x0402002d, 0x83380580, 0x00000046,
+	0x04020004, 0x59a80010, 0x80180580, 0x04000027,
+	0x59340200, 0x8c000514, 0x0400000f, 0x83380580,
+	0x00000030, 0x0400000c, 0x83380580, 0x0000003f,
+	0x04000009, 0x83380580, 0x00000034, 0x04000006,
+	0x83380580, 0x00000024, 0x04000003, 0x42027000,
+	0x0000004c, 0x0201f800, 0x0002075a, 0x04000018,
+	0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+	0x48066202, 0x83380580, 0x0000004c, 0x04020009,
+	0x4a026406, 0x00000011, 0x813669c0, 0x04020005,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x4802601e,
+	0x0201f000, 0x000207a1, 0x59880052, 0x4803c857,
+	0x80000000, 0x48031052, 0x1c01f000, 0x42001000,
+	0x00008049, 0x59cc1806, 0x800c1930, 0x0201f800,
+	0x00103a3e, 0x0201f800, 0x00107942, 0x040007f3,
+	0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+	0x48066202, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00002900, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x59a80026,
+	0x4803c857, 0x8c000508, 0x04000010, 0x59cc0006,
+	0x82000500, 0xff000000, 0x82000d80, 0x03000000,
+	0x0400000c, 0x82000d80, 0x20000000, 0x04000009,
+	0x82000d80, 0x05000000, 0x04000006, 0x82000d80,
+	0x21000000, 0x04000003, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fd, 0x59cc2006,
+	0x82102500, 0xff000000, 0x9c1021c0, 0x0401f807,
+	0x820c1c00, 0x0010b4e3, 0x500c1800, 0x800c0500,
+	0x4803c857, 0x1c01f000, 0x40100800, 0x41781800,
+	0x82040480, 0x00000020, 0x04001004, 0x800c1800,
+	0x40000800, 0x0401f7fb, 0x82040500, 0x0000000f,
+	0x82000400, 0x0010ab38, 0x50000000, 0x8c040d08,
+	0x04000002, 0x900001c0, 0x1c01f000, 0x4803c856,
+	0x0401fac3, 0x0402000a, 0x0201f800, 0x0010210a,
+	0x04020007, 0x59cc0002, 0x82000500, 0xff000000,
+	0x82000d80, 0x08000000, 0x04000802, 0x1c01f000,
+	0x4803c856, 0x59cc0400, 0x82000d00, 0x0000ff00,
+	0x840409c0, 0x82040580, 0x00000033, 0x0402001f,
+	0x0401f976, 0x04000038, 0x59cc0a04, 0x48066202,
+	0x59cc0006, 0x4803c857, 0x82000500, 0xffff0000,
+	0x82000d80, 0x02000000, 0x04020009, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x0402002b, 0x42027000,
+	0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+	0x01000000, 0x04020024, 0x59cc0006, 0x82000500,
+	0x0000ffff, 0x04020020, 0x42027000, 0x00000016,
+	0x0201f000, 0x000207a1, 0x82040580, 0x00000032,
+	0x04020019, 0x59cc0006, 0x82000500, 0xffff0000,
+	0x82000d80, 0x14000000, 0x04020013, 0x42027000,
+	0x00000038, 0x59cc0001, 0x0401f810, 0x0402000e,
+	0x0201f800, 0x001045a6, 0x0402000b, 0x0201f800,
+	0x0002075a, 0x04000008, 0x49366009, 0x4a026406,
+	0x00000004, 0x59cc0c04, 0x48066202, 0x0201f000,
+	0x000207a1, 0x1c01f000, 0x4803c857, 0x4c580000,
+	0x4c100000, 0x4c380000, 0x4c340000, 0x82003500,
+	0x00ffffff, 0x82181500, 0x00ff0000, 0x82081580,
+	0x00ff0000, 0x04020016, 0x82181480, 0x00fffffc,
+	0x04001013, 0x82181580, 0x00fffffd, 0x04020004,
+	0x42028800, 0x000007fd, 0x0401f040, 0x82181580,
+	0x00fffffe, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f03a, 0x82181580, 0x00fffffc, 0x04020004,
+	0x42028800, 0x000007fc, 0x0401f034, 0x41781000,
+	0x42002000, 0x00000000, 0x4200b000, 0x000007f0,
+	0x41ac7000, 0x50380000, 0x80006d40, 0x04020005,
+	0x800811c0, 0x0402001e, 0x8410155e, 0x0401f01c,
+	0x58340212, 0x82000500, 0x0000ff00, 0x04000011,
+	0x59a84010, 0x82204500, 0x00ffff00, 0x82180500,
+	0x00ffff00, 0x04000002, 0x80200580, 0x58340002,
+	0x0402000f, 0x82000500, 0x000000ff, 0x82184500,
+	0x000000ff, 0x80204580, 0x04020009, 0x0401f006,
+	0x58340002, 0x82000500, 0x00ffffff, 0x80184580,
+	0x04020003, 0x40128800, 0x0401f00c, 0x80102000,
+	0x80387000, 0x8058b040, 0x040207db, 0x800811c0,
+	0x04020005, 0x481bc857, 0x82000540, 0x00000001,
+	0x0401f003, 0x840a8d1e, 0x80000580, 0x5c006800,
+	0x5c007000, 0x5c002000, 0x5c00b000, 0x1c01f000,
+	0x59a80026, 0x8c00050e, 0x04000003, 0x8c000502,
+	0x04000006, 0x59cc0c00, 0x80040910, 0x82040500,
+	0x0000000f, 0x0c01f002, 0x1c01f000, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105de5, 0x00105d0f,
+	0x00105d11, 0x00105d29, 0x00105d2c, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105d0f, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105d0f, 0x4803c856,
+	0x1c01f000, 0x0401f8c5, 0x04000014, 0x82140500,
+	0x000003ff, 0x800000c4, 0x82000480, 0x00000008,
+	0x0400100e, 0x59cc0001, 0x59326809, 0x59340802,
+	0x80040580, 0x82000500, 0x00ffffff, 0x04020007,
+	0x59cc0a04, 0x48066202, 0x42027000, 0x00000046,
+	0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+	0x1c01f000, 0x59cc0004, 0x4803c857, 0x1c01f000,
+	0x0401f8aa, 0x04000016, 0x82140500, 0x000003ff,
+	0x800000c4, 0x82000480, 0x0000000c, 0x04001010,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x59326809,
+	0x59340802, 0x82040d00, 0x00ffffff, 0x80040580,
+	0x04020007, 0x59cc0a04, 0x48066202, 0x42027000,
+	0x00000045, 0x0201f000, 0x000207a1, 0x59cc0004,
+	0x4803c857, 0x1c01f000, 0x4817c857, 0x0401f9c8,
+	0x04020011, 0x0201f800, 0x0010210a, 0x0402000e,
+	0x59cc0002, 0x82000500, 0xff000000, 0x82000580,
+	0x00000000, 0x04020008, 0x82040500, 0x0000000f,
+	0x82000c80, 0x00000006, 0x04021003, 0x4803c857,
+	0x0c01f002, 0x1c01f000, 0x00105d60, 0x00105d64,
+	0x00105d60, 0x00105d60, 0x00105db2, 0x00105dc3,
+	0x4803c857, 0x59cc0004, 0x4803c857, 0x1c01f000,
+	0x59cc0004, 0x4803c857, 0x59a80016, 0x800001c0,
+	0x040207f8, 0x59cc0802, 0x8c040d2e, 0x0402001d,
+	0x0201f800, 0x00107942, 0x02000800, 0x001005d8,
+	0x59cc0001, 0x4803c857, 0x0401ff28, 0x0402000d,
+	0x0201f800, 0x00020245, 0x0402000a, 0x4a026406,
+	0x00000005, 0x49366009, 0x59cc0c04, 0x48066202,
+	0x42027000, 0x00000088, 0x0201f000, 0x000207a1,
+	0x42028800, 0x0000ffff, 0x417a6800, 0x59cc0001,
+	0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7f0,
+	0x59cc0001, 0x4803c857, 0x0401ff10, 0x040207d5,
+	0x0201f800, 0x001045a6, 0x040207d2, 0x59cc0005,
+	0x8c000500, 0x04020004, 0x59340200, 0x8c00050e,
+	0x040207cc, 0x0201f800, 0x001049f3, 0x0402000f,
+	0x0401f83e, 0x040007c7, 0x0201f800, 0x0002075a,
+	0x040007c4, 0x49366009, 0x4a026406, 0x00000002,
+	0x59cc0c04, 0x48066202, 0x42027000, 0x00000088,
+	0x0201f000, 0x000207a1, 0x0201f800, 0x0002075a,
+	0x040007b8, 0x49366009, 0x4a026406, 0x00000004,
+	0x59cc0c04, 0x48066202, 0x42027000, 0x00000001,
+	0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+	0x59cc0802, 0x8c040d2e, 0x0400000b, 0x0401f81f,
+	0x04000009, 0x0401f960, 0x04020007, 0x59cc0a04,
+	0x48066202, 0x42027000, 0x00000089, 0x0201f000,
+	0x000207a1, 0x4933c857, 0x1c01f000, 0x59cc0004,
+	0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b,
+	0x0401f80e, 0x04000009, 0x0401f94f, 0x04020007,
+	0x59cc0a04, 0x48066202, 0x42027000, 0x0000008a,
+	0x0201f000, 0x000207a1, 0x4933c857, 0x1c01f000,
+	0x59cc0a04, 0x0401f002, 0x59cc0c04, 0x59a8000e,
+	0x59a81067, 0x80080400, 0x80040480, 0x04021008,
+	0x40040000, 0x800000c4, 0x800408ca, 0x80040c00,
+	0x82066400, 0x0010d1c0, 0x1c01f000, 0x80000580,
+	0x0401f7fe, 0x59cc0802, 0x8c040d2e, 0x04020010,
+	0x0401ffec, 0x0400000e, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x59326809, 0x59340802, 0x82040d00,
+	0x00ffffff, 0x80040580, 0x04020005, 0x42027000,
+	0x00000051, 0x0201f000, 0x000207a1, 0x59cc0004,
+	0x4803c857, 0x1c01f000, 0x4803c856, 0x42003000,
+	0x00000105, 0x0401f001, 0x4803c856, 0x4c3c0000,
+	0x41cc7800, 0x0401f803, 0x5c007800, 0x1c01f000,
+	0x4803c856, 0x4c580000, 0x583c0400, 0x82000500,
+	0x0000f000, 0x82000580, 0x0000c000, 0x04000024,
+	0x0201f800, 0x0002075a, 0x04000021, 0x4c180000,
+	0x583c0001, 0x0401fe89, 0x0402001f, 0x0201f800,
+	0x001045a6, 0x0402001c, 0x49366009, 0x0201f800,
+	0x001007e4, 0x04000018, 0x492e6017, 0x497a5800,
+	0x497a5a04, 0x48125c04, 0x832cac00, 0x00000005,
+	0x4200b000, 0x00000007, 0x403ca000, 0x0201f800,
+	0x0010ab17, 0x5c003000, 0x481a641a, 0x4a026403,
+	0x0000003e, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x0201f800, 0x0010672b, 0x5c00b000,
+	0x1c01f000, 0x0201f800, 0x0002077d, 0x5c003000,
+	0x0401f7fb, 0x4803c856, 0x59cc0400, 0x82000d00,
+	0x0000ff00, 0x82040500, 0x0000f000, 0x840409c0,
+	0x82000580, 0x00002000, 0x04020049, 0x82040580,
+	0x00000022, 0x0402003a, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000c80, 0x00000007, 0x04001004,
+	0x82000480, 0x0000000c, 0x0400103f, 0x59cc0006,
+	0x82000500, 0xffff0000, 0x82000d80, 0x04000000,
+	0x04000039, 0x82000d80, 0x60000000, 0x04000036,
+	0x82000d80, 0x54000000, 0x04000033, 0x82000d80,
+	0x03000000, 0x04020015, 0x59a80826, 0x8c040d02,
+	0x0402002d, 0x8c040d08, 0x0402002b, 0x0201f800,
+	0x001048ec, 0x0400002b, 0x59a8001d, 0x800000d0,
+	0x59a80810, 0x82040d00, 0x000000ff, 0x80040540,
+	0x59cc0800, 0x82040d00, 0x00ffffff, 0x80040580,
+	0x0402001b, 0x0401f01c, 0x59c40802, 0x8c040d0c,
+	0x04020017, 0x82000d80, 0x52000000, 0x040007ec,
+	0x82000d80, 0x05000000, 0x040007e9, 0x82000d80,
+	0x50000000, 0x040007e6, 0x0401f00d, 0x82040580,
+	0x00000023, 0x0402000a, 0x0401ff58, 0x04000008,
+	0x59300c03, 0x82040580, 0x00000002, 0x04000006,
+	0x82040580, 0x00000051, 0x04000003, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+	0x03000000, 0x04000004, 0x82000d80, 0x52000000,
+	0x040207f3, 0x59a80026, 0x82000500, 0x00000009,
+	0x82000580, 0x00000008, 0x040007ef, 0x0401f7ec,
+	0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+	0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+	0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+	0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83cc1400, 0x0000000d, 0x0201f800,
+	0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+	0x83cc1400, 0x0000000f, 0x0201f800, 0x0010855a,
+	0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+	0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+	0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+	0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+	0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83cc1400, 0x00000009, 0x0201f800,
+	0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+	0x4803c857, 0x4c580000, 0x40003000, 0x42002000,
+	0x000007f0, 0x4200b000, 0x00000010, 0x83ac7400,
+	0x000007f0, 0x50380000, 0x80026d40, 0x04000006,
+	0x59340002, 0x82000500, 0x00ffffff, 0x80180580,
+	0x04000010, 0x80102000, 0x80387000, 0x8058b040,
+	0x040207f5, 0x82100480, 0x00000800, 0x42002000,
+	0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000,
+	0x040217ed, 0x82000540, 0x00000001, 0x0401f002,
+	0x40128800, 0x5c00b000, 0x1c01f000, 0x59a80026,
+	0x8c00050e, 0x04000004, 0x8c000502, 0x04000003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x59300c06, 0x82040580, 0x00000002,
+	0x04000006, 0x82040580, 0x00000005, 0x04000003,
+	0x82000540, 0x00000001, 0x1c01f000, 0x59c80000,
+	0x84000558, 0x84000512, 0x48039000, 0x1c01f000,
+	0x4a03281a, 0x000003e8, 0x4a032802, 0x0010d1c0,
+	0x4a032800, 0x00000000, 0x4a032808, 0x00107049,
+	0x42000000, 0x00000005, 0x83947c00, 0x00000009,
+	0x49787801, 0x4a007802, 0x00106fff, 0x823c7c00,
+	0x00000003, 0x80000040, 0x040207fa, 0x4a032819,
+	0xffff0000, 0x4201d000, 0x00000064, 0x0401f96e,
+	0x4201d000, 0x000186a0, 0x0401f184, 0x00000000,
+	0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+	0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+	0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+	0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+	0x4c640000, 0x4cc80000, 0x4ccc0000, 0x0201f800,
+	0x0002057b, 0x5c019800, 0x5c019000, 0x5c00c800,
+	0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+	0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+	0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x59940004, 0x80000540, 0x0402000a,
+	0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+	0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+	0x80000580, 0x1c01f000, 0x5994001f, 0x80000540,
+	0x0402000a, 0x59940025, 0x80040400, 0x02001800,
+	0x001005d8, 0x4803281f, 0x480b2820, 0x4a03281e,
+	0x00000001, 0x80000580, 0x1c01f000, 0x59940022,
+	0x80000540, 0x0402000a, 0x59940025, 0x80040400,
+	0x02001800, 0x001005d8, 0x48032822, 0x480b2823,
+	0x4a032821, 0x0000000a, 0x80000580, 0x1c01f000,
+	0x4c000000, 0x59940005, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x497b2804, 0x497b2805,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59940020,
+	0x4803c857, 0x480bc857, 0x80080580, 0x04020003,
+	0x497b281f, 0x497b2820, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59940023, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x497b2822, 0x497b2823,
+	0x5c000000, 0x1c01f000, 0x4937c857, 0x48ebc857,
+	0x59340203, 0x80e80480, 0x04001002, 0x48ea6a03,
+	0x1c01f000, 0x5c03e000, 0x1c01f000, 0x4d440000,
+	0x42007800, 0x00000010, 0x59968801, 0x0201f800,
+	0x00020245, 0x04020012, 0x59341a03, 0x800c1840,
+	0x0400100f, 0x59940027, 0x800c0480, 0x04000003,
+	0x48026a03, 0x0402100a, 0x5934000f, 0x497a6a03,
+	0x80000540, 0x04000006, 0x4c3c0000, 0x5934140b,
+	0x0201f800, 0x00020253, 0x5c007800, 0x81468800,
+	0x83440480, 0x00000800, 0x04021007, 0x803c7840,
+	0x040207e7, 0x49472801, 0x5c028800, 0x5c03e000,
+	0x1c01f000, 0x4a032800, 0x00000002, 0x497b2801,
+	0x0401f7fa, 0x42007800, 0x00000010, 0x59966002,
+	0x59300205, 0x80000d40, 0x04000006, 0x59940027,
+	0x80040480, 0x48026205, 0x0400102d, 0x0400002c,
+	0x59300206, 0x80000d40, 0x04000014, 0x59b800e4,
+	0x8c000524, 0x04020011, 0x4a0370e4, 0x00030000,
+	0x40000000, 0x59b800e4, 0x8c000524, 0x04000004,
+	0x4a0370e4, 0x00020000, 0x0401f008, 0x59940027,
+	0x80040480, 0x48026206, 0x4a0370e4, 0x00020000,
+	0x0400101c, 0x0400001b, 0x83326400, 0x00000024,
+	0x49332802, 0x41540000, 0x81300480, 0x04021005,
+	0x803c7840, 0x040207db, 0x5c03e000, 0x1c01f000,
+	0x59940026, 0x48032827, 0x4a032802, 0x0010d1c0,
+	0x497b2826, 0x80000540, 0x0400000f, 0x4a032800,
+	0x00000001, 0x5c03e000, 0x1c01f000, 0x4c3c0000,
+	0x0201f800, 0x001091db, 0x5c007800, 0x0401f7d1,
+	0x4c3c0000, 0x0201f800, 0x00108d5d, 0x5c007800,
+	0x0401f7e2, 0x4a032800, 0x00000000, 0x5c03e000,
+	0x1c01f000, 0x59a8086b, 0x8c040d30, 0x04020029,
+	0x8c040d32, 0x0400000f, 0x59a80069, 0x81640480,
+	0x04001019, 0x59a8000b, 0x81500580, 0x04000005,
+	0x59a8006a, 0x59a81066, 0x80080580, 0x04020012,
+	0x900411c0, 0x82081500, 0x00007000, 0x0401f012,
+	0x82040500, 0x0000001f, 0x04000016, 0x80040840,
+	0x82040500, 0x0000001f, 0x04000003, 0x4807506b,
+	0x0401f010, 0x900401c0, 0x82000500, 0x0000001f,
+	0x80040d40, 0x900401c0, 0x80040580, 0x82001500,
+	0x00007000, 0x82040500, 0xffff8fff, 0x80080540,
+	0x4803506b, 0x80081114, 0x0201f800, 0x001006e2,
+	0x1c01f000, 0x4a032807, 0x000007d0, 0x4a032806,
+	0x0000000a, 0x1c01f000, 0x42000800, 0x000007d0,
+	0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+	0x83947c00, 0x00000009, 0x83180400, 0x00105f43,
+	0x50000000, 0x803c7c00, 0x48047801, 0x4a007800,
+	0x0000000a, 0x1c01f000, 0x83180480, 0x00000005,
+	0x02021800, 0x001005d8, 0x83947c00, 0x00000009,
+	0x83180400, 0x00105f43, 0x50000000, 0x803c7c00,
+	0x49787801, 0x1c01f000, 0x4807c857, 0x480bc857,
+	0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+	0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+	0x1c01f000, 0x4807c857, 0x480bc857, 0x59940025,
+	0x80040400, 0x02001800, 0x001005d8, 0x4803281c,
+	0x480b281d, 0x4a03281b, 0x0000000a, 0x1c01f000,
+	0x4c000000, 0x5994001d, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x4803281c, 0x4803281d,
+	0x5c000000, 0x1c01f000, 0x80e9d1c0, 0x0400000e,
+	0x0401f836, 0x04025000, 0x4203e000, 0x80000000,
+	0x40e81000, 0x41780800, 0x42000000, 0x00000064,
+	0x0201f800, 0x001066a0, 0x59940024, 0x80080400,
+	0x48032824, 0x1c01f000, 0x42001000, 0x00105065,
+	0x0401fef0, 0x42001000, 0x00105058, 0x0401ffe1,
+	0x42001000, 0x00104148, 0x0401feea, 0x42001000,
+	0x001041bc, 0x0401fee7, 0x42001000, 0x001041f3,
+	0x0401f6f8, 0x4203e000, 0x70000000, 0x4203e000,
+	0xb0300000, 0x41fc0000, 0x40ebf800, 0x80e80480,
+	0x04001011, 0x04000004, 0x82000480, 0x00000003,
+	0x0402100d, 0x42000000, 0x0000000f, 0x04004004,
+	0x80000040, 0x040207fe, 0x0401f007, 0x4203e000,
+	0x70000000, 0x42000000, 0x0010b87e, 0x0201f800,
+	0x0010aa47, 0x1c01f000, 0x4203e000, 0x80000000,
+	0x4203e000, 0xb0400000, 0x41fc0000, 0x40ebf800,
+	0x80e80480, 0x04001011, 0x04000004, 0x82000480,
+	0x00000003, 0x0402100d, 0x42000000, 0x0000000f,
+	0x04005004, 0x80000040, 0x040207fe, 0x0401f007,
+	0x4203e000, 0x80000000, 0x42000000, 0x0010b87f,
+	0x0201f800, 0x0010aa47, 0x1c01f000, 0x59a8000e,
+	0x82000480, 0x00000100, 0x599c0a02, 0x800409c0,
+	0x04020002, 0x80040800, 0x80041480, 0x04001002,
+	0x40000800, 0x48075067, 0x59a8100e, 0x40040000,
+	0x800acc80, 0x4967500e, 0x49675069, 0x59aaa80b,
+	0x41640800, 0x42001000, 0x00000024, 0x0201f800,
+	0x00106681, 0x8206a400, 0x0010d1c0, 0x49535065,
+	0x4152b000, 0x42006000, 0x0010be65, 0x4a006004,
+	0x0000012c, 0x4a006005, 0xda10da10, 0x4a006008,
+	0x00000011, 0x4a006009, 0x0010be65, 0x4a00600a,
+	0x001010b8, 0x599c0014, 0x48006011, 0x599c0015,
+	0x48006012, 0x42006000, 0x0010be41, 0x4a006203,
+	0x00000008, 0x4a006406, 0x00000006, 0x4a006002,
+	0xffff0000, 0x4a006008, 0x0010be65, 0x4a006014,
+	0x0010be65, 0x599c0014, 0x48006015, 0x599c0015,
+	0x48006016, 0x599c0413, 0x48006017, 0x49506018,
+	0x49546019, 0x59a80067, 0x4800601a, 0x4a00601b,
+	0x0010b465, 0x4a00601c, 0x0010b466, 0x4a00601d,
+	0x0010b46a, 0x42000000, 0xb0000000, 0x42000800,
+	0x0010be41, 0x0201f800, 0x00100b68, 0x1c01f000,
+	0x82000d00, 0x000000c0, 0x04000004, 0x82040d80,
+	0x000000c0, 0x04020055, 0x82000d00, 0x00002020,
+	0x59300414, 0x84000512, 0x82040d80, 0x00002020,
+	0x0400000b, 0x8c000514, 0x0402000f, 0x48026414,
+	0x813e79c0, 0x02020000, 0x000206d0, 0x42027000,
+	0x00000043, 0x0201f000, 0x000207a1, 0x59326809,
+	0x59340a00, 0x8c040d0a, 0x040007f3, 0x84000552,
+	0x0401f7f1, 0x84000514, 0x592c080d, 0x48066015,
+	0x0401f7ef, 0x59326809, 0x59340a00, 0x8c040d0a,
+	0x02000000, 0x000206e3, 0x59300c14, 0x84040d52,
+	0x48066414, 0x0201f000, 0x000206e3, 0x0201f800,
+	0x00020086, 0x813e79c0, 0x02020000, 0x000206d0,
+	0x0201f000, 0x000206f1, 0x8c00051e, 0x02000000,
+	0x000206fd, 0x82000d00, 0x00002020, 0x82040d80,
+	0x00002020, 0x04000014, 0x82000500, 0x000000c0,
+	0x82000d80, 0x00000080, 0x04000008, 0x813e79c0,
+	0x02020000, 0x000206d0, 0x42027000, 0x00000041,
+	0x0201f000, 0x000207a1, 0x813e79c0, 0x02020000,
+	0x000206d0, 0x42027000, 0x00000043, 0x0201f000,
+	0x000207a1, 0x59326809, 0x59340a00, 0x8c040d0a,
+	0x040007ea, 0x59300c14, 0x84040d52, 0x48066414,
+	0x0401f7e6, 0x492fc857, 0x42000800, 0x00000006,
+	0x0201f000, 0x000206f8, 0x492fc857, 0x42000800,
+	0x00000004, 0x0201f000, 0x000206f8, 0x4807c856,
+	0x59a80068, 0x800409c0, 0x04000003, 0x80080540,
+	0x0401f002, 0x80080500, 0x48035068, 0x1c01f000,
+	0x4a030800, 0x00000000, 0x4a030802, 0x00000001,
+	0x497b0803, 0x497b0804, 0x1c01f000, 0x59840002,
+	0x8c000500, 0x04000004, 0x84000500, 0x4a030800,
+	0x00000001, 0x84000544, 0x84000506, 0x48030802,
+	0x82000d00, 0x0fffffff, 0x42000000, 0x90000000,
+	0x0201f800, 0x00100b94, 0x59a80069, 0x82000480,
+	0x00000007, 0x48035069, 0x80000580, 0x42000800,
+	0x0010b519, 0x48000800, 0x48000801, 0x1c01f000,
+	0x59a80069, 0x82000480, 0x00000007, 0x48035069,
+	0x1c01f000, 0x83640480, 0x00000008, 0x0400101b,
+	0x58c80a03, 0x80000580, 0x82000400, 0x00000008,
+	0x80040840, 0x040207fd, 0x815c0480, 0x04001013,
+	0x4200b000, 0x00000007, 0x0201f800, 0x0002075a,
+	0x4a026203, 0x00000004, 0x4a026406, 0x00000009,
+	0x4a026203, 0x00000004, 0x4a026007, 0x00000101,
+	0x0401f809, 0x0401f880, 0x8058b040, 0x040207f3,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x0201f800, 0x001007e4, 0x492e6008,
+	0x58c80a03, 0x4a025a04, 0x0000002c, 0x497a5800,
+	0x497a5801, 0x497a5c04, 0x497a5c06, 0x497a5805,
+	0x4a025a08, 0x00000005, 0x4a025a07, 0x00000002,
+	0x58c80201, 0x48025c04, 0x58c80202, 0x48025c07,
+	0x58c80204, 0x48025c08, 0x4a02580d, 0x0000ffff,
+	0x80040840, 0x0400000c, 0x412c2000, 0x0201f800,
+	0x001007e4, 0x4a025a04, 0x0000000a, 0x497a5c04,
+	0x48125800, 0x492c2001, 0x412c2000, 0x80040840,
+	0x040207f7, 0x1c01f000, 0x4d7c0000, 0x4202f800,
+	0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+	0x59847803, 0x803c79c0, 0x0400001e, 0x4c5c0000,
+	0x583cb808, 0x585c3408, 0x801831c0, 0x0400000b,
+	0x0401f84a, 0x04000016, 0x42001000, 0x0010b519,
+	0x0401f87f, 0x04000012, 0x0201f800, 0x001007d3,
+	0x0400000f, 0x492cb805, 0x585c0005, 0x80000540,
+	0x02000800, 0x001005d8, 0x0401f830, 0x585c5408,
+	0x0401f80b, 0x5c00b800, 0x5c03e000, 0x817ef840,
+	0x040207e1, 0x5c02f800, 0x1c01f000, 0x5c00b800,
+	0x5c03e000, 0x5c02f800, 0x1c01f000, 0x4803c856,
+	0x405c6000, 0x802851c0, 0x04000018, 0x585c0204,
+	0x82000d00, 0x0000000f, 0x82040c00, 0x001010bd,
+	0x50044000, 0x4cf00000, 0x4d000000, 0x4d040000,
+	0x4021e000, 0x40320800, 0x59860004, 0x4c280000,
+	0x0401f934, 0x5c005000, 0x40f04000, 0x41046000,
+	0x0201f800, 0x0010109b, 0x040207f6, 0x5c020800,
+	0x5c020000, 0x5c01e000, 0x58c80204, 0x4800bc08,
+	0x0201f800, 0x00020086, 0x4a026007, 0x00000101,
+	0x497a6009, 0x0401f055, 0x4803c856, 0x59840003,
+	0x80026540, 0x04000003, 0x59300000, 0x48030803,
+	0x1c01f000, 0x4803c856, 0x59840003, 0x48026000,
+	0x49330803, 0x1c01f000, 0x58cc0805, 0x40180000,
+	0x80040480, 0x0400100d, 0x82cc0580, 0x0010b50e,
+	0x02020800, 0x001005d8, 0x58c80205, 0x80040480,
+	0x0400101d, 0x82000540, 0x00000001, 0x1c01f000,
+	0x80003580, 0x0401f7fe, 0x82cc0580, 0x0010b50e,
+	0x02020800, 0x001005d8, 0x58c80400, 0x8c000504,
+	0x040007f8, 0x58c8040b, 0x8c00051e, 0x040007f5,
+	0x8c000500, 0x040207f3, 0x84000540, 0x4801940b,
+	0x42000000, 0x0010b839, 0x0201f800, 0x0010aa47,
+	0x42001000, 0x00008026, 0x0201f800, 0x00103a3e,
+	0x0401f7e8, 0x58c8040b, 0x8c00051e, 0x040007e2,
+	0x8c000502, 0x040207e0, 0x84000542, 0x4801940b,
+	0x42000000, 0x0010b838, 0x0201f800, 0x0010aa47,
+	0x42001000, 0x00008025, 0x42001800, 0x00000000,
+	0x0201f800, 0x00103a3e, 0x0401f7d3, 0x4803c856,
+	0x58080000, 0x42001800, 0x00000007, 0x58080801,
+	0x80040480, 0x04020004, 0x400c0000, 0x80000540,
+	0x0401f005, 0x04001003, 0x800c0480, 0x0401f002,
+	0x80000080, 0x1c01f000, 0x4803c856, 0x59300008,
+	0x80000d40, 0x02000800, 0x001005d8, 0x58040005,
+	0x80000540, 0x02000800, 0x001005d8, 0x59300007,
+	0x82000500, 0x00000101, 0x82000580, 0x00000101,
+	0x02020800, 0x001005d8, 0x42001000, 0x0010b519,
+	0x58080801, 0x82040400, 0x0010b51b, 0x497a6414,
+	0x4a026015, 0x0000ffff, 0x45300000, 0x80040800,
+	0x82040480, 0x00000008, 0x04001002, 0x80000d80,
+	0x48041001, 0x82040400, 0x0010b51b, 0x45780000,
+	0x1c01f000, 0x4933c857, 0x59300808, 0x800409c0,
+	0x02000800, 0x001005d8, 0x4d2c0000, 0x58065805,
+	0x812e59c0, 0x02020800, 0x001007f4, 0x49780805,
+	0x40065800, 0x0201f800, 0x001007fd, 0x5c025800,
+	0x4d300000, 0x0201f800, 0x0002077d, 0x5c026000,
+	0x1c01f000, 0x59300406, 0x82000580, 0x00000009,
+	0x04020006, 0x59300007, 0x8c000510, 0x04000003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x1c01f000, 0x59840802, 0x8c040d04, 0x1c01f000,
+	0x4803c856, 0x59840802, 0x84040d04, 0x84040d40,
+	0x4a030800, 0x00000000, 0x48070802, 0x82040d00,
+	0x0fffffff, 0x42000000, 0x90000000, 0x0201f000,
+	0x00100b94, 0x4807c857, 0x4805980a, 0x49799801,
+	0x49799803, 0x49799806, 0x49799807, 0x49799808,
+	0x49799805, 0x49799809, 0x0401f8c9, 0x0400000a,
+	0x0401f8eb, 0x04000008, 0x48359800, 0x48359802,
+	0x48359806, 0x4a019804, 0x00000001, 0x4a019807,
+	0x00000005, 0x1c01f000, 0x4807c857, 0x58cc1007,
+	0x40040000, 0x80080480, 0x04021020, 0x4c040000,
+	0x4c080000, 0x0401f8da, 0x5c001000, 0x5c000800,
+	0x0400001c, 0x58cc0006, 0x80006540, 0x0402000b,
+	0x48359800, 0x48359802, 0x48359806, 0x49799801,
+	0x49799803, 0x49786801, 0x49786800, 0x49799804,
+	0x49799807, 0x0401f005, 0x48306801, 0x48346000,
+	0x48359806, 0x49786800, 0x58cc0004, 0x58cc1007,
+	0x80000000, 0x82081400, 0x00000005, 0x48019804,
+	0x48099807, 0x0401f7df, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x40083000,
+	0x58cc0801, 0x82040480, 0x00000005, 0x02021800,
+	0x001005d8, 0x82040400, 0x00106418, 0x50000000,
+	0x58cca800, 0x8054ac00, 0x42001800, 0x00000005,
+	0x40040000, 0x800c0480, 0x80082480, 0x04021002,
+	0x40080000, 0x8000b0c2, 0x8058b400, 0x5450a800,
+	0x8050a000, 0x8054a800, 0x8058b040, 0x040207fc,
+	0x40001000, 0x58cc2805, 0x58cc0807, 0x58cc2001,
+	0x80142c00, 0x80040c80, 0x80102400, 0x48159805,
+	0x48059807, 0x48119801, 0x82100580, 0x00000005,
+	0x0400000c, 0x48119801, 0x40080000, 0x80181480,
+	0x40083000, 0x04000003, 0x040217d6, 0x80000580,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+	0x58cc0800, 0x800409c0, 0x02000800, 0x001005d8,
+	0x58040800, 0x48059800, 0x41782000, 0x0401f7ee,
+	0x0401f813, 0x50f00000, 0x81040400, 0x40001800,
+	0x585c0204, 0x4803c857, 0x82000580, 0x0000002c,
+	0x02020800, 0x001005d8, 0x58040202, 0x800000e0,
+	0x81000540, 0x48001802, 0x58040000, 0x48001800,
+	0x58040001, 0x48001801, 0x1c01f000, 0x4807c856,
+	0x58cc0005, 0x80000040, 0x02001800, 0x001005d8,
+	0x48019805, 0x58cc1003, 0x82080480, 0x00000005,
+	0x02021800, 0x001005d8, 0x82080400, 0x00106418,
+	0x50000000, 0x58cc0802, 0x80040c00, 0x80081000,
+	0x82080480, 0x00000005, 0x0402000f, 0x58cc2002,
+	0x58100000, 0x80006d40, 0x04000009, 0x4c340000,
+	0x0401f858, 0x5c006800, 0x49786801, 0x48359802,
+	0x58cc0004, 0x80000040, 0x48019804, 0x49799803,
+	0x0401f002, 0x48099803, 0x1c01f000, 0x4807c856,
+	0x41781800, 0x58c80201, 0x80000540, 0x04000002,
+	0x800c1800, 0x58c80c01, 0x80040c80, 0x0400100a,
+	0x04000009, 0x800c1800, 0x58c80202, 0x80041480,
+	0x04001005, 0x04000004, 0x800c1800, 0x40080800,
+	0x0401f7fb, 0x480d9204, 0x400c0000, 0x42002000,
+	0x00000001, 0x80000040, 0x04000007, 0x04001006,
+	0x80102000, 0x82000480, 0x00000005, 0x04000002,
+	0x040217fc, 0x48119203, 0x1c01f000, 0x4807c856,
+	0x4d2c0000, 0x58cc000a, 0x80000540, 0x02000800,
+	0x001005d8, 0x82002400, 0x00000005, 0x0201f800,
+	0x001007d3, 0x04000012, 0x492d9809, 0x497a5800,
+	0x497a5801, 0x0201f800, 0x001007d3, 0x0400000c,
+	0x58cc0009, 0x48025800, 0x497a5801, 0x492d9809,
+	0x82102480, 0x00000005, 0x040217f7, 0x82000540,
+	0x00000001, 0x5c025800, 0x1c01f000, 0x58cc0009,
+	0x80025d40, 0x040007fc, 0x592c2000, 0x0201f800,
+	0x001007f4, 0x40100000, 0x0401f7fa, 0x58cc0009,
+	0x48cfc857, 0x80006d40, 0x04000005, 0x50340000,
+	0x48019809, 0x49786800, 0x49786801, 0x1c01f000,
+	0x4813c857, 0x58cc0009, 0x48002000, 0x48119809,
+	0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0009,
+	0x80025d40, 0x04000007, 0x592c0000, 0x4c000000,
+	0x0201f800, 0x001007f4, 0x5c000000, 0x0401f7f9,
+	0x5c025800, 0x1c01f000, 0x4807c856, 0x4d2c0000,
+	0x58cc0002, 0x80025d40, 0x04000007, 0x592c0000,
+	0x4c000000, 0x0201f800, 0x001007f4, 0x5c000000,
+	0x0401f7f9, 0x49799800, 0x49799802, 0x49799801,
+	0x49799803, 0x49799806, 0x49799807, 0x49799808,
+	0x49799809, 0x4979980a, 0x5c025800, 0x1c01f000,
+	0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+	0x0000000f, 0x00000012, 0x4803c856, 0x0401f857,
+	0x4a00c204, 0x0000003c, 0x59301009, 0x82080580,
+	0x0010b524, 0x04000013, 0x58080802, 0x82040d00,
+	0x00ffffff, 0x58080403, 0x4804c005, 0x4800c406,
+	0x4a00c207, 0x00000003, 0x59300811, 0x585c0404,
+	0x4978c206, 0x4804c407, 0x80000540, 0x0400000d,
+	0x58600206, 0x84000540, 0x4800c206, 0x0401f009,
+	0x585c080a, 0x82040d00, 0x00ffffff, 0x4804c005,
+	0x4a00c406, 0x000007ff, 0x4978c207, 0x0401f7ef,
+	0x82603c00, 0x00000008, 0x58605404, 0x40282000,
+	0x405c6000, 0x585c0a04, 0x82040d00, 0x0000000f,
+	0x82040c00, 0x001010bd, 0x50044000, 0x80004d80,
+	0x50200000, 0x80307400, 0x58380402, 0x8c244d00,
+	0x04020003, 0x48003a00, 0x0401f003, 0x48003c00,
+	0x801c3800, 0x80244800, 0x80102040, 0x04000006,
+	0x0201f800, 0x0010109b, 0x02000800, 0x001005d8,
+	0x0401f7f0, 0x1c01f000, 0x4803c856, 0x4d340000,
+	0x59300009, 0x80026d40, 0x02000800, 0x001005d8,
+	0x59340401, 0x80000540, 0x0400000e, 0x59840000,
+	0x80000540, 0x0400000b, 0x836c0580, 0x00000003,
+	0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+	0x42003000, 0x00000004, 0x0201f800, 0x00103aae,
+	0x5c026800, 0x1c01f000, 0x4803c856, 0x80001580,
+	0x58c80c01, 0x59300011, 0x80040c80, 0x48066011,
+	0x58c80201, 0x80000540, 0x04000005, 0x80081000,
+	0x80040c80, 0x04001007, 0x04000006, 0x58c80202,
+	0x80081000, 0x80040c80, 0x04001002, 0x040207fd,
+	0x4808bc08, 0x4808c404, 0x1c01f000, 0x4803c856,
+	0x4a0370e5, 0x00020000, 0x59b800e5, 0x8c000524,
+	0x040207fc, 0x4a0370e5, 0x00030000, 0x40000000,
+	0x40000000, 0x59b800e5, 0x8c000524, 0x040207f5,
+	0x5934000e, 0x80006d40, 0x04000010, 0x81300580,
+	0x04020004, 0x58340000, 0x4802680e, 0x0401f00a,
+	0x40347800, 0x58340000, 0x80006d40, 0x02000800,
+	0x001005d8, 0x81300580, 0x040207fa, 0x58340000,
+	0x48007800, 0x497a6000, 0x4a0370e5, 0x00020000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x4d2c0000,
+	0x42000800, 0x000003ff, 0x4a0370e5, 0x00020000,
+	0x59b800e5, 0x8c000524, 0x04000005, 0x80040840,
+	0x040207fa, 0x0201f800, 0x001005d8, 0x4a0370e5,
+	0x00030000, 0x40000000, 0x40000000, 0x59b800e5,
+	0x8c000524, 0x040207f1, 0x5934000e, 0x80026540,
+	0x0400000e, 0x4933c857, 0x59300000, 0x4802680e,
+	0x4a026203, 0x00000004, 0x497a6206, 0x497a6009,
+	0x4a026007, 0x00000101, 0x59325808, 0x497a5c08,
+	0x0401fd81, 0x0401f7f1, 0x4a0370e5, 0x00020000,
+	0x5c025800, 0x5c026000, 0x1c01f000, 0x4803c856,
+	0x4c000000, 0x0201f800, 0x00105c9a, 0x04020011,
+	0x0201f800, 0x001045a6, 0x02020800, 0x001005d8,
+	0x5c000000, 0x48026802, 0x0201f800, 0x0002075a,
+	0x04000009, 0x49366009, 0x4a026406, 0x00000001,
+	0x42027000, 0x00000001, 0x0201f000, 0x000207a1,
+	0x5c000000, 0x1c01f000, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x0c01f001, 0x00106503, 0x00106503, 0x00106503,
+	0x00106505, 0x00106565, 0x00106503, 0x00106503,
+	0x001065b7, 0x001065b8, 0x00106503, 0x00106503,
+	0x00106503, 0x00106503, 0x00106503, 0x0201f800,
+	0x001005d8, 0x493bc857, 0x83380480, 0x00000050,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x00106518,
+	0x0010653a, 0x00106516, 0x00106516, 0x00106516,
+	0x00106516, 0x00106549, 0x0201f800, 0x001005d8,
+	0x4d2c0000, 0x59325808, 0x592c0206, 0x48025c06,
+	0x4a025a06, 0x00000000, 0x4c5c0000, 0x592cbc0a,
+	0x592c0000, 0x48026008, 0x0201f800, 0x00104cde,
+	0x59300008, 0x80000540, 0x04000008, 0x4a026203,
+	0x00000007, 0x42027000, 0x00000043, 0x5c00b800,
+	0x5c025800, 0x0401f08a, 0x8c5cbd08, 0x04020006,
+	0x4a026203, 0x00000007, 0x497a6206, 0x497a6008,
+	0x0401f003, 0x0201f800, 0x0002077d, 0x5c00b800,
+	0x5c025800, 0x1c01f000, 0x0201f800, 0x00106b8a,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000006, 0x4d400000, 0x42028000, 0x00000001,
+	0x0401f8f8, 0x5c028000, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x00106b8a, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42003000, 0x00000014, 0x0201f800, 0x0010a942,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000006, 0x4d400000, 0x42028000, 0x00000029,
+	0x0401f8dc, 0x5c028000, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x493bc857, 0x497a6206, 0x83380480,
+	0x00000054, 0x02021800, 0x001005d8, 0x83380480,
+	0x00000047, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x001065b6, 0x0010657f, 0x0010657d, 0x0010657d,
+	0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+	0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+	0x00106583, 0x0201f800, 0x001005d8, 0x59300011,
+	0x82000500, 0xffff0000, 0x04020034, 0x59840802,
+	0x8c040d04, 0x04000025, 0x59300009, 0x80026d40,
+	0x0400001f, 0x4c5c0000, 0x4c600000, 0x497a6206,
+	0x5930b808, 0x585c0005, 0x8000c540, 0x02000800,
+	0x001005d8, 0x0401fe8d, 0x40625800, 0x0201f800,
+	0x00104cde, 0x4978b805, 0x0401fef5, 0x497a6009,
+	0x585c3408, 0x0401fcbd, 0x0400000e, 0x42001000,
+	0x0010b519, 0x0401fcf2, 0x0400000a, 0x0201f800,
+	0x001007e4, 0x04000007, 0x492cb805, 0x585c5408,
+	0x0401fc83, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x0401fca9, 0x0401f7fc, 0x8c040d06, 0x040207fc,
+	0x59300009, 0x80026d40, 0x04000006, 0x5934000e,
+	0x80000540, 0x02020800, 0x001005d8, 0x497a6009,
+	0x0401fd0d, 0x0401f7f2, 0x0401f06f, 0x4803c856,
+	0x4803c856, 0x83380580, 0x00000043, 0x02020800,
+	0x001005d8, 0x4a026203, 0x00000003, 0x493a6403,
+	0x59325808, 0x592c000f, 0x48026011, 0x497a6013,
+	0x592c0406, 0x800000c2, 0x800010c4, 0x80081400,
+	0x480a6206, 0x0201f800, 0x00100f4e, 0x42000800,
+	0x80000060, 0x0401f154, 0x42000000, 0x0010b875,
+	0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x82000d80, 0x00000003, 0x04000006, 0x82000d80,
+	0x00000004, 0x04000045, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106c55, 0x59300004, 0x8c00053e,
+	0x04020007, 0x0201f800, 0x00106b6c, 0x02020800,
+	0x001005d8, 0x0201f000, 0x00106c4b, 0x0401f9c3,
+	0x0201f800, 0x00106c4b, 0x59325808, 0x42028000,
+	0x00000006, 0x0401f84b, 0x0201f000, 0x0002077d,
+	0x4803c856, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x82000d80, 0x00000003,
+	0x04000006, 0x82000d80, 0x00000004, 0x04000023,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x59300004, 0x8c00053e,
+	0x04020006, 0x0201f800, 0x00106f60, 0x02020800,
+	0x001005d8, 0x0401f010, 0x0201f800, 0x00108cd6,
+	0x04020004, 0x0201f800, 0x00106e62, 0x0402000a,
+	0x0401f99a, 0x02020800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+	0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x00100e99, 0x4933c857, 0x4c5c0000, 0x4d340000,
+	0x497a6206, 0x5930b808, 0x59300009, 0x80026d40,
+	0x04020e5f, 0x42001000, 0x0010b519, 0x0401fc60,
+	0x04000009, 0x58c80204, 0x4800bc08, 0x41785000,
+	0x0201f800, 0x00106227, 0x5c026800, 0x5c00b800,
+	0x1c01f000, 0x4978bc08, 0x0401fc17, 0x0401f7fb,
+	0x4803c856, 0x0201f800, 0x00109037, 0x0400000f,
+	0x592c0000, 0x80000d40, 0x04000009, 0x497a5800,
+	0x49425a06, 0x4c040000, 0x0201f800, 0x000202da,
+	0x5c000800, 0x40065800, 0x0401f7f6, 0x49425a06,
+	0x0201f800, 0x000202da, 0x1c01f000, 0x4933c857,
+	0x59300c06, 0x82040580, 0x0000000e, 0x04000004,
+	0x82040580, 0x00000009, 0x04020004, 0x0401ffe5,
+	0x497a6008, 0x80000580, 0x1c01f000, 0x592e6009,
+	0x83300480, 0x0010d1c0, 0x04001016, 0x41580000,
+	0x81300480, 0x04021013, 0x40040000, 0x59300c06,
+	0x80040580, 0x04020012, 0x59300a03, 0x82040580,
+	0x00000007, 0x02020800, 0x001005d8, 0x59300008,
+	0x80000540, 0x02020800, 0x001005d8, 0x0201f800,
+	0x0002077d, 0x42000000, 0x00000000, 0x0401f009,
+	0x42000000, 0x00000008, 0x0401f006, 0x82040580,
+	0x00000007, 0x040207fb, 0x42000000, 0x00000005,
+	0x592c0a06, 0x48065c06, 0x48025a06, 0x0201f000,
+	0x000202da, 0x4c0c0000, 0x4c100000, 0x4c140000,
+	0x4c180000, 0x80001d80, 0x80002580, 0x42003000,
+	0x00000020, 0x82040500, 0x00000001, 0x04000003,
+	0x40080000, 0x800c1c00, 0x400c2800, 0x800c1902,
+	0x80102102, 0x82140500, 0x00000001, 0x04000003,
+	0x82102540, 0x80000000, 0x80040902, 0x80183040,
+	0x040207f1, 0x40100800, 0x400c0000, 0x5c003000,
+	0x5c002800, 0x5c002000, 0x5c001800, 0x1c01f000,
+	0x4c580000, 0x4200b000, 0x00000020, 0x80000540,
+	0x04000018, 0x80041c80, 0x04021016, 0x800810c2,
+	0x80040982, 0x04001006, 0x80041c80, 0x04021005,
+	0x8058b040, 0x040207fa, 0x0401f006, 0x80041c80,
+	0x400c0800, 0x80081000, 0x8058b040, 0x040207f4,
+	0x4c000000, 0x41f00000, 0x82000500, 0xf7ffffff,
+	0x4003e000, 0x5c000000, 0x5c00b000, 0x1c01f000,
+	0x4c000000, 0x41f00000, 0x82000540, 0x08000000,
+	0x0401f7f8, 0x4a0378e8, 0x00000000, 0x4a03c821,
+	0x00000010, 0x4a03c823, 0x00000004, 0x0401f82c,
+	0x4a0378e9, 0x00003a0d, 0x4a0378e8, 0x00000001,
+	0x42000000, 0x00001000, 0x50000000, 0x82000480,
+	0x24220001, 0x04000004, 0x59e00002, 0x84000548,
+	0x4803c002, 0x42000800, 0x00000005, 0x4203a000,
+	0x00007600, 0x42000000, 0x00001000, 0x50000000,
+	0x82000480, 0x24320001, 0x04021003, 0x4a03a005,
+	0xd0000001, 0x59d00006, 0x4a03a005, 0x90000001,
+	0x83d3a400, 0x00000020, 0x80040840, 0x040207fa,
+	0x59e00003, 0x82000500, 0xffffffe0, 0x82000540,
+	0x00008000, 0x4803c003, 0x59c40006, 0x82000500,
+	0xfffcffff, 0x48038806, 0x1c01f000, 0x4d900000,
+	0x4d180000, 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6,
+	0xaaaaaaaa, 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4,
+	0xaaaaaaaa, 0x42000800, 0x0000bf00, 0x4a00081a,
+	0x0010b7d4, 0x4a00081b, 0x001010bd, 0x4a00081c,
+	0x001010cd, 0x4a031800, 0x00000000, 0x4a031801,
+	0x0010b544, 0x4a031802, 0x0010b54b, 0x42000800,
+	0x0010b7d7, 0x417a3000, 0x811b20c8, 0x83932400,
+	0x0000bf32, 0x48072000, 0x4a032001, 0x00000000,
+	0x83180400, 0x001070ea, 0x50000000, 0x48032002,
+	0x82040c00, 0x00000003, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017f1, 0x5c023000, 0x5c032000,
+	0x1c01f000, 0x48066004, 0x497a6000, 0x497a6001,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+	0xa0000000, 0x480378e1, 0x1c01f000, 0x4933c857,
+	0x42000800, 0x80000040, 0x48066004, 0x497a6000,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+	0x60000000, 0x480378e1, 0x1c01f000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d300000, 0x4d340000,
+	0x4d2c0000, 0x4d180000, 0x4c5c0000, 0x4c600000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0,
+	0x0400002c, 0x41302800, 0x4178c000, 0x59300000,
+	0x4c000000, 0x59326809, 0x5930b801, 0x59300406,
+	0x82000d80, 0x00000006, 0x04020003, 0x8d3e7d18,
+	0x04000010, 0x8d3e7d06, 0x04000007, 0x82000580,
+	0x00000003, 0x04020004, 0x59340200, 0x8c00050e,
+	0x04020008, 0x0401f92f, 0x4c0c0000, 0x4c140000,
+	0x0401fb5f, 0x5c002800, 0x5c001800, 0x0401f005,
+	0x41301800, 0x8060c1c0, 0x04020002, 0x400cc000,
+	0x805cb9c0, 0x04000003, 0x405e6000, 0x0401f7e3,
+	0x5c026000, 0x813261c0, 0x04000006, 0x8060c1c0,
+	0x04000002, 0x40602800, 0x4178c000, 0x0401f7d8,
+	0x417a3000, 0x0201f800, 0x001070d8, 0x59926004,
+	0x813261c0, 0x04000023, 0x59326809, 0x4130c000,
+	0x59300001, 0x8000bd40, 0x04000016, 0x40026000,
+	0x40602800, 0x5930b801, 0x59300406, 0x82000d80,
+	0x00000006, 0x0400000e, 0x8d3e7d06, 0x04000007,
+	0x82000580, 0x00000003, 0x04020004, 0x59340200,
+	0x8c00050e, 0x04020006, 0x0401f8dc, 0x4c140000,
+	0x0401fb2f, 0x5c002800, 0x0401f002, 0x41302800,
+	0x405e6000, 0x813261c0, 0x040207eb, 0x8060c1c0,
+	0x04000004, 0x40626000, 0x4178c000, 0x0401f7e7,
+	0x811a3000, 0x83180480, 0x00000005, 0x040017d6,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c00c000, 0x5c00b800, 0x5c023000, 0x5c025800,
+	0x5c026800, 0x5c026000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d340000, 0x4d180000,
+	0x4d900000, 0x42003000, 0x0000bf2e, 0x59326809,
+	0x58182001, 0x40102800, 0x801021c0, 0x04000016,
+	0x41300000, 0x80100580, 0x04000011, 0x58100009,
+	0x81340580, 0x0402000b, 0x40101800, 0x58102001,
+	0x41300000, 0x801021c0, 0x0400000b, 0x80100d80,
+	0x04000007, 0x40101800, 0x58102001, 0x0401f7fa,
+	0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bd,
+	0x0401f01a, 0x42032000, 0x0000bf32, 0x417a3000,
+	0x59902004, 0x40102800, 0x801021c0, 0x0400000b,
+	0x58100009, 0x81340580, 0x04020008, 0x41300000,
+	0x80100580, 0x0400000c, 0x40102800, 0x58102001,
+	0x801021c0, 0x040207fa, 0x811a3000, 0x83180480,
+	0x00000005, 0x0402100d, 0x83932400, 0x00000010,
+	0x0401f7ec, 0x0401f881, 0x5c032000, 0x5c023000,
+	0x5c026800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x0401fb6f, 0x040007f7,
+	0x5c032000, 0x5c023000, 0x5c026800, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+	0x1c01f000, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x4d300000, 0x4d340000, 0x4d180000, 0x4d2c0000,
+	0x4c5c0000, 0x4c600000, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x42003000, 0x0000bf2e,
+	0x581a6001, 0x813261c0, 0x04000023, 0x41302800,
+	0x5930b800, 0x59326809, 0x59340403, 0x81440580,
+	0x04000006, 0x805cb9c0, 0x0400001b, 0x41302800,
+	0x405e6000, 0x0401f7f7, 0x5930b801, 0x8d3e7d00,
+	0x04000003, 0x0401fb67, 0x0402000e, 0x59300406,
+	0x82000580, 0x00000006, 0x04020003, 0x8d3e7d18,
+	0x04000008, 0x0401f867, 0x4c0c0000, 0x4c140000,
+	0x0401fa97, 0x5c002800, 0x5c001800, 0x0401f002,
+	0x41301800, 0x405e6000, 0x813261c0, 0x040207eb,
+	0x0401f02d, 0x417a3000, 0x0201f800, 0x001070d8,
+	0x59926004, 0x813261c0, 0x04000005, 0x59326809,
+	0x59340403, 0x81440580, 0x04000006, 0x811a3000,
+	0x83180480, 0x00000005, 0x040017f4, 0x0401f01e,
+	0x4130c000, 0x59300001, 0x8000bd40, 0x04000012,
+	0x40026000, 0x40602800, 0x5930b801, 0x8d3e7d00,
+	0x04000003, 0x0401fb3b, 0x0402000a, 0x59300406,
+	0x82000580, 0x00000006, 0x04000006, 0x0401f81b,
+	0x4c140000, 0x0401fa6e, 0x5c002800, 0x0401f002,
+	0x41302800, 0x405e6000, 0x813261c0, 0x040207ef,
+	0x8060c1c0, 0x04000004, 0x40626000, 0x4178c000,
+	0x0401f7eb, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x5c00c000, 0x5c00b800, 0x5c025800,
+	0x5c023000, 0x5c026800, 0x5c026000, 0x5c03e000,
+	0x04000be3, 0x1c01f000, 0x0401fbc8, 0x59900004,
+	0x81300580, 0x04020018, 0x4c140000, 0x0201f800,
+	0x00106dc3, 0x0401fbb8, 0x5c002800, 0x59300001,
+	0x800001c0, 0x04020003, 0x497a680c, 0x1c01f000,
+	0x42003000, 0x0000bf2e, 0x497a6001, 0x58180801,
+	0x800409c0, 0x04020004, 0x48003000, 0x48003001,
+	0x1c01f000, 0x58180800, 0x48000800, 0x48003000,
+	0x1c01f000, 0x59300001, 0x48002801, 0x800001c0,
+	0x04020002, 0x4816680c, 0x497a6001, 0x1c01f000,
+	0x0401fba6, 0x42003000, 0x0000bf2e, 0x58180001,
+	0x81300580, 0x0402001c, 0x59300801, 0x800409c0,
+	0x0400000e, 0x59300000, 0x800001c0, 0x04020005,
+	0x48043001, 0x48043000, 0x497a6001, 0x1c01f000,
+	0x59300000, 0x48000800, 0x48043001, 0x497a6000,
+	0x497a6001, 0x1c01f000, 0x59300800, 0x800409c0,
+	0x04020005, 0x49783001, 0x49783000, 0x497a680c,
+	0x1c01f000, 0x48043001, 0x497a6000, 0x497a680c,
+	0x1c01f000, 0x58180000, 0x81300580, 0x0402000c,
+	0x59300001, 0x800001c0, 0x04020005, 0x48143000,
+	0x49782800, 0x497a680c, 0x1c01f000, 0x48003000,
+	0x48002800, 0x497a6001, 0x1c01f000, 0x59300000,
+	0x800001c0, 0x04020008, 0x59300001, 0x48001801,
+	0x800001c0, 0x04020002, 0x480e680c, 0x497a6001,
+	0x1c01f000, 0x59300801, 0x800409c0, 0x04020006,
+	0x59300800, 0x48042800, 0x497a6000, 0x497a680c,
+	0x1c01f000, 0x59300000, 0x48000800, 0x48042800,
+	0x497a6000, 0x497a6001, 0x1c01f000, 0x0401fb82,
+	0x4df00000, 0x0401f839, 0x040208c4, 0x04020945,
+	0x04020a89, 0x04020005, 0x5c03e000, 0x04000b70,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x04000b6c,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4d2c0000,
+	0x4d340000, 0x4d300000, 0x41783000, 0x598e6009,
+	0x813261c0, 0x04000021, 0x59300406, 0x82000580,
+	0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000a,
+	0x0401f017, 0x82040580, 0x00000005, 0x04020006,
+	0x8d3e7d16, 0x04000004, 0x59300420, 0x8c000500,
+	0x0402000f, 0x0401fa4e, 0x59300000, 0x4c000000,
+	0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+	0x04000005, 0x0401f867, 0x4c180000, 0x0401f9bc,
+	0x5c003000, 0x5c026000, 0x0401f7e2, 0x41303000,
+	0x59326000, 0x0401f7df, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+	0x598cb809, 0x41783000, 0x805cb9c0, 0x04000013,
+	0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+	0x0401f7fa, 0x0401f84b, 0x598c000d, 0x81300580,
+	0x02000800, 0x001070b9, 0x59300403, 0x82000580,
+	0x00000042, 0x04020002, 0x497a6007, 0x80000580,
+	0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+	0x5c00b800, 0x1c01f000, 0x0401fb27, 0x4df00000,
+	0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000,
+	0x598e6009, 0x813261c0, 0x0400002c, 0x59300c06,
+	0x82040580, 0x00000006, 0x04020004, 0x8d3e7d18,
+	0x0402000a, 0x0401f022, 0x82040580, 0x00000005,
+	0x04020006, 0x8d3e7d18, 0x04000004, 0x59300420,
+	0x8c000500, 0x0402001a, 0x59326809, 0x59340403,
+	0x81440580, 0x04020016, 0x8d3e7d00, 0x04000006,
+	0x82040580, 0x00000003, 0x04020011, 0x0401fa35,
+	0x0402000f, 0x0401f9f6, 0x59300000, 0x4c000000,
+	0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+	0x04000005, 0x0401f80f, 0x4c180000, 0x0401f964,
+	0x5c003000, 0x5c026000, 0x0401f7d7, 0x41303000,
+	0x59326000, 0x0401f7d4, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x5c03e000, 0x04000ae5, 0x1c01f000,
+	0x59300800, 0x497a6000, 0x0401fac8, 0x801831c0,
+	0x04020009, 0x598c0008, 0x81300580, 0x04020004,
+	0x48031808, 0x48031809, 0x0401f008, 0x48071809,
+	0x0401f006, 0x48043000, 0x598c0008, 0x81300580,
+	0x04020002, 0x481b1808, 0x0401f2ca, 0x4d2c0000,
+	0x4d300000, 0x4d340000, 0x41783000, 0x598e600b,
+	0x813261c0, 0x04000013, 0x8d3e7d06, 0x04000005,
+	0x59326809, 0x59340200, 0x8c00050e, 0x0402000a,
+	0x0401f9bf, 0x59300000, 0x4c000000, 0x0401f853,
+	0x4c180000, 0x0401f932, 0x5c003000, 0x5c026000,
+	0x0401f7f0, 0x41303000, 0x59326000, 0x0401f7ed,
+	0x0201f800, 0x00104773, 0x5c026800, 0x5c026000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+	0x598cb80b, 0x41783000, 0x805cb9c0, 0x0400000f,
+	0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+	0x0401f7fa, 0x0401f835, 0x598c000d, 0x81300580,
+	0x02000800, 0x001070b9, 0x497a6007, 0x80000580,
+	0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+	0x5c00b800, 0x1c01f000, 0x0401fa9f, 0x4df00000,
+	0x4d340000, 0x4d300000, 0x4d2c0000, 0x0201f800,
+	0x00020245, 0x02020800, 0x001005d8, 0x41783000,
+	0x598e600b, 0x813261c0, 0x04000014, 0x59300009,
+	0x81340580, 0x0402000e, 0x8d3e7d00, 0x04000003,
+	0x0401f9bc, 0x0402000a, 0x0401f97d, 0x59300000,
+	0x4c000000, 0x0401f811, 0x4c180000, 0x0401f8f0,
+	0x5c003000, 0x5c026000, 0x0401f7ef, 0x41303000,
+	0x59326000, 0x0401f7ec, 0x0201f800, 0x0010479c,
+	0x5c025800, 0x5c026000, 0x5c026800, 0x5c03e000,
+	0x04000a6f, 0x1c01f000, 0x59300800, 0x497a6000,
+	0x0401fa52, 0x801831c0, 0x04020009, 0x598c000a,
+	0x81300580, 0x04020004, 0x4803180a, 0x4803180b,
+	0x0401f008, 0x4807180b, 0x0401f006, 0x48043000,
+	0x598c000a, 0x81300580, 0x04020002, 0x481b180a,
+	0x0401f254, 0x0401fa64, 0x4df00000, 0x4d300000,
+	0x598e6005, 0x813261c0, 0x04000020, 0x59300000,
+	0x4c000000, 0x59300c06, 0x82040580, 0x00000011,
+	0x04020007, 0x833c0500, 0x00001800, 0x04000015,
+	0x8d3e7d16, 0x04020013, 0x0401f009, 0x82040580,
+	0x00000004, 0x04020006, 0x8d3e7d16, 0x04000004,
+	0x59300420, 0x8c000500, 0x0402000a, 0x0201f800,
+	0x0010914e, 0x02000800, 0x0010801c, 0x0201f800,
+	0x00109326, 0x0201f800, 0x0002077d, 0x0401fa31,
+	0x5c026000, 0x0401f7e0, 0x497b1805, 0x497b1804,
+	0x5c026000, 0x5c03e000, 0x04000a31, 0x1c01f000,
+	0x4933c857, 0x4c5c0000, 0x4c600000, 0x813261c0,
+	0x02000800, 0x001005d8, 0x41300000, 0x598cb805,
+	0x405cc000, 0x805cb9c0, 0x04000025, 0x805c0d80,
+	0x04000004, 0x405cc000, 0x5860b800, 0x0401f7fa,
+	0x598c000d, 0x81300580, 0x02000800, 0x001070b9,
+	0x0401fa02, 0x598c0005, 0x805c0580, 0x04020009,
+	0x585c0000, 0x48031805, 0x4978b800, 0x598c0004,
+	0x805c0580, 0x0402000d, 0x497b1804, 0x0401f00b,
+	0x598c0004, 0x805c0580, 0x04020005, 0x48631804,
+	0x4978b800, 0x4978c000, 0x0401f004, 0x585c0000,
+	0x4800c000, 0x4978b800, 0x0401f9fe, 0x80000580,
+	0x5c00c000, 0x5c00b800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x4933c857, 0x0401fa04, 0x4df00000, 0x4d2c0000,
+	0x4d340000, 0x4d300000, 0x4c5c0000, 0x4178b800,
+	0x8d3e7d18, 0x0400000d, 0x8d3e7d16, 0x0402000b,
+	0x0201f800, 0x00109037, 0x04000008, 0x0201f800,
+	0x00109597, 0x04020005, 0x592c0207, 0x492fc857,
+	0x8200bd00, 0x0000000f, 0x41783000, 0x598e6005,
+	0x813261c0, 0x04000029, 0x59326809, 0x813669c0,
+	0x04000023, 0x59340403, 0x81440580, 0x04020020,
+	0x59300c06, 0x82040580, 0x00000011, 0x0400001a,
+	0x82040580, 0x00000004, 0x04020004, 0x59300420,
+	0x8c000500, 0x04020016, 0x0201f800, 0x00109037,
+	0x04000008, 0x0201f800, 0x00109597, 0x04020005,
+	0x59300403, 0x82000580, 0x00000043, 0x0400000c,
+	0x0401f8c3, 0x59300000, 0x4c000000, 0x0401f812,
+	0x4c180000, 0x0401f836, 0x5c003000, 0x5c026000,
+	0x0401f7dc, 0x805cb9c0, 0x040207ec, 0x41303000,
+	0x59326000, 0x0401f7d7, 0x5c00b800, 0x5c026000,
+	0x5c026800, 0x5c025800, 0x5c03e000, 0x040009b4,
+	0x1c01f000, 0x59300800, 0x497a6000, 0x0401f997,
+	0x801831c0, 0x04020009, 0x598c0004, 0x81300580,
+	0x04020004, 0x48031804, 0x48031805, 0x0401f008,
+	0x48071805, 0x0401f006, 0x48043000, 0x598c0004,
+	0x81300580, 0x04020002, 0x481b1804, 0x0401f199,
+	0x4943c857, 0x0401f9a8, 0x4df00000, 0x0401fe34,
+	0x0401fecb, 0x5c03e000, 0x04000999, 0x1c01f000,
+	0x4947c857, 0x0401f9a0, 0x4df00000, 0x4d3c0000,
+	0x853e7d00, 0x0401fe75, 0x0401fefc, 0x5c027800,
+	0x5c03e000, 0x0400098e, 0x1c01f000, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x4d340000, 0x4d2c0000,
+	0x59326809, 0x59325808, 0x59300406, 0x82000c80,
+	0x00000012, 0x02021800, 0x001005d8, 0x4933c857,
+	0x4943c857, 0x493fc857, 0x4803c857, 0x0c01f804,
+	0x5c025800, 0x5c026800, 0x1c01f000, 0x00106ae5,
+	0x00106ae7, 0x00106af1, 0x00106b0b, 0x00106ae7,
+	0x00106afb, 0x00106b23, 0x00106ae5, 0x00106ae5,
+	0x00106b36, 0x00106b2d, 0x00106ae5, 0x00106ae5,
+	0x00106ae5, 0x00106ae5, 0x00106ae5, 0x00106b3c,
+	0x00106b3c, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x00109134, 0x02000800, 0x00102074, 0x0201f800,
+	0x00109326, 0x0201f800, 0x0010801c, 0x0201f000,
+	0x00107911, 0x812e59c0, 0x02020800, 0x001005d8,
+	0x5930021d, 0x82000580, 0x00000003, 0x02000800,
+	0x0010912a, 0x0201f000, 0x00107911, 0x0201f800,
+	0x00109037, 0x02000000, 0x00107911, 0x592c1204,
+	0x82081500, 0x000000ff, 0x82080580, 0x00000055,
+	0x02020800, 0x001005d8, 0x49425a06, 0x0201f800,
+	0x000202da, 0x0201f000, 0x00107911, 0x59300004,
+	0x8400055c, 0x48026004, 0x59300007, 0x8c000500,
+	0x02020800, 0x00100e99, 0x0201f800, 0x00109037,
+	0x0400000d, 0x4a025a04, 0x00000103, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x001091c6, 0x0201f800,
+	0x0010a693, 0x0201f800, 0x000202da, 0x0201f800,
+	0x0010912a, 0x0201f000, 0x00107911, 0x59300007,
+	0x8c000500, 0x02020800, 0x00100e99, 0x0201f800,
+	0x00109037, 0x02020800, 0x0010a3ef, 0x0201f000,
+	0x00107911, 0x0201f800, 0x00109037, 0x04000005,
+	0x49425a06, 0x497a5c09, 0x0201f800, 0x000202da,
+	0x0201f000, 0x00107911, 0x0201f800, 0x00109037,
+	0x02020800, 0x0010664f, 0x0201f000, 0x00107911,
+	0x0201f800, 0x00109037, 0x04000004, 0x49425a06,
+	0x0201f800, 0x000202da, 0x59325817, 0x0201f800,
+	0x001007fd, 0x0201f000, 0x00107911, 0x598c000d,
+	0x81300580, 0x04000003, 0x497a6007, 0x1c01f000,
+	0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+	0x4a038804, 0x0000000c, 0x497b2807, 0x0401f00a,
+	0x0401facd, 0x59300403, 0x82000d80, 0x00000040,
+	0x04000004, 0x82000580, 0x00000042, 0x04020002,
+	0x497a6007, 0x0201f800, 0x001070b9, 0x80000580,
+	0x1c01f000, 0x59300804, 0x8c040d3e, 0x04020004,
+	0x82000540, 0x00000001, 0x0401f005, 0x4933c857,
+	0x84040d3e, 0x48066004, 0x80000580, 0x1c01f000,
+	0x59300804, 0x8c040d20, 0x04020004, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x4d380000,
+	0x59300804, 0x84040d20, 0x48066004, 0x42027000,
+	0x00000049, 0x59300203, 0x82000580, 0x00000003,
+	0x04000003, 0x42027000, 0x00000013, 0x0201f800,
+	0x000207a1, 0x80000580, 0x5c027000, 0x1c01f000,
+	0x59300017, 0x81480580, 0x04020003, 0x59300018,
+	0x814c0580, 0x1c01f000, 0x4d2c0000, 0x4d300000,
+	0x0401f8c9, 0x4df00000, 0x0201f800, 0x00106062,
+	0x59900001, 0x82000500, 0x00000003, 0x0c01f001,
+	0x00106bba, 0x00106b9a, 0x00106b98, 0x00106b98,
+	0x0201f800, 0x001005d8, 0x59926004, 0x0401f88e,
+	0x813261c0, 0x0400001d, 0x59300004, 0x8c000516,
+	0x04000004, 0x59325808, 0x497a5808, 0x497a5809,
+	0x0401f88e, 0x59300001, 0x800001c0, 0x0400000e,
+	0x497a6001, 0x42003000, 0x0000bf2e, 0x58180801,
+	0x800409c0, 0x04020004, 0x48003001, 0x48003000,
+	0x0401f00a, 0x58180800, 0x48000800, 0x48003000,
+	0x0401f006, 0x59300809, 0x800409c0, 0x02000800,
+	0x001005d8, 0x4978080c, 0x5c03e000, 0x04000890,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x4d300000,
+	0x497b2807, 0x0401f894, 0x4df00000, 0x598c0000,
+	0x82000500, 0x00000007, 0x4803c857, 0x0c01f001,
+	0x00106bef, 0x00106bd2, 0x00106bdb, 0x00106bdf,
+	0x00106bea, 0x00106bef, 0x00106bd0, 0x00106bd0,
+	0x0201f800, 0x001005d8, 0x598c000d, 0x80026540,
+	0x04000004, 0x0401f81e, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001070b9, 0x0401f015, 0x0401f827,
+	0x0201f800, 0x001070b9, 0x0401f011, 0x598c000d,
+	0x80026540, 0x0400000e, 0x0401f838, 0x04000004,
+	0x0401f80f, 0x04000002, 0x0401f81c, 0x0201f800,
+	0x001070b9, 0x0401f006, 0x0401f830, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001070b9, 0x5c03e000,
+	0x0400085b, 0x5c026000, 0x1c01f000, 0x598c0009,
+	0x81300580, 0x0402000c, 0x0401f84e, 0x0401f83b,
+	0x59300000, 0x800001c0, 0x04000004, 0x48031809,
+	0x497a6000, 0x0401f003, 0x497b1809, 0x497b1808,
+	0x80000580, 0x1c01f000, 0x4d2c0000, 0x59300406,
+	0x82000580, 0x00000003, 0x04020012, 0x598c000b,
+	0x81300580, 0x0402000f, 0x0401f83a, 0x59325808,
+	0x497a5808, 0x497a5809, 0x0401f824, 0x59300000,
+	0x800001c0, 0x04000004, 0x4803180b, 0x497a6000,
+	0x0401f003, 0x497b180a, 0x497b180b, 0x80000580,
+	0x5c025800, 0x1c01f000, 0x598c0005, 0x81300580,
+	0x0402000c, 0x0401f827, 0x0401f814, 0x59300000,
+	0x800001c0, 0x04000004, 0x48031805, 0x497a6000,
+	0x0401f003, 0x497b1805, 0x497b1804, 0x80000580,
+	0x1c01f000, 0x4a032001, 0x00000000, 0x497b2004,
+	0x497b2005, 0x59900006, 0x82000500, 0x0000ffff,
+	0x48032006, 0x1c01f000, 0x4c040000, 0x59300004,
+	0x82000500, 0x7ffeffff, 0x48026004, 0x59bc00e4,
+	0x8c000514, 0x04000009, 0x42000800, 0x0000bf00,
+	0x58040012, 0x81300580, 0x04020004, 0x49780812,
+	0x4a0378e4, 0x00000800, 0x5c000800, 0x1c01f000,
+	0x4803c856, 0x598c000c, 0x80000540, 0x04000003,
+	0x80000040, 0x4803180c, 0x1c01f000, 0x59bc00ea,
+	0x82000500, 0x00000007, 0x82000580, 0x00000003,
+	0x04020004, 0x4803c856, 0x4a0378e8, 0x00000001,
+	0x1c01f000, 0x59bc00ea, 0x82000500, 0x00000007,
+	0x82000580, 0x00000001, 0x04020011, 0x4803c856,
+	0x42000800, 0x00000000, 0x0401f80e, 0x42000800,
+	0x00001000, 0x59bc00ea, 0x82000500, 0x00000007,
+	0x82000580, 0x00000003, 0x04000005, 0x80040840,
+	0x040207f9, 0x0201f800, 0x001005d8, 0x1c01f000,
+	0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000001, 0x02020800, 0x001005d8, 0x59bc00ea,
+	0x8c000516, 0x040207fe, 0x480778e1, 0x1c01f000,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x480778e1,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x480b78e1,
+	0x1c01f000, 0x82000d00, 0x80000018, 0x02020800,
+	0x001005d0, 0x0201f800, 0x001005d8, 0x00106c97,
+	0x00106d3b, 0x00106d55, 0x00106c97, 0x00106c99,
+	0x00106cba, 0x00106cd9, 0x00106d0d, 0x00106c97,
+	0x00106d39, 0x00106c97, 0x00106c97, 0x00106c97,
+	0x00106c97, 0x00106c97, 0x00106c97, 0x0201f800,
+	0x001005d8, 0x4d300000, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x0201f800, 0x001070d8,
+	0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0,
+	0x59300004, 0x8c000520, 0x04000011, 0x82000500,
+	0xfffefeff, 0x48026004, 0x4a026203, 0x00000003,
+	0x0401ffa9, 0x0201f800, 0x00100fd0, 0x5c022800,
+	0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000,
+	0x4a0378e4, 0x00000008, 0x0401f795, 0x84000510,
+	0x48026004, 0x0401f7f6, 0x4d300000, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x0201f800,
+	0x001070d8, 0x59bc00ea, 0x8c000510, 0x040007fe,
+	0x59be60e0, 0x59300004, 0x8c000520, 0x0400000f,
+	0x82000500, 0xfffefeff, 0x48026004, 0x0401ff8a,
+	0x0201f800, 0x0010100e, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x5c026000, 0x4a0378e4,
+	0x00000008, 0x0401f776, 0x84000510, 0x48026004,
+	0x0401f7f6, 0x4d300000, 0x4d2c0000, 0x4d340000,
+	0x4da40000, 0x4cd00000, 0x59bc00ea, 0x8c000510,
+	0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+	0x001005d8, 0x59300004, 0x8c000520, 0x0400001d,
+	0x82000500, 0xfffefeff, 0x48026004, 0x59326809,
+	0x42034800, 0x0010b544, 0x04011000, 0x4a03c840,
+	0x0010b54b, 0x4a03c842, 0x00000012, 0x04011000,
+	0x4a03c840, 0x0010b55d, 0x4a03c842, 0x000000ff,
+	0x04011000, 0x4a03c840, 0x0010b65c, 0x4a03c842,
+	0x000000ff, 0x0401fbf2, 0x5c01a000, 0x5c034800,
+	0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+	0x84000510, 0x48026004, 0x5c01a000, 0x5c034800,
+	0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+	0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000,
+	0x4cd00000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x0401fbc3, 0x59bc00ea, 0x8c000510,
+	0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+	0x001005d8, 0x59300004, 0x8c000520, 0x0400000f,
+	0x82000500, 0xfffefeff, 0x48026004, 0x0201f800,
+	0x0010783a, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x5c01a000, 0x5c026800, 0x5c025800,
+	0x5c026000, 0x1c01f000, 0x84000510, 0x48026004,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c01a000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x0201f800, 0x001005d8, 0x4d300000,
+	0x4d380000, 0x42000000, 0x0010b8c4, 0x0201f800,
+	0x0010aa47, 0x0401ff14, 0x598e600d, 0x59c40004,
+	0x8c000506, 0x04000004, 0x0401f8db, 0x4a038804,
+	0x00000008, 0x813261c0, 0x04000006, 0x0401fb87,
+	0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+	0x4a0378e4, 0x00000002, 0x5c027000, 0x5c026000,
+	0x0401f6f7, 0x4d180000, 0x4d300000, 0x4d380000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x0401fef9, 0x417a3000, 0x59c40804, 0x83180400,
+	0x0010709f, 0x50000000, 0x80040500, 0x0400001b,
+	0x42000000, 0x0010b8c5, 0x0201f800, 0x0010aa47,
+	0x0401fb70, 0x59926004, 0x0401f859, 0x83180400,
+	0x0010709f, 0x50000000, 0x48038804, 0x813261c0,
+	0x0400000a, 0x59300004, 0x8c00050c, 0x04020003,
+	0x4a026203, 0x00000003, 0x42027000, 0x0000004a,
+	0x0201f800, 0x000207a1, 0x59c40004, 0x82000500,
+	0x00f80000, 0x04000005, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017dd, 0x4a0378e4, 0x00000008,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c027000, 0x5c026000, 0x5c023000, 0x0401f6c0,
+	0x4d2c0000, 0x4d340000, 0x59326809, 0x598c0800,
+	0x82040580, 0x00000004, 0x04020004, 0x838c1400,
+	0x00000005, 0x0401f00c, 0x82040580, 0x00000001,
+	0x04020004, 0x838c1400, 0x00000009, 0x0401f006,
+	0x82040580, 0x00000002, 0x04020022, 0x838c1400,
+	0x0000000b, 0x41306800, 0x58340000, 0x80007d40,
+	0x0400001c, 0x583c0009, 0x81340580, 0x04020006,
+	0x403c6800, 0x583c0000, 0x80007d40, 0x040207fa,
+	0x0401f014, 0x4933c857, 0x483fc857, 0x583c0000,
+	0x48006800, 0x49307800, 0x443c1000, 0x80000580,
+	0x4803180d, 0x4803180f, 0x598c0000, 0x82000580,
+	0x00000003, 0x04000003, 0x4a031800, 0x00000000,
+	0x80000580, 0x5c026800, 0x5c025800, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fb, 0x491bc857,
+	0x59c80840, 0x82040540, 0x00000010, 0x48039040,
+	0x59c41008, 0x82080500, 0xffffff7f, 0x48038808,
+	0x4c040000, 0x4c080000, 0x0401fabb, 0x04020007,
+	0x0401fabf, 0x04000022, 0x48038804, 0x0201f800,
+	0x0010107a, 0x0401f042, 0x4a038803, 0x00000008,
+	0x59c40003, 0x82000500, 0x00000003, 0x040007fd,
+	0x8c000502, 0x04020007, 0x0401fab1, 0x04000014,
+	0x48038804, 0x0201f800, 0x0010107a, 0x0401f034,
+	0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+	0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+	0xc0000000, 0x04000006, 0x59c400a3, 0x84000540,
+	0x480388a3, 0x4a038805, 0xc0000000, 0x0201f800,
+	0x0010101d, 0x4a03a005, 0x30000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59900006, 0x82000500,
+	0xffff0000, 0x48032006, 0x59d00005, 0x8c000504,
+	0x040207fe, 0x42000800, 0x00007600, 0x83180540,
+	0x60000000, 0x480008a1, 0x811800dc, 0x59c80840,
+	0x80040540, 0x48039040, 0x82000540, 0x00003000,
+	0x48039040, 0x59c80040, 0x82000500, 0x00003000,
+	0x040207fd, 0x0201f800, 0x00101068, 0x83180400,
+	0x0010709f, 0x50000000, 0x48038804, 0x80000580,
+	0x4df00000, 0x0201f800, 0x00106062, 0x5c03e000,
+	0x5c001000, 0x5c000800, 0x480b8808, 0x48079040,
+	0x1c01f000, 0x4803c856, 0x59c80840, 0x82040540,
+	0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+	0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+	0x59c40004, 0x82000500, 0x00000003, 0x04020010,
+	0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+	0x4a038804, 0x0000000c, 0x8c000504, 0x0401f025,
+	0x59c80040, 0x8400056e, 0x48039040, 0x59c80040,
+	0x8c00052e, 0x040207fe, 0x0401f01e, 0x4a038803,
+	0x00000008, 0x59c40003, 0x82000500, 0x00000003,
+	0x040007fd, 0x8c000502, 0x04020006, 0x59c40004,
+	0x4a038804, 0x0000000c, 0x8c000504, 0x0401f011,
+	0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+	0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+	0xc0000000, 0x04000007, 0x59c400a3, 0x84000540,
+	0x480388a3, 0x4a038805, 0xc0000000, 0x80000580,
+	0x497b2807, 0x5c001000, 0x5c000800, 0x480b8808,
+	0x48079040, 0x1c01f000, 0x4933c857, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdee,
+	0x4df00000, 0x0401fa6f, 0x59900004, 0x800001c0,
+	0x04000011, 0x81300580, 0x0402000f, 0x59300004,
+	0x84000520, 0x48026004, 0x0401ff51, 0x04020009,
+	0x5c03e000, 0x04000dd6, 0x80000580, 0x5c022800,
+	0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000,
+	0x0401fd0e, 0x42027000, 0x00000049, 0x59300004,
+	0x84000520, 0x48026004, 0x8c00050c, 0x02020800,
+	0x000207a1, 0x5c03e000, 0x04000dc5, 0x82000540,
+	0x00000001, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fdc6,
+	0x4df00000, 0x598c000d, 0x80026540, 0x04000012,
+	0x59300004, 0x84000520, 0x48026004, 0x0401ff8a,
+	0x04000017, 0x0401fd26, 0x42027000, 0x00000013,
+	0x59300004, 0x8c00050c, 0x02020800, 0x000207a1,
+	0x5c03e000, 0x04000daa, 0x82000540, 0x00000001,
+	0x1c01f000, 0x836c1580, 0x00000001, 0x040007f9,
+	0x836c1580, 0x00000004, 0x040007f6, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x5c03e000,
+	0x04000d9b, 0x80000580, 0x1c01f000, 0x4d300000,
+	0x4d180000, 0x4d3c0000, 0x0401fd9f, 0x4df00000,
+	0x4a0378e4, 0x0000000f, 0x0401f9ff, 0x417a3000,
+	0x59926004, 0x813261c0, 0x04000010, 0x417a7800,
+	0x0201f800, 0x001048d9, 0x0400000a, 0x59300c06,
+	0x82040580, 0x00000003, 0x04000004, 0x82040580,
+	0x00000006, 0x04020003, 0x42027800, 0x00000002,
+	0x0201f800, 0x00108be3, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017eb, 0x42000800, 0x00000040,
+	0x0201f800, 0x00101345, 0x4a0378e4, 0x0000000a,
+	0x5c03e000, 0x04000d72, 0x5c027800, 0x5c023000,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0401fd75, 0x4df00000, 0x59c80840, 0x82040540,
+	0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+	0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+	0x42001000, 0x00000003, 0x0401f9c2, 0x598e600d,
+	0x813261c0, 0x04020f9d, 0x040009c7, 0x497b2807,
+	0x0401f80a, 0x5c001000, 0x5c000800, 0x480b8808,
+	0x84040d74, 0x48079040, 0x5c03e000, 0x04000d50,
+	0x5c026000, 0x1c01f000, 0x4d380000, 0x4d180000,
+	0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x59c41004, 0x480bc857, 0x82080500,
+	0x00003ff0, 0x04000025, 0x417a3000, 0x4c080000,
+	0x0201f800, 0x00106062, 0x5c001000, 0x82080500,
+	0x00000210, 0x04020004, 0x811a3000, 0x80081102,
+	0x0401f7f7, 0x0401f9c3, 0x59926004, 0x4933c857,
+	0x813261c0, 0x04020005, 0x59c400a3, 0x8c00051a,
+	0x02000800, 0x001005d8, 0x0401fea5, 0x04000009,
+	0x0401fc6a, 0x42027000, 0x00000049, 0x59300004,
+	0x8c00050c, 0x02020800, 0x000207a1, 0x0401f007,
+	0x42027000, 0x0000004a, 0x4a026203, 0x00000003,
+	0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x5c026000, 0x5c023000,
+	0x5c027000, 0x1c01f000, 0x4d300000, 0x4d180000,
+	0x4d900000, 0x0401fd1c, 0x42001000, 0x00000000,
+	0x598c0000, 0x82000580, 0x00000005, 0x04000971,
+	0x417a3000, 0x811b20c8, 0x83932400, 0x0000bf32,
+	0x59900001, 0x82000580, 0x00000001, 0x0402000d,
+	0x42000800, 0x000007d0, 0x59926004, 0x59300011,
+	0x82000500, 0xfff00000, 0x80000540, 0x04000003,
+	0x42000800, 0x00001b58, 0x0201f800, 0x00106054,
+	0x811a3000, 0x83180480, 0x00000005, 0x040017ea,
+	0x59c81040, 0x84081534, 0x480b9040, 0x0401fcf0,
+	0x5c032000, 0x5c023000, 0x5c026000, 0x1c01f000,
+	0x4933c857, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x4d380000, 0x0401fcef, 0x4df00000,
+	0x59300004, 0x8c00053e, 0x04020007, 0x8c000520,
+	0x04000025, 0x0201f800, 0x00106b6c, 0x04000022,
+	0x0401f02a, 0x598c000d, 0x81300580, 0x04000011,
+	0x0201f800, 0x00108cd6, 0x04020024, 0x0401f918,
+	0x04000022, 0x48038804, 0x0401f95e, 0x0201f800,
+	0x0010107a, 0x0401fc0d, 0x42027000, 0x00000049,
+	0x59300004, 0x8c00050c, 0x0402000d, 0x0401f00e,
+	0x59c40004, 0x8c000504, 0x04000014, 0x4a038804,
+	0x00000004, 0x0401fc36, 0x42027000, 0x00000013,
+	0x59300004, 0x8c00050c, 0x04000003, 0x0201f800,
+	0x000207a1, 0x5c03e000, 0x04000cb9, 0x5c027000,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x04000cb0,
+	0x5c027000, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x497b2807, 0x0401fcb0, 0x59c400af, 0x800001c0,
+	0x04020004, 0x0401fca2, 0x0201f000, 0x001014fb,
+	0x598c000f, 0x82001480, 0x00000002, 0x04021007,
+	0x80000000, 0x4803180f, 0x80000580, 0x0201f800,
+	0x0010604d, 0x0400000e, 0x0401fed8, 0x0402000c,
+	0x0401fdd4, 0x0400000a, 0x0201f800, 0x0010a9c7,
+	0x0401f916, 0x4d380000, 0x42027000, 0x00000014,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc88,
+	0x0201f000, 0x001014fb, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x4d300000, 0x0201f800,
+	0x00106062, 0x0401fc88, 0x59c400af, 0x800001c0,
+	0x04000027, 0x0401f907, 0x59926004, 0x4933c857,
+	0x59300004, 0x8c000516, 0x0400000b, 0x0401fe8b,
+	0x0402001f, 0x0201f800, 0x00106b8a, 0x0401fc70,
+	0x42000800, 0x80000804, 0x0201f800, 0x00106721,
+	0x0401f017, 0x42001800, 0x00007530, 0x0401f8c1,
+	0x04020004, 0x0201f800, 0x00106052, 0x0401f010,
+	0x0401fe7a, 0x0402000e, 0x0201f800, 0x0010a9c7,
+	0x59300004, 0x8c00050c, 0x04020003, 0x4a026203,
+	0x00000003, 0x4d380000, 0x42027000, 0x0000004a,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc54,
+	0x5c026000, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x0201f000, 0x001014fb, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000,
+	0x4d2c0000, 0x0401fc50, 0x0401f8d2, 0x59926004,
+	0x4933c857, 0x0401f880, 0x04000016, 0x0201f800,
+	0x00106062, 0x813261c0, 0x04000034, 0x59325808,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x0201f800,
+	0x0010513b, 0x0402001d, 0x592c0208, 0x84000550,
+	0x48025a08, 0x0201f800, 0x00105258, 0x04020027,
+	0x592c0208, 0x84000510, 0x48025a08, 0x0401f023,
+	0x0201f800, 0x00106052, 0x0401f020, 0x0201f800,
+	0x0010a9c7, 0x0401fd9e, 0x592c0208, 0x84000550,
+	0x48025a08, 0x4d380000, 0x42027000, 0x0000004a,
+	0x4a026203, 0x00000003, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x0401f011, 0x59900006, 0x82000500,
+	0xffff0000, 0x040207ee, 0x59c408af, 0x82040480,
+	0x000003e8, 0x040217ea, 0x59900006, 0x82000400,
+	0x00010000, 0x48032006, 0x0201f800, 0x00106052,
+	0x0201f800, 0x0010411d, 0x5c025800, 0x5c026000,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x0401f403, 0x4d300000, 0x4d2c0000, 0x0401fc0a,
+	0x598e600d, 0x4933c857, 0x59c41004, 0x8c081500,
+	0x04000007, 0x0201f800, 0x0010513b, 0x04020007,
+	0x0201f800, 0x00105258, 0x0402002f, 0x0201f800,
+	0x0010604d, 0x0401f02c, 0x598c000f, 0x80000540,
+	0x04020011, 0x59c408af, 0x82040480, 0x000003e8,
+	0x0402100d, 0x598c080f, 0x80040800, 0x4807180f,
+	0x0201f800, 0x0010604d, 0x42000000, 0x0010b852,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010411d,
+	0x0401f019, 0x0401fdb4, 0x813261c0, 0x04020003,
+	0x0401f849, 0x0401f014, 0x0201f800, 0x0010a9c7,
+	0x59300406, 0x82000580, 0x00000003, 0x04020007,
+	0x59325808, 0x812e59c0, 0x04000004, 0x592c0208,
+	0x84000550, 0x48025a08, 0x0401f854, 0x4d380000,
+	0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x5c025800, 0x5c026000, 0x0201f000,
+	0x00106c4b, 0x59c40804, 0x83180400, 0x00107095,
+	0x50000000, 0x80040500, 0x1c01f000, 0x59c40804,
+	0x83180400, 0x0010709a, 0x50000000, 0x80040500,
+	0x1c01f000, 0x00000210, 0x00000420, 0x00000840,
+	0x00001080, 0x00002100, 0x00004000, 0x00008000,
+	0x00010000, 0x00020000, 0x00040000, 0x00080000,
+	0x00100000, 0x00200000, 0x00400000, 0x00800000,
+	0x59900806, 0x80040120, 0x800c0480, 0x04021004,
+	0x82000540, 0x00000001, 0x0401f005, 0x82040c00,
+	0x00010000, 0x48072006, 0x80000580, 0x1c01f000,
+	0x480bc857, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x480b1800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x497b180d, 0x497b1803, 0x497b180e,
+	0x497b180f, 0x497b1810, 0x598c0000, 0x82000580,
+	0x00000003, 0x04000009, 0x836c0580, 0x00000002,
+	0x04020004, 0x4a031800, 0x00000005, 0x0401f003,
+	0x4a031800, 0x00000000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x1c01f000, 0x59300004, 0x8c00050c,
+	0x04020003, 0x4a026203, 0x00000001, 0x1c01f000,
+	0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+	0x491bc857, 0x811b20c8, 0x83932400, 0x0000bf32,
+	0x811ba0ca, 0x83d3a400, 0x00007600, 0x83180400,
+	0x001070ea, 0x50034800, 0x811a28c2, 0x83162c00,
+	0x00006100, 0x1c01f000, 0x0010b75b, 0x0010b772,
+	0x0010b789, 0x0010b7a0, 0x0010b7b7, 0x4933c857,
+	0x59300406, 0x82000c80, 0x00000012, 0x04021016,
+	0x4803c857, 0x04011000, 0x0c01f001, 0x00107109,
+	0x00107198, 0x001074d1, 0x00107556, 0x00107198,
+	0x001074d1, 0x00107556, 0x00107109, 0x00107198,
+	0x00107109, 0x00107109, 0x00107109, 0x00107109,
+	0x00107109, 0x00107109, 0x00107109, 0x0010710f,
+	0x0010710f, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x00106c4b, 0x42001000,
+	0x0010b7f6, 0x50081000, 0x4930100c, 0x58080002,
+	0x82000580, 0x00000100, 0x04020032, 0x59325808,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x59326809,
+	0x813669c0, 0x04000019, 0x592c040b, 0x82000500,
+	0x0000e000, 0x04000003, 0x0401fba8, 0x0401f002,
+	0x0401fb98, 0x42001000, 0x0010b7f6, 0x50081000,
+	0x4930100b, 0x492c100a, 0x82d00400, 0x00000006,
+	0x48001003, 0x592c000d, 0x80000104, 0x48001004,
+	0x592c000e, 0x48001007, 0x592c000f, 0x48001008,
+	0x0201f000, 0x00100858, 0x42026800, 0x0010be0d,
+	0x592c080a, 0x48066802, 0x82040500, 0x00ffff00,
+	0x04000007, 0x497a6a12, 0x59a81010, 0x82081500,
+	0x00ffff00, 0x80080580, 0x040207dc, 0x82040d00,
+	0x000000ff, 0x800408d0, 0x48066a12, 0x0401f7d7,
+	0x1c01f000, 0x4d2c0000, 0x4d300000, 0x4c580000,
+	0x4c540000, 0x4c500000, 0x5832580a, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x58300002, 0x4a006002,
+	0x00000100, 0x82000580, 0x00000100, 0x0402001c,
+	0x5830000b, 0x5832600c, 0x81300580, 0x04020010,
+	0x0401f828, 0x04020010, 0x592c080d, 0x80040904,
+	0x4004b000, 0x4200a000, 0x0010b54b, 0x4050a800,
+	0x0201f800, 0x0010ab28, 0x42001000, 0x0000dc00,
+	0x0201f800, 0x001078bc, 0x0401f003, 0x0401f819,
+	0x04000fa3, 0x5c00a000, 0x5c00a800, 0x5c00b000,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x5830000b,
+	0x5832600c, 0x81300580, 0x040207f5, 0x0401f80d,
+	0x040207f5, 0x0201f800, 0x001068d3, 0x02020800,
+	0x001005d8, 0x4a025a06, 0x00000002, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x0401f7ea,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x598c000d,
+	0x81300580, 0x04020009, 0x598c0005, 0x81300580,
+	0x04020006, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59300403, 0x82000c80, 0x00000056, 0x02021800,
+	0x001005d8, 0x4803c857, 0x0c01f001, 0x00107302,
+	0x0010731d, 0x0010732e, 0x00107431, 0x001073f1,
+	0x001073f5, 0x00107406, 0x0010741a, 0x0010740f,
+	0x0010741a, 0x00107455, 0x0010741a, 0x00107497,
+	0x0010741a, 0x001074a5, 0x0010741a, 0x0010740f,
+	0x0010741a, 0x001074a9, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x00107574, 0x00107593, 0x0010759d,
+	0x001071f5, 0x001075b3, 0x00107406, 0x001071f5,
+	0x00107406, 0x0010741a, 0x001071f5, 0x0010732e,
+	0x00107431, 0x001071f5, 0x00107603, 0x0010741a,
+	0x001071f5, 0x00107613, 0x0010741a, 0x001071f5,
+	0x0010740f, 0x001072f3, 0x001071f7, 0x001071f5,
+	0x0010762a, 0x0010765d, 0x001076d7, 0x001071f5,
+	0x001076e7, 0x00107404, 0x001076da, 0x001071f5,
+	0x001075bf, 0x00107700, 0x001071f5, 0x00107735,
+	0x00107788, 0x001071f5, 0x0010720c, 0x00107265,
+	0x00107272, 0x001071f5, 0x00107406, 0x001071f5,
+	0x001072b9, 0x001072c4, 0x001071f5, 0x001071f5,
+	0x00107220, 0x00107245, 0x001077c7, 0x00107808,
+	0x0010782e, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001077fc, 0x0201f800, 0x001005d8, 0x0401fac5,
+	0x59325808, 0x592c0009, 0x4801a006, 0x592c000a,
+	0x4801a007, 0x592c000b, 0x4801a008, 0x592c000c,
+	0x4801a009, 0x592c000d, 0x4801a00a, 0x4979a00b,
+	0x592c0809, 0x82040d00, 0x00000fff, 0x80040904,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x4a026202, 0x0000ffff, 0x0401faae, 0x4d2c0000,
+	0x4a01a006, 0x05000000, 0x59325808, 0x592c0009,
+	0x4801a007, 0x592c000a, 0x4801a008, 0x592c000b,
+	0x4801a009, 0x42000800, 0x00000004, 0x42001000,
+	0x0000dc00, 0x5c025800, 0x0201f000, 0x001078bc,
+	0x4c580000, 0x4c500000, 0x4c540000, 0x4d2c0000,
+	0x0401fa98, 0x59325808, 0x5930040b, 0x800000c2,
+	0x4200a800, 0x0010b54b, 0x592cb205, 0x832ca400,
+	0x00000006, 0x0201f800, 0x0010ab17, 0x40580000,
+	0x8054ac00, 0x592c0001, 0x80000540, 0x04000003,
+	0x40025800, 0x0401f7f5, 0x4200a000, 0x0010b54b,
+	0x4050a800, 0x5930b40b, 0x0201f800, 0x0010ab28,
+	0x59300c0b, 0x42001000, 0x0000dc00, 0x5c025800,
+	0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+	0x001078bc, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4d2c0000, 0x42034800, 0x0010b544, 0x0401fa7f,
+	0x59325808, 0x4a025805, 0x02000000, 0x592c0802,
+	0x82d0ac00, 0x00000006, 0x592cb011, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x40580000,
+	0x8054ac00, 0x592e5801, 0x41780000, 0x812e5d40,
+	0x040207f6, 0x42001000, 0x0000dc00, 0x5c025800,
+	0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+	0x001078bc, 0x0401fa57, 0x4a01a006, 0x78000000,
+	0x5930001c, 0x840001c0, 0x4801a407, 0x4979a207,
+	0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+	0x0201f000, 0x001078bc, 0x4c580000, 0x4c540000,
+	0x4c500000, 0x0401fa55, 0x4a01a006, 0x02000000,
+	0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009,
+	0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b,
+	0x5930001c, 0x82000d80, 0x0000e000, 0x04000016,
+	0x82000d80, 0x0000df00, 0x04000006, 0x4a01a407,
+	0x00000010, 0x42000800, 0x00000006, 0x0401f027,
+	0x4a03c840, 0x0010b4eb, 0x4a03c842, 0x0000000d,
+	0x42001800, 0x0010b4eb, 0x0201f800, 0x001007af,
+	0x42000000, 0x0000df00, 0x4200a000, 0x0010b4eb,
+	0x0401f00d, 0x4a03c840, 0x0010b4f8, 0x4a03c842,
+	0x0000000d, 0x42001800, 0x0010b4f8, 0x0201f800,
+	0x001007af, 0x42000000, 0x0000e000, 0x4200a000,
+	0x0010b4f8, 0x82000540, 0x00000010, 0x4801a407,
+	0x4a01a207, 0x00000034, 0x4200b000, 0x0000000d,
+	0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010ab17,
+	0x42000800, 0x00000013, 0x42001000, 0x0000dc00,
+	0x5c00a000, 0x5c00a800, 0x5c00b000, 0x0201f000,
+	0x001078bc, 0x0401fa03, 0x4a01a006, 0x63000028,
+	0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x0401fa06, 0x41780000, 0x41780800, 0x42002000,
+	0x00080000, 0x0c01f81b, 0x80000000, 0x80040800,
+	0x42001000, 0x0000000c, 0x59841802, 0x8c0c1d00,
+	0x04020008, 0x42002000, 0x00050000, 0x0c01f811,
+	0x80000000, 0x80040800, 0x82081400, 0x00000004,
+	0x82080540, 0x02000000, 0x4801a006, 0x800408e0,
+	0x5930001c, 0x80040540, 0x4801a007, 0x80080904,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x001072e9, 0x001072eb, 0x001072ed, 0x001072ef,
+	0x001072f1, 0x4811a008, 0x1c01f000, 0x4811a009,
+	0x1c01f000, 0x4811a00a, 0x1c01f000, 0x4811a00b,
+	0x1c01f000, 0x4811a00c, 0x1c01f000, 0x4a026009,
+	0x0010be0d, 0x59a80010, 0x82000500, 0x000000ff,
+	0x800000d0, 0x42026800, 0x0010be0d, 0x48026a12,
+	0x0401fa3b, 0x41780800, 0x42001000, 0x00005c00,
+	0x0201f000, 0x001078bc, 0x0401f9ba, 0x4a01a006,
+	0x52000000, 0x4979a007, 0x599c0017, 0x8c000500,
+	0x04000005, 0x599c0402, 0x0201f800, 0x001015da,
+	0x4805a007, 0x59a80002, 0x4801a008, 0x59a80003,
+	0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001,
+	0x4801a00b, 0x59a80010, 0x4801a00c, 0x42000800,
+	0x00000007, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f99d,
+	0x4a01a006, 0x05000000, 0x59a80010, 0x4801a007,
+	0x59a80002, 0x59a80803, 0x4801a008, 0x4805a009,
+	0x42000800, 0x00000004, 0x42001000, 0x0000dc00,
+	0x0201f000, 0x001078bc, 0x4a026202, 0x0000ffff,
+	0x0401f98c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x001048f6, 0x5c027800, 0x4a01a006, 0x03000000,
+	0x59340403, 0x82000580, 0x000007fe, 0x0402006e,
+	0x4a01a006, 0x04000000, 0x81a40800, 0x4a000800,
+	0x22fffffe, 0x5934000a, 0x84000500, 0x4802680a,
+	0x59c41002, 0x8408150c, 0x480b8802, 0x59a80026,
+	0x8c000508, 0x04000010, 0x59a8002a, 0x4801a007,
+	0x59a8002b, 0x82000500, 0xffff2000, 0x599c0818,
+	0x8c040d16, 0x04000002, 0x8400056a, 0x4801a008,
+	0x4a01a009, 0x00002710, 0x59a8002d, 0x4801a00a,
+	0x0401f039, 0x59a8002a, 0x4801a007, 0x0201f800,
+	0x0010513b, 0x04020009, 0x497b8880, 0x82000500,
+	0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+	0x5c000000, 0x48038880, 0x59a8002b, 0x0201f800,
+	0x0010513b, 0x04020004, 0x82000500, 0x37ffffff,
+	0x0401f003, 0x82000500, 0x3fffffff, 0x599c0818,
+	0x8c040d16, 0x04000002, 0x8400056a, 0x59a80805,
+	0x8c040d10, 0x04000019, 0x59300c03, 0x82041580,
+	0x00000051, 0x04000015, 0x82041580, 0x00000031,
+	0x04000012, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4200b000, 0x00000004, 0x4200a000, 0x0010b8fa,
+	0x82d0ac00, 0x0000001f, 0x4c000000, 0x0201f800,
+	0x0010ab17, 0x5c000000, 0x5c00a800, 0x5c00a000,
+	0x5c00b000, 0x8400057a, 0x4801a008, 0x4979a009,
+	0x4979a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+	0x4805a00c, 0x59a80000, 0x59a80801, 0x4801a00d,
+	0x4805a00e, 0x4979a00f, 0x4979a010, 0x4979a011,
+	0x4979a012, 0x4979a013, 0x4979a014, 0x4979a015,
+	0x4979a016, 0x59a8002e, 0x84000576, 0x4801a017,
+	0x59a8002f, 0x4801a018, 0x4979a019, 0x4979a01a,
+	0x0401f043, 0x59a80026, 0x8c000508, 0x0400000d,
+	0x59a8002a, 0x82000500, 0x0000ffff, 0x59c40880,
+	0x80040d80, 0x04000007, 0x497b8880, 0x4c000000,
+	0x0201f800, 0x00101606, 0x5c000000, 0x48038880,
+	0x59a8002a, 0x4801a007, 0x4c640000, 0x4d2c0000,
+	0x59a8c82b, 0x0201f800, 0x00109037, 0x0400000d,
+	0x0201f800, 0x00109597, 0x0402000a, 0x592c0207,
+	0x8c00050e, 0x04000007, 0x8264cd00, 0x0000ffff,
+	0x592c0009, 0x82000500, 0xffff0000, 0x8064cd40,
+	0x4865a008, 0x5c025800, 0x5c00c800, 0x59a8002c,
+	0x4801a009, 0x59a8002d, 0x4801a00a, 0x59a80002,
+	0x59a80803, 0x4801a00b, 0x4805a00c, 0x59a80000,
+	0x59a80801, 0x4801a00d, 0x4805a00e, 0x4979a00f,
+	0x4979a010, 0x4979a011, 0x4979a012, 0x4979a013,
+	0x4979a014, 0x4979a015, 0x4979a016, 0x59a8002e,
+	0x4801a017, 0x59a8002f, 0x4801a018, 0x59a80030,
+	0x4801a019, 0x59a80031, 0x4801a01a, 0x42000800,
+	0x0000001d, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x0401f8cb, 0x4a01a006, 0x50000000,
+	0x0401f7b5, 0x0401f8c7, 0x4a01a406, 0x21000010,
+	0x4a01a206, 0x00000014, 0x4979a007, 0x4979a008,
+	0x4979a009, 0x4979a00a, 0x42000800, 0x00000005,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x0401f8bf, 0x0401f002, 0x0401f8c4, 0x4a01a006,
+	0x02000000, 0x42000800, 0x00000001, 0x42001000,
+	0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f8bb,
+	0x4a01a006, 0x02000000, 0x59300403, 0x82000580,
+	0x00000031, 0x04020794, 0x81a40800, 0x4a000801,
+	0x00fffffe, 0x0401f72b, 0x0401f8b0, 0x4a01a006,
+	0x01000000, 0x5930041a, 0x80000540, 0x04000003,
+	0x4801a407, 0x0401f003, 0x4a01a407, 0x00000003,
+	0x5930021a, 0x80000540, 0x04000003, 0x4801a207,
+	0x0401f003, 0x4a01a207, 0x00002a00, 0x42000800,
+	0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f889,
+	0x4a01a406, 0x00002010, 0x4a01a206, 0x00000014,
+	0x4a01a407, 0x00000800, 0x4a01a207, 0x00002000,
+	0x80000580, 0x599c0817, 0x8c040d0a, 0x04020003,
+	0x82000540, 0x00000020, 0x8c040d08, 0x04000003,
+	0x82000540, 0x00000010, 0x82000540, 0x00000002,
+	0x5934080a, 0x8c040d14, 0x04000005, 0x82040d00,
+	0x00000380, 0x80040540, 0x0401f006, 0x599c0818,
+	0x8c040d18, 0x04000003, 0x82000540, 0x00000380,
+	0x0401f03c, 0x0401f875, 0x4a01a406, 0x00000210,
+	0x4a01a206, 0x00000014, 0x4a01a407, 0x00000800,
+	0x5934000a, 0x8c000516, 0x04000014, 0x59340c05,
+	0x82040500, 0x00000030, 0x04000013, 0x59340a05,
+	0x82040500, 0x0000c000, 0x04020009, 0x8c040d1a,
+	0x04000004, 0x4a01a207, 0x00002100, 0x0401f00c,
+	0x4a01a207, 0x00000100, 0x0401f009, 0x4a01a207,
+	0x00000400, 0x0401f006, 0x4a01a207, 0x00000700,
+	0x0401f003, 0x4a01a207, 0x00000800, 0x80000580,
+	0x599c0817, 0x8c040d0a, 0x04020003, 0x82000540,
+	0x00000020, 0x8c040d08, 0x04000003, 0x82000540,
+	0x00000010, 0x82000540, 0x00000002, 0x59340a00,
+	0x8c040d0e, 0x0400000b, 0x84000550, 0x599c1017,
+	0x8c08150a, 0x04020004, 0x8c040d0a, 0x04000002,
+	0x8400054e, 0x8c040d1c, 0x04000002, 0x84000552,
+	0x4801a20a, 0x42000800, 0x00000005, 0x42001000,
+	0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f833,
+	0x4a01a006, 0x02100014, 0x4a01a007, 0x01000000,
+	0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800,
+	0x00000005, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x0401f825, 0x4a01a006, 0x02000000,
+	0x0401f65d, 0x4933c857, 0x0401f820, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x0000000b, 0x42000800,
+	0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x42005000, 0x32000000, 0x42006000,
+	0x08290000, 0x41786800, 0x41787800, 0x0401f3df,
+	0x42005000, 0x22000000, 0x42006000, 0x01290000,
+	0x41786800, 0x41787800, 0x0401f3d8, 0x42005000,
+	0x33000000, 0x42006000, 0x08980000, 0x41786800,
+	0x41787800, 0x0401f3d1, 0x42005000, 0x23000000,
+	0x42006000, 0x01980000, 0x41786800, 0x41787800,
+	0x0401f3ca, 0x59300403, 0x82000c80, 0x00000085,
+	0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+	0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+	0x0c01f001, 0x001074eb, 0x001074ed, 0x001074fb,
+	0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+	0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+	0x001074eb, 0x001074eb, 0x00107506, 0x0201f800,
+	0x001005d8, 0x4933c857, 0x0401f850, 0x59300402,
+	0x4801a407, 0x5930001c, 0x4801a207, 0x4979a408,
+	0x4a01a208, 0x0000ffff, 0x42000800, 0x00000003,
+	0x42001000, 0x0000dc00, 0x0401f3c2, 0x4933c857,
+	0x0401f84e, 0x4a01a406, 0x00000003, 0x4a01a206,
+	0x00000300, 0x42000800, 0x00000001, 0x42001000,
+	0x0000dc00, 0x0401f3b7, 0x4d2c0000, 0x59325808,
+	0x4933c857, 0x492fc857, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x59340a12, 0x82040d00, 0x0000ff00,
+	0x592c000a, 0x82000500, 0x000000ff, 0x900001c0,
+	0x80040540, 0x82000540, 0x00000011, 0x44034800,
+	0x81a5a000, 0x42001000, 0x00000009, 0x42000800,
+	0x00000003, 0x592c0009, 0x82000500, 0xff000000,
+	0x82001d80, 0x84000000, 0x04000009, 0x82001d80,
+	0x85000000, 0x02020800, 0x001005d8, 0x42001000,
+	0x00000007, 0x42000800, 0x00000001, 0x832c1c00,
+	0x00000009, 0x500c0000, 0x4401a000, 0x800c1800,
+	0x80d1a000, 0x80081040, 0x040207fb, 0x42001000,
+	0x0000dc00, 0x5c025800, 0x0401f386, 0x42005000,
+	0x81000000, 0x42006000, 0x00090000, 0x41786800,
+	0x41787800, 0x0401f35d, 0x42005000, 0x84000000,
+	0x42006000, 0x00990000, 0x59300406, 0x82000580,
+	0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+	0x41787800, 0x0401f351, 0x42005000, 0x85000000,
+	0x42006000, 0x00990000, 0x59300406, 0x82000580,
+	0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+	0x41787800, 0x0401f345, 0x59300403, 0x82000c80,
+	0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+	0x0000004b, 0x02001800, 0x001005d8, 0x59326809,
+	0x59368c03, 0x4803c857, 0x0c01f001, 0x001075da,
+	0x001075e2, 0x001075ea, 0x001075f2, 0x0010756b,
+	0x0010756b, 0x0010756b, 0x001075d2, 0x0201f800,
+	0x001005d8, 0x42005000, 0x06000000, 0x42006000,
+	0x08290000, 0x41786800, 0x41787800, 0x0401f327,
+	0x4933c857, 0x0401ff47, 0x4a01a006, 0x12000000,
+	0x59300406, 0x82000580, 0x00000004, 0x04020003,
+	0x59340002, 0x0401f002, 0x59a80010, 0x82000500,
+	0x00ffffff, 0x4801a007, 0x59300419, 0x4801a408,
+	0x59300219, 0x4801a208, 0x4979a009, 0x4979a00a,
+	0x4979a00b, 0x4979a00c, 0x4979a00d, 0x4979a00e,
+	0x4979a00f, 0x4979a010, 0x42000800, 0x0000000b,
+	0x42001000, 0x0000dc00, 0x0401f32a, 0x0401ff29,
+	0x4a01a006, 0x0f000000, 0x5930001c, 0x4801a007,
+	0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+	0x0401f320, 0x0401ff2d, 0x4a01a006, 0x02000000,
+	0x59c40085, 0x48031004, 0x59880000, 0x4801a007,
+	0x59880001, 0x4801a008, 0x59880002, 0x4801a009,
+	0x59880003, 0x4801a00a, 0x59880004, 0x4801a00b,
+	0x59880005, 0x4801a00c, 0x42000800, 0x00000007,
+	0x42001000, 0x0000dc00, 0x0401f30a, 0x4a026202,
+	0x0000ffff, 0x0401ff07, 0x4a01a006, 0x62000000,
+	0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0401f2fe, 0x0401fefd,
+	0x59300808, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x8204a400, 0x0000000a, 0x5930b01c, 0x82d0ac00,
+	0x00000006, 0x0201f800, 0x0010ab17, 0x5930081c,
+	0x42001000, 0x0000dc00, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x0401f2eb, 0x0401ff9b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00001000, 0x0401f020, 0x0401ff93, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00004000, 0x0401f018, 0x0401ff8b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00002000, 0x0401f010, 0x0401ff83, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00000400, 0x0401f008, 0x0401ff7b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00000200, 0x4979a009, 0x4979a00a, 0x4979a00b,
+	0x4979a00c, 0x4979a00d, 0x42000800, 0x00000008,
+	0x42001000, 0x0000dc00, 0x0401f2ba, 0x0401fec7,
+	0x4a01a006, 0x02000014, 0x4979a407, 0x4979a207,
+	0x59a8003a, 0x4801a008, 0x59a8003b, 0x4801a009,
+	0x4a01a00a, 0x00047878, 0x42000800, 0x00000005,
+	0x42001000, 0x0000dc00, 0x0401f2aa, 0x0401feb7,
+	0x4a01a006, 0x02140018, 0x4a01a407, 0x00000800,
+	0x5930001c, 0x82000d00, 0xff000000, 0x900409c0,
+	0x4805a207, 0x82000500, 0x00ffffff, 0x4801a00a,
+	0x4979a408, 0x4979a208, 0x4979a409, 0x4979a209,
+	0x4979a00b, 0x42000800, 0x00000006, 0x42001000,
+	0x0000dc00, 0x0401f293, 0x4803c856, 0x4d380000,
+	0x4d1c0000, 0x42027000, 0x00000035, 0x0201f800,
+	0x001093ba, 0x0402001e, 0x0401fe8a, 0x4a01a006,
+	0x13000000, 0x5932381e, 0x591c0019, 0x4801a005,
+	0x591c0406, 0x82000580, 0x00000003, 0x04000007,
+	0x59300809, 0x58040002, 0x82000500, 0x00ffffff,
+	0x4801a007, 0x0401f003, 0x59a80010, 0x4801a007,
+	0x59300419, 0x4801a408, 0x59300219, 0x4801a208,
+	0x42000800, 0x00000003, 0x42001000, 0x0000dc00,
+	0x5c023800, 0x5c027000, 0x0401f26e, 0x0201f800,
+	0x00106c55, 0x598c000d, 0x81300580, 0x02020800,
+	0x001005d8, 0x0201f800, 0x00106bbf, 0x0201f800,
+	0x0002077d, 0x5c023800, 0x5c027000, 0x0201f000,
+	0x00106c4b, 0x4803c856, 0x4d2c0000, 0x4d1c0000,
+	0x5932381e, 0x811e39c0, 0x02000800, 0x001005d8,
+	0x591c0c06, 0x82040580, 0x00000006, 0x0400000d,
+	0x82040580, 0x00000003, 0x04000036, 0x4a026403,
+	0x00000037, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00001700, 0x5c023800, 0x5c025800, 0x0401f064,
+	0x0401f84b, 0x42001000, 0x40000000, 0x591c0203,
+	0x591c0804, 0x8c040d3e, 0x04020023, 0x82000c80,
+	0x0000000e, 0x0c001003, 0x0201f800, 0x001005d8,
+	0x00107691, 0x0010769d, 0x00107693, 0x0010769d,
+	0x00107699, 0x00107691, 0x00107691, 0x0010769d,
+	0x0010769d, 0x00107691, 0x00107691, 0x00107691,
+	0x00107691, 0x00107691, 0x0010769d, 0x00107691,
+	0x0010769d, 0x0201f800, 0x001005d8, 0x591c0414,
+	0x4803c857, 0x8c000518, 0x04000003, 0x8c000512,
+	0x04000003, 0x80001580, 0x0401f003, 0x42001000,
+	0x20000000, 0x591c0015, 0x4801a00a, 0x0401f018,
+	0x0401f81f, 0x591e5808, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x592c100f, 0x591c0011, 0x80080480,
+	0x4801a00a, 0x591c0203, 0x591c0804, 0x8c040d3e,
+	0x04020007, 0x82000d80, 0x00000002, 0x04000007,
+	0x82000d80, 0x00000004, 0x04000004, 0x42001000,
+	0x40000000, 0x0401f002, 0x80001580, 0x4809a00b,
+	0x42000800, 0x00000006, 0x42001000, 0x0000dc00,
+	0x5c023800, 0x5c025800, 0x0401f1fe, 0x4803c856,
+	0x0401fe0a, 0x4a01a006, 0x02000000, 0x59300c19,
+	0x4805a407, 0x59300a19, 0x4805a207, 0x59a81010,
+	0x59300809, 0x58041802, 0x820c1d00, 0x00ffffff,
+	0x5930081e, 0x58040406, 0x82000580, 0x00000003,
+	0x04020004, 0x4809a008, 0x480da009, 0x0401f003,
+	0x480da008, 0x4809a009, 0x1c01f000, 0x4803c856,
+	0x0401fdf2, 0x0401f003, 0x4803c856, 0x0401fde8,
+	0x4a01a006, 0x01000000, 0x5930041a, 0x4801a407,
+	0x5930021a, 0x4801a207, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0401f1d6, 0x4803c856,
+	0x4d1c0000, 0x0401fdcc, 0x4a01a006, 0x14000000,
+	0x5932381e, 0x591c0019, 0x4801a005, 0x59300419,
+	0x4801a407, 0x59300219, 0x4801a207, 0x59300015,
+	0x4801a008, 0x59300216, 0x82000500, 0x000000ff,
+	0x840001c0, 0x4801a409, 0x42000800, 0x00000004,
+	0x42001000, 0x0000dc00, 0x5c023800, 0x0401f1bd,
+	0x4803c856, 0x0401f80b, 0x5930041a, 0x900001c0,
+	0x4801a005, 0x0401f9ec, 0x41780800, 0x42001000,
+	0x00005c00, 0x0401f9b3, 0x0201f000, 0x0010604d,
+	0x4803c856, 0x59300817, 0x82041c00, 0x00000005,
+	0x46034800, 0x00000021, 0x58040404, 0x82000500,
+	0x0000f000, 0x82000580, 0x00003000, 0x04000003,
+	0x46034800, 0x00000041, 0x81a5a000, 0x580c0001,
+	0x82000d00, 0x00ffffff, 0x82040d40, 0xc2000000,
+	0x4805a000, 0x580c0800, 0x82041500, 0x00ffffff,
+	0x82000500, 0xff000000, 0x80080540, 0x4801a001,
+	0x580c0002, 0x82000580, 0x00c00000, 0x82000500,
+	0x00fd0300, 0x4801a002, 0x580c0003, 0x4801a003,
+	0x580c0404, 0x4801a404, 0x580c0204, 0x4801a204,
+	0x1c01f000, 0x4803c856, 0x59a80026, 0x82000500,
+	0x00000028, 0x04020009, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000003, 0x497a6a12, 0x0401f003,
+	0x4a026a12, 0x0000ff00, 0x42005000, 0x22000000,
+	0x42006000, 0x01380000, 0x41786800, 0x41787800,
+	0x0401f952, 0x59301008, 0x4a01a006, 0x54000000,
+	0x59a80010, 0x82000500, 0x00ffffff, 0x58080c0a,
+	0x800408f0, 0x80040540, 0x4801a007, 0x5808000a,
+	0x82000500, 0xff000000, 0x4801a008, 0x59a80002,
+	0x4801a009, 0x59a80003, 0x4801a00a, 0x59a80000,
+	0x4801a00b, 0x59a80001, 0x4801a00c, 0x5808000c,
+	0x9c0001c0, 0x4801a00d, 0x5808000d, 0x9c0001c0,
+	0x4801a00e, 0x5808000e, 0x9c0001c0, 0x4801a00f,
+	0x5808000f, 0x9c0001c0, 0x4801a010, 0x58080010,
+	0x9c0001c0, 0x4801a011, 0x58080011, 0x9c0001c0,
+	0x4801a012, 0x58080012, 0x9c0001c0, 0x4801a013,
+	0x58080013, 0x9c0001c0, 0x4801a014, 0x58080010,
+	0x9c0001c0, 0x4801a015, 0x58080011, 0x9c0001c0,
+	0x4801a016, 0x58080012, 0x9c0001c0, 0x4801a017,
+	0x58080013, 0x9c0001c0, 0x4801a018, 0x42000800,
+	0x00000013, 0x42001000, 0x0000dc00, 0x0401f135,
+	0x4803c856, 0x42005000, 0x22000000, 0x42006000,
+	0x01290000, 0x41786800, 0x41787800, 0x0401f90b,
+	0x59301008, 0x4a01a006, 0x55000000, 0x5808000b,
+	0x82000500, 0x00ffffff, 0x58080c0a, 0x800408f0,
+	0x80040540, 0x4801a007, 0x5808080a, 0x82040d00,
+	0xff000000, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x80040540, 0x4801a008, 0x5808000c, 0x9c0001c0,
+	0x4801a009, 0x5808000d, 0x9c0001c0, 0x4801a00a,
+	0x5808000e, 0x9c0001c0, 0x4801a00b, 0x5808000f,
+	0x9c0001c0, 0x4801a00c, 0x59a80002, 0x4801a00d,
+	0x59a80003, 0x4801a00e, 0x59a80000, 0x4801a00f,
+	0x59a80001, 0x4801a010, 0x58080010, 0x4801a011,
+	0x58080011, 0x4801a012, 0x58080012, 0x4801a013,
+	0x58080013, 0x4801a014, 0x4979a015, 0x4979a016,
+	0x4979a017, 0x4979a018, 0x42000800, 0x00000013,
+	0x42001000, 0x0000dc00, 0x0401f0f6, 0x0401fd03,
+	0x5930001c, 0x800001c0, 0x04000008, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+	0x00000002, 0x0401f028, 0x4a01a006, 0x02000000,
+	0x41780800, 0x836c0580, 0x00000004, 0x04020003,
+	0x84040d42, 0x0401f00d, 0x0201f800, 0x0010513b,
+	0x04020003, 0x84040d4a, 0x0401f002, 0x84040d48,
+	0x59a80026, 0x8c000506, 0x04020003, 0x8c00050a,
+	0x04000002, 0x84040d46, 0x4805a207, 0x59c40085,
+	0x48031004, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4200b000, 0x00000006, 0x8388a400, 0x00000000,
+	0x82d0ac00, 0x00000008, 0x0201f800, 0x0010ab17,
+	0x5c00a800, 0x5c00a000, 0x5c00b000, 0x42000800,
+	0x00000008, 0x42001000, 0x0000dc00, 0x0401f0c1,
+	0x0401fcc0, 0x4a01a006, 0x56000000, 0x59340006,
+	0x4801a007, 0x59340007, 0x4801a008, 0x42000800,
+	0x00000003, 0x42001000, 0x0000dc00, 0x0401f0b5,
+	0x4803c856, 0x0401fcc1, 0x5930081c, 0x800409c0,
+	0x0400000e, 0x82040580, 0x0000ffff, 0x04000004,
+	0x82040480, 0x00000007, 0x04021008, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+	0x00000002, 0x0401f012, 0x4a01a006, 0x0200001c,
+	0x4a01a007, 0x00000001, 0x42001000, 0x0010b4f0,
+	0x50080000, 0x9c0001c0, 0x4801a009, 0x59a80010,
+	0x4801a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+	0x4805a00c, 0x42000800, 0x00000007, 0x42001000,
+	0x0000dc00, 0x0401f08f, 0x4d2c0000, 0x0401fc8d,
+	0x59325808, 0x592c0008, 0x82000500, 0x00ffffff,
+	0x4801a001, 0x4a01a006, 0x51000000, 0x5c025800,
+	0x0201f000, 0x00107344, 0x4803c856, 0x59a80810,
+	0x82040d00, 0x000000ff, 0x59325808, 0x59326809,
+	0x59a83026, 0x8c18350a, 0x04020008, 0x8c00050e,
+	0x04020006, 0x80001d80, 0x59a82010, 0x82102500,
+	0x000000ff, 0x0401f001, 0x59300406, 0x4803c857,
+	0x82000d80, 0x00000009, 0x04000006, 0x82000d80,
+	0x0000000a, 0x0400002e, 0x0201f800, 0x001005d8,
+	0x59300015, 0x8c00051e, 0x04020020, 0x42005000,
+	0x04000000, 0x42006000, 0x05000000, 0x592c040a,
+	0x82000500, 0x00000030, 0x800000e0, 0x80306540,
+	0x5934000a, 0x8c000508, 0x04000002, 0x84306546,
+	0x41786800, 0x41787800, 0x0401f831, 0x59300c14,
+	0x80040000, 0x48026414, 0x40040000, 0x800000d0,
+	0x82000540, 0x00000020, 0x4801a403, 0x83180d40,
+	0x00000038, 0x42001000, 0x0000c920, 0x0401f860,
+	0x0201f000, 0x00106052, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000003, 0x497a6a12, 0x0401f7dc,
+	0x4a026a12, 0x0000ff00, 0x0401f7d9, 0x42005000,
+	0x02000000, 0x42006000, 0x20290000, 0x41786800,
+	0x41787800, 0x0401f812, 0x83180d40, 0x00000038,
+	0x42001000, 0x0000c9a0, 0x0401f849, 0x42000800,
+	0x000007d0, 0x59300011, 0x82000500, 0xfff00000,
+	0x80000540, 0x04000003, 0x42000800, 0x00001b58,
+	0x41781000, 0x0201f000, 0x00106054, 0x4201a000,
+	0x00000000, 0x0401f003, 0x4201a000, 0x00000011,
+	0x59340a12, 0x82040d00, 0x0000ff00, 0x59a80010,
+	0x82000500, 0x000000ff, 0x900001c0, 0x80040540,
+	0x80d00540, 0x44034800, 0x81a5a000, 0x59340002,
+	0x82000500, 0x00ffffff, 0x80280540, 0x4801a000,
+	0x59a80010, 0x4801a001, 0x4831a002, 0x82340540,
+	0x00000000, 0x4801a003, 0x59300402, 0x4801a404,
+	0x59300a02, 0x4805a204, 0x8c30652e, 0x04000003,
+	0x4805a404, 0x4801a204, 0x483da005, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x0401f822, 0x5c000800,
+	0x40040000, 0x80081540, 0x800000c4, 0x82000540,
+	0x00002000, 0x4803910a, 0x59b400f6, 0x82000500,
+	0x00000018, 0x040207fd, 0x4a0368f0, 0x0010b544,
+	0x4a0368f1, 0x0010b54b, 0x480b68f3, 0x4a0378e4,
+	0x00008000, 0x0201f000, 0x0010604d, 0x4807c857,
+	0x480a2800, 0x4c040000, 0x0401f80a, 0x5c000800,
+	0x59b400f6, 0x8c00050a, 0x040207fe, 0x49a768f2,
+	0x480768f4, 0x4a0378e4, 0x00008000, 0x1c01f000,
+	0x4a0378e4, 0x0000c000, 0x59bc00e4, 0x8c000520,
+	0x0400000c, 0x4a0378e4, 0x00008000, 0x42007000,
+	0x000003e8, 0x59bc00e4, 0x8c000520, 0x040007f5,
+	0x80387040, 0x02000800, 0x001005d8, 0x0401f7fa,
+	0x1c01f000, 0x82000500, 0xffff0000, 0x82000580,
+	0x01050000, 0x0402000d, 0x599c0818, 0x8c040d10,
+	0x0400000a, 0x59a80807, 0x8c040d0a, 0x04000007,
+	0x42001000, 0x0000804f, 0x41781800, 0x41782000,
+	0x0201f800, 0x00103a3e, 0x1c01f000, 0x41781000,
+	0x42026000, 0x0010d1c0, 0x59a8180e, 0x480a6402,
+	0x4a026202, 0x0000ffff, 0x80081000, 0x800c1840,
+	0x04000004, 0x83326400, 0x00000024, 0x0401f7f8,
+	0x1c01f000, 0x4933c857, 0x59300203, 0x82000580,
+	0x00000000, 0x0400002c, 0x59300406, 0x4803c857,
+	0x82000d80, 0x00000004, 0x04000011, 0x82000d80,
+	0x00000001, 0x0400000e, 0x82000d80, 0x00000003,
+	0x04000006, 0x82000d80, 0x00000006, 0x04020011,
+	0x0201f800, 0x0010a5df, 0x5930001c, 0x800001c0,
+	0x02020800, 0x0010984e, 0x0401f00a, 0x5930081e,
+	0x4807c857, 0x800409c0, 0x04000006, 0x5804001c,
+	0x4803c857, 0x81300580, 0x04020002, 0x4978081c,
+	0x497a6008, 0x4a026004, 0x00004000, 0x59a80037,
+	0x82000c80, 0x00000051, 0x04001002, 0x80000102,
+	0x48026206, 0x497a6205, 0x497a6009, 0x4a026406,
+	0x00000007, 0x1c01f000, 0x8166c9c0, 0x0400001c,
+	0x41626000, 0x41580000, 0x59300a03, 0x82040d80,
+	0x00000000, 0x04000008, 0x83326400, 0x00000024,
+	0x81300c80, 0x040017f9, 0x42026000, 0x0010d1c0,
+	0x0401f7f6, 0x4933c857, 0x8166c840, 0x83300c00,
+	0x00000024, 0x80040480, 0x04021006, 0x4006c000,
+	0x4a026203, 0x00000008, 0x813261c0, 0x1c01f000,
+	0x4202c000, 0x0010d1c0, 0x0401f7fa, 0x42000000,
+	0x0010b854, 0x0201f800, 0x0010aa47, 0x4933c856,
+	0x417a6000, 0x0401f7f5, 0x4933c857, 0x83380580,
+	0x00000013, 0x0402000b, 0x59300004, 0x8c00053e,
+	0x04000007, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00106c4b, 0x1c01f000,
+	0x4933c857, 0x59880052, 0x80000000, 0x48031052,
+	0x1c01f000, 0x4933c857, 0x59300203, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x00107991,
+	0x00107efd, 0x0010804a, 0x00107991, 0x001080b0,
+	0x00107af5, 0x00107991, 0x00107991, 0x00107e93,
+	0x00107991, 0x00107991, 0x00107991, 0x00107991,
+	0x00107991, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x001079a8, 0x00108a3d,
+	0x001079a8, 0x001079a8, 0x001079a8, 0x001079a8,
+	0x001079a8, 0x001079a8, 0x001089e5, 0x00108a58,
+	0x00108ac6, 0x00108a58, 0x00108ac6, 0x001079a8,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x4d2c0000, 0x59325808, 0x59300203,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001079c5,
+	0x001079c5, 0x001079c5, 0x001079e1, 0x00107a2d,
+	0x001079c5, 0x001079c5, 0x001079c5, 0x001079c7,
+	0x001079c5, 0x001079c5, 0x001079c5, 0x001079c5,
+	0x001079c5, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x83380580, 0x00000040, 0x02020800, 0x001005d8,
+	0x4a026007, 0x00082000, 0x4a026203, 0x00000003,
+	0x493a6403, 0x4a025c08, 0x00000001, 0x592c000d,
+	0x48026011, 0x497a6013, 0x592c0208, 0x800000c2,
+	0x800010c4, 0x80081400, 0x480a6206, 0x0201f800,
+	0x00100f4e, 0x42000800, 0x80000060, 0x0201f000,
+	0x00106721, 0x4933c857, 0x83380480, 0x00000050,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x001079f4,
+	0x001079ff, 0x001079f2, 0x001079f2, 0x001079f2,
+	0x001079f2, 0x00107a0a, 0x0201f800, 0x001005d8,
+	0x4a026203, 0x00000004, 0x4a025c08, 0x00000002,
+	0x592c0207, 0x48025c09, 0x592c0209, 0x48025a07,
+	0x592c000c, 0x4802580d, 0x1c01f000, 0x0201f800,
+	0x00106b8a, 0x0201f800, 0x00109037, 0x04000005,
+	0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x0201f800, 0x00106b8a,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x42003000, 0x00000014, 0x41782800,
+	0x42002000, 0x00000002, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010985e, 0x5c028800, 0x5c028000, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00109037, 0x02000000, 0x0002077d, 0x4a025a06,
+	0x00000029, 0x0201f800, 0x000202da, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x83380580, 0x00000048,
+	0x04000005, 0x83380580, 0x00000053, 0x02020800,
+	0x001005d8, 0x592c0206, 0x82000580, 0x00000007,
+	0x04000009, 0x59300011, 0x80000540, 0x04000006,
+	0x592c080c, 0x80040480, 0x4802580c, 0x4a025a06,
+	0x00000015, 0x592c0206, 0x80000540, 0x04020003,
+	0x4a025a06, 0x00000000, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x0201f800,
+	0x001007e4, 0x02000800, 0x001005d8, 0x497a5a06,
+	0x59c80017, 0x82000500, 0x0000f000, 0x48025c07,
+	0x59a80816, 0x82040c00, 0x00000018, 0x48065a07,
+	0x412c7800, 0x4d2c0000, 0x41cca000, 0x42002800,
+	0x00000001, 0x42001000, 0x0000002c, 0x82040480,
+	0x0000002d, 0x04021006, 0x832cac00, 0x00000009,
+	0x0201f800, 0x00108b96, 0x0401f02e, 0x40043000,
+	0x42000800, 0x0000002c, 0x832cac00, 0x00000009,
+	0x0201f800, 0x00108b96, 0x82183480, 0x0000002c,
+	0x0201f800, 0x001007e4, 0x0400001a, 0x80142800,
+	0x4a025804, 0x00000110, 0x492c7801, 0x82180c80,
+	0x0000003d, 0x04021007, 0x40180800, 0x832cac00,
+	0x00000005, 0x0201f800, 0x00108b96, 0x0401f015,
+	0x82081400, 0x0000003c, 0x82183480, 0x0000003c,
+	0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+	0x00000005, 0x0201f800, 0x00108b96, 0x0401f7e5,
+	0x5c025800, 0x592c0206, 0x8400055e, 0x48025a06,
+	0x592c0407, 0x80080540, 0x48025c07, 0x0401f002,
+	0x5c025800, 0x813669c0, 0x04000003, 0x59343403,
+	0x0401f003, 0x42003000, 0x0000ffff, 0x49325808,
+	0x481a5c06, 0x82100580, 0x00000054, 0x04020002,
+	0x491e5813, 0x841401c0, 0x80100540, 0x48025804,
+	0x592c0001, 0x497a5801, 0x4c000000, 0x0201f800,
+	0x000202da, 0x5c025800, 0x812e59c0, 0x040207f9,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+	0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x412cb800,
+	0x592c040b, 0x8c000516, 0x04000003, 0x41cca000,
+	0x0401f003, 0x83cca400, 0x00000006, 0x4008b000,
+	0x41781000, 0x82580480, 0x00000012, 0x04001004,
+	0x4200b000, 0x00000012, 0x40001000, 0x4c080000,
+	0x4d2c0000, 0x0201f800, 0x001007e4, 0x04000023,
+	0x5c001800, 0x492c1801, 0x485a5800, 0x832cac00,
+	0x00000002, 0x0201f800, 0x0010ab28, 0x585c040b,
+	0x8c000500, 0x0400000e, 0x832c1400, 0x00000002,
+	0x8c000516, 0x04000003, 0x82081400, 0x00000006,
+	0x46001000, 0x00000001, 0x80081000, 0x46001000,
+	0x00000900, 0x84000500, 0x4800bc0b, 0x5c001000,
+	0x800811c0, 0x040207da, 0x82000540, 0x00000001,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+	0x5c00b800, 0x1c01f000, 0x5c025800, 0x5c001000,
+	0x0401f7f8, 0x4933c857, 0x83380d80, 0x00000015,
+	0x04020003, 0x0201f000, 0x0002077d, 0x83380d80,
+	0x00000016, 0x02020800, 0x001005d8, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x4d2c0000, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x59325808, 0x83cca400,
+	0x00000006, 0x59cc1806, 0x820c0580, 0x01000000,
+	0x04020004, 0x4200b000, 0x00000002, 0x0401f00f,
+	0x4200b000, 0x00000008, 0x832cac00, 0x00000005,
+	0x0201f800, 0x0010ab17, 0x8c0c1d00, 0x0400000b,
+	0x4200b000, 0x00000008, 0x592e5801, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+	0x0201f800, 0x0010ab17, 0x0401f816, 0x5c00b000,
+	0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x83cca400, 0x00000006, 0x5930a808, 0x8254ac00,
+	0x00000005, 0x4200b000, 0x00000007, 0x0201f800,
+	0x0010ab17, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x4933c857, 0x0201f800, 0x00109037, 0x02000000,
+	0x0002077d, 0x4d2c0000, 0x0201f800, 0x00109597,
+	0x0402000b, 0x41780800, 0x4d400000, 0x42028000,
+	0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x5c025800, 0x0201f000, 0x0002077d, 0x5931d821,
+	0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+	0x58ec0009, 0x0801f800, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x59cc1806, 0x820c0580,
+	0x02000000, 0x04020014, 0x4a026802, 0x00fffffd,
+	0x5934000a, 0x84000504, 0x4802680a, 0x59300808,
+	0x800409c0, 0x02000000, 0x0002077d, 0x4a000a04,
+	0x00000103, 0x480c0805, 0x5931d821, 0x58ef400b,
+	0x58ee580d, 0x58ec0009, 0x0801f800, 0x0201f000,
+	0x0002077d, 0x42000000, 0x0010b86c, 0x0201f800,
+	0x0010aa47, 0x4c0c0000, 0x0401f804, 0x5c001800,
+	0x040207eb, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x59325808, 0x812e59c0, 0x04020009, 0x497a6206,
+	0x497a6205, 0x4d380000, 0x42027000, 0x00000022,
+	0x0401fb77, 0x5c027000, 0x80000580, 0x5c025800,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x59325808, 0x592e5801,
+	0x832cac00, 0x00000005, 0x83cca400, 0x00000006,
+	0x59c80817, 0x82040d00, 0x000003ff, 0x82041480,
+	0x0000000f, 0x0400101b, 0x4200b000, 0x0000000f,
+	0x0201f800, 0x0010ab17, 0x592e5801, 0x832cac00,
+	0x00000005, 0x82080c80, 0x0000000f, 0x0400100d,
+	0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab17,
+	0x592e5801, 0x832cac00, 0x00000005, 0x82041480,
+	0x0000000f, 0x04001007, 0x42001000, 0x0000000f,
+	0x4008b000, 0x0201f800, 0x0010ab17, 0x0401f004,
+	0x4004b000, 0x0201f800, 0x0010ab17, 0x5931d821,
+	0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+	0x592e5801, 0x58ec0009, 0x0801f800, 0x0201f800,
+	0x0002077d, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x59cc0006,
+	0x82000d80, 0x01000000, 0x0400002c, 0x59cc0007,
+	0x9000b1c0, 0x8258b500, 0x000000ff, 0x8058b104,
+	0x8258b400, 0x00000002, 0x82580c80, 0x00000007,
+	0x04001003, 0x4200b000, 0x00000006, 0x83cca400,
+	0x00000006, 0x59301008, 0x800811c0, 0x02000800,
+	0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x82000d00, 0xff000000, 0x800409c0,
+	0x04000019, 0x8200b500, 0x000000ff, 0x8058b104,
+	0x82580c80, 0x0000000e, 0x04001003, 0x4200b000,
+	0x0000000d, 0x58081001, 0x800811c0, 0x02000800,
+	0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x0401f008, 0x59301008, 0x800811c0,
+	0x02000800, 0x001005d8, 0x48001005, 0x59cc0007,
+	0x48001006, 0x0401ff3b, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857,
+	0x42000800, 0x00000000, 0x59cc0006, 0x82000580,
+	0x02000000, 0x04000003, 0x42000800, 0x00000001,
+	0x4d2c0000, 0x59325808, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x48065a06, 0x0201f800, 0x000202da,
+	0x5c025800, 0x0201f000, 0x0002077d, 0x4933c857,
+	0x4d2c0000, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x4200b000, 0x00000002, 0x59cc0806, 0x82040580,
+	0x01000000, 0x04000004, 0x8204b500, 0x0000ffff,
+	0x8058b104, 0x83cca400, 0x00000006, 0x59300008,
+	0x8200ac00, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x0401ff0c, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4803c857,
+	0x4807c857, 0x480bc857, 0x480fc857, 0x4813c857,
+	0x481bc857, 0x492fc857, 0x4d2c0000, 0x4c000000,
+	0x0201f800, 0x001007d3, 0x5c000000, 0x0400000f,
+	0x48025803, 0x5c000000, 0x4802580a, 0x4c000000,
+	0x481a5801, 0x48125809, 0x48065804, 0x480a5807,
+	0x480e5808, 0x412c1000, 0x0201f800, 0x00100858,
+	0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x4d1c0000, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x59341002, 0x82081500, 0x00ffffff,
+	0x80080580, 0x0402001f, 0x497a6205, 0x4d380000,
+	0x42027000, 0x00000035, 0x0201f800, 0x001093ba,
+	0x5c027000, 0x04020012, 0x591c001c, 0x800001c0,
+	0x0400000f, 0x497a381c, 0x591c0414, 0x8c000502,
+	0x02000800, 0x001005d8, 0x84000502, 0x48023c14,
+	0x591c1406, 0x82080580, 0x00000003, 0x04000006,
+	0x82080580, 0x00000006, 0x04000005, 0x0401fc9e,
+	0x0401f004, 0x0401f805, 0x0401f002, 0x0401f8c0,
+	0x5c023800, 0x1c01f000, 0x4d2c0000, 0x591e5808,
+	0x4933c857, 0x491fc857, 0x493bc857, 0x492fc857,
+	0x83380580, 0x00000015, 0x040000b3, 0x83380580,
+	0x00000016, 0x040200ae, 0x4d300000, 0x411e6000,
+	0x59cc0207, 0x4803c857, 0x82000d00, 0x0000ff00,
+	0x82040580, 0x00001700, 0x04000004, 0x82040580,
+	0x00000300, 0x0402005b, 0x591c0203, 0x4803c857,
+	0x82000580, 0x0000000d, 0x0400003f, 0x812e59c0,
+	0x0400009a, 0x591c0202, 0x4803c857, 0x82000580,
+	0x0000ffff, 0x0402007e, 0x592c020a, 0x4803c857,
+	0x82000500, 0x00000003, 0x82000580, 0x00000002,
+	0x04020007, 0x592c080f, 0x591c0011, 0x4803c857,
+	0x4807c857, 0x80040580, 0x04020071, 0x591c0414,
+	0x4803c857, 0x8c000500, 0x0402006d, 0x41780800,
+	0x591c1206, 0x42000000, 0x0000000a, 0x0201f800,
+	0x001066a0, 0x592c0406, 0x4803c857, 0x800001c0,
+	0x0400000c, 0x80080c80, 0x04001004, 0x02020800,
+	0x001005d8, 0x80001040, 0x480a5c06, 0x800811c0,
+	0x04020004, 0x0201f800, 0x00108d88, 0x0401f06b,
+	0x0201f800, 0x0010912a, 0x591c0817, 0x591c0018,
+	0x48065808, 0x48025809, 0x59300007, 0x8c000500,
+	0x02020800, 0x00100e99, 0x497a3808, 0x0201f800,
+	0x000201ba, 0x0402004a, 0x411e6000, 0x0401fc3e,
+	0x0401f05a, 0x0401fc6d, 0x04000013, 0x49366009,
+	0x4a026406, 0x00000003, 0x492e6008, 0x591c0817,
+	0x591c1018, 0x48066017, 0x480a6018, 0x4d380000,
+	0x591e7403, 0x4d300000, 0x411e6000, 0x0401fc2e,
+	0x5c026000, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x0401f046, 0x59a80039, 0x48023a05, 0x0401f043,
+	0x59cc0407, 0x82000580, 0x0000000b, 0x04020025,
+	0x59340a00, 0x84040d0e, 0x48066a00, 0x592c0a04,
+	0x82040d00, 0x000000ff, 0x82040d80, 0x00000014,
+	0x04000003, 0x4a02621d, 0x00000003, 0x59300007,
+	0x8c000500, 0x02020800, 0x00100e99, 0x4d400000,
+	0x42028000, 0x00000003, 0x592c0a08, 0x0201f800,
+	0x00104e70, 0x0201f800, 0x000202da, 0x5c028000,
+	0x497a6008, 0x4a026403, 0x00000085, 0x4a026203,
+	0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+	0x8000404b, 0x0201f800, 0x00020721, 0x0401f01b,
+	0x59cc0207, 0x82000580, 0x00002a00, 0x04020004,
+	0x59a80039, 0x48023a05, 0x0401f014, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x4a025a04, 0x00000103,
+	0x591c0007, 0x8c000500, 0x02020800, 0x00100e99,
+	0x591c0402, 0x48025c06, 0x4a025a06, 0x00000003,
+	0x0201f800, 0x000202c1, 0x0201f800, 0x00107911,
+	0x0201f800, 0x001049b2, 0x5c026000, 0x0201f800,
+	0x0002077d, 0x0401f002, 0x5c026000, 0x5c025800,
+	0x1c01f000, 0x0401f819, 0x0401f7fd, 0x4933c857,
+	0x83380580, 0x00000015, 0x04020004, 0x59a80039,
+	0x48023a05, 0x0401f00d, 0x83380580, 0x00000016,
+	0x0402000d, 0x4d300000, 0x411e6000, 0x0201f800,
+	0x0010a5df, 0x0201f800, 0x000206fd, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x497a381c, 0x0201f800,
+	0x0002077d, 0x1c01f000, 0x591c0414, 0x84000540,
+	0x48023c14, 0x59cc100b, 0x4933c857, 0x491fc857,
+	0x492fc857, 0x4803c857, 0x480bc857, 0x8c08153c,
+	0x04000006, 0x59a80039, 0x48023a05, 0x497a381c,
+	0x0201f000, 0x0002077d, 0x4d300000, 0x411e6000,
+	0x0201f800, 0x00108bd7, 0x5c026000, 0x591c0406,
+	0x82000580, 0x00000000, 0x02000000, 0x0002077d,
+	0x591c0403, 0x82000580, 0x00000050, 0x0402000d,
+	0x4d300000, 0x411e6000, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000043, 0x0201f800, 0x00020721,
+	0x5c026000, 0x497a381c, 0x0201f000, 0x0002077d,
+	0x591c0203, 0x82000580, 0x0000000d, 0x04000014,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x591c0203,
+	0x82000580, 0x00000004, 0x04020011, 0x592c020a,
+	0x8c000502, 0x0400000e, 0x4a023812, 0x0fffffff,
+	0x592c0208, 0x8400051e, 0x48025a08, 0x42000000,
+	0x00000001, 0x48023a14, 0x0401f021, 0x42000000,
+	0x00000007, 0x48023a14, 0x0401f01d, 0x592c020a,
+	0x4803c857, 0x8c000500, 0x0402000b, 0x8c000502,
+	0x040007f7, 0x591c0414, 0x8c00051c, 0x040207eb,
+	0x591c0011, 0x4803c857, 0x800001c0, 0x040007f0,
+	0x0401f7e6, 0x8c08153a, 0x040207ed, 0x59cc000a,
+	0x592c180f, 0x4803c857, 0x480fc857, 0x800c0580,
+	0x040007e7, 0x59cc000a, 0x4803c857, 0x48023816,
+	0x42000000, 0x00000005, 0x48023a14, 0x0201f000,
+	0x00109259, 0x4933c857, 0x4d1c0000, 0x59cc0001,
+	0x59341002, 0x80080580, 0x82000500, 0x00ffffff,
+	0x04020041, 0x59301419, 0x0201f800, 0x00109410,
+	0x02000800, 0x001005d8, 0x591c1406, 0x82080580,
+	0x00000007, 0x04000038, 0x82080580, 0x00000002,
+	0x04000035, 0x82080580, 0x00000000, 0x04000032,
+	0x591c0202, 0x82000d80, 0x0000ffff, 0x04000004,
+	0x59301a19, 0x800c0580, 0x0402002b, 0x83380580,
+	0x00000015, 0x04000026, 0x4d300000, 0x4d2c0000,
+	0x411e6000, 0x59325808, 0x0201f800, 0x00109037,
+	0x02000800, 0x001005d8, 0x592c0204, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000014, 0x04000003,
+	0x4a02621d, 0x00000003, 0x42028000, 0x00000003,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x000202da, 0x5c025800, 0x497a6008, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+	0x00020721, 0x5c026000, 0x0401f003, 0x59a80039,
+	0x48023a05, 0x497a381c, 0x0201f800, 0x0002077d,
+	0x5c023800, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x4d2c0000, 0x59325808, 0x83383580, 0x00000015,
+	0x04000010, 0x59342200, 0x84102502, 0x48126a00,
+	0x0201f800, 0x00109037, 0x04000066, 0x0201f800,
+	0x00109597, 0x04020005, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x0401fa0a, 0x0401f079,
+	0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x04020015, 0x83cc1400, 0x0000000a, 0x4200b000,
+	0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+	0x0010855a, 0x0402000c, 0x0201f800, 0x00102074,
+	0x59342200, 0x59cc1007, 0x800811c0, 0x04000003,
+	0x480a6801, 0x84102542, 0x8410251a, 0x48126a00,
+	0x0401f05f, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+	0x48026a00, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x02000800, 0x001005d8, 0x49366009, 0x497a6008,
+	0x4a026406, 0x00000001, 0x4a026403, 0x00000001,
+	0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+	0x0201f800, 0x00103b25, 0x04000011, 0x41782800,
+	0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010a43e, 0x5c028000,
+	0x4a026406, 0x00000004, 0x4a026203, 0x00000007,
+	0x4a026420, 0x00000001, 0x0401f009, 0x4a026203,
+	0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x0201f800, 0x0010672b, 0x5c026000,
+	0x0201f800, 0x00109037, 0x04000022, 0x0201f800,
+	0x00109597, 0x04020022, 0x0401f9ae, 0x0401f01d,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x59340200, 0x84000558, 0x48026a00, 0x42003000,
+	0x00000003, 0x41782800, 0x42002000, 0x00000005,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x5c027800, 0x0201f800, 0x00102074,
+	0x0201f800, 0x0002077d, 0x0401f002, 0x0401fca9,
+	0x5c025800, 0x5c00b000, 0x1c01f000, 0x4933c857,
+	0x41380000, 0x83383480, 0x00000056, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00107ef7, 0x00107ef2,
+	0x00107ef7, 0x00107ef7, 0x00107ef7, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef7, 0x00107ef0, 0x00107ef7,
+	0x00107ef7, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef7, 0x00107ef7, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef7,
+	0x00107ef0, 0x00107ef7, 0x00107ef7, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x0201f800, 0x001005d8, 0x4a026203, 0x00000001,
+	0x493a6403, 0x0201f000, 0x0010672b, 0x4933c857,
+	0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+	0x0010672b, 0x4933c857, 0x59300403, 0x82003480,
+	0x00000056, 0x02021800, 0x001005d8, 0x83383580,
+	0x00000013, 0x04000093, 0x83383580, 0x00000027,
+	0x0402004b, 0x0201f800, 0x00106bbf, 0x0201f800,
+	0x00109134, 0x0400000b, 0x0201f800, 0x0010914e,
+	0x04000041, 0x59300403, 0x82000d80, 0x00000022,
+	0x04020038, 0x0401fc61, 0x0400003a, 0x0401f03a,
+	0x0201f800, 0x00102074, 0x42000800, 0x00000007,
+	0x0201f800, 0x00104571, 0x0401f8fe, 0x4d440000,
+	0x59368c03, 0x83440580, 0x000007fe, 0x04020008,
+	0x59a81026, 0x84081540, 0x0201f800, 0x0010513b,
+	0x04020002, 0x8408154a, 0x480b5026, 0x42028000,
+	0x00000029, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x836c0580, 0x00000003,
+	0x0400000c, 0x59326809, 0x59340008, 0x800001c0,
+	0x04020008, 0x59368c03, 0x4933c857, 0x4937c857,
+	0x4947c857, 0x0201f800, 0x001045fb, 0x0401f00c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000015, 0x41782800, 0x42002000,
+	0x00000003, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x0201f800, 0x00109326, 0x0201f000, 0x0002077d,
+	0x1c01f000, 0x0401f8cb, 0x0401f7fa, 0x83380580,
+	0x00000014, 0x0400000b, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x040000ed, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42003000,
+	0x00000016, 0x41782800, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42002000, 0x00000009, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x00109134, 0x0402000c,
+	0x0201f800, 0x00102074, 0x0401f89e, 0x59340c03,
+	0x82040580, 0x000007fe, 0x040207ca, 0x59a80826,
+	0x84040d40, 0x48075026, 0x0401f7c6, 0x0201f800,
+	0x0010914e, 0x04020003, 0x0401f892, 0x0401f7c1,
+	0x59300403, 0x82000d80, 0x00000032, 0x04020004,
+	0x0201f800, 0x0010230c, 0x0401f7ba, 0x59300403,
+	0x82000d80, 0x00000022, 0x04000886, 0x0401f7b5,
+	0x4803c857, 0x0c01f001, 0x00108016, 0x00108016,
+	0x00108016, 0x00108016, 0x00108016, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff9, 0x00108016, 0x00107ff0, 0x00108016,
+	0x00108016, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00108016, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00108007, 0x00108016, 0x00107ff0, 0x00108000,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108000,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00108003, 0x00107ff0, 0x00107ff2, 0x00108016,
+	0x00107ff0, 0x00108016, 0x00108016, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+	0x0201f800, 0x000202da, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x4a026203, 0x00000005, 0x59a80039,
+	0x48026205, 0x59a80037, 0x48026206, 0x1c01f000,
+	0x5930081e, 0x49780a05, 0x0401f014, 0x0201f800,
+	0x00109326, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x0010230c, 0x0201f800, 0x00106c55, 0x04000005,
+	0x0201f800, 0x00106bbf, 0x0201f000, 0x0002077d,
+	0x0201f800, 0x00106bbf, 0x0201f800, 0x0002077d,
+	0x0201f000, 0x00106c4b, 0x4933c857, 0x4a026203,
+	0x00000002, 0x59a80037, 0x48026206, 0x1c01f000,
+	0x4933c857, 0x0201f800, 0x00109037, 0x0400002a,
+	0x4d2c0000, 0x0201f800, 0x00109597, 0x0402000a,
+	0x4d400000, 0x42028000, 0x00000031, 0x42000800,
+	0x00000004, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x0401f01c, 0x59300c06, 0x82040580, 0x00000010,
+	0x04000004, 0x82040580, 0x00000011, 0x0402000a,
+	0x4a025a06, 0x00000031, 0x4a02580d, 0x00000004,
+	0x4a02580e, 0x000000ff, 0x0201f800, 0x000202da,
+	0x0401f00c, 0x592c0404, 0x8c00051e, 0x04000009,
+	0x4a025a04, 0x00000103, 0x4a025805, 0x01000000,
+	0x5931d821, 0x58ef400b, 0x58ec0009, 0x0801f800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x59340400,
+	0x82000500, 0x000000ff, 0x82003480, 0x0000000c,
+	0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+	0x0000004d, 0x02000000, 0x0010938b, 0x82180d80,
+	0x00000033, 0x02000000, 0x00109349, 0x82180d80,
+	0x00000028, 0x02000000, 0x0010918f, 0x82180d80,
+	0x00000029, 0x02000000, 0x001091a3, 0x82180d80,
+	0x0000001f, 0x02000000, 0x00107b28, 0x82180d80,
+	0x00000055, 0x02000000, 0x00107b01, 0x82180d80,
+	0x00000000, 0x04000591, 0x82180d80, 0x00000022,
+	0x02000000, 0x00107b55, 0x82180d80, 0x00000035,
+	0x02000000, 0x00107c50, 0x82180d80, 0x00000039,
+	0x04000539, 0x82180d80, 0x0000003d, 0x02000000,
+	0x00107b85, 0x82180d80, 0x00000044, 0x02000000,
+	0x00107bc2, 0x82180d80, 0x00000049, 0x02000000,
+	0x00107c17, 0x82180d80, 0x00000041, 0x02000000,
+	0x00107c03, 0x82180d80, 0x00000043, 0x02000000,
+	0x001094dc, 0x82180d80, 0x00000051, 0x02000000,
+	0x00109542, 0x82180d80, 0x00000004, 0x04020003,
+	0x42000000, 0x00000001, 0x83380d80, 0x00000015,
+	0x04000006, 0x83380d80, 0x00000016, 0x02020000,
+	0x00107974, 0x0401f20f, 0x4d2c0000, 0x4d3c0000,
+	0x0c01f804, 0x5c027800, 0x5c025800, 0x1c01f000,
+	0x001080b8, 0x001080bc, 0x001080b8, 0x00108131,
+	0x001080b8, 0x00108226, 0x001082bf, 0x001080b8,
+	0x001080b8, 0x00108288, 0x001080b8, 0x0010829a,
+	0x4933c857, 0x497a6007, 0x59300808, 0x58040000,
+	0x4a000a04, 0x00000103, 0x0201f000, 0x0002077d,
+	0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+	0x4933c857, 0x59a80016, 0x82000580, 0x00000074,
+	0x0402005c, 0x0201f800, 0x0010a2c8, 0x04020016,
+	0x0401f85c, 0x0201f800, 0x00109037, 0x0400000c,
+	0x0201f800, 0x00109597, 0x04020009, 0x41780800,
+	0x4d400000, 0x42028000, 0x00000000, 0x0201f800,
+	0x0010943b, 0x5c028000, 0x0401f003, 0x0201f800,
+	0x00102074, 0x0201f800, 0x001048c1, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x00109037, 0x04000007,
+	0x0201f800, 0x00109597, 0x04020004, 0x0401ff3d,
+	0x0201f000, 0x0002077d, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+	0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+	0x4d300000, 0x0201f800, 0x0002075a, 0x02000800,
+	0x001005d8, 0x49366009, 0x497a6008, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+	0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+	0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+	0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+	0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x0401f009, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x0201f800, 0x0010672b, 0x5c026000, 0x0401ff05,
+	0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+	0x0401ff00, 0x42000000, 0x00000001, 0x0401f0c7,
+	0x4933c857, 0x59340200, 0x8c000500, 0x0400000d,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x5c027800, 0x0201f800, 0x00103b25, 0x04000005,
+	0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+	0x1c01f000, 0x4933c857, 0x59a80816, 0x82040580,
+	0x00000074, 0x0400000e, 0x4807c857, 0x82040580,
+	0x00000100, 0x040200a0, 0x59cc0408, 0x4803c857,
+	0x8c000500, 0x0400009c, 0x59341403, 0x82080580,
+	0x000007fe, 0x04000006, 0x0401f097, 0x59341403,
+	0x82080580, 0x000007fe, 0x04020003, 0x0401fa9c,
+	0x0401f04c, 0x0201f800, 0x0010462a, 0x59341403,
+	0x82080580, 0x000007fc, 0x0402001f, 0x4a026802,
+	0x00fffffc, 0x0201f800, 0x00109037, 0x04000012,
+	0x0201f800, 0x00109597, 0x0402000f, 0x0401f8a9,
+	0x41780800, 0x4d400000, 0x42028000, 0x00000000,
+	0x0201f800, 0x0010943b, 0x5c028000, 0x42000800,
+	0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+	0x0002077d, 0x42000800, 0x00000004, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+	0x0002077d, 0x59a80005, 0x8c000514, 0x04000011,
+	0x0201f800, 0x0010513b, 0x42001000, 0x00000010,
+	0x04020009, 0x59340002, 0x82000500, 0x00ff0000,
+	0x82000580, 0x00ff0000, 0x04000006, 0x42001000,
+	0x00000008, 0x0201f800, 0x00104c6d, 0x0402005a,
+	0x0201f800, 0x00109037, 0x0400005b, 0x0201f800,
+	0x00109597, 0x04020005, 0x592c0404, 0x8c00051c,
+	0x040207c9, 0x0401f877, 0x42000800, 0x00000005,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x4a026403, 0x00000003, 0x0201f000, 0x0010672b,
+	0x59cc0408, 0x8c000518, 0x04000010, 0x0201f800,
+	0x001092e5, 0x0201f800, 0x0010513b, 0x04000004,
+	0x59cc0408, 0x8c000516, 0x040207b3, 0x59a80026,
+	0x8400054a, 0x48035026, 0x59a80010, 0x84000570,
+	0x48038832, 0x0401f7ac, 0x42001000, 0x000000ef,
+	0x480b5010, 0x497b8830, 0x84081570, 0x480b8832,
+	0x59c40802, 0x84040d4c, 0x48078802, 0x0201f800,
+	0x0010930f, 0x59a80026, 0x84000548, 0x48035026,
+	0x0201f800, 0x0010a3da, 0x0402079b, 0x59a80026,
+	0x8400054c, 0x48035026, 0x42000800, 0x00000006,
+	0x0201f800, 0x00104571, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000000, 0x000000e8, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x001045a6, 0x02020800,
+	0x001005d8, 0x49366009, 0x59340200, 0x8400051a,
+	0x48026a00, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+	0x0010672b, 0x0401fe43, 0x42000000, 0x00000001,
+	0x0401f00a, 0x599c0017, 0x8c00050a, 0x040007ab,
+	0x42000800, 0x00000004, 0x0201f800, 0x00104571,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x80003540,
+	0x04000005, 0x42000800, 0x00000007, 0x0201f800,
+	0x00104571, 0x801831c0, 0x0402000e, 0x59302008,
+	0x801021c0, 0x04000004, 0x58100404, 0x8c00051e,
+	0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+	0x42003000, 0x00000012, 0x0201f800, 0x00103aae,
+	0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+	0x4c5c0000, 0x4d2c0000, 0x59325808, 0x0201f800,
+	0x00105755, 0x5c025800, 0x59cc0008, 0x48002805,
+	0x59cc0009, 0x48002806, 0x49782807, 0x49782808,
+	0x49782809, 0x4978280a, 0x59cc0013, 0x8c00053e,
+	0x04000009, 0x59cc0414, 0x900001c0, 0x59ccbc15,
+	0x805c0540, 0x48002807, 0x59cc0416, 0x900001c0,
+	0x48002808, 0x59cc0017, 0x8c00053e, 0x04000009,
+	0x59cc0418, 0x900001c0, 0x59ccbc19, 0x805c0540,
+	0x48002809, 0x59cc041a, 0x900001c0, 0x4800280a,
+	0x5c00b800, 0x1c01f000, 0x4933c857, 0x59a80016,
+	0x82000580, 0x00000014, 0x04020048, 0x59a80005,
+	0x8c000514, 0x04000015, 0x0201f800, 0x0010513b,
+	0x42001000, 0x00000010, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x0400000a, 0x42001000, 0x00000008, 0x0201f800,
+	0x00104c6d, 0x04000005, 0x59a80005, 0x84000556,
+	0x48035005, 0x0401f031, 0x836c0580, 0x00000003,
+	0x0402000b, 0x59300008, 0x80000540, 0x04020008,
+	0x59341c03, 0x42002000, 0x00000006, 0x42003000,
+	0x00000013, 0x0201f800, 0x00103aae, 0x0201f800,
+	0x0010468d, 0x0401fecf, 0x0401fa1d, 0x0402001f,
+	0x59340404, 0x80000540, 0x0400001c, 0x42000800,
+	0x00000006, 0x0201f800, 0x00104571, 0x0201f800,
+	0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+	0x0402000a, 0x41780800, 0x4d400000, 0x42028000,
+	0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x0201f000, 0x0002077d, 0x4a025a04, 0x00000103,
+	0x4a025805, 0x02000000, 0x0201f800, 0x00102074,
+	0x0201f000, 0x0002077d, 0x0201f800, 0x00104c19,
+	0x0201f800, 0x00109037, 0x04000007, 0x0201f800,
+	0x00109597, 0x04020004, 0x0401fda2, 0x0201f000,
+	0x0002077d, 0x0401fd9f, 0x80000580, 0x59a80005,
+	0x8c000516, 0x04000005, 0x84000516, 0x48035005,
+	0x82000540, 0x00000001, 0x0401ff60, 0x1c01f000,
+	0x4933c857, 0x59a80016, 0x82000580, 0x00000014,
+	0x0402000b, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000001, 0x0201f000, 0x0010672b, 0x42000000,
+	0x00000001, 0x0401f74d, 0x4933c857, 0x40003000,
+	0x59a80016, 0x82000580, 0x00000004, 0x0402000a,
+	0x82183580, 0x0000000b, 0x04020005, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0201f000,
+	0x0002077d, 0x42000000, 0x00000001, 0x0401f73b,
+	0x4803c857, 0x4d2c0000, 0x4d3c0000, 0x0c01f804,
+	0x5c027800, 0x5c025800, 0x1c01f000, 0x001080b8,
+	0x001082ce, 0x001080b8, 0x00108323, 0x001080b8,
+	0x00108391, 0x001082bf, 0x001080b8, 0x001080b8,
+	0x001083b1, 0x001080b8, 0x001083c1, 0x4933c857,
+	0x4d1c0000, 0x59301403, 0x82080580, 0x00000003,
+	0x04000008, 0x82081580, 0x0000001e, 0x04020003,
+	0x0201f800, 0x0002077d, 0x5c023800, 0x1c01f000,
+	0x0401ff5a, 0x0401f7fd, 0x4933c857, 0x0201f800,
+	0x00109037, 0x0400000b, 0x0201f800, 0x00109597,
+	0x04020008, 0x4200b000, 0x00000002, 0x0201f800,
+	0x0010957d, 0x0401fd43, 0x0201f000, 0x0002077d,
+	0x0401f8f5, 0x04020030, 0x417a7800, 0x0201f800,
+	0x00104567, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x59340200, 0x84000558, 0x48026a00, 0x4a026403,
+	0x00000002, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x0201f800, 0x00103b25, 0x04000011,
+	0x4d400000, 0x41782800, 0x42003000, 0x00000005,
+	0x42028000, 0x00000029, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x4a026203, 0x00000007, 0x4a026406,
+	0x00000004, 0x4a026420, 0x00000001, 0x1c01f000,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x0201f800, 0x0010672b,
+	0x0401f7f7, 0x59cc0407, 0x82000580, 0x00000009,
+	0x0402000a, 0x59340412, 0x82000500, 0x000000ff,
+	0x0400000c, 0x80000040, 0x48026c12, 0x4a026206,
+	0x0000000a, 0x0401f7ea, 0x59cc0207, 0x82000500,
+	0x0000ff00, 0x82000580, 0x00001900, 0x040007c2,
+	0x0401fcfc, 0x80000580, 0x0401f6c4, 0x4933c857,
+	0x59a80032, 0x80000540, 0x04000015, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020011, 0x59a80010,
+	0x80000000, 0x48035010, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000002, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+	0x0402000e, 0x4c580000, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fcd5,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x0201f000, 0x0002077d, 0x0401fcce, 0x59cc3407,
+	0x82183500, 0x000000ff, 0x82180580, 0x00000005,
+	0x0400001c, 0x82180580, 0x0000000b, 0x04000016,
+	0x59cc0207, 0x82000500, 0x0000ff00, 0x04020004,
+	0x82180580, 0x00000009, 0x04000012, 0x82000580,
+	0x00001900, 0x0402000c, 0x82180580, 0x00000009,
+	0x0400000c, 0x42000800, 0x00000004, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+	0x0002077d, 0x42000000, 0x00000001, 0x0401f677,
+	0x0201f800, 0x00109037, 0x59325808, 0x04000008,
+	0x592c0204, 0x82000580, 0x00000139, 0x040007f6,
+	0x592c0404, 0x8c00051e, 0x040207f3, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020007, 0x59a80026,
+	0x84000540, 0x48035026, 0x0201f800, 0x00104229,
+	0x0401f7e9, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42003000, 0x00000005, 0x0201f800, 0x0010a942,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0401f7dd, 0x4933c857, 0x0401f84d, 0x0402000b,
+	0x42000800, 0x00000005, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000003,
+	0x0201f000, 0x0010672b, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0201f800, 0x00109597,
+	0x0402000a, 0x4c580000, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fc71,
+	0x0201f000, 0x0002077d, 0x0401fc6e, 0x80000580,
+	0x0401f636, 0x4933c857, 0x0401f82d, 0x0402000b,
+	0x42000800, 0x00000009, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000005,
+	0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+	0x0401f626, 0x4933c857, 0x0401f81d, 0x0402000b,
+	0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+	0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+	0x0401f616, 0x4933c857, 0x59cc0407, 0x82000580,
+	0x00000003, 0x04020009, 0x59cc0207, 0x82000500,
+	0x0000ff00, 0x82000d80, 0x00002a00, 0x04000003,
+	0x82000d80, 0x00001e00, 0x1c01f000, 0x4933c857,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4933c857,
+	0x4d400000, 0x4c580000, 0x59a80026, 0x82000540,
+	0x00000003, 0x48035026, 0x0401f85c, 0x04000038,
+	0x4d340000, 0x4d440000, 0x59a80026, 0x84000552,
+	0x48035026, 0x0201f800, 0x00103b25, 0x0400000c,
+	0x42028000, 0x0000002a, 0x42028800, 0x0000ffff,
+	0x42003000, 0x00000002, 0x0201f800, 0x0010a446,
+	0x59a80805, 0x84040d44, 0x48075005, 0x42028000,
+	0x0000002a, 0x4d3c0000, 0x42027800, 0x00000204,
+	0x0201f800, 0x00101fe5, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00101e45, 0x4200b000, 0x00000010, 0x42028800,
+	0x000007f0, 0x4d2c0000, 0x83440580, 0x000007fe,
+	0x04000003, 0x0201f800, 0x001045fb, 0x81468800,
+	0x8058b040, 0x040207f9, 0x5c025800, 0x59cc0408,
+	0x8c00051e, 0x04000004, 0x59a80026, 0x84000512,
+	0x48035026, 0x5c028800, 0x5c026800, 0x0201f800,
+	0x0010462a, 0x4a026802, 0x00fffffe, 0x59a80826,
+	0x84040d50, 0x59cc0013, 0x8c00053e, 0x04000003,
+	0x8c000536, 0x04000004, 0x59cc0017, 0x8c000536,
+	0x04020002, 0x84040d10, 0x48075026, 0x59cc0800,
+	0x82040d00, 0x00ffffff, 0x48075010, 0x80040110,
+	0x4803501d, 0x48038881, 0x0201f800, 0x0010513b,
+	0x04000007, 0x59cc0009, 0x48035035, 0x59cc000a,
+	0x48035036, 0x0201f800, 0x001092e5, 0x5c00b000,
+	0x5c028000, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x59a80010, 0x82000500, 0x00ffff00, 0x04000022,
+	0x59cc1000, 0x82081500, 0x00ffff00, 0x80080580,
+	0x04000004, 0x42000000, 0x0010b83b, 0x0401f016,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0401f900, 0x04000004,
+	0x42000000, 0x0010b83c, 0x0401f00b, 0x83cc1400,
+	0x0000000d, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000008, 0x0401f8f5, 0x04000007, 0x42000000,
+	0x0010b83d, 0x0201f800, 0x0010aa47, 0x82000540,
+	0x00000001, 0x5c00b000, 0x1c01f000, 0x4933c857,
+	0x59cc0206, 0x82000580, 0x00000014, 0x04020016,
+	0x59cc0407, 0x82000580, 0x00000800, 0x04020012,
+	0x59cc0207, 0x8c00051a, 0x0400000d, 0x82000500,
+	0x00000f00, 0x82000580, 0x00000100, 0x04020008,
+	0x59cc020a, 0x8c000508, 0x04020003, 0x8c00050a,
+	0x04000003, 0x80000580, 0x1c01f000, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x4943c857,
+	0x493fc857, 0x4c5c0000, 0x4d300000, 0x4d340000,
+	0x4d2c0000, 0x4d380000, 0x4130b800, 0x42026000,
+	0x0010d1c0, 0x59a8000e, 0x81640480, 0x040210bd,
+	0x8d3e7d12, 0x04000004, 0x405c0000, 0x81300580,
+	0x040000b3, 0x59300406, 0x82000c80, 0x00000012,
+	0x04021015, 0x59326809, 0x0c01f001, 0x0010854f,
+	0x001084bc, 0x001084d3, 0x001084de, 0x001084b7,
+	0x001084ce, 0x00108507, 0x0010854f, 0x001084b5,
+	0x0010851b, 0x0010852a, 0x001084b5, 0x001084b5,
+	0x001084b5, 0x001084b5, 0x0010854f, 0x00108540,
+	0x00108538, 0x0201f800, 0x001005d8, 0x8d3e7d18,
+	0x04000004, 0x59300420, 0x8c000500, 0x04020094,
+	0x59300403, 0x82000580, 0x00000043, 0x04000090,
+	0x0201f800, 0x00109134, 0x02000800, 0x00102074,
+	0x0201f800, 0x0010914e, 0x02000800, 0x0010801c,
+	0x8d3e7d06, 0x04000084, 0x0201f800, 0x001092d7,
+	0x04000083, 0x0401f080, 0x8d3e7d16, 0x04000004,
+	0x59300420, 0x8c000500, 0x0402007d, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000077, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0201f800,
+	0x0010912a, 0x0401f070, 0x813669c0, 0x02000800,
+	0x001005d8, 0x8d3e7d06, 0x04000004, 0x59340200,
+	0x8c00050e, 0x0402006a, 0x59300004, 0x8400055c,
+	0x48026004, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400005c, 0x4a025a04, 0x00000103,
+	0x59300402, 0x48025c06, 0x592c0408, 0x8c000512,
+	0x04000006, 0x4d2c0000, 0x592e5809, 0x0201f800,
+	0x001007fd, 0x5c025800, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x0010959c, 0x0201f800, 0x000202da,
+	0x0201f800, 0x0010912a, 0x0401f047, 0x8c000518,
+	0x04000047, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400003c, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x0010a693, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x0401f033, 0x0201f800,
+	0x001062d5, 0x04000032, 0x59300203, 0x82000580,
+	0x00000004, 0x04020004, 0x0201f800, 0x00100e99,
+	0x0401f02b, 0x42027000, 0x00000047, 0x0201f800,
+	0x000207a1, 0x0401f026, 0x59300203, 0x82000580,
+	0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+	0x0201f800, 0x00109037, 0x0400001b, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0401f016,
+	0x833c0500, 0x00001800, 0x04000015, 0x8d3e7d16,
+	0x04020013, 0x59325817, 0x0201f800, 0x001007fd,
+	0x59300203, 0x82000580, 0x00000004, 0x02000800,
+	0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000005, 0x49425a06, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x83326400,
+	0x00000024, 0x41580000, 0x81300480, 0x04001742,
+	0x5c027000, 0x5c025800, 0x5c026800, 0x5c026000,
+	0x5c00b800, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x480bc857, 0x480fc857, 0x485bc857,
+	0x50080800, 0x500c0000, 0x80042580, 0x04020007,
+	0x80081000, 0x800c1800, 0x8058b040, 0x040207f9,
+	0x80000580, 0x1c01f000, 0x4803c857, 0x4807c857,
+	0x480bc857, 0x480fc857, 0x80040480, 0x04001006,
+	0x42000000, 0x00000001, 0x82040d40, 0x00000001,
+	0x1c01f000, 0x41780000, 0x0401f7fc, 0x83380480,
+	0x00000053, 0x02021800, 0x001005d8, 0x83380480,
+	0x0000004b, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x0010858a, 0x0010858a, 0x0010858a, 0x0010858a,
+	0x00108588, 0x00108588, 0x00108588, 0x0010858a,
+	0x0201f800, 0x001005d8, 0x493bc857, 0x4a026203,
+	0x0000000d, 0x493a6403, 0x42000800, 0x80000000,
+	0x0201f000, 0x00020721, 0x83380580, 0x00000013,
+	0x04020008, 0x59300403, 0x82000580, 0x00000050,
+	0x02020800, 0x001005d8, 0x0201f000, 0x0002077d,
+	0x4933c857, 0x83380580, 0x00000027, 0x04020030,
+	0x4933c857, 0x0201f800, 0x00106bbf, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x492fc857, 0x0400000d, 0x4a025a04, 0x00000103,
+	0x59300c02, 0x48065c06, 0x4a025a06, 0x00000029,
+	0x497a5c09, 0x592c0c08, 0x84040d50, 0x48065c08,
+	0x0201f800, 0x000202da, 0x5c025800, 0x42003000,
+	0x00000015, 0x41782800, 0x42002000, 0x00000003,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x0201f000, 0x0002077d, 0x83380580,
+	0x00000014, 0x0402000c, 0x59300403, 0x82000c80,
+	0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x4803c857,
+	0x0c01f00e, 0x83380580, 0x00000053, 0x0400000a,
+	0x83380580, 0x00000048, 0x02020800, 0x001005d8,
+	0x59300403, 0x82000580, 0x00000050, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x001085ff, 0x001085fd,
+	0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+	0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+	0x001085fd, 0x00108616, 0x00108616, 0x00108616,
+	0x00108616, 0x001085fd, 0x00108616, 0x001085fd,
+	0x00108616, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x0201f800, 0x00106bbf, 0x0201f800, 0x00109037,
+	0x02000000, 0x0002077d, 0x4d2c0000, 0x59325808,
+	0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+	0x4a025a06, 0x00000006, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300004, 0x8c00053e, 0x04020029,
+	0x59325808, 0x592c0c08, 0x59cc2a08, 0x82141d00,
+	0x00000c00, 0x04000002, 0x59cc1809, 0x84040d58,
+	0x48065c08, 0x82143500, 0x00000fff, 0x04020027,
+	0x59340200, 0x8c00050e, 0x04020080, 0x0201f800,
+	0x0002082b, 0x04020006, 0x4a025a06, 0x00000000,
+	0x59300811, 0x800409c0, 0x0402094b, 0x4a025a04,
+	0x00000103, 0x48065807, 0x480e580a, 0x48165c09,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x59cc0208, 0x8c000518,
+	0x02020000, 0x001091d1, 0x0201f000, 0x0002077d,
+	0x0201f800, 0x00106f60, 0x040007d6, 0x4d3c0000,
+	0x42027800, 0x00000002, 0x0201f800, 0x00108be3,
+	0x5c027800, 0x0401f7cf, 0x4817c857, 0x480fc857,
+	0x82180500, 0x000000ff, 0x0400000e, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000048,
+	0x04020008, 0x592c0407, 0x800001c0, 0x04000005,
+	0x0201f800, 0x0010973f, 0x0201f000, 0x00109787,
+	0x82180d00, 0x00000c00, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04020032, 0x4a025a06, 0x00000000,
+	0x41782000, 0x8c183510, 0x04000007, 0x59cc000c,
+	0x82000500, 0x000000ff, 0x04000002, 0x4803c857,
+	0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512,
+	0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+	0x040007b8, 0x82041480, 0x0000001d, 0x04001006,
+	0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800,
+	0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400,
+	0x0000000c, 0x832cac00, 0x0000000d, 0x0201f800,
+	0x00108b9f, 0x5c00a800, 0x5c00a000, 0x0401f7a5,
+	0x59300011, 0x59301402, 0x480a5c06, 0x48025807,
+	0x480e580a, 0x48165c09, 0x0201f800, 0x00108b48,
+	0x0201f800, 0x00108b84, 0x0401f7a6, 0x592c020a,
+	0x8c000502, 0x040007cd, 0x592c0208, 0x8c00050e,
+	0x040207ca, 0x59300011, 0x800c0d80, 0x040007c7,
+	0x4803c857, 0x480fc857, 0x8c183514, 0x02000000,
+	0x0010920f, 0x80000540, 0x040007c0, 0x4807c856,
+	0x0201f000, 0x0010920f, 0x592c020a, 0x8c000502,
+	0x04000782, 0x59300011, 0x800001c0, 0x0400077f,
+	0x592c0208, 0x8c00050e, 0x0402077c, 0x0201f000,
+	0x0010920f, 0x59cc2006, 0x59cc2807, 0x0401f035,
+	0x0401f034, 0x1c01f000, 0x4933c857, 0x5930001c,
+	0x800001c0, 0x02020800, 0x0010984e, 0x59325808,
+	0x592c0c08, 0x41782800, 0x41781800, 0x84040d58,
+	0x48065c08, 0x41783000, 0x59340200, 0x8c00050e,
+	0x04020018, 0x0201f800, 0x0002082b, 0x04020007,
+	0x4a025a06, 0x00000000, 0x59300811, 0x4807c857,
+	0x800409c0, 0x040208ac, 0x4a025a04, 0x00000103,
+	0x48065807, 0x480e580a, 0x48165c09, 0x4933c857,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x592c020a, 0x8c000502, 0x040007ea, 0x59300011,
+	0x4803c857, 0x800001c0, 0x040007e6, 0x592c0208,
+	0x8c00050e, 0x040207e3, 0x0201f000, 0x0010920f,
+	0x5930001c, 0x800001c0, 0x4c100000, 0x4c140000,
+	0x02020800, 0x0010984e, 0x5c002800, 0x5c002000,
+	0x4a026203, 0x00000002, 0x4a026403, 0x00000043,
+	0x59325808, 0x592c020a, 0x8c000502, 0x04020018,
+	0x40100000, 0x592c080f, 0x80040c80, 0x40140000,
+	0x80040480, 0x04001014, 0x48126013, 0x48166011,
+	0x59300004, 0x8c00053e, 0x04020008, 0x497a6205,
+	0x0201f800, 0x00100f93, 0x04020009, 0x59300804,
+	0x0201f000, 0x00106721, 0x0201f800, 0x00106f60,
+	0x040007f7, 0x0201f000, 0x00107974, 0x4933c857,
+	0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7eb,
+	0x83380480, 0x00000058, 0x04021005, 0x83380480,
+	0x00000040, 0x04001002, 0x0c01f002, 0x1c01f000,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x00108740, 0x00108740, 0x00108742, 0x00108740,
+	0x00108740, 0x00108740, 0x00108740, 0x0010874f,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x0010877d, 0x00108740, 0x00108740, 0x00108740,
+	0x0201f800, 0x001005d8, 0x4933c857, 0x0201f800,
+	0x00106dc3, 0x4a026203, 0x00000002, 0x59a80039,
+	0x48026205, 0x59300011, 0x59300815, 0x80040c80,
+	0x48066015, 0x0201f000, 0x00106b8a, 0x4933c857,
+	0x0201f800, 0x00106b8a, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00109037, 0x04000010, 0x4d2c0000, 0x59325808,
+	0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+	0x4a025a06, 0x00000029, 0x497a5c09, 0x592c0c08,
+	0x84040d50, 0x48065c08, 0x0201f800, 0x000202da,
+	0x5c025800, 0x42003000, 0x00000014, 0x41782800,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42002000,
+	0x00000002, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010985e, 0x5c028800, 0x5c028000, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x59300808, 0x49780c09,
+	0x4978080a, 0x58041408, 0x84081558, 0x48080c08,
+	0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020023,
+	0x497a5a06, 0x5930001f, 0x80000540, 0x04000017,
+	0x497a5a06, 0x4c040000, 0x4c080000, 0x4c0c0000,
+	0x4c100000, 0x4c140000, 0x58f41003, 0x40040000,
+	0x80081480, 0x5930001f, 0x4809e803, 0x0201f800,
+	0x00100d56, 0x5c002800, 0x5c002000, 0x5c001800,
+	0x5c001000, 0x5c000800, 0x592c0206, 0x80000540,
+	0x04020009, 0x0401f005, 0x592c0408, 0x8c00051c,
+	0x04000002, 0x592c0803, 0x4807c857, 0x4a025a06,
+	0x00000015, 0x1c01f000, 0x5930001f, 0x80000540,
+	0x04000009, 0x4a025a06, 0x00000011, 0x5930001f,
+	0x4c040000, 0x0201f800, 0x00100d56, 0x5c000800,
+	0x0401f7f5, 0x4807c856, 0x4a025a06, 0x00000007,
+	0x1c01f000, 0x83380480, 0x00000058, 0x04021007,
+	0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001087db,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087dd, 0x001087db, 0x001087db, 0x00108860,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087db, 0x001087db, 0x00108910, 0x00108939,
+	0x00108918, 0x001087db, 0x00108945, 0x0201f800,
+	0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300007, 0x8c00050e, 0x0400007c,
+	0x8c000500, 0x0400006e, 0x8c00051c, 0x04000009,
+	0x84000500, 0x48026007, 0x59325808, 0x592c3c08,
+	0x841c3d58, 0x481e5c08, 0x0201f000, 0x000207dd,
+	0x59325808, 0x592c3c08, 0x841c3d58, 0x59300007,
+	0x8c00051c, 0x040207f3, 0x481e5c08, 0x42000000,
+	0x00000005, 0x40000000, 0x80000040, 0x040207fe,
+	0x59300007, 0x8c00051c, 0x040207ea, 0x59cc0a08,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000048, 0x0402000c, 0x497a580b, 0x82040500,
+	0x000000ff, 0x04000008, 0x592c0407, 0x800001c0,
+	0x04000005, 0x0201f800, 0x0010973f, 0x0201f000,
+	0x00100e56, 0x48065c09, 0x41782000, 0x82040500,
+	0x00000c00, 0x04000002, 0x59cc2009, 0x82043500,
+	0x00000fff, 0x04020027, 0x481e5c08, 0x4a025a06,
+	0x00000000, 0x801831c0, 0x02000000, 0x00100e56,
+	0x41782000, 0x8c183510, 0x04000002, 0x59cc200b,
+	0x4812580c, 0x41780000, 0x8c183512, 0x04000002,
+	0x59cc000a, 0x4802580b, 0x80100c00, 0x02001800,
+	0x001005d8, 0x02000000, 0x00100e56, 0x82041480,
+	0x0000001d, 0x0402100c, 0x4c500000, 0x4c540000,
+	0x83cca400, 0x0000000c, 0x832cac00, 0x0000000d,
+	0x0401fb67, 0x5c00a800, 0x5c00a000, 0x0201f000,
+	0x00100e56, 0x0401fb0b, 0x0201f000, 0x00100e56,
+	0x412c7800, 0x0201f800, 0x001007e4, 0x02000800,
+	0x001005d8, 0x492c7809, 0x841c3d52, 0x481c7c08,
+	0x4a025a04, 0x00000103, 0x4812580a, 0x48065c09,
+	0x583c0404, 0x583c1005, 0x583c2208, 0x48025c04,
+	0x480a5805, 0x48125a08, 0x0401f7c8, 0x8c000524,
+	0x04000794, 0x59325808, 0x4c000000, 0x592c0408,
+	0x8c00051c, 0x5c000000, 0x04020003, 0x4a026011,
+	0xffffffff, 0x84000524, 0x0401f78a, 0x1c01f000,
+	0x59a80039, 0x48026205, 0x59325808, 0x4a026203,
+	0x00000002, 0x592c2408, 0x59300807, 0x4933c857,
+	0x4807c857, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000048, 0x04020004, 0x8c102500,
+	0x02020000, 0x00109787, 0x4a025a06, 0x00000000,
+	0x8c040d1e, 0x04000027, 0x41780800, 0x497a5c09,
+	0x592c1c09, 0x59300011, 0x59341200, 0x497a6205,
+	0x8c08150e, 0x0402006e, 0x4807c857, 0x4806580a,
+	0x80000d40, 0x04020f04, 0x59300402, 0x48025c06,
+	0x48065807, 0x4a025a04, 0x00000103, 0x4c040000,
+	0x4c0c0000, 0x4c100000, 0x0201f800, 0x0010959c,
+	0x5c002000, 0x5c001800, 0x5c000800, 0x8c102512,
+	0x0402001a, 0x4c0c0000, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x5c001800, 0x8c0c1d18,
+	0x02000000, 0x0002077d, 0x0201f000, 0x001091d1,
+	0x4813c857, 0x8c102518, 0x0400004b, 0x41780800,
+	0x592c1c09, 0x820c0580, 0x00001000, 0x040007d6,
+	0x8c102512, 0x040007d4, 0x592c7809, 0x583c080a,
+	0x583c1c09, 0x0401f7d0, 0x4807c857, 0x592c7809,
+	0x59300402, 0x592c1404, 0x8c08151e, 0x0402000d,
+	0x592c1206, 0x48007c06, 0x48047807, 0x48087a06,
+	0x84102512, 0x48107c08, 0x4c0c0000, 0x0201f800,
+	0x001007fd, 0x403e5800, 0x0401faca, 0x0401f7d9,
+	0x48025c06, 0x48065807, 0x583c080c, 0x583c000b,
+	0x80040c00, 0x82041480, 0x0000001d, 0x04001006,
+	0x583c1001, 0x480a5801, 0x49787801, 0x42000800,
+	0x0000001c, 0x82040c00, 0x00000014, 0x4c0c0000,
+	0x4c500000, 0x4c540000, 0x823ca400, 0x00000008,
+	0x832cac00, 0x00000008, 0x4c100000, 0x4c3c0000,
+	0x0401facb, 0x5c007800, 0x5c002000, 0x5c00a800,
+	0x5c00a000, 0x84102512, 0x48125c08, 0x403e5800,
+	0x0201f800, 0x001007fd, 0x42034000, 0x0010b4a4,
+	0x59a1d81e, 0x80edd9c0, 0x02000800, 0x001005d8,
+	0x48efc857, 0x58ec0009, 0x4803c857, 0x0801f800,
+	0x0401f7ac, 0x4933c857, 0x1c01f000, 0x59301414,
+	0x480bc857, 0x8c08151c, 0x0402000e, 0x80000540,
+	0x4803c857, 0x0400078d, 0x80042c80, 0x0402178b,
+	0x8c081514, 0x04020005, 0x592c080f, 0x4807c857,
+	0x80040480, 0x48026016, 0x8408155c, 0x480a6414,
+	0x59301007, 0x8408151e, 0x480a6007, 0x4a025c09,
+	0x00000001, 0x0201f800, 0x0010959c, 0x497a5c09,
+	0x8c102512, 0x04000006, 0x4d2c0000, 0x403e5800,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x82102500,
+	0xffffedff, 0x48125c08, 0x0201f000, 0x0010920f,
+	0x59325808, 0x592c0408, 0x8c000518, 0x04000004,
+	0x412df800, 0x0201f000, 0x00100e6f, 0x1c01f000,
+	0x4933c857, 0x59325808, 0x497a5c09, 0x4a025a06,
+	0x00000000, 0x4a025a04, 0x00000103, 0x59300811,
+	0x4807c857, 0x800409c0, 0x0402000a, 0x48065807,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x59340200, 0x8c00050e, 0x04020005, 0x59300811,
+	0x0401fe55, 0x48065807, 0x0401f7f2, 0x592c0208,
+	0x8c00050e, 0x040207fa, 0x4933c857, 0x0201f000,
+	0x0010920f, 0x4933c857, 0x59325808, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x592c020a, 0x8c000502,
+	0x02000800, 0x001005d8, 0x4a026206, 0x00000002,
+	0x1c01f000, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300007, 0x4933c857, 0x4803c857,
+	0x8c00050e, 0x04000037, 0x8c000500, 0x04000029,
+	0x8c00051c, 0x0400000a, 0x84000500, 0x48026007,
+	0x59325808, 0x592c3c08, 0x481fc857, 0x841c3d58,
+	0x481e5c08, 0x0201f000, 0x000207dd, 0x59325808,
+	0x592c3c08, 0x841c3d58, 0x59300007, 0x8c00051c,
+	0x040207f2, 0x481e5c08, 0x42000000, 0x00000005,
+	0x40000000, 0x80000040, 0x040207fe, 0x59300007,
+	0x8c00051c, 0x040207e9, 0x592c0204, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000048, 0x04020003,
+	0x497a580b, 0x0401f002, 0x497a5c09, 0x481e5c08,
+	0x4a025a06, 0x00000000, 0x0201f000, 0x00100e56,
+	0x8c000524, 0x040007d9, 0x59325808, 0x4c000000,
+	0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003,
+	0x4a026011, 0xffffffff, 0x84000524, 0x0401f7cf,
+	0x1c01f000, 0x4933c857, 0x41780800, 0x83380480,
+	0x00000058, 0x0402100b, 0x83380480, 0x00000040,
+	0x04001008, 0x4d2c0000, 0x59325808, 0x812e59c0,
+	0x0c020806, 0x5c025800, 0x0201f000, 0x0002077d,
+	0x493bc857, 0x1c01f000, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089b0,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089b5, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x0201f800, 0x001005d8,
+	0x59cc0a08, 0x497a5807, 0x4807c857, 0x82040d00,
+	0x00000fff, 0x59300402, 0x48025c06, 0x4a025a04,
+	0x00000103, 0x48065c09, 0x4a025a06, 0x00000000,
+	0x800409c0, 0x02000000, 0x000202c1, 0x59cc0009,
+	0x4802580a, 0x82042500, 0x00000100, 0x04000002,
+	0x59cc200b, 0x4812580c, 0x82040500, 0x00000200,
+	0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+	0x02001800, 0x001005d8, 0x02000000, 0x000202da,
+	0x82041480, 0x0000001d, 0x04001006, 0x592c0404,
+	0x8c00051e, 0x0400000e, 0x42000800, 0x0000001c,
+	0x4c500000, 0x4c540000, 0x83cca400, 0x0000000c,
+	0x832cac00, 0x0000000d, 0x0401f9c1, 0x5c00a800,
+	0x5c00a000, 0x0201f000, 0x000202da, 0x0401f965,
+	0x0401f1a0, 0x83380480, 0x00000093, 0x02021800,
+	0x001005d8, 0x83380480, 0x00000085, 0x02001800,
+	0x001005d8, 0x0c01f001, 0x001089fd, 0x001089fb,
+	0x001089fb, 0x00108a04, 0x001089fb, 0x001089fb,
+	0x001089fb, 0x001089fb, 0x001089fb, 0x001089fb,
+	0x001089fb, 0x001089fb, 0x001089fb, 0x0201f800,
+	0x001005d8, 0x4a026203, 0x00000001, 0x493a6403,
+	0x42000800, 0x80000040, 0x0201f000, 0x00020721,
+	0x4933c857, 0x59cc1204, 0x480a601c, 0x59cc1404,
+	0x0201f800, 0x00109410, 0x0400001b, 0x591c0203,
+	0x82000580, 0x00000000, 0x04000017, 0x591c0009,
+	0x81340580, 0x04020014, 0x4d300000, 0x4d1c0000,
+	0x411e6000, 0x0401f9c2, 0x5c023800, 0x5c026000,
+	0x0400000b, 0x59cc0005, 0x8c000500, 0x04020003,
+	0x0401f98c, 0x0401f003, 0x4a023a03, 0x00000002,
+	0x4a026403, 0x00000086, 0x0401f005, 0x0401f9a6,
+	0x040007f5, 0x4a026403, 0x00000087, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x59340200, 0x8c00050e, 0x0400000d,
+	0x59cc1404, 0x0201f800, 0x00109410, 0x04000009,
+	0x591c0414, 0x8c00051a, 0x04000006, 0x4d300000,
+	0x411e6000, 0x0201f800, 0x0010921e, 0x5c026000,
+	0x1c01f000, 0x83380580, 0x00000013, 0x0402000a,
+	0x59300403, 0x82000d80, 0x00000086, 0x04000012,
+	0x82000d80, 0x00000087, 0x02020800, 0x001005d8,
+	0x0401f00d, 0x83380580, 0x00000027, 0x04000005,
+	0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+	0x493bc857, 0x0201f800, 0x00106bbf, 0x0201f000,
+	0x00107911, 0x4933c857, 0x0201f000, 0x00107911,
+	0x83380580, 0x00000013, 0x04020005, 0x59300403,
+	0x82000480, 0x00000085, 0x0c01f04d, 0x83380580,
+	0x00000027, 0x04020041, 0x4933c857, 0x0201f800,
+	0x00106bbf, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000015,
+	0x41782800, 0x42002000, 0x00000003, 0x42028000,
+	0x00000029, 0x4d400000, 0x4d440000, 0x59368c03,
+	0x0201f800, 0x0010985e, 0x5c028800, 0x5c028000,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00109037, 0x0400000c, 0x4d2c0000,
+	0x59325808, 0x4a025a04, 0x00000103, 0x59300402,
+	0x48025c06, 0x497a5c09, 0x49425a06, 0x0201f800,
+	0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+	0x0201f000, 0x0002077d, 0x83380580, 0x00000089,
+	0x04000005, 0x83380580, 0x0000008a, 0x02020000,
+	0x00107974, 0x0201f800, 0x00106f60, 0x02020000,
+	0x00107974, 0x59300a03, 0x82040580, 0x0000000a,
+	0x0400002a, 0x82040580, 0x0000000c, 0x04000027,
+	0x0201f800, 0x001005d8, 0x83380580, 0x00000014,
+	0x040207ea, 0x4933c857, 0x0201f800, 0x00106bbf,
+	0x42028000, 0x00000006, 0x0401f7d2, 0x00108aba,
+	0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+	0x00108ab8, 0x00108ac0, 0x00108ab8, 0x00108ab8,
+	0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+	0x0201f800, 0x001005d8, 0x4933c857, 0x59a80037,
+	0x48026206, 0x4a026203, 0x0000000a, 0x1c01f000,
+	0x4933c857, 0x59a80037, 0x48026206, 0x4a026203,
+	0x0000000c, 0x1c01f000, 0x83380580, 0x00000089,
+	0x04000008, 0x83380580, 0x0000008a, 0x04000032,
+	0x4933c857, 0x493bc857, 0x0201f000, 0x00107974,
+	0x4933c857, 0x59325808, 0x59300a1d, 0x82040580,
+	0x00000003, 0x04020004, 0x0201f800, 0x001049b2,
+	0x0401f00c, 0x5930021d, 0x82000580, 0x00000001,
+	0x04020008, 0x59300c16, 0x82040580, 0x00000039,
+	0x0400002c, 0x82040580, 0x00000035, 0x04000029,
+	0x4c340000, 0x41306800, 0x0201f800, 0x0002075a,
+	0x04000010, 0x4a026203, 0x00000001, 0x4a026403,
+	0x0000001e, 0x59cc0c07, 0x48066419, 0x59cc0a07,
+	0x48066219, 0x49366009, 0x4a026406, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x40366000, 0x0201f800, 0x0002077d, 0x5c006800,
+	0x1c01f000, 0x4933c857, 0x5930021d, 0x82000580,
+	0x00000001, 0x04020040, 0x59300c16, 0x82040580,
+	0x00000035, 0x04000007, 0x82040580, 0x0000001e,
+	0x04000004, 0x82040580, 0x00000039, 0x04020036,
+	0x4933c857, 0x4c500000, 0x4d1c0000, 0x4130a000,
+	0x40067000, 0x0201f800, 0x001093ba, 0x04020029,
+	0x0201f800, 0x0002075a, 0x04000026, 0x491fc857,
+	0x4933c857, 0x83380580, 0x00000035, 0x04000004,
+	0x83380580, 0x00000039, 0x04020002, 0x4932381c,
+	0x493a6403, 0x4a026203, 0x00000001, 0x4a026406,
+	0x00000001, 0x58500809, 0x4807c857, 0x48066009,
+	0x58500c15, 0x4807c857, 0x48066415, 0x58500a15,
+	0x4807c857, 0x48066215, 0x58500a16, 0x4807c857,
+	0x48066216, 0x58500c19, 0x4807c857, 0x48066419,
+	0x58500a19, 0x4807c857, 0x48066219, 0x491e601e,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x40526000, 0x5c023800, 0x5c00a000, 0x0201f000,
+	0x0002077d, 0x5930021d, 0x82000580, 0x00000003,
+	0x02000800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x4803c856, 0x4c500000, 0x4c540000, 0x412c7800,
+	0x4c3c0000, 0x42002800, 0x00000001, 0x82040480,
+	0x00000101, 0x04001003, 0x42000800, 0x00000100,
+	0x40043000, 0x42000800, 0x0000001c, 0x83cca400,
+	0x0000000c, 0x832cac00, 0x0000000d, 0x0401f844,
+	0x82183480, 0x0000001c, 0x592e5801, 0x812e59c0,
+	0x02020800, 0x001007fd, 0x0201f800, 0x001007e4,
+	0x04000017, 0x80142800, 0x4a025a04, 0x00000110,
+	0x497a5c04, 0x492c7801, 0x82180c80, 0x0000003d,
+	0x04021006, 0x40180800, 0x832cac00, 0x00000005,
+	0x0401f82f, 0x0401f00a, 0x82183480, 0x0000003c,
+	0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+	0x00000005, 0x0401f826, 0x0401f7e8, 0x5c007800,
+	0x841429c0, 0x82142d40, 0x00000003, 0x48147a04,
+	0x403e5800, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+	0x492fc857, 0x812e59c0, 0x0400000f, 0x4d2c0000,
+	0x4c3c0000, 0x592c7801, 0x803c79c0, 0x04000006,
+	0x497a5801, 0x0201f800, 0x000202da, 0x403e5800,
+	0x0401f7f9, 0x5c007800, 0x0201f800, 0x000202da,
+	0x5c025800, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x82040c00, 0x00000003, 0x8004b104, 0x0201f800,
+	0x0010ab17, 0x5c00b000, 0x1c01f000, 0x4803c856,
+	0x4c580000, 0x82040c00, 0x00000003, 0x8004b104,
+	0x0201f800, 0x0010ab17, 0x5c00b000, 0x1c01f000,
+	0x591c0c06, 0x82040580, 0x00000003, 0x04000004,
+	0x82040580, 0x00000002, 0x0402001a, 0x4d300000,
+	0x4d2c0000, 0x411e6000, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400000f, 0x4d400000, 0x42028000,
+	0x00000013, 0x592c0a08, 0x84040d54, 0x0201f800,
+	0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x0201f800, 0x0010912a,
+	0x0201f800, 0x00107911, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x59cc0005, 0x8c000500, 0x0402000b,
+	0x591c0406, 0x82000580, 0x00000002, 0x04020007,
+	0x591c0c03, 0x82040580, 0x00000085, 0x04000003,
+	0x82040580, 0x0000008b, 0x1c01f000, 0x4933c857,
+	0x4d3c0000, 0x42027800, 0x00000002, 0x59300406,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f80a, 0x5c027800, 0x1c01f000, 0x4933c857,
+	0x59300406, 0x82000c80, 0x00000012, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00108c01, 0x00108bfe,
+	0x00108bfe, 0x00108c29, 0x00108bfc, 0x00108bfe,
+	0x00108c1a, 0x00108bfe, 0x00108bfc, 0x001065f4,
+	0x00108bfe, 0x00108bfe, 0x00108bfe, 0x00108bfc,
+	0x00108bfc, 0x00108bfc, 0x00108cf9, 0x00108bfe,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x8d3e7d02, 0x04020016,
+	0x0201f800, 0x00109037, 0x0400000f, 0x59325808,
+	0x41780800, 0x4d400000, 0x42028000, 0x00000005,
+	0x0201f800, 0x00104e70, 0x5c028000, 0x0201f800,
+	0x0010959c, 0x0201f800, 0x001091cc, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x001048d9, 0x0402000c, 0x4d400000, 0x42028000,
+	0x00000010, 0x0201f800, 0x0010a1d1, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x5c028000,
+	0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0401f8b8, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00108c43,
+	0x00108cb0, 0x00108c5a, 0x00108cc3, 0x00108cab,
+	0x00108c41, 0x00108c43, 0x00108c43, 0x00108c47,
+	0x00108c43, 0x00108c43, 0x00108c43, 0x00108c43,
+	0x00108c5a, 0x0201f800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401f7b8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59300406, 0x82000580,
+	0x00000003, 0x040207b4, 0x59300203, 0x82000580,
+	0x0000000d, 0x040007b0, 0x8d3e7d02, 0x040207ae,
+	0x4d340000, 0x59326809, 0x0201f800, 0x001049b2,
+	0x5c026800, 0x0401f7a8, 0x59300004, 0x8400055c,
+	0x48026004, 0x0201f800, 0x00106c4b, 0x59300406,
+	0x82000580, 0x00000006, 0x04000043, 0x8d3e7d02,
+	0x04020041, 0x497a621d, 0x59300203, 0x82000580,
+	0x0000000d, 0x04000003, 0x4a02621d, 0x00000003,
+	0x0401fbcb, 0x04000024, 0x4d2c0000, 0x4d400000,
+	0x59325808, 0x0201f800, 0x001091cc, 0x592c0408,
+	0x8c000512, 0x04000009, 0x4d2c0000, 0x84000512,
+	0x48025c08, 0x592c0809, 0x40065800, 0x0201f800,
+	0x001007fd, 0x5c025800, 0x4d400000, 0x42028000,
+	0x00000005, 0x592c0a08, 0x8c040d0e, 0x04000004,
+	0x42028000, 0x00000002, 0x0401f001, 0x0201f800,
+	0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x497a6008, 0x5c028000,
+	0x5c025800, 0x8d3e7d00, 0x04000009, 0x4d340000,
+	0x59326809, 0x0201f800, 0x001049b2, 0x5c026800,
+	0x0201f800, 0x00107911, 0x0401f00b, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+	0x00020721, 0x5c03e000, 0x02020800, 0x00106c55,
+	0x82000540, 0x00000001, 0x1c01f000, 0x0201f800,
+	0x00106c4b, 0x0201f800, 0x00100e99, 0x0401f7ab,
+	0x598c000d, 0x81300580, 0x04020004, 0x0201f800,
+	0x00106e8e, 0x0402001b, 0x0201f800, 0x001068d3,
+	0x04020006, 0x59300c03, 0x82040580, 0x00000040,
+	0x0400078b, 0x0401f79d, 0x0201f800, 0x00106b6c,
+	0x04000010, 0x0201f800, 0x001005d8, 0x0401f813,
+	0x04020004, 0x0201f800, 0x00106e62, 0x04020009,
+	0x0201f800, 0x001067ae, 0x040207f4, 0x59300c03,
+	0x82040580, 0x00000040, 0x04000779, 0x0401f78b,
+	0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f75e, 0x417a3000, 0x42032000,
+	0x0000bf32, 0x59900004, 0x81300580, 0x04000009,
+	0x83932400, 0x00000010, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017f8, 0x82000540, 0x00000001,
+	0x1c01f000, 0x59300004, 0x8c00053e, 0x04000010,
+	0x8c00050c, 0x0402000e, 0x8c000516, 0x04020006,
+	0x82000d00, 0x0000001f, 0x82040580, 0x00000005,
+	0x04020004, 0x42000000, 0x00000003, 0x0401f005,
+	0x42000000, 0x00000001, 0x0401f002, 0x59300203,
+	0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00108d13,
+	0x00108d30, 0x00108d17, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x0201f800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401f6e8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x4d2c0000, 0x59325808,
+	0x59300403, 0x82000580, 0x00000052, 0x02000800,
+	0x00101231, 0x0401fb16, 0x02000800, 0x001005d8,
+	0x4a025a06, 0x00000005, 0x0201f800, 0x000202da,
+	0x0201f800, 0x00104c19, 0x0201f800, 0x00107911,
+	0x5c025800, 0x82000540, 0x00000001, 0x1c01f000,
+	0x598c000d, 0x81300580, 0x0402001a, 0x59300004,
+	0x8c000520, 0x04000004, 0x84000520, 0x48026004,
+	0x0401f01a, 0x42001000, 0x0010b7f6, 0x50081000,
+	0x58080002, 0x82000580, 0x00000100, 0x0400000a,
+	0x5808000c, 0x81300580, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+	0x0401f7cf, 0x0201f800, 0x00106e8e, 0x0402000c,
+	0x59300004, 0x8c000520, 0x04000004, 0x84000520,
+	0x48026004, 0x0401f7c6, 0x0201f800, 0x001068d3,
+	0x040007c3, 0x0201f800, 0x001005d8, 0x59300203,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f7a7, 0x59300406, 0x4933c857, 0x4803c857,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f001, 0x00108d7c, 0x00108e41, 0x00108f79,
+	0x00108d88, 0x00107911, 0x00108d7c, 0x0010a1c0,
+	0x0002077d, 0x00108e41, 0x001065ce, 0x00108fda,
+	0x00108d77, 0x00108d77, 0x00108d77, 0x00108d77,
+	0x00108d77, 0x001096eb, 0x001096eb, 0x0201f800,
+	0x001005d8, 0x0401fbd5, 0x02000000, 0x0010801c,
+	0x1c01f000, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00106c4b, 0x0201f000,
+	0x0002077d, 0x4a026206, 0x00000001, 0x1c01f000,
+	0x42000000, 0x0010b872, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401faa8,
+	0x04000007, 0x59325808, 0x592c0208, 0x8400054c,
+	0x48025a08, 0x42028000, 0x00000006, 0x0201f800,
+	0x00106c55, 0x0401ff4c, 0x4803c857, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f806,
+	0x0201f800, 0x00106c4b, 0x5c028000, 0x5c025800,
+	0x1c01f000, 0x00108e40, 0x00108db5, 0x00108dc3,
+	0x00108de5, 0x00108e11, 0x00108db3, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108db3, 0x00108db3,
+	0x00108db3, 0x00108db3, 0x00108dc3, 0x0201f800,
+	0x001005d8, 0x598c000d, 0x81300580, 0x04020004,
+	0x0201f800, 0x00106e8e, 0x04020038, 0x0201f800,
+	0x001068d3, 0x0400003b, 0x0201f800, 0x00106b6c,
+	0x04000032, 0x0201f800, 0x001005d8, 0x497a621d,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000014,
+	0x04000003, 0x4a02621d, 0x00000003, 0x592c0a08,
+	0x0201f800, 0x00104e70, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x497a6008, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x4a026004, 0x8000404b, 0x0201f800,
+	0x00106c4b, 0x42000800, 0x8000404b, 0x0201f000,
+	0x00020721, 0x0401fef1, 0x04020004, 0x0201f800,
+	0x00106e62, 0x04020009, 0x0201f800, 0x001067ae,
+	0x040207d2, 0x59300c03, 0x82040580, 0x00000040,
+	0x04000008, 0x0401f7d2, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ae,
+	0x0201f800, 0x00106c4b, 0x812e59c0, 0x04000013,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x0010959c, 0x0201f800, 0x000202da, 0x59300203,
+	0x82000580, 0x0000000d, 0x04000008, 0x0201f800,
+	0x00106c4b, 0x4d340000, 0x59326809, 0x0201f800,
+	0x001049b2, 0x5c026800, 0x0201f800, 0x00107911,
+	0x0401f030, 0x812e59c0, 0x02000800, 0x001005d8,
+	0x0201f800, 0x0010940a, 0x04020004, 0x0201f800,
+	0x00100e99, 0x0401f7aa, 0x0201f800, 0x00106c4b,
+	0x592c0208, 0x8400050c, 0x48025a08, 0x592c0406,
+	0x800000c2, 0x800008c4, 0x80040c00, 0x48066206,
+	0x42000000, 0x10000000, 0x41300800, 0x0201f800,
+	0x00100b94, 0x0400000d, 0x592c0208, 0x8c00051c,
+	0x04020006, 0x8400055c, 0x48025a08, 0x4a026206,
+	0x00000002, 0x0401f00f, 0x4d300000, 0x0201f800,
+	0x001012e5, 0x5c026000, 0x59300203, 0x82000580,
+	0x00000004, 0x04020007, 0x4d380000, 0x42027000,
+	0x00000048, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x1c01f000, 0x42000000, 0x0010b86e, 0x0201f800,
+	0x0010aa47, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x4803c857, 0x0c01f001,
+	0x00108e5a, 0x00108d85, 0x00108e5c, 0x00108e5a,
+	0x00108e5c, 0x00108e5c, 0x00108d7d, 0x00108e5a,
+	0x00108d79, 0x00108e5a, 0x00108e5a, 0x00108e5a,
+	0x00108e5a, 0x00108e5a, 0x0201f800, 0x001005d8,
+	0x4d340000, 0x4d2c0000, 0x59326809, 0x59340400,
+	0x82000500, 0x000000ff, 0x82000c80, 0x0000000c,
+	0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+	0x00000004, 0x04020004, 0x42000000, 0x00000001,
+	0x0401f006, 0x82180d80, 0x00000000, 0x04020003,
+	0x42000000, 0x00000001, 0x4803c857, 0x0c01f804,
+	0x5c025800, 0x5c026800, 0x1c01f000, 0x00108e83,
+	0x00108f22, 0x00108e85, 0x00108eba, 0x00108e85,
+	0x00108f3f, 0x00108e85, 0x00108e8f, 0x00108e83,
+	0x00108f3f, 0x00108e83, 0x00108e9e, 0x0201f800,
+	0x001005d8, 0x59300403, 0x82000d80, 0x00000016,
+	0x0400002e, 0x82000d80, 0x00000004, 0x0400002b,
+	0x82000d80, 0x00000002, 0x04000028, 0x0401fabf,
+	0x04000079, 0x59300403, 0x82000d80, 0x00000022,
+	0x040000ae, 0x82000d80, 0x00000039, 0x040000b3,
+	0x82000d80, 0x00000035, 0x040000b0, 0x82000d80,
+	0x0000001e, 0x0400001b, 0x0401f999, 0x04000007,
+	0x0201f800, 0x00109597, 0x04020004, 0x0201f800,
+	0x00104a14, 0x0401f011, 0x59300403, 0x82000d80,
+	0x00000001, 0x04020004, 0x0201f800, 0x001049e7,
+	0x0400000a, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010801c,
+	0x0201f000, 0x00107911, 0x0401f97d, 0x04000004,
+	0x0201f800, 0x00109597, 0x040000a9, 0x59300c03,
+	0x82040580, 0x00000016, 0x04000056, 0x82040580,
+	0x00000002, 0x04020034, 0x59a80026, 0x8c000502,
+	0x04020013, 0x0201f800, 0x0010513b, 0x04020010,
+	0x0201f800, 0x00105151, 0x04020006, 0x42000000,
+	0x00000001, 0x0201f800, 0x00105113, 0x0401f094,
+	0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f08d, 0x59340403,
+	0x82000580, 0x000007fc, 0x04000008, 0x59a80026,
+	0x8c00050a, 0x04020084, 0x59340212, 0x82000500,
+	0x0000ff00, 0x04000082, 0x59340412, 0x82000500,
+	0x000000ff, 0x04000010, 0x80000040, 0x48026c12,
+	0x497a6008, 0x4a026406, 0x00000007, 0x4a026206,
+	0x00000398, 0x497a6205, 0x0201f800, 0x0002075a,
+	0x04000005, 0x49366009, 0x4a026406, 0x00000001,
+	0x0401f020, 0x59300403, 0x82000d80, 0x00000002,
+	0x0402000d, 0x59340403, 0x82000580, 0x000007fe,
+	0x04020009, 0x59a80026, 0x84000540, 0x48035026,
+	0x0201f800, 0x00104237, 0x0201f800, 0x0010801c,
+	0x0401f00c, 0x0201f800, 0x0010801c, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00102074, 0x0201f000, 0x00107911,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+	0x0201f000, 0x0010672b, 0x0401f915, 0x04020793,
+	0x0201f800, 0x00102074, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x42003000,
+	0x00000018, 0x41782800, 0x42002000, 0x00000000,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x0201f000, 0x00107911, 0x0201f800,
+	0x00104a14, 0x0401f7c8, 0x42000000, 0x0010b86d,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00107b76,
+	0x040207c1, 0x1c01f000, 0x4d380000, 0x59327403,
+	0x0201f800, 0x001093ba, 0x5c027000, 0x02020000,
+	0x0002077d, 0x836c0580, 0x00000003, 0x04000004,
+	0x4a026206, 0x00000002, 0x1c01f000, 0x59300403,
+	0x48026416, 0x4a02621d, 0x00000001, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+	0x00020721, 0x0201f800, 0x00102074, 0x0201f800,
+	0x0010801c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x497a6008, 0x4a026406,
+	0x00000007, 0x4a026206, 0x00000398, 0x497a6205,
+	0x1c01f000, 0x42000000, 0x0010b870, 0x0201f800,
+	0x0010aa47, 0x4d340000, 0x59326809, 0x59300203,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x4803c857, 0x0c01f803, 0x5c026800, 0x1c01f000,
+	0x00108f96, 0x00108d85, 0x00108f96, 0x00108f96,
+	0x00108f96, 0x00108f96, 0x00108f96, 0x00108f96,
+	0x00108f96, 0x00108d85, 0x00108f98, 0x00108d85,
+	0x00108fa0, 0x00108f96, 0x0201f800, 0x001005d8,
+	0x4a026403, 0x0000008b, 0x4a026203, 0x0000000b,
+	0x42000800, 0x8000404b, 0x0201f000, 0x00020721,
+	0x59300a1d, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000011,
+	0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x41306800, 0x0201f800,
+	0x0002075a, 0x04000008, 0x49366009, 0x4d300000,
+	0x40366000, 0x0201f800, 0x00107911, 0x5c026000,
+	0x0401f002, 0x40366000, 0x497a6008, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+	0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+	0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+	0x42003000, 0x00000004, 0x4d400000, 0x42028000,
+	0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x1c01f000, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x42000000, 0x0010b876,
+	0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x0c01f001, 0x0010900b, 0x00108ff3, 0x00108ff7,
+	0x0010900c, 0x00108ff5, 0x00108ff3, 0x00108ff3,
+	0x00108ff3, 0x00108ff3, 0x00108ff3, 0x00108ff3,
+	0x00108ff3, 0x00108ff3, 0x00108ff3, 0x0201f800,
+	0x001005d8, 0x0201f800, 0x00100e99, 0x4d2c0000,
+	0x59325808, 0x4a025a06, 0x00000006, 0x0201f800,
+	0x000202da, 0x5c025800, 0x497a6008, 0x4a02621d,
+	0x0000000a, 0x4a026403, 0x00000085, 0x4a026203,
+	0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+	0x8000404b, 0x0201f000, 0x00020721, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0401fcc7,
+	0x04020004, 0x0201f800, 0x00106e62, 0x0402000c,
+	0x0201f800, 0x001067ae, 0x04020005, 0x5c03e000,
+	0x0201f800, 0x00106c4b, 0x0401f7dd, 0x0201f800,
+	0x00106b6c, 0x02020800, 0x001005d8, 0x5c03e000,
+	0x0201f800, 0x00106c4b, 0x59300203, 0x82000d80,
+	0x00000003, 0x02000800, 0x001005d8, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ba,
+	0x4803c856, 0x59a8000e, 0x59a80867, 0x80040400,
+	0x80080480, 0x04021004, 0x82000540, 0x00000001,
+	0x1c01f000, 0x80000580, 0x1c01f000, 0x4803c856,
+	0x4c080000, 0x59301008, 0x82081500, 0xfff00000,
+	0x5c001000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x0400000a, 0x0401f82f,
+	0x4d380000, 0x42027000, 0x0000004b, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x0400001b, 0x0401f81f,
+	0x4d300000, 0x0201f800, 0x00106c55, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00106ab4, 0x0201f800,
+	0x001067fd, 0x5c027800, 0x0201f800, 0x0010a2ff,
+	0x0201f800, 0x00106c4b, 0x5c026000, 0x8d3e7d3e,
+	0x0402000b, 0x4d380000, 0x42027000, 0x0000004c,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x0201f800,
+	0x0002077d, 0x0401f7fa, 0x592c0407, 0x494a6017,
+	0x494e6018, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000003, 0x800000c2, 0x800008c4, 0x80040400,
+	0x48026206, 0x1c01f000, 0x493bc857, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x0400000d, 0x0401ffef,
+	0x4d400000, 0x42028000, 0x00000005, 0x0401f80d,
+	0x5c028000, 0x8d3e7d3e, 0x04020007, 0x0201f800,
+	0x000207a1, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x0201f800, 0x0002077d, 0x0401f7fa,
+	0x4803c856, 0x0201f800, 0x00106c55, 0x4d3c0000,
+	0x4d440000, 0x59368c03, 0x42027800, 0x00000001,
+	0x0201f800, 0x001069b6, 0x0201f800, 0x0010692e,
+	0x0201f800, 0x001067fd, 0x0201f800, 0x0010a2ff,
+	0x5c028800, 0x5c027800, 0x0201f000, 0x00106c4b,
+	0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x0400000f, 0x481a601c, 0x48ee6021, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x0000001f, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000e, 0x48ee6021, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x00000055, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x0000003d, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+	0x492fc857, 0x4933c857, 0x592c0404, 0x8c00051e,
+	0x04000003, 0x48efc857, 0x48ee6021, 0x4a026406,
+	0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+	0x00000000, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+	0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x0400000f, 0x48ee6021, 0x481a601c, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x00000044, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x00000049, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x59300009, 0x80001540,
+	0x02000800, 0x001005d8, 0x5808040b, 0x4803c856,
+	0x80000040, 0x04001002, 0x4800140b, 0x1c01f000,
+	0x4803c856, 0x59300403, 0x82000d80, 0x00000002,
+	0x04000015, 0x82000d80, 0x00000003, 0x04000012,
+	0x82000d80, 0x00000004, 0x0400000f, 0x82000d80,
+	0x00000008, 0x0400000c, 0x82000d80, 0x0000000a,
+	0x04000009, 0x599c0819, 0x8c040d0e, 0x04000004,
+	0x82000d80, 0x00000000, 0x04000003, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x4c000000,
+	0x4d2c0000, 0x59300406, 0x82000580, 0x00000004,
+	0x0400001d, 0x59300008, 0x80025d40, 0x800001c0,
+	0x04000019, 0x0201f800, 0x00109597, 0x04000014,
+	0x59300406, 0x82004580, 0x00000010, 0x04000010,
+	0x82004580, 0x00000011, 0x0400000d, 0x82004580,
+	0x00000003, 0x0400000c, 0x82004580, 0x00000002,
+	0x04000009, 0x82004580, 0x0000000a, 0x04000006,
+	0x592c0404, 0x8c00051e, 0x04000003, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c000000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x04000013, 0x49366009,
+	0x48ee6021, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x4d380000, 0x42027000, 0x00000028,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856,
+	0x83380580, 0x00000015, 0x0402000d, 0x59a80016,
+	0x82000580, 0x00000074, 0x04020009, 0x0201f800,
+	0x0010462a, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000029, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010801c, 0x0201f000, 0x0002077d, 0x4803c856,
+	0x83380580, 0x00000016, 0x04020007, 0x42000800,
+	0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+	0x00107b38, 0x83380580, 0x00000015, 0x04020013,
+	0x59a80016, 0x82000580, 0x00000014, 0x0402000f,
+	0x0201f800, 0x0010468d, 0x0201f800, 0x0010846f,
+	0x0402000a, 0x59340404, 0x80000540, 0x04000007,
+	0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+	0x0201f000, 0x00107b38, 0x0201f800, 0x0010801c,
+	0x0201f000, 0x0002077d, 0x4803c856, 0x592c0206,
+	0x82000580, 0x00000005, 0x04000002, 0x1c01f000,
+	0x4803c856, 0x592c0208, 0x8400054a, 0x48025a08,
+	0x1c01f000, 0x497a6205, 0x497a6008, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000050, 0x42000800,
+	0x80000043, 0x0201f000, 0x00020721, 0x4933c857,
+	0x4d340000, 0x59326809, 0x59340200, 0x8c00050e,
+	0x04000006, 0x59300406, 0x82000c80, 0x00000012,
+	0x04021004, 0x0c01f806, 0x5c026800, 0x1c01f000,
+	0x0201f800, 0x00108d7c, 0x0401f7fc, 0x00108d7c,
+	0x001091fd, 0x00109201, 0x00109204, 0x0010a49b,
+	0x0010a4b8, 0x0010a4bc, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x4803c856, 0x40000000, 0x40000000,
+	0x1c01f000, 0x40000000, 0x40000000, 0x1c01f000,
+	0x5930001c, 0x4803c857, 0x59300414, 0x4933c857,
+	0x4803c857, 0x8c000502, 0x04000005, 0x84000502,
+	0x84000540, 0x48026414, 0x1c01f000, 0x42000000,
+	0xd0000000, 0x41300800, 0x0201f800, 0x00100b94,
+	0x0401f80a, 0x04020008, 0x59a80037, 0x82000400,
+	0x0000000a, 0x48026205, 0x59300414, 0x84000542,
+	0x48026414, 0x1c01f000, 0x4933c857, 0x4d340000,
+	0x59326809, 0x59340200, 0x8c00050e, 0x02000800,
+	0x001005d8, 0x5930001c, 0x80000540, 0x0402002f,
+	0x59a80021, 0x80000540, 0x0402002a, 0x4d1c0000,
+	0x41323800, 0x0201f800, 0x0002075a, 0x04000023,
+	0x4932381c, 0x591c0414, 0x84000542, 0x48023c14,
+	0x49366009, 0x591c0406, 0x82000580, 0x00000003,
+	0x04000006, 0x591c0202, 0x48026419, 0x591c0402,
+	0x48026219, 0x0401f005, 0x591c0202, 0x48026219,
+	0x591c0402, 0x48026419, 0x491e601e, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000035, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x411e6000, 0x5c023800, 0x80000580,
+	0x5c026800, 0x1c01f000, 0x411e6000, 0x5c023800,
+	0x59a80039, 0x48026205, 0x82000540, 0x00000001,
+	0x0401f7f8, 0x4933c857, 0x4d2c0000, 0x4932381c,
+	0x4a026202, 0x0000ffff, 0x591e5808, 0x591c0007,
+	0x8c00051e, 0x04000005, 0x8400051e, 0x48023807,
+	0x497a5c09, 0x0401f014, 0x592c0408, 0x8c000518,
+	0x04000011, 0x84000518, 0x48025c08, 0x4a025c09,
+	0x00000001, 0x0401fb2f, 0x497a5c09, 0x592c0408,
+	0x8c000512, 0x04000008, 0x4d2c0000, 0x84000512,
+	0x48025c08, 0x592e5809, 0x0201f800, 0x001007fd,
+	0x5c025800, 0x59a80039, 0x48026205, 0x591c0214,
+	0x48026216, 0x82000d80, 0x00000001, 0x04000008,
+	0x4a023a03, 0x00000002, 0x82000580, 0x00000005,
+	0x04000008, 0x497a6015, 0x0401f01e, 0x591c0007,
+	0x84000540, 0x48023807, 0x4a023a03, 0x00000004,
+	0x591c0414, 0x4803c857, 0x8400051c, 0x84000554,
+	0x48023c14, 0x592c000f, 0x40001000, 0x591c0816,
+	0x80040480, 0x040217f0, 0x591c0016, 0x82000500,
+	0xfffffffc, 0x48026015, 0x48023816, 0x591c0a14,
+	0x4807c857, 0x82040d80, 0x00000005, 0x04020005,
+	0x480bc857, 0x4803c857, 0x4a023812, 0xffffffff,
+	0x591c0402, 0x48026419, 0x591c0202, 0x48026219,
+	0x591e6809, 0x49366009, 0x4a026406, 0x00000001,
+	0x4a026403, 0x00000039, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x59300414,
+	0x8c000514, 0x04000015, 0x8c00051c, 0x04020012,
+	0x59300016, 0x80100480, 0x04001006, 0x04000005,
+	0x59300414, 0x84000514, 0x8400055c, 0x0401f009,
+	0x48126016, 0x48126012, 0x40100000, 0x592c180f,
+	0x800c0480, 0x48026011, 0x59300414, 0x84000514,
+	0x48026414, 0x1c01f000, 0x4933c857, 0x8c00051c,
+	0x04020006, 0x59300012, 0x48026016, 0x59300414,
+	0x8400055c, 0x48026414, 0x1c01f000, 0x59300c03,
+	0x4933c857, 0x4807c857, 0x82040480, 0x00000034,
+	0x04001006, 0x82040480, 0x0000003c, 0x04021003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x41780800, 0x59a81035, 0x42000000,
+	0x00000032, 0x0201f800, 0x001066a0, 0x800811c0,
+	0x04020003, 0x42001000, 0x00000014, 0x480b5037,
+	0x59a81036, 0x480b502d, 0x41780800, 0x42000000,
+	0x00000064, 0x0201f800, 0x001066a0, 0x800811c0,
+	0x04020003, 0x42001000, 0x00000014, 0x480b5038,
+	0x82081400, 0x0000000a, 0x480b5039, 0x42000800,
+	0x00000001, 0x0201f800, 0x00106c78, 0x42000000,
+	0x30000000, 0x40080800, 0x0201f800, 0x00100b68,
+	0x42000800, 0x00000003, 0x59a81010, 0x0201f800,
+	0x00106c78, 0x0201f000, 0x00104906, 0x4a035037,
+	0x00000028, 0x4a035038, 0x00000014, 0x4a03502d,
+	0x000007d0, 0x42001000, 0x0000001e, 0x480b5039,
+	0x42000800, 0x00000001, 0x0201f800, 0x00106c78,
+	0x42000000, 0x30000000, 0x40080800, 0x0201f800,
+	0x00100b68, 0x42000800, 0x00000003, 0x59a81010,
+	0x0201f000, 0x00106c78, 0x4933c857, 0x4d2c0000,
+	0x59300403, 0x82000580, 0x0000003e, 0x04020005,
+	0x59325817, 0x812e59c0, 0x02020800, 0x001007f4,
+	0x5c025800, 0x1c01f000, 0x4937c857, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x04000011, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x42000800,
+	0x00000009, 0x0201f800, 0x00104571, 0x4d380000,
+	0x42027000, 0x00000033, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c580000,
+	0x4d3c0000, 0x59325808, 0x83380580, 0x00000015,
+	0x04020022, 0x59a8b016, 0x82580c80, 0x00000019,
+	0x04001003, 0x4200b000, 0x00000018, 0x8058b104,
+	0x0401fa07, 0x80000580, 0x0401fa17, 0x832cac00,
+	0x00000009, 0x83cca400, 0x00000006, 0x0201f800,
+	0x0010ab17, 0x42027800, 0x00000001, 0x592c100a,
+	0x8c081518, 0x04020006, 0x59a80010, 0x592c100d,
+	0x80080580, 0x04020006, 0x417a7800, 0x59301009,
+	0x58081403, 0x0201f800, 0x001020a1, 0x0201f800,
+	0x00107b38, 0x0401f008, 0x4200b000, 0x00000002,
+	0x0401fa09, 0x0201f800, 0x0010801c, 0x0201f800,
+	0x0002077d, 0x5c027800, 0x5c00b000, 0x5c025800,
+	0x1c01f000, 0x4933c856, 0x49366009, 0x4a026406,
+	0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+	0x0000004d, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+	0x4d2c0000, 0x83380580, 0x00000015, 0x04020027,
+	0x59a80816, 0x59325808, 0x5930040b, 0x800000c4,
+	0x80040580, 0x04020021, 0x4c500000, 0x4c540000,
+	0x4c580000, 0x83cca400, 0x00000006, 0x4050a800,
+	0x5930b40b, 0x0201f800, 0x0010ab28, 0x83cca400,
+	0x00000006, 0x592cb205, 0x832cac00, 0x00000006,
+	0x0201f800, 0x0010ab17, 0x592e5801, 0x812e59c0,
+	0x040207f9, 0x5931d821, 0x58ef400b, 0x58ee580d,
+	0x4a025a04, 0x00000103, 0x58ec0009, 0x0801f800,
+	0x59300402, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x0201f800, 0x0010801c,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x83380580,
+	0x00000035, 0x04000005, 0x59301419, 0x0401f851,
+	0x04000027, 0x0401f006, 0x4d300000, 0x5932601e,
+	0x0401f856, 0x5c026000, 0x04000020, 0x591c0c06,
+	0x82040580, 0x00000003, 0x04000004, 0x82040580,
+	0x00000006, 0x0402001c, 0x591c0c02, 0x59300419,
+	0x80040580, 0x04000009, 0x59300219, 0x80040580,
+	0x04020015, 0x591c0a02, 0x59300419, 0x80040580,
+	0x04020011, 0x0401f009, 0x59300a19, 0x82040580,
+	0x0000ffff, 0x04000005, 0x591c0202, 0x59300a19,
+	0x80040580, 0x04020008, 0x591c0009, 0x59300809,
+	0x80040580, 0x1c01f000, 0x417a3800, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x59b800e4,
+	0x8c000538, 0x02020800, 0x001005d8, 0x42000800,
+	0x0000012c, 0x4a0370e4, 0x20000000, 0x59b800e4,
+	0x80040840, 0x02000800, 0x001005d8, 0x8c00053c,
+	0x040207f9, 0x4a0370e4, 0x30000000, 0x40000000,
+	0x40000000, 0x40000000, 0x59b800e4, 0x8c00053c,
+	0x040207f1, 0x1c01f000, 0x4803c856, 0x4a0370e4,
+	0x20000000, 0x40000000, 0x59b800e4, 0x8c000538,
+	0x040207fb, 0x1c01f000, 0x59300807, 0x8c040d1e,
+	0x592c0c08, 0x04020002, 0x8c040d18, 0x1c01f000,
+	0x0401fc1c, 0x04000008, 0x42000800, 0x00000024,
+	0x0201f800, 0x00106681, 0x82063c00, 0x0010d1c0,
+	0x491fc857, 0x1c01f000, 0x83300480, 0x0010d1c0,
+	0x0400100a, 0x59a8000b, 0x81300480, 0x04021007,
+	0x59301402, 0x0401ffef, 0x04000007, 0x411c0000,
+	0x81300580, 0x04000003, 0x81780500, 0x0401f002,
+	0x81300540, 0x1c01f000, 0x4947c857, 0x4d300000,
+	0x0201f800, 0x00020245, 0x0402000a, 0x42026000,
+	0x0010bde9, 0x49366009, 0x492e6008, 0x0201f800,
+	0x0010203c, 0x80000580, 0x5c026000, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fc, 0x4933c857,
+	0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+	0x4d2c0000, 0x4d340000, 0x4d440000, 0x4c580000,
+	0x59325808, 0x59326809, 0x49425a06, 0x0201f800,
+	0x00105755, 0x592e8c06, 0x592c4207, 0x82200500,
+	0x0000000f, 0x0c01f806, 0x5c00b000, 0x5c028800,
+	0x5c026800, 0x5c025800, 0x1c01f000, 0x00109466,
+	0x00109488, 0x0010948f, 0x00109493, 0x0010949c,
+	0x00109463, 0x00109463, 0x00109463, 0x001094a0,
+	0x001094ac, 0x001094ac, 0x00109463, 0x00109463,
+	0x00109463, 0x00109463, 0x00109463, 0x4803c857,
+	0x0201f800, 0x001005d8, 0x814281c0, 0x04020012,
+	0x41785800, 0x592c0404, 0x8c00051c, 0x04020002,
+	0x59345c05, 0x442c2800, 0x59340008, 0x48002802,
+	0x59340009, 0x48002801, 0x59340006, 0x48002804,
+	0x59340007, 0x48002803, 0x4200b000, 0x0000000b,
+	0x0401f037, 0x592c0207, 0x8c00051e, 0x4200b000,
+	0x00000002, 0x04020032, 0x8204b540, 0x00000000,
+	0x0400002f, 0x44042800, 0x59326809, 0x59340400,
+	0x48002801, 0x4200b000, 0x00000002, 0x0401f028,
+	0x814281c0, 0x04020030, 0x59345c05, 0x442c2800,
+	0x4200b000, 0x00000001, 0x0401f021, 0x8340b540,
+	0x00000000, 0x0400001e, 0x0401f027, 0x814281c0,
+	0x04020025, 0x59340200, 0x44002800, 0x59340001,
+	0x48002801, 0x4200b000, 0x00000002, 0x0401f014,
+	0x8340b540, 0x00000000, 0x0402001b, 0x0401f010,
+	0x8340b540, 0x00000000, 0x0400000d, 0x0201f800,
+	0x00104a1f, 0x04000014, 0x8c20450e, 0x04000002,
+	0x497a6009, 0x4178b000, 0x497a5a06, 0x0401f004,
+	0x8340b540, 0x00000000, 0x0402000b, 0x592c0404,
+	0x8400051c, 0x48025c04, 0x592c0207, 0x8400051e,
+	0x48025a07, 0x0401f8aa, 0x497a6008, 0x0201f000,
+	0x000202da, 0x592c0207, 0x8c00051e, 0x4200b000,
+	0x00000002, 0x040207f2, 0x8204b540, 0x00000000,
+	0x040007ef, 0x44042800, 0x4200b000, 0x00000001,
+	0x0401f7eb, 0x4937c857, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x04000011, 0x49366009, 0x4a026406,
+	0x00000001, 0x492e6008, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4d380000, 0x42027000,
+	0x00000043, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+	0x4937c857, 0x4d2c0000, 0x59325808, 0x83380580,
+	0x00000015, 0x04020025, 0x59a80016, 0x82000580,
+	0x00000004, 0x04020021, 0x59a80010, 0x592c1009,
+	0x80080580, 0x04020010, 0x4d440000, 0x592e8c06,
+	0x592c0207, 0x4803c856, 0x82000500, 0x00000080,
+	0x84000548, 0x4d3c0000, 0x42027800, 0x00001000,
+	0x0201f800, 0x001049bb, 0x5c027800, 0x5c028800,
+	0x0401f004, 0x4803c856, 0x0201f800, 0x00104a1f,
+	0x0201f800, 0x00109037, 0x04000017, 0x4d400000,
+	0x42028000, 0x00000000, 0x41780800, 0x0401ff38,
+	0x5c028000, 0x0401f00e, 0x0201f800, 0x00104a1f,
+	0x040207f4, 0x0201f800, 0x00109037, 0x0400000a,
+	0x4c580000, 0x4200b000, 0x00000002, 0x0401f86e,
+	0x5c00b000, 0x0201f800, 0x0010801c, 0x0201f800,
+	0x0002077d, 0x5c025800, 0x1c01f000, 0x4937c857,
+	0x4d300000, 0x0201f800, 0x0002075a, 0x04000012,
+	0x49366009, 0x4a026406, 0x00000001, 0x4d3c0000,
+	0x4d380000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x492e6008, 0x42027000, 0x00000004, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x5c027800, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x4937c857,
+	0x4d300000, 0x0201f800, 0x00107942, 0x0400000d,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x00000051, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x59325808, 0x83383580, 0x00000015, 0x04020011,
+	0x592c0008, 0x82000500, 0x00ffffff, 0x0402000a,
+	0x0201f800, 0x00105755, 0x59cc0000, 0x82000500,
+	0x00ffffff, 0x44002800, 0x4200b000, 0x00000001,
+	0x0401f80b, 0x0201f800, 0x00107b38, 0x0401f006,
+	0x4200b000, 0x00000002, 0x0401f823, 0x0201f800,
+	0x0010801c, 0x5c00b000, 0x1c01f000, 0x492fc857,
+	0x4c580000, 0x4c000000, 0x8058b1c0, 0x0400000b,
+	0x82580500, 0xfffffff0, 0x02020800, 0x001005d8,
+	0x8058b0d0, 0x592c0408, 0x82000500, 0xfffff0ff,
+	0x80580540, 0x48025c08, 0x5c000000, 0x5c00b000,
+	0x1c01f000, 0x492fc857, 0x4c000000, 0x4c040000,
+	0x800000d8, 0x592c0c08, 0x82040d00, 0xffff0fff,
+	0x80040540, 0x48025c08, 0x5c000800, 0x5c000000,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808,
+	0x592c0207, 0x8400055e, 0x48025a07, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x0401ffd9, 0x0201f800,
+	0x00105755, 0x46002800, 0x00000018, 0x80142800,
+	0x8058b040, 0x83cca400, 0x00000007, 0x4014a800,
+	0x0201f800, 0x0010ab17, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x5c025800, 0x1c01f000, 0x59325808,
+	0x592c0204, 0x82000580, 0x00000152, 0x1c01f000,
+	0x5930001f, 0x80000540, 0x02020800, 0x00100d56,
+	0x1c01f000, 0x4d2c0000, 0x59325808, 0x59300203,
+	0x4933c857, 0x492fc857, 0x493bc857, 0x4803c857,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001095bd,
+	0x001095c8, 0x00109603, 0x001095bd, 0x001095bd,
+	0x001095bd, 0x001095bd, 0x001095bd, 0x001095bf,
+	0x001095bd, 0x001095bd, 0x001095bd, 0x001095bd,
+	0x001095bd, 0x0201f800, 0x001005d8, 0x83383480,
+	0x00000056, 0x02021800, 0x001005d8, 0x493a6403,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x83380580, 0x00000013, 0x0402000f, 0x592c000c,
+	0x800001c0, 0x04000006, 0x4a026203, 0x00000002,
+	0x59a80037, 0x48026206, 0x1c01f000, 0x4a025a06,
+	0x00000000, 0x0201f800, 0x000202da, 0x0201f000,
+	0x0002077d, 0x83380580, 0x00000027, 0x0400001a,
+	0x83380580, 0x00000014, 0x04000012, 0x83380580,
+	0x00000015, 0x04000005, 0x83380580, 0x00000016,
+	0x02020800, 0x001005d8, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x02020800, 0x001005d8, 0x0401f014,
+	0x0201f800, 0x00106bbf, 0x4a02580e, 0x00000011,
+	0x0401f005, 0x0201f800, 0x00106bbf, 0x4a02580e,
+	0x00000010, 0x4a025a06, 0x00000031, 0x4a02580d,
+	0x00000004, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00104c19, 0x0201f000, 0x00107911, 0x59341400,
+	0x82081d00, 0x000000ff, 0x59300c03, 0x480bc857,
+	0x4807c857, 0x82040580, 0x00000053, 0x0400002e,
+	0x82040580, 0x00000002, 0x04000016, 0x82040580,
+	0x00000001, 0x04000017, 0x82040580, 0x00000003,
+	0x0400001c, 0x82040580, 0x00000005, 0x0400001d,
+	0x82040580, 0x00000033, 0x0400001a, 0x82040580,
+	0x00000000, 0x0400001b, 0x82040580, 0x00000004,
+	0x02020800, 0x001005d8, 0x0401f8a1, 0x0401f016,
+	0x820c0580, 0x00000003, 0x0400084c, 0x0401f012,
+	0x820c0580, 0x0000000b, 0x0402000f, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0401f00a,
+	0x820c0580, 0x00000005, 0x04000864, 0x0401f006,
+	0x820c0580, 0x00000009, 0x04000889, 0x0401f002,
+	0x0401f893, 0x4a026403, 0x00000052, 0x59a81016,
+	0x592c040b, 0x8c000500, 0x04000003, 0x42001000,
+	0x00000008, 0x592c040b, 0x8c000516, 0x04000003,
+	0x82081400, 0x00000018, 0x592c000c, 0x497a580d,
+	0x497a580e, 0x80080c80, 0x04000009, 0x04001005,
+	0x4a025a06, 0x00000007, 0x40001000, 0x0401f006,
+	0x4a025a06, 0x00000015, 0x0401f003, 0x4a025a06,
+	0x00000000, 0x480a580c, 0x82081400, 0x00000003,
+	0x80081104, 0x0201f800, 0x00107ab5, 0x04000010,
+	0x592c1001, 0x480a600b, 0x58080800, 0x82080400,
+	0x00000002, 0x592c1011, 0x592c1812, 0x42003000,
+	0x00000000, 0x42002000, 0x00101200, 0x0201f800,
+	0x00107c32, 0x04000002, 0x1c01f000, 0x4a025a06,
+	0x0000002c, 0x497a580c, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x83380580, 0x00000015,
+	0x0402000a, 0x59a80005, 0x8c000514, 0x0402000b,
+	0x0201f800, 0x0010462a, 0x42000800, 0x00000004,
+	0x0201f000, 0x00104571, 0x42000800, 0x00000007,
+	0x0201f000, 0x00104571, 0x0201f800, 0x0010513b,
+	0x42001000, 0x00000010, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x040007ec, 0x42001000, 0x00000008, 0x0201f800,
+	0x00104c6d, 0x040007e7, 0x592c040b, 0x84000540,
+	0x48025c0b, 0x0401f7e9, 0x83380580, 0x00000015,
+	0x0402000f, 0x59a80005, 0x8c000514, 0x04020010,
+	0x0201f800, 0x0010468d, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x00104567, 0x5c027800, 0x42000800,
+	0x00000006, 0x0201f000, 0x00104571, 0x42000800,
+	0x00000004, 0x0201f000, 0x00104571, 0x0201f800,
+	0x0010513b, 0x42001000, 0x00000010, 0x04020009,
+	0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+	0x00ff0000, 0x040007e7, 0x42001000, 0x00000008,
+	0x0201f800, 0x00104c6d, 0x040007e2, 0x592c040b,
+	0x84000540, 0x48025c0b, 0x0401f7e9, 0x42000800,
+	0x00000004, 0x0201f000, 0x00104571, 0x83380580,
+	0x00000015, 0x04020005, 0x0201f800, 0x0010a2c8,
+	0x02000800, 0x001048c1, 0x1c01f000, 0x83380580,
+	0x00000015, 0x0402001d, 0x4c580000, 0x83cc1400,
+	0x00000008, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000006, 0x0201f800, 0x0010855a, 0x04020012,
+	0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000008, 0x0201f800, 0x0010855a,
+	0x04020009, 0x59342200, 0x59cc1007, 0x800811c0,
+	0x04000003, 0x480a6801, 0x84102542, 0x8410251a,
+	0x48126a00, 0x5c00b000, 0x1c01f000, 0x42000000,
+	0x0010b87b, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00106c55, 0x59300203, 0x4933c857, 0x4803c857,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x0201f000, 0x00106c4b, 0x0010970b,
+	0x0010971a, 0x0010970c, 0x00109709, 0x00109709,
+	0x00109709, 0x00109709, 0x00109709, 0x00109709,
+	0x00109709, 0x00109709, 0x00109709, 0x00109709,
+	0x00109709, 0x0201f800, 0x001005d8, 0x1c01f000,
+	0x59300403, 0x82000580, 0x00000052, 0x02000000,
+	0x00108d85, 0x0201f800, 0x00104c19, 0x59325808,
+	0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+	0x0201f000, 0x00107911, 0x59301804, 0x840c0520,
+	0x48026004, 0x598c000d, 0x81300580, 0x04020010,
+	0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b7f6,
+	0x50081000, 0x58080002, 0x82000580, 0x00000100,
+	0x0400000e, 0x5808000c, 0x81300580, 0x02020800,
+	0x001005d8, 0x4978100c, 0x0401f003, 0x8c0c1d20,
+	0x040207dc, 0x0201f800, 0x001068d3, 0x040007d9,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x00106e8e,
+	0x040007f9, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f7bd, 0x4933c857,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x592c0c07,
+	0x4806580a, 0x59cc0809, 0x48065807, 0x59cc0a08,
+	0x4806580b, 0x59c80817, 0x82040500, 0x000003ff,
+	0x800010c4, 0x8c040d14, 0x04000005, 0x59cc0002,
+	0x82000500, 0x00000003, 0x80081480, 0x82080480,
+	0x000000f1, 0x02021800, 0x001005d8, 0x480a621a,
+	0x412c0800, 0x0201f800, 0x001007d3, 0x02000800,
+	0x001005d8, 0x492c0809, 0x58040408, 0x84000552,
+	0x84000540, 0x48000c08, 0x82081400, 0x00000003,
+	0x80081104, 0x83cca400, 0x00000006, 0x832cac00,
+	0x00000004, 0x42000800, 0x00000010, 0x82080480,
+	0x00000010, 0x04021003, 0x40080800, 0x80000580,
+	0x4004b000, 0x4c000000, 0x0201f800, 0x0010ab28,
+	0x5c000000, 0x800001c0, 0x0400000d, 0x412c1000,
+	0x4c000000, 0x0201f800, 0x001007d3, 0x02000800,
+	0x001005d8, 0x492c1001, 0x832cac00, 0x00000004,
+	0x5c000000, 0x40001000, 0x0401f7e9, 0x5c00b000,
+	0x5c00a800, 0x5c00a000, 0x1c01f000, 0x4933c857,
+	0x4d2c0000, 0x4c380000, 0x59325808, 0x5930021a,
+	0x48025a08, 0x59301011, 0x800811c0, 0x04020008,
+	0x4a025a06, 0x00000000, 0x592c000b, 0x82000500,
+	0x00000c00, 0x0400000b, 0x0401f00b, 0x8c08153e,
+	0x04000006, 0x4a025a06, 0x00000007, 0x80081080,
+	0x80081000, 0x0401f003, 0x4a025a06, 0x00000015,
+	0x480a5807, 0x42000000, 0x0010bed9, 0x50007000,
+	0x5838000b, 0x80000540, 0x04020008, 0x4930700c,
+	0x4930700b, 0x58380002, 0x82000580, 0x00000000,
+	0x04020809, 0x0401f005, 0x82001400, 0x00000000,
+	0x45301000, 0x4930700b, 0x5c007000, 0x5c025800,
+	0x1c01f000, 0x4933c857, 0x592c0009, 0x40001000,
+	0x4800700a, 0x82080400, 0x00000004, 0x48007003,
+	0x592c000d, 0x592c100e, 0x48007007, 0x48087008,
+	0x592c000a, 0x592c1208, 0x80080c80, 0x04001002,
+	0x40001000, 0x82081400, 0x00000003, 0x80081104,
+	0x82080480, 0x00000010, 0x04021003, 0x80000580,
+	0x0401f003, 0x42001000, 0x00000010, 0x4800700d,
+	0x48087004, 0x800810c4, 0x48087005, 0x40381000,
+	0x0201f800, 0x00100858, 0x1c01f000, 0x4d2c0000,
+	0x0201f800, 0x001007d3, 0x02000800, 0x001005d8,
+	0x42000800, 0x0010bed9, 0x452c0800, 0x497a580b,
+	0x497a580c, 0x497a580d, 0x4a025809, 0x001097ea,
+	0x4a025802, 0x00000100, 0x4a025801, 0x00000000,
+	0x5c025800, 0x1c01f000, 0x4833c857, 0x4d300000,
+	0x4d2c0000, 0x4c5c0000, 0x4030b800, 0x585c000a,
+	0x80025d40, 0x04020004, 0x585c000c, 0x4c000000,
+	0x0401f044, 0x585c0002, 0x82000580, 0x00000100,
+	0x04020022, 0x592c0801, 0x4c040000, 0x0201f800,
+	0x001007f4, 0x5c000800, 0x800409c0, 0x0400001c,
+	0x4804b80a, 0x585c100d, 0x800811c0, 0x04020005,
+	0x40065800, 0x0201f800, 0x001007fd, 0x0401f014,
+	0x82080480, 0x00000010, 0x04021003, 0x80000580,
+	0x0401f003, 0x42001000, 0x00000010, 0x4800b80d,
+	0x4808b804, 0x800810c4, 0x4808b805, 0x82040400,
+	0x00000004, 0x4800b803, 0x405c1000, 0x0201f800,
+	0x00100858, 0x0401f025, 0x0401f828, 0x585c000c,
+	0x80026540, 0x59300000, 0x80000d40, 0x04020002,
+	0x4800b80b, 0x4800b80c, 0x497a6000, 0x4c000000,
+	0x4978b80a, 0x59325808, 0x4a025a04, 0x00000103,
+	0x59300402, 0x48025c06, 0x592c100b, 0x4c080000,
+	0x0201f800, 0x000202c1, 0x0201f800, 0x0010912a,
+	0x5c001000, 0x8c081518, 0x04000004, 0x0201f800,
+	0x001091d1, 0x0401f003, 0x0201f800, 0x0002077d,
+	0x405c7000, 0x5c000000, 0x80026540, 0x04000003,
+	0x59325808, 0x0401ff78, 0x5c00b800, 0x5c025800,
+	0x5c026000, 0x1c01f000, 0x483bc857, 0x5838000a,
+	0x40025800, 0x0201f800, 0x001007fd, 0x5838000c,
+	0x80026540, 0x59300008, 0x80025d40, 0x4a025a06,
+	0x00000002, 0x1c01f000, 0x4803c857, 0x4d1c0000,
+	0x497a601c, 0x41323800, 0x40026000, 0x4d3c0000,
+	0x42027800, 0x00000005, 0x0401f83c, 0x5c027800,
+	0x411e6000, 0x59300414, 0x84000502, 0x48026414,
+	0x5c023800, 0x1c01f000, 0x481bc857, 0x4933c857,
+	0x4c5c0000, 0x4c600000, 0x4010b800, 0x4014c000,
+	0x0201f800, 0x0010a942, 0x0201f800, 0x00103b25,
+	0x04000008, 0x40602800, 0x405c3000, 0x0201f800,
+	0x0010a446, 0x82000540, 0x00000001, 0x0401f002,
+	0x80000580, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x4803c856, 0x4d300000, 0x42026000, 0x0010d1c0,
+	0x59a8000e, 0x81640580, 0x04000016, 0x59300c06,
+	0x82040580, 0x00000001, 0x04000009, 0x82040580,
+	0x00000004, 0x04000006, 0x82040580, 0x00000010,
+	0x02000800, 0x00108cf9, 0x0401f005, 0x4807c857,
+	0x0201f800, 0x001092d7, 0x04020808, 0x83326400,
+	0x00000024, 0x41580000, 0x81300480, 0x040017e9,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x59300403,
+	0x4803c857, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x59300406, 0x4803c857, 0x82000d80, 0x00000002,
+	0x04000018, 0x82000d80, 0x00000001, 0x04000009,
+	0x82000d80, 0x00000004, 0x04000006, 0x4933c856,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x0401f03c,
+	0x59300203, 0x82000d80, 0x00000001, 0x04000018,
+	0x82000d80, 0x00000002, 0x04000026, 0x82000d80,
+	0x00000005, 0x04000023, 0x0201f800, 0x001005d8,
+	0x59300203, 0x82000d80, 0x00000009, 0x0400000c,
+	0x82000d80, 0x0000000b, 0x04000009, 0x82000d80,
+	0x0000000a, 0x04000017, 0x82000d80, 0x0000000c,
+	0x04000014, 0x0201f800, 0x001005d8, 0x598c000d,
+	0x81300580, 0x04020004, 0x0201f800, 0x00106e8e,
+	0x0402000c, 0x59300004, 0x4803c857, 0x8c000520,
+	0x04000004, 0x84000520, 0x48026004, 0x0401f005,
+	0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x59300406,
+	0x82000d80, 0x00000002, 0x04000009, 0x0201f800,
+	0x00104c19, 0x0201f800, 0x0010914e, 0x02000800,
+	0x0010801c, 0x8d3e7d00, 0x04000003, 0x0201f000,
+	0x00107911, 0x4a02621d, 0x00000001, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+	0x00020721, 0x4933c857, 0x59368c03, 0x4c180000,
+	0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f803, 0x5c003000, 0x1c01f000,
+	0x0010990a, 0x00109dcf, 0x00109edb, 0x0010990a,
+	0x0010990a, 0x0010990a, 0x0010990a, 0x0010990a,
+	0x0010992d, 0x0010990a, 0x0010990a, 0x0010990a,
+	0x0010990a, 0x0010990a, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x42028800, 0x0000ffff, 0x813669c0,
+	0x04000002, 0x59368c03, 0x4c180000, 0x59300203,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c003000, 0x1c01f000, 0x00109929,
+	0x0010a180, 0x00109929, 0x00109929, 0x00109929,
+	0x00109929, 0x00109929, 0x0010a952, 0x0010a0ed,
+	0x0010a52c, 0x0010a562, 0x0010a52c, 0x0010a562,
+	0x00109929, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x001005d8, 0x83383480, 0x00000051, 0x02021800,
+	0x001005d8, 0x41380000, 0x493bc857, 0x4d1c0000,
+	0x4d400000, 0x0c01f804, 0x5c028000, 0x5c023800,
+	0x1c01f000, 0x0010998a, 0x00109b69, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x00109b74, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x001099ac, 0x001099f5, 0x00109a0c, 0x00109a62,
+	0x00109ac6, 0x00109b04, 0x00109b34, 0x0010998a,
+	0x0010998a, 0x00109b7c, 0x0010998a, 0x0010998a,
+	0x00109b8a, 0x00109b93, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x00109c15,
+	0x0010998a, 0x0010998a, 0x00109a9a, 0x0010998a,
+	0x0010998a, 0x00109bec, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x00109c23, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x00109c6c, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x00109cb9, 0x0010998a, 0x00109ce5, 0x00109cf0,
+	0x0010998a, 0x0010998a, 0x0010998c, 0x00109cfb,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010999b,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x00109d02,
+	0x00109d0a, 0x00109d28, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x0201f800, 0x0010a592, 0x040203a4,
+	0x0201f800, 0x0010210a, 0x040203a1, 0x59cc0407,
+	0x4802601c, 0x4a026403, 0x00000045, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x4933c857,
+	0x0201f800, 0x0010a592, 0x04020395, 0x0201f800,
+	0x0010210a, 0x04020392, 0x0401fbce, 0x040201a0,
+	0x59cc0007, 0x4802601c, 0x4a026403, 0x0000004a,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x04020009,
+	0x0201f800, 0x001048ec, 0x04020006, 0x82000500,
+	0x00000009, 0x82000580, 0x00000008, 0x04020008,
+	0x4a026403, 0x00000009, 0x4a02641a, 0x00000009,
+	0x4a02621a, 0x00000000, 0x0401f1b2, 0x0201f800,
+	0x001048c1, 0x0201f800, 0x00104a09, 0x04000021,
+	0x0201f800, 0x001049ed, 0x0400001e, 0x0201f800,
+	0x0010a252, 0x04020025, 0x42028000, 0x00000029,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x0201f800, 0x0010462a, 0x836c0580,
+	0x00000002, 0x04020004, 0x59a8001b, 0x80000000,
+	0x4803501b, 0x4a026403, 0x00000008, 0x42003000,
+	0x00000003, 0x0201f800, 0x00103b25, 0x04000191,
+	0x4a026203, 0x00000007, 0x41782800, 0x0401f180,
+	0x0201f800, 0x0010a3da, 0x040207e1, 0x4a026403,
+	0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a,
+	0x00001900, 0x0401f183, 0x4a026403, 0x00000009,
+	0x4a02641a, 0x00000003, 0x4a02621a, 0x00000f00,
+	0x0401f17c, 0x4933c857, 0x0201f800, 0x0010210a,
+	0x0402033b, 0x0201f800, 0x001048ec, 0x04020338,
+	0x493a6403, 0x0201f800, 0x0010a22d, 0x04020006,
+	0x42003000, 0x00000005, 0x4a026403, 0x00000006,
+	0x0401f7d9, 0x4a026403, 0x00000007, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00000000, 0x0401f165,
+	0x4933c857, 0x0201f800, 0x001048ec, 0x04020324,
+	0x0201f800, 0x0010a592, 0x02000800, 0x0010210a,
+	0x0402031f, 0x0201f800, 0x00104a09, 0x04020005,
+	0x42027800, 0x00000001, 0x0201f800, 0x00104567,
+	0x0201f800, 0x001049fc, 0x0402002b, 0x59cc0206,
+	0x82003500, 0x00000003, 0x0402002e, 0x82003480,
+	0x00000014, 0x0400102b, 0x5934300a, 0x84183516,
+	0x82000580, 0x00000014, 0x04020002, 0x84183556,
+	0x481a680a, 0x59cc0406, 0x82000500, 0x00000003,
+	0x04020020, 0x0201f800, 0x0010a29f, 0x04020028,
+	0x0201f800, 0x001049e7, 0x0402000c, 0x417a7800,
+	0x0201f800, 0x001020a1, 0x42003000, 0x00000006,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b865,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010468d,
+	0x4a026403, 0x0000000a, 0x42003000, 0x00000020,
+	0x0401f795, 0x4a026403, 0x0000000b, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001e00, 0x0401f121,
+	0x42000000, 0x0010b860, 0x0201f800, 0x0010aa47,
+	0x4a026403, 0x0000000b, 0x4a02641a, 0x00000007,
+	0x4a02621a, 0x00000000, 0x0401f116, 0x4a026403,
+	0x0000000b, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00000000, 0x0401f10f, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x040202ce, 0x0201f800, 0x0010a592,
+	0x040202cb, 0x0201f800, 0x0010210a, 0x040202c8,
+	0x59cc0206, 0x82003500, 0x00000003, 0x0402001d,
+	0x82003480, 0x00000014, 0x0400101a, 0x59cc0406,
+	0x82000500, 0x00000003, 0x04020016, 0x59340400,
+	0x82000580, 0x00000707, 0x04000019, 0x417a7800,
+	0x0201f800, 0x001020a1, 0x42003000, 0x0000000a,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b862,
+	0x0201f800, 0x0010aa47, 0x4a026403, 0x0000000c,
+	0x41782800, 0x42003000, 0x00000021, 0x0401f752,
+	0x4a026403, 0x0000000d, 0x4a02641a, 0x00000007,
+	0x4a02621a, 0x00000000, 0x0401f0de, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00001e00, 0x0401f0d7, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x04020296, 0x0201f800, 0x0010a592,
+	0x04020293, 0x0201f800, 0x0010210a, 0x04020290,
+	0x0401facc, 0x0402001a, 0x493a6403, 0x4c5c0000,
+	0x0401fad2, 0x0402000e, 0x4a026403, 0x0000002e,
+	0x405c2800, 0x42003000, 0x00000024, 0x0201f800,
+	0x00103b25, 0x0400000c, 0x4a026203, 0x00000007,
+	0x405c2800, 0x5c00b800, 0x0401f0ad, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000007, 0x4a02621a,
+	0x00000000, 0x5c00b800, 0x0401f0b2, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00001e00, 0x0401f0ab, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x040206ef, 0x59a80026, 0x82000500,
+	0x00000009, 0x82000580, 0x00000008, 0x040006e9,
+	0x0201f800, 0x001049fc, 0x0402002d, 0x0201f800,
+	0x0010a2a7, 0x04020007, 0x4a026403, 0x0000000e,
+	0x41782800, 0x42003000, 0x00000052, 0x0401f702,
+	0x4933c857, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+	0x48026a00, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00103b25, 0x04000076,
+	0x42003000, 0x00000007, 0x0401f062, 0x4933c857,
+	0x4a026403, 0x0000000f, 0x4a02641a, 0x00000003,
+	0x4a02621a, 0x00001e00, 0x0401f072, 0x59340400,
+	0x82000580, 0x00000703, 0x040007f5, 0x0401f040,
+	0x4933c857, 0x0201f800, 0x001048ec, 0x0402022c,
+	0x59a80026, 0x82000500, 0x00000009, 0x82000580,
+	0x00000008, 0x04000226, 0x0201f800, 0x001049f3,
+	0x0402002f, 0x0201f800, 0x0010a2c8, 0x02000800,
+	0x0010a252, 0x04020007, 0x4a026403, 0x00000010,
+	0x41782800, 0x42003000, 0x00000050, 0x0401f6c2,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+	0x0401f7c5, 0x4a026403, 0x00000011, 0x4a02641a,
+	0x00000003, 0x4a02621a, 0x00001e00, 0x0401f03d,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x02000800,
+	0x0010a592, 0x040201fa, 0x0401fa36, 0x04020008,
+	0x4a026403, 0x00000012, 0x0401f032, 0x59340400,
+	0x82000580, 0x00000703, 0x040007eb, 0x4d3c0000,
+	0x417a7800, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000017,
+	0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00103b25,
+	0x04000015, 0x42003000, 0x00000006, 0x41782800,
+	0x42028000, 0x00000029, 0x4933c857, 0x4a026403,
+	0x00000001, 0x4a026203, 0x00000007, 0x0201f800,
+	0x0010a974, 0x0201f000, 0x0010a43e, 0x42028000,
+	0x00000046, 0x0201f800, 0x0010a974, 0x0201f000,
+	0x0010a43e, 0x4933c857, 0x4a026403, 0x00000001,
+	0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x4933c857, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x4a026403, 0x00000005, 0x0401f7f5,
+	0x0201f800, 0x0010a592, 0x040201b5, 0x0201f800,
+	0x0010210a, 0x040201b2, 0x0401f9ee, 0x040207c0,
+	0x4a026403, 0x00000020, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x0201f800, 0x0010210a,
+	0x040201a7, 0x4a026403, 0x00000023, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010a592, 0x02000800, 0x0010210a, 0x0402019c,
+	0x0401f9d8, 0x040207aa, 0x40300800, 0x59a81010,
+	0x59cc0007, 0x82000500, 0x00ffffff, 0x80080580,
+	0x04000019, 0x59cc1408, 0x0201f800, 0x0010902c,
+	0x0400002d, 0x59cc0c08, 0x4d300000, 0x0201f800,
+	0x00105dd7, 0x41323800, 0x5c026000, 0x04000026,
+	0x591c0202, 0x82000580, 0x0000ffff, 0x04000005,
+	0x59cc1208, 0x591c0202, 0x80080580, 0x0402001e,
+	0x591c0406, 0x82000580, 0x00000007, 0x0402001a,
+	0x0401f02c, 0x59cc1208, 0x82080580, 0x0000ffff,
+	0x0400000c, 0x0201f800, 0x00109410, 0x04000012,
+	0x59cc1408, 0x591c0202, 0x80080580, 0x0402000e,
+	0x591c0009, 0x81340580, 0x04000016, 0x0401f00a,
+	0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a405,
+	0x04020010, 0x59cc1208, 0x82080580, 0x0000ffff,
+	0x04000019, 0x4a026403, 0x00000026, 0x4a02621a,
+	0x00001700, 0x59cc1204, 0x82081580, 0x0000ffff,
+	0x04020798, 0x4a026403, 0x00000025, 0x0401f795,
+	0x591c0406, 0x82000580, 0x00000007, 0x040207f2,
+	0x591c0403, 0x82000580, 0x00000024, 0x04020006,
+	0x4d300000, 0x411e6000, 0x0201f800, 0x0002077d,
+	0x5c026000, 0x4a026403, 0x00000025, 0x0401f785,
+	0x4933c857, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x5c00b000, 0x04000004, 0x4a026403, 0x00000031,
+	0x0401f770, 0x0201f800, 0x00107911, 0x0201f800,
+	0x0010513b, 0x0402000f, 0x0201f800, 0x00105149,
+	0x04020008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0201f800, 0x001050a2, 0x0401f005,
+	0x42000000, 0x00000001, 0x0201f800, 0x00105113,
+	0x1c01f000, 0x0201f800, 0x0010210a, 0x0402011c,
+	0x0401f958, 0x0402072a, 0x493a6403, 0x0401f996,
+	0x04020004, 0x4a026403, 0x0000002b, 0x0401f751,
+	0x4a026403, 0x0000002c, 0x0401f74e, 0x4933c857,
+	0x0201f800, 0x0010210a, 0x0402010d, 0x0201f800,
+	0x001049e7, 0x04020740, 0x0201f800, 0x001048d9,
+	0x0400003c, 0x59cc0408, 0x48026419, 0x59cc0208,
+	0x48026219, 0x59cc0807, 0x59340002, 0x82000500,
+	0x00ffffff, 0x80040580, 0x04000012, 0x59a80010,
+	0x80040580, 0x04020021, 0x59cc1408, 0x0201f800,
+	0x00109410, 0x04000023, 0x0201f800, 0x0010a4ca,
+	0x04000020, 0x0201f800, 0x0010a921, 0x0400001d,
+	0x491e601e, 0x4a026403, 0x00000036, 0x0401f0e6,
+	0x59cc1208, 0x82080580, 0x0000ffff, 0x04000009,
+	0x0201f800, 0x00109410, 0x04000012, 0x591c0202,
+	0x59cc0c08, 0x80040580, 0x0402000e, 0x0401f7eb,
+	0x59cc1408, 0x41327800, 0x0201f800, 0x0010a405,
+	0x04000008, 0x0401f7e5, 0x4803c856, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001500, 0x0401f006,
+	0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00001700, 0x4a026403, 0x00000037, 0x0401f0c6,
+	0x4803c856, 0x4a026403, 0x00000012, 0x0401f0c2,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x040200c4,
+	0x0201f800, 0x001049e7, 0x040206f7, 0x0201f800,
+	0x001048d9, 0x0400003e, 0x59cc0407, 0x48026419,
+	0x59cc1207, 0x480a6219, 0x82080580, 0x0000ffff,
+	0x04000005, 0x0201f800, 0x00109410, 0x0400002c,
+	0x0401f006, 0x59cc1407, 0x41327800, 0x0201f800,
+	0x0010a405, 0x04000026, 0x59cc0c07, 0x591c0202,
+	0x80040580, 0x04020022, 0x4d300000, 0x411e6000,
+	0x0201f800, 0x00108bd7, 0x5c026000, 0x59cc0c09,
+	0x82040d00, 0x0000ff00, 0x840409c0, 0x0201f800,
+	0x0010a921, 0x04000016, 0x82040580, 0x00000001,
+	0x0400000a, 0x82040580, 0x00000005, 0x04000004,
+	0x82040580, 0x00000007, 0x04020007, 0x591c0008,
+	0x80000540, 0x04000004, 0x59cc2808, 0x0201f000,
+	0x0010a4de, 0x4803c856, 0x4a02641a, 0x00000009,
+	0x4a02621a, 0x00002a00, 0x0401f006, 0x4803c856,
+	0x4a02641a, 0x00000003, 0x4a02621a, 0x00000300,
+	0x4a026403, 0x0000003b, 0x0401f07b, 0x4803c856,
+	0x4a02641a, 0x0000000b, 0x4a02621a, 0x00000000,
+	0x0401f7f8, 0x4c080000, 0x0201f800, 0x001048ec,
+	0x04000026, 0x0201f800, 0x001048c1, 0x0201f800,
+	0x0010a601, 0x0402001e, 0x59a80026, 0x82000540,
+	0x00000003, 0x48035026, 0x59a8001d, 0x800000d0,
+	0x59a80810, 0x82040d00, 0x000000ff, 0x80041540,
+	0x480b5010, 0x42000800, 0x00000003, 0x0201f800,
+	0x00106c78, 0x497b5028, 0x0201f800, 0x00103b25,
+	0x04000003, 0x4a032804, 0x000007d0, 0x8c00050a,
+	0x0402000a, 0x0201f800, 0x0002077d, 0x0201f800,
+	0x00101e45, 0x5c001000, 0x1c01f000, 0x0201f800,
+	0x0010a623, 0x0401f7fc, 0x5c001000, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x0010210a, 0x0402004c,
+	0x0201f800, 0x0010a628, 0x4a026403, 0x00000047,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x0201f800, 0x0010210a, 0x04020041, 0x0201f800,
+	0x0010a628, 0x4a026403, 0x00000047, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010210a, 0x04020036, 0x0201f800, 0x0010a628,
+	0x0201f000, 0x0002077d, 0x0401f834, 0x04000030,
+	0x4a026403, 0x0000004e, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x4a026403, 0x0000004f,
+	0x497a601c, 0x59cc0a06, 0x82040d00, 0x000000ff,
+	0x800409c0, 0x0400065f, 0x82040580, 0x00000001,
+	0x04020005, 0x59cc0808, 0x59a80005, 0x80040580,
+	0x04000658, 0x82040580, 0x00000002, 0x0402000a,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x0400064c, 0x4a02601c, 0x00000001, 0x0401f649,
+	0x4a026403, 0x00000050, 0x59cc0207, 0x4802601c,
+	0x0401f644, 0x4a026203, 0x00000001, 0x42000800,
+	0x80000040, 0x0201f000, 0x00020721, 0x4803c857,
+	0x0201f000, 0x0002077d, 0x4d2c0000, 0x4c500000,
+	0x4c580000, 0x4c540000, 0x59a80016, 0x82000c80,
+	0x00000829, 0x04021029, 0x0201f800, 0x001007d3,
+	0x04000026, 0x492e6008, 0x59a80016, 0x80000104,
+	0x48025802, 0x83cca400, 0x00000006, 0x82000c80,
+	0x0000000b, 0x04001013, 0x4a025811, 0x0000000b,
+	0x4200b000, 0x0000000b, 0x832c0400, 0x00000005,
+	0x4000a800, 0x0201f800, 0x0010ab17, 0x412c7000,
+	0x0201f800, 0x001007d3, 0x04000010, 0x492c7001,
+	0x40040000, 0x800409c0, 0x04000009, 0x0401f7ec,
+	0x48025811, 0x4000b000, 0x832c0400, 0x00000005,
+	0x4000a800, 0x0201f800, 0x0010ab17, 0x82000540,
+	0x00000001, 0x0401f006, 0x497b5016, 0x59325808,
+	0x0201f800, 0x001007fd, 0x80000580, 0x5c00a800,
+	0x5c00b000, 0x5c00a000, 0x5c025800, 0x1c01f000,
+	0x4d340000, 0x59326809, 0x59343400, 0x4933c857,
+	0x4937c857, 0x481bc857, 0x0201f800, 0x001049f3,
+	0x5c026800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x4d3c0000, 0x0401f840, 0x0402002c, 0x59cc0207,
+	0x82000d00, 0x0000ff00, 0x900411c0, 0x59cc000a,
+	0x82000500, 0x00ffffff, 0x80081540, 0x480a601c,
+	0x8c040d18, 0x0400000e, 0x42003000, 0x00000008,
+	0x0201f800, 0x0010a932, 0x42000000, 0x0010b863,
+	0x0201f800, 0x0010aa47, 0x4200b800, 0x00000002,
+	0x42027800, 0x00000001, 0x0401f011, 0x4178b800,
+	0x8c040d1a, 0x04000011, 0x59cc000a, 0x0201f800,
+	0x00105c9a, 0x0402000d, 0x42003000, 0x00000009,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b863,
+	0x0201f800, 0x0010aa47, 0x417a7800, 0x0201f800,
+	0x001020a1, 0x0401f004, 0x82000540, 0x00000001,
+	0x0401f002, 0x80000580, 0x5c027800, 0x5c00b800,
+	0x1c01f000, 0x4933c857, 0x59cc0206, 0x82000480,
+	0x00000010, 0x04021006, 0x4a02621a, 0x00000000,
+	0x82000540, 0x00000001, 0x0401f002, 0x80000580,
+	0x1c01f000, 0x4933c857, 0x4a02621a, 0x00000000,
+	0x59cc0407, 0x82000500, 0x0000ff00, 0x82000580,
+	0x00000800, 0x04020009, 0x59cc0006, 0x82000500,
+	0x00ff0000, 0x82000d80, 0x00140000, 0x04000003,
+	0x82000d80, 0x00100000, 0x1c01f000, 0x4933c857,
+	0x59300403, 0x82003480, 0x00000051, 0x02021800,
+	0x001005d8, 0x83383580, 0x00000013, 0x04020003,
+	0x4803c857, 0x0c01f012, 0x83383580, 0x00000027,
+	0x04000005, 0x83383580, 0x00000014, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001048c1, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x00107911, 0x00109e3c,
+	0x00109e45, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e45, 0x00109e50, 0x00109ecd, 0x00109e95,
+	0x00109ecd, 0x00109ead, 0x00109ecd, 0x00109ebe,
+	0x00109ecd, 0x00109ec6, 0x00109ecd, 0x00109ec6,
+	0x00109ecd, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e45, 0x00109e3c, 0x00109ecd,
+	0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109e3c,
+	0x00109eca, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109ecd,
+	0x00109e3c, 0x00109ec3, 0x00109ecd, 0x00109e3c,
+	0x00109e4a, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109ec9, 0x00109ecd, 0x00109e3c,
+	0x00109e3c, 0x00109ecd, 0x00109ecd, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3e, 0x00109e3c, 0x00109e3e, 0x00109e3c,
+	0x00109e3c, 0x00109e3e, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3e, 0x00109e3e, 0x00109e3e,
+	0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x59a80037, 0x48026206, 0x4a026203,
+	0x00000002, 0x1c01f000, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x00104567, 0x5c027800, 0x0401f07e,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x59a80026, 0x8c000508, 0x04000012, 0x59326809,
+	0x4c580000, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83341400, 0x00000006, 0x0201f800,
+	0x0010855a, 0x80000540, 0x5c00b000, 0x0402006a,
+	0x59340200, 0x8400051a, 0x48026a00, 0x0401f01b,
+	0x599c0017, 0x8c00050a, 0x04020063, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x59340212, 0x82000500, 0x0000ff00, 0x04000056,
+	0x599c0019, 0x8c00050e, 0x04020053, 0x416c0000,
+	0x82000580, 0x00000002, 0x04020004, 0x59a8001b,
+	0x80000000, 0x4803501b, 0x42000800, 0x00000003,
+	0x0201f800, 0x00104571, 0x4a026406, 0x00000001,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+	0x0201f800, 0x0010672b, 0x4ce80000, 0x4201d000,
+	0x00000001, 0x0201f800, 0x00105fae, 0x5c01d000,
+	0x1c01f000, 0x0201f800, 0x001049f3, 0x04000036,
+	0x0201f800, 0x0010645e, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0201f800, 0x0010a96a,
+	0x0402002d, 0x42000800, 0x00000005, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000003, 0x0201f000,
+	0x0010672b, 0x42000800, 0x00000006, 0x0401f820,
+	0x59303009, 0x599c0017, 0x8c00050a, 0x0402001a,
+	0x59a80026, 0x8c000508, 0x04000017, 0x0201f800,
+	0x001049e7, 0x04000014, 0x59a8001b, 0x80000000,
+	0x4803501b, 0x0401f7c5, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0401f792, 0x42000800,
+	0x00000004, 0x0401f006, 0x0201f800, 0x001048c1,
+	0x0401f005, 0x0401f004, 0x0401f003, 0x0201f800,
+	0x00104571, 0x0201f000, 0x0002077d, 0x4933c857,
+	0x4807c857, 0x0201f800, 0x00104571, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+	0x0201f800, 0x00102074, 0x1c01f000, 0x4933c857,
+	0x59340400, 0x80000110, 0x82003480, 0x0000000c,
+	0x02021800, 0x001005d8, 0x83383580, 0x00000015,
+	0x04020002, 0x0c01f006, 0x83383580, 0x00000016,
+	0x02020800, 0x001005d8, 0x0c01f00d, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x00109f30, 0x00109f03, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x00109f30, 0x00109f37, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x4933c857,
+	0x599c0017, 0x8c00050a, 0x0402001b, 0x813669c0,
+	0x04000019, 0x59340212, 0x82000500, 0x0000ff00,
+	0x04000015, 0x599c0019, 0x8c00050e, 0x04020012,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x5c027800, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+	0x0010672b, 0x59cc0001, 0x0201f800, 0x00105c9a,
+	0x0402000b, 0x0201f800, 0x00020245, 0x02020000,
+	0x0002077d, 0x59345002, 0x0201f800, 0x001042b4,
+	0x482a6802, 0x0201f000, 0x0002077d, 0x1c01f000,
+	0x4933c857, 0x59303403, 0x82183580, 0x0000001e,
+	0x02000000, 0x0002077d, 0x1c01f000, 0x4933c857,
+	0x0201f800, 0x001083df, 0x02020000, 0x0002077d,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+	0x0201f000, 0x0010672b, 0x493bc857, 0x83380580,
+	0x00000051, 0x0402000b, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x0400006d, 0x0201f800, 0x001005d8,
+	0x83380580, 0x00000027, 0x04000014, 0x83380580,
+	0x00000048, 0x04000006, 0x83380580, 0x00000014,
+	0x0400000e, 0x02020800, 0x001005d8, 0x0201f800,
+	0x00106f60, 0x02020000, 0x00107974, 0x59300203,
+	0x82000580, 0x00000004, 0x02000000, 0x0002086e,
+	0x0201f800, 0x001005d8, 0x59300403, 0x82000c80,
+	0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x40027000,
+	0x4803c857, 0x0c01f001, 0x00109f76, 0x00109f78,
+	0x00109f78, 0x00109f93, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x59325808, 0x812e59c0,
+	0x04000016, 0x832c0500, 0x00ff0000, 0x04000013,
+	0x4a026203, 0x00000002, 0x59326809, 0x59340200,
+	0x8c00050e, 0x0402000d, 0x42028000, 0x00000004,
+	0x0201f800, 0x0010a3ef, 0x497a6008, 0x59300206,
+	0x80000540, 0x04020003, 0x59a80038, 0x48026206,
+	0x4a026203, 0x00000007, 0x1c01f000, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00109037, 0x02000000,
+	0x00107911, 0x59325808, 0x0201f800, 0x001007f4,
+	0x0201f000, 0x00107911, 0x0201f800, 0x001005d8,
+	0x59325808, 0x592c040a, 0x8c000502, 0x04000007,
+	0x4a026203, 0x00000007, 0x42027000, 0x00000043,
+	0x0201f000, 0x000207a1, 0x4a026203, 0x00000004,
+	0x1c01f000, 0x0201f800, 0x0010a597, 0x02000000,
+	0x0002086c, 0x1c01f000, 0x4a026203, 0x00000001,
+	0x4a026403, 0x00000041, 0x42027800, 0x80002042,
+	0x0201f000, 0x00020721, 0x83380580, 0x00000051,
+	0x04000006, 0x83380580, 0x00000041, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x0201f800, 0x000206fd,
+	0x0201f800, 0x0010a5df, 0x0201f000, 0x0002077d,
+	0x83380480, 0x00000050, 0x02021800, 0x001005d8,
+	0x83380480, 0x00000049, 0x02001800, 0x001005d8,
+	0x0c01f001, 0x00109fda, 0x00109ffb, 0x00109fd8,
+	0x00109fd8, 0x00109fd8, 0x00109fd8, 0x00109ffb,
+	0x0201f800, 0x001005d8, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400000d, 0x82000d00, 0x000000c0,
+	0x82040d80, 0x00000080, 0x0400000d, 0x59300804,
+	0x8c040d18, 0x0402000a, 0x42027000, 0x00000041,
+	0x0201f000, 0x0002088d, 0x4a026203, 0x00000007,
+	0x497a6206, 0x0201f000, 0x000206fd, 0x59325808,
+	0x592c0c0a, 0x8c040d1a, 0x04020005, 0x0201f800,
+	0x000206fd, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x0010a597, 0x040007fa, 0x1c01f000, 0x0201f800,
+	0x00106b8a, 0x59325808, 0x59326809, 0x59340200,
+	0x8c00050e, 0x0400000e, 0x592c040a, 0x82000500,
+	0x000000c0, 0x82000580, 0x00000080, 0x04000005,
+	0x592c000f, 0x59301815, 0x800c1c80, 0x480e6015,
+	0x4a026203, 0x00000002, 0x0401f00d, 0x42028000,
+	0x00000004, 0x0401fbde, 0x59300206, 0x80000540,
+	0x04020004, 0x59a80038, 0x800000c2, 0x48026206,
+	0x497a6008, 0x4a026203, 0x00000007, 0x1c01f000,
+	0x4a026203, 0x00000007, 0x497a6206, 0x0201f000,
+	0x000206fd, 0x4a026203, 0x00000007, 0x497a6206,
+	0x0201f000, 0x000206f8, 0x59300414, 0x8c00051c,
+	0x02020000, 0x0002087e, 0x59325808, 0x592c200f,
+	0x40080000, 0x80102480, 0x59300015, 0x80102400,
+	0x48126015, 0x0201f000, 0x0002087e, 0x8c040d0e,
+	0x0402000a, 0x4a026203, 0x00000006, 0x0401f823,
+	0x5930001f, 0x80000540, 0x02020800, 0x00100d7c,
+	0x0201f000, 0x000206f8, 0x4a026203, 0x00000002,
+	0x1c01f000, 0x42000800, 0x00000001, 0x0201f800,
+	0x00100d7c, 0x82040580, 0x00000001, 0x02000000,
+	0x00020885, 0x0401f7d8, 0x59300414, 0x8c00051c,
+	0x04000006, 0x0201f800, 0x00100b63, 0x02000000,
+	0x00020877, 0x1c01f000, 0x59300011, 0x80000540,
+	0x04020005, 0x0201f800, 0x00100b63, 0x02000000,
+	0x00020877, 0x1c01f000, 0x492fc857, 0x480bc857,
+	0x8c08153e, 0x04000006, 0x80081080, 0x80081000,
+	0x42000800, 0x00000009, 0x0401f003, 0x42000800,
+	0x00000015, 0x480a580b, 0x1c01f000, 0x83380580,
+	0x00000013, 0x04000005, 0x83380580, 0x00000014,
+	0x02020800, 0x001005d8, 0x59300414, 0x8c000516,
+	0x02000800, 0x001005d8, 0x1c01f000, 0x0201f800,
+	0x001005d8, 0x59300008, 0x80000540, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x59300414, 0x8c000516,
+	0x02000800, 0x001005d8, 0x1c01f000, 0x4a026203,
+	0x00000004, 0x493a6403, 0x42000800, 0x80002001,
+	0x0201f000, 0x00020721, 0x4a026203, 0x00000003,
+	0x493a6403, 0x0201f800, 0x000200c9, 0x59325808,
+	0x592c040a, 0x8c00051e, 0x04000012, 0x82000500,
+	0x000000c0, 0x82000580, 0x00000080, 0x04000011,
+	0x59300414, 0x8c000512, 0x0402000a, 0x8c000510,
+	0x04020008, 0x592c040c, 0x80000540, 0x04020005,
+	0x82080d40, 0x80003065, 0x0201f000, 0x00106721,
+	0x82080d40, 0x80002065, 0x0201f000, 0x00106721,
+	0x82080d40, 0x80002042, 0x0201f000, 0x00106721,
+	0x4933c857, 0x493bc857, 0x83380480, 0x00000044,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000041,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x0010a0b6,
+	0x0010a0c6, 0x0010a0db, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400001d, 0x82001d00, 0x000000c0,
+	0x820c1d80, 0x000000c0, 0x04000018, 0x4a026203,
+	0x00000001, 0x493a6403, 0x42000800, 0x80002042,
+	0x0201f000, 0x00020721, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400000d, 0x82001d00, 0x000000c0,
+	0x820c1d80, 0x000000c0, 0x04000008, 0x4a026203,
+	0x00000001, 0x493a6403, 0x42000800, 0x80002001,
+	0x0201f000, 0x00020721, 0x497a6008, 0x497a6206,
+	0x42028000, 0x00000004, 0x0401f315, 0x59325808,
+	0x592c040a, 0x8c00051e, 0x040007f8, 0x82001d00,
+	0x000000c0, 0x820c1d80, 0x000000c0, 0x040007f3,
+	0x4a026203, 0x00000003, 0x493a6403, 0x0201f800,
+	0x000200c9, 0x82080d40, 0x80002065, 0x0201f000,
+	0x00106721, 0x4933c857, 0x493bc857, 0x83380580,
+	0x00000085, 0x04000006, 0x83380580, 0x00000088,
+	0x0400000a, 0x0201f800, 0x001005d8, 0x4a026203,
+	0x00000009, 0x493a6403, 0x42000800, 0x8000004b,
+	0x0201f000, 0x00020721, 0x4d1c0000, 0x813669c0,
+	0x04000004, 0x0201f800, 0x0010a592, 0x04020044,
+	0x59cc1404, 0x0401f846, 0x04000018, 0x591c0406,
+	0x82000500, 0x0000001f, 0x82002580, 0x00000006,
+	0x04000007, 0x82002580, 0x00000004, 0x0400002e,
+	0x82002580, 0x00000011, 0x0402000c, 0x497a3a05,
+	0x42002000, 0x00000054, 0x0201f800, 0x00107a4a,
+	0x4a026203, 0x00000007, 0x493a6403, 0x0201f800,
+	0x0010a974, 0x0401f02c, 0x0201f800, 0x00103b25,
+	0x04000004, 0x42023800, 0xffffffff, 0x0401f7f1,
+	0x813669c0, 0x04020009, 0x59cc0001, 0x0201f800,
+	0x00105c9a, 0x0402001e, 0x0201f800, 0x001045a6,
+	0x0402001b, 0x49366009, 0x4a026403, 0x00000087,
+	0x59cc1204, 0x82081580, 0x0000ffff, 0x04020003,
+	0x4a026403, 0x00000086, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x0401f00d, 0x591c0203, 0x82000580, 0x00000007,
+	0x040207de, 0x4d300000, 0x411e6000, 0x0201f800,
+	0x00107911, 0x5c026000, 0x0401f7d8, 0x0201f800,
+	0x00107911, 0x5c023800, 0x1c01f000, 0x4933c857,
+	0x480bc857, 0x42002800, 0x0010d1c0, 0x41300000,
+	0x80140580, 0x04000017, 0x58140203, 0x82000580,
+	0x00000000, 0x04000013, 0x58140202, 0x80080580,
+	0x04020010, 0x58141c06, 0x820c0580, 0x00000005,
+	0x0400000c, 0x820c0580, 0x00000009, 0x0400001d,
+	0x59302009, 0x58140009, 0x800001c0, 0x0400000b,
+	0x801021c0, 0x04000003, 0x80100580, 0x04000010,
+	0x82142c00, 0x00000024, 0x41540000, 0x80140480,
+	0x0402100e, 0x0401f7e2, 0x5814001e, 0x801021c0,
+	0x04000005, 0x58102002, 0x82102500, 0x00ffffff,
+	0x0401f7f2, 0x5810201e, 0x0401f7f0, 0x40163800,
+	0x81300540, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x58141807, 0x8c0c1d10, 0x040207ea, 0x0401f7e1,
+	0x4933c857, 0x493bc857, 0x83380580, 0x00000013,
+	0x0402000e, 0x59300403, 0x82000c80, 0x00000085,
+	0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+	0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+	0x4803c857, 0x0c01f018, 0x83380580, 0x00000027,
+	0x04000005, 0x83380580, 0x00000014, 0x02020000,
+	0x00107974, 0x0201f800, 0x00106bbf, 0x59325808,
+	0x812e59c0, 0x02000000, 0x00107911, 0x4a025a06,
+	0x00000031, 0x4a025811, 0x00000004, 0x4a025812,
+	0x000000ff, 0x0201f800, 0x000202da, 0x0201f000,
+	0x00107911, 0x0010a1b7, 0x0010a1be, 0x0010a1be,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b9, 0x0201f800,
+	0x001005d8, 0x59325808, 0x4a025a06, 0x00000000,
+	0x0201f800, 0x000202da, 0x0201f000, 0x00107911,
+	0x4933c857, 0x42000000, 0x0010b873, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x0010a5df, 0x497a6205,
+	0x42028000, 0x0000000b, 0x0401f807, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x497a6206,
+	0x1c01f000, 0x4933c857, 0x4943c857, 0x59300406,
+	0x82000580, 0x00000007, 0x04020002, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+	0x00108ce5, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x0010a205, 0x0010a209,
+	0x0010a1f0, 0x0010a217, 0x0010a22a, 0x0010a1f0,
+	0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+	0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+	0x4d400000, 0x5930001f, 0x80000540, 0x04000005,
+	0x41400800, 0x0201f800, 0x00100d7c, 0x40068000,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x040209f3, 0x4c5c0000, 0x5930b809, 0x0201f800,
+	0x00107911, 0x485e6009, 0x5c00b800, 0x5c025800,
+	0x5c028000, 0x5c03e000, 0x02000000, 0x00106c4b,
+	0x1c01f000, 0x598c000d, 0x81300580, 0x04020004,
+	0x0201f800, 0x00106e8e, 0x04020016, 0x0201f800,
+	0x001068d3, 0x040007df, 0x0201f800, 0x00106b6c,
+	0x04000010, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x00108cd6, 0x04020004, 0x0201f800, 0x00106e62,
+	0x04020008, 0x0201f800, 0x001067ae, 0x040007d1,
+	0x0201f800, 0x00106b6c, 0x02020800, 0x001005d8,
+	0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f7b9, 0x0201f800, 0x00100e99,
+	0x0401f7c4, 0x4933c857, 0x4d440000, 0x4d340000,
+	0x59cc0007, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x0402001a, 0x59300009, 0x4c000000,
+	0x49366009, 0x42003000, 0x0000000b, 0x0201f800,
+	0x0010a942, 0x42000000, 0x0010b861, 0x0201f800,
+	0x0010aa47, 0x4d3c0000, 0x4d400000, 0x42028000,
+	0x00000029, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c028000, 0x5c027800, 0x5c000000, 0x48026009,
+	0x59cc0007, 0x48026802, 0x80000580, 0x5c026800,
+	0x5c028800, 0x1c01f000, 0x4933c857, 0x4c040000,
+	0x59a80016, 0x82000580, 0x00000074, 0x04020040,
+	0x59cc0a08, 0x82040480, 0x00000100, 0x04001033,
+	0x59cc0c08, 0x82040500, 0x00008000, 0x04000035,
+	0x59a80032, 0x80000540, 0x04020009, 0x59301009,
+	0x58080212, 0x82000500, 0x0000ff00, 0x04000004,
+	0x82040500, 0x00000800, 0x0400002a, 0x59cc0c09,
+	0x80040840, 0x04001024, 0x59a80826, 0x8c040d06,
+	0x04000004, 0x59cc0c0f, 0x8c040d1e, 0x04020012,
+	0x59cc0a17, 0x800409c0, 0x04020012, 0x59cc0a18,
+	0x82040480, 0x00000100, 0x04001014, 0x59cc0c18,
+	0x800409c0, 0x0402000e, 0x59cc0c19, 0x80040840,
+	0x04001011, 0x59cc0c1a, 0x80040840, 0x04001011,
+	0x0401f018, 0x4a02621a, 0x00000100, 0x0401f012,
+	0x4a02621a, 0x00000300, 0x0401f00f, 0x4a02621a,
+	0x00000500, 0x0401f00c, 0x4a02621a, 0x00000700,
+	0x0401f009, 0x4a02621a, 0x00000900, 0x0401f006,
+	0x4a02621a, 0x00000f00, 0x0401f003, 0x4a02621a,
+	0x00002d00, 0x82000540, 0x00000001, 0x0401f002,
+	0x80000580, 0x5c000800, 0x1c01f000, 0x59cc0407,
+	0x4803c857, 0x82000580, 0x00000800, 0x04000003,
+	0x4a02621a, 0x00000000, 0x1c01f000, 0x4933c857,
+	0x4c040000, 0x4c080000, 0x4c0c0000, 0x4c580000,
+	0x59cc000c, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x04020012, 0x83cc1400, 0x00000008,
+	0x4200b000, 0x00000002, 0x83341c00, 0x00000006,
+	0x0201f800, 0x0010855a, 0x04020009, 0x83cc1400,
+	0x0000000a, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+	0x5c001800, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x4933c857, 0x4c000000, 0x4c040000, 0x4c080000,
+	0x4c0c0000, 0x4c580000, 0x59cc0001, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x00020245, 0x04020014,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x0402000c, 0x83cc1400, 0x0000000d, 0x4200b000,
+	0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+	0x0010855a, 0x04000014, 0x4933c856, 0x4933c856,
+	0x4933c857, 0x59340009, 0x4803c857, 0x5934000e,
+	0x4803c857, 0x59340008, 0x4803c857, 0x5934000d,
+	0x4803c857, 0x59340007, 0x4803c857, 0x5934000c,
+	0x4803c857, 0x59340006, 0x4803c857, 0x5934000b,
+	0x4803c857, 0x5c00b000, 0x5c001800, 0x5c001000,
+	0x5c000800, 0x5c000000, 0x1c01f000, 0x4933c857,
+	0x4947c857, 0x4943c857, 0x4c600000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d2c0000, 0x4d300000,
+	0x4d340000, 0x4130c000, 0x42026000, 0x0010d1c0,
+	0x59a8000e, 0x8060c1c0, 0x04000005, 0x82601580,
+	0x0010bde9, 0x04000002, 0x80000040, 0x81640480,
+	0x040210be, 0x40600000, 0x81300580, 0x040000b6,
+	0x0401f97a, 0x040200b4, 0x59326809, 0x59300406,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f001, 0x0010a3cd, 0x0010a338, 0x0010a351,
+	0x0010a35c, 0x0010a335, 0x0010a34c, 0x0010a387,
+	0x0010a3cd, 0x0010a333, 0x0010a39a, 0x0010a3ae,
+	0x0010a333, 0x0010a333, 0x0010a333, 0x0010a333,
+	0x0010a3cd, 0x0010a3c4, 0x0010a3bc, 0x0201f800,
+	0x001005d8, 0x59300420, 0x8c000500, 0x04020096,
+	0x59300403, 0x82000580, 0x00000043, 0x04000092,
+	0x0201f800, 0x00109134, 0x04000007, 0x0201f800,
+	0x0010914e, 0x0402008a, 0x0201f800, 0x0010801c,
+	0x0401f087, 0x0201f800, 0x00102074, 0x0201f800,
+	0x0010914e, 0x02000800, 0x0010801c, 0x0401f080,
+	0x8d3e7d18, 0x04000004, 0x59300420, 0x8c000500,
+	0x0402007d, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000077, 0x49425a06, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x0201f800, 0x0010912a, 0x0401f070,
+	0x8d3e7d00, 0x04000007, 0x59300017, 0x81480580,
+	0x0402006d, 0x59300018, 0x814c0580, 0x0402006a,
+	0x59300203, 0x82000580, 0x00000004, 0x02000800,
+	0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+	0x0400005f, 0x4a025a04, 0x00000103, 0x59300004,
+	0x8400055c, 0x48026004, 0x592c0408, 0x8c000512,
+	0x04000007, 0x4d2c0000, 0x592c0009, 0x40025800,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x49425a06,
+	0x497a5c09, 0x0401fb16, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+	0x0201f800, 0x0010912a, 0x0401f045, 0x8d3e7d18,
+	0x04000045, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400003a, 0x49425a06, 0x497a5c09,
+	0x0401faff, 0x0201f800, 0x0010959c, 0x0201f800,
+	0x000202da, 0x0401f032, 0x0201f800, 0x001062d5,
+	0x04000031, 0x59300203, 0x82000580, 0x00000004,
+	0x0400002d, 0x59300203, 0x82000580, 0x00000003,
+	0x04020029, 0x0201f800, 0x00106b8a, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000021, 0x0201f800,
+	0x000202da, 0x0401f01e, 0x59300203, 0x82000580,
+	0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000015, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0401f010,
+	0x833c0500, 0x00001800, 0x0400000f, 0x8d3e7d16,
+	0x0402000d, 0x59325817, 0x0201f800, 0x001007fd,
+	0x59325808, 0x0201f800, 0x00109037, 0x04000004,
+	0x49425a06, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00107911, 0x83326400, 0x00000024, 0x41580000,
+	0x81300480, 0x0400173b, 0x5c026800, 0x5c026000,
+	0x5c025800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x5c00c000, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x5c00b000, 0x80000540, 0x1c01f000, 0x492fc857,
+	0x4943c857, 0x59a8000c, 0x812c0480, 0x04001011,
+	0x59a8000d, 0x812c0480, 0x0402100e, 0x592c0000,
+	0x80005d40, 0x04000008, 0x497a5800, 0x49425a06,
+	0x4c2c0000, 0x0201f800, 0x000202da, 0x5c025800,
+	0x0401f7f7, 0x49425a06, 0x0201f000, 0x000202da,
+	0x1c01f000, 0x493fc857, 0x4933c857, 0x480bc857,
+	0x0201f800, 0x00103b25, 0x0400002e, 0x41502800,
+	0x813e79c0, 0x04020006, 0x59a80066, 0x80000000,
+	0x59a8086a, 0x80040580, 0x04000026, 0x41300000,
+	0x80140580, 0x0400001a, 0x58140203, 0x82000580,
+	0x00000000, 0x04000016, 0x58140202, 0x80080580,
+	0x04020013, 0x58141c06, 0x820c0580, 0x00000005,
+	0x0400000f, 0x820c0580, 0x00000009, 0x04000017,
+	0x59300009, 0x58142009, 0x801021c0, 0x04020006,
+	0x5814201e, 0x59301809, 0x580c0002, 0x82000500,
+	0x00ffffff, 0x80100580, 0x04000007, 0x82142c00,
+	0x00000024, 0x41540000, 0x80140480, 0x04021005,
+	0x0401f7df, 0x40163800, 0x81300540, 0x0401f002,
+	0x80000580, 0x1c01f000, 0x58141807, 0x8c0c1d10,
+	0x040207f3, 0x0401f7e7, 0x42002000, 0x0000ffff,
+	0x59301009, 0x800811c0, 0x04000002, 0x58082403,
+	0x41301000, 0x0401f007, 0x41781000, 0x41442000,
+	0x0401f004, 0x41781000, 0x42002000, 0x0000ffff,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x480bc857,
+	0x4813c857, 0x492fc857, 0x4943c857, 0x4d2c0000,
+	0x0201f800, 0x001007e4, 0x02000800, 0x001005d8,
+	0x4a025a04, 0x0000010d, 0x800811c0, 0x04000017,
+	0x83400580, 0x00000029, 0x04020010, 0x82180580,
+	0x00000002, 0x0400000a, 0x82180580, 0x00000003,
+	0x04000007, 0x82180580, 0x00000008, 0x04000004,
+	0x82180580, 0x00000009, 0x04020004, 0x4a025809,
+	0xffffffff, 0x0401f002, 0x480a5809, 0x58080202,
+	0x48025c13, 0x0401f005, 0x4a025809, 0xffffffff,
+	0x4a025c13, 0x0000ffff, 0x49425a08, 0x48125a06,
+	0x82100580, 0x0000ffff, 0x0400000e, 0x4d440000,
+	0x4d340000, 0x40128800, 0x0201f800, 0x00020245,
+	0x02020800, 0x001005d8, 0x59340002, 0x82000500,
+	0x00ffffff, 0x48025812, 0x5c026800, 0x5c028800,
+	0x497a5800, 0x497a5c04, 0x83400580, 0x00000046,
+	0x04020002, 0x48165a07, 0x481a5c08, 0x0401fbed,
+	0x5c025800, 0x1c01f000, 0x59300809, 0x800409c0,
+	0x04000004, 0x58040403, 0x81440580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fd, 0x4933c857,
+	0x4c040000, 0x59300403, 0x82000d80, 0x0000001e,
+	0x04020016, 0x800000d0, 0x59300a16, 0x82040d00,
+	0x000000ff, 0x80040540, 0x4803c857, 0x48026416,
+	0x4a026403, 0x00000085, 0x4a026203, 0x00000009,
+	0x4a026406, 0x00000005, 0x4a02621d, 0x00000004,
+	0x59a80038, 0x48026206, 0x42000800, 0x8000004b,
+	0x0201f800, 0x00020721, 0x5c000800, 0x1c01f000,
+	0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+	0x59300414, 0x4933c857, 0x4803c857, 0x8c000518,
+	0x04000009, 0x8c000512, 0x02020000, 0x0010921e,
+	0x0401f91b, 0x0201f800, 0x000206fd, 0x0201f800,
+	0x0002077d, 0x1c01f000, 0x591c0406, 0x4803c857,
+	0x82000c80, 0x00000009, 0x0402100b, 0x0c01f001,
+	0x0010a4d9, 0x0010a4d9, 0x0010a4d9, 0x0010a4db,
+	0x0010a4d9, 0x0010a4db, 0x0010a4db, 0x0010a4d9,
+	0x0010a4db, 0x80000580, 0x1c01f000, 0x82000540,
+	0x00000001, 0x1c01f000, 0x591c0406, 0x82000500,
+	0x0000001f, 0x82000580, 0x00000006, 0x0400000e,
+	0x4803c857, 0x4a026403, 0x0000003b, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00002a00, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f000,
+	0x00020721, 0x4803c856, 0x4c040000, 0x4c140000,
+	0x4d300000, 0x411e6000, 0x0401f8e9, 0x497a6205,
+	0x59300414, 0x4803c857, 0x82000500, 0xffffadff,
+	0x48026414, 0x497a6405, 0x5c026000, 0x0201f800,
+	0x001007e4, 0x02000800, 0x001005d8, 0x5c002800,
+	0x5c000800, 0x4a025a04, 0x0000010d, 0x497a5800,
+	0x497a5c04, 0x4a025a08, 0x00000045, 0x491e5809,
+	0x59300402, 0x48025c07, 0x59300419, 0x48025c0b,
+	0x591c0414, 0x84000556, 0x48023c14, 0x591c1809,
+	0x580c0403, 0x48025a06, 0x4816580a, 0x48065a0b,
+	0x0401f99d, 0x4d400000, 0x42028000, 0x00000045,
+	0x591c0202, 0x4c000000, 0x4d300000, 0x411e6000,
+	0x0401fcb1, 0x5c026000, 0x5c000000, 0x48023a02,
+	0x5c028000, 0x4a023c06, 0x00000006, 0x4a023a03,
+	0x00000007, 0x497a3a06, 0x497a3a05, 0x1c01f000,
+	0x4933c857, 0x83380580, 0x00000013, 0x0402000b,
+	0x59300403, 0x4803c857, 0x82000d80, 0x00000085,
+	0x0400002b, 0x82000d80, 0x0000008b, 0x04000028,
+	0x0201f800, 0x001005d8, 0x83380580, 0x00000027,
+	0x0402000c, 0x0201f800, 0x00106bbf, 0x4d2c0000,
+	0x4d400000, 0x59325808, 0x42028000, 0x00000004,
+	0x0401feab, 0x5c028000, 0x5c025800, 0x1c01f000,
+	0x83380580, 0x00000014, 0x040007f3, 0x83380580,
+	0x00000089, 0x04000005, 0x83380580, 0x0000008a,
+	0x02020000, 0x00107974, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300a03, 0x82040580,
+	0x0000000a, 0x04000009, 0x82040580, 0x0000000c,
+	0x04000006, 0x0201f800, 0x001005d8, 0x4a026203,
+	0x0000000a, 0x1c01f000, 0x83380480, 0x00000093,
+	0x0402100c, 0x83380480, 0x00000085, 0x04001009,
+	0x83380580, 0x00000089, 0x0400000a, 0x83380580,
+	0x0000008a, 0x04000022, 0x0201f800, 0x001005d8,
+	0x493bc857, 0x4933c857, 0x0201f000, 0x00107974,
+	0x4933c857, 0x4c340000, 0x41306800, 0x0201f800,
+	0x0002075a, 0x04000011, 0x4a026203, 0x00000001,
+	0x4a026403, 0x0000001e, 0x59cc0c07, 0x48066419,
+	0x59cc0a07, 0x48066219, 0x58340809, 0x48066009,
+	0x4a026406, 0x00000004, 0x42000800, 0x80000040,
+	0x0201f800, 0x00020721, 0x40366000, 0x0201f800,
+	0x0002077d, 0x5c006800, 0x1c01f000, 0x4933c857,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x59300809,
+	0x58040200, 0x8c00051a, 0x1c01f000, 0x0201f800,
+	0x001048df, 0x0400001e, 0x4a026203, 0x00000002,
+	0x59300414, 0x84000558, 0x48026414, 0x8c000512,
+	0x04000004, 0x59a80039, 0x48026205, 0x0401f007,
+	0x59a80839, 0x59a80037, 0x80040400, 0x82000400,
+	0x0000000a, 0x48026205, 0x59300009, 0x82000c00,
+	0x00000011, 0x50040000, 0x80000540, 0x04000004,
+	0x82000c00, 0x00000000, 0x0401f7fb, 0x45300800,
+	0x497a6000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x82100500, 0xfffffeef, 0x04020020, 0x4d2c0000,
+	0x4937c857, 0x59340811, 0x83341400, 0x00000011,
+	0x800409c0, 0x0400000e, 0x40040000, 0x81300580,
+	0x04000005, 0x58040800, 0x82041400, 0x00000000,
+	0x0401f7f8, 0x59300800, 0x497a6000, 0x44041000,
+	0x0201f800, 0x000206fd, 0x0401f002, 0x4933c857,
+	0x592c0000, 0x80000540, 0x02020800, 0x001005d8,
+	0x5c025800, 0x492e6008, 0x0201f800, 0x000206fd,
+	0x0201f000, 0x0002077d, 0x492fc857, 0x4a025a06,
+	0x00000006, 0x0201f000, 0x000202da, 0x4c340000,
+	0x59300009, 0x800001c0, 0x04000010, 0x82006c00,
+	0x00000011, 0x50340000, 0x80000540, 0x04000009,
+	0x81300580, 0x04000005, 0x50340000, 0x82006c00,
+	0x00000000, 0x0401f7f8, 0x59300000, 0x44006800,
+	0x5c006800, 0x1c01f000, 0x59300c06, 0x82040580,
+	0x00000005, 0x040007fb, 0x82040580, 0x00000011,
+	0x040007f8, 0x82040580, 0x00000006, 0x040007f5,
+	0x82040580, 0x00000001, 0x040007f2, 0x0201f800,
+	0x001005d8, 0x4933c857, 0x4c080000, 0x4c0c0000,
+	0x4c580000, 0x59a8101d, 0x59cc1807, 0x820c1d00,
+	0x00ffffff, 0x800c0110, 0x80083580, 0x04020014,
+	0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+	0x59300009, 0x82001c00, 0x00000006, 0x0201f800,
+	0x0010855a, 0x0402000a, 0x83cc1400, 0x0000000a,
+	0x4200b000, 0x00000002, 0x59300009, 0x82001c00,
+	0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+	0x5c001800, 0x5c001000, 0x1c01f000, 0x4933c856,
+	0x0201f800, 0x0010421b, 0x0201f000, 0x00101e45,
+	0x493bc857, 0x4d2c0000, 0x0201f800, 0x001007e4,
+	0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+	0x4c580000, 0x4c540000, 0x4200b000, 0x00000006,
+	0x4578a800, 0x8054a800, 0x8058b040, 0x040207fd,
+	0x83380580, 0x00000046, 0x04020004, 0x4a025a04,
+	0x00000144, 0x0401f008, 0x4a025a04, 0x00000146,
+	0x83380580, 0x00000041, 0x04000003, 0x4a025a06,
+	0x00000001, 0x59cc0007, 0x82000500, 0xff000000,
+	0x80000110, 0x59cc1008, 0x82081500, 0xff000000,
+	0x80081540, 0x480a580a, 0x83380580, 0x00000046,
+	0x04020006, 0x59cc0007, 0x82000500, 0x00ffffff,
+	0x4802580b, 0x0401f005, 0x59cc0008, 0x82000500,
+	0x00ffffff, 0x4802580b, 0x83380580, 0x00000046,
+	0x04020004, 0x83cc1400, 0x00000009, 0x0401f003,
+	0x83cc1400, 0x0000000d, 0x50080000, 0x9c0001c0,
+	0x4802580c, 0x80081000, 0x50080000, 0x9c0001c0,
+	0x4802580d, 0x83380580, 0x00000046, 0x04020008,
+	0x59cc000b, 0x9c0001c0, 0x4802580e, 0x59cc000c,
+	0x9c0001c0, 0x4802580f, 0x0401f007, 0x59cc000f,
+	0x9c0001c0, 0x4802580e, 0x59cc0010, 0x9c0001c0,
+	0x4802580f, 0x83380580, 0x00000046, 0x04020004,
+	0x83cc1400, 0x00000011, 0x0401f003, 0x83cc1400,
+	0x00000015, 0x412c3000, 0x82183400, 0x00000010,
+	0x4200b000, 0x00000004, 0x50080000, 0x9c0001c0,
+	0x44003000, 0x80081000, 0x80183000, 0x8058b040,
+	0x040207fa, 0x5c00a800, 0x5c00b000, 0x0201f800,
+	0x000202da, 0x5c025800, 0x1c01f000, 0x4933c857,
+	0x492fc857, 0x59300809, 0x58040200, 0x8c00051e,
+	0x04000004, 0x592c0208, 0x84000558, 0x48025a08,
+	0x1c01f000, 0x59e0180f, 0x599c0413, 0x800c1000,
+	0x80080580, 0x04020002, 0x41781000, 0x59e00010,
+	0x59e00810, 0x80040d80, 0x040207fd, 0x80080580,
+	0x0400000b, 0x4c080000, 0x599c0814, 0x599c1015,
+	0x800c00cc, 0x80040c00, 0x82081440, 0x00000000,
+	0x5c001800, 0x82000540, 0x00000001, 0x4803c857,
+	0x1c01f000, 0x492fc857, 0x42007000, 0x0010b7f8,
+	0x58380807, 0x800409c0, 0x04020005, 0x492c7008,
+	0x492c7007, 0x0201f000, 0x00100875, 0x492c0800,
+	0x492c7007, 0x1c01f000, 0x59300203, 0x4933c857,
+	0x4937c857, 0x493bc857, 0x4803c857, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+	0x0010a6da, 0x0010a82c, 0x0010a6da, 0x0010a6da,
+	0x0010a6da, 0x0010a6da, 0x0010a6da, 0x0010a791,
+	0x0010a6dc, 0x0010a6da, 0x0010a6da, 0x0010a6da,
+	0x0010a6da, 0x0010a6da, 0x0201f800, 0x001005d8,
+	0x83380580, 0x0000004c, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001048ec, 0x04020020, 0x59a80826,
+	0x82040500, 0x00000009, 0x82000580, 0x00000008,
+	0x0400001a, 0x8c040d12, 0x0400003d, 0x59cc0806,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x0400001f, 0x82040580, 0x50000000, 0x04000005,
+	0x82040580, 0x52000000, 0x02020000, 0x0002077d,
+	0x813669c0, 0x04000006, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x4a026403,
+	0x00000001, 0x0401f014, 0x59cc0806, 0x82040d00,
+	0xff000000, 0x82040580, 0x03000000, 0x04000008,
+	0x82040580, 0x50000000, 0x04000005, 0x82040580,
+	0x52000000, 0x02020000, 0x0002077d, 0x4a026403,
+	0x00000009, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00000000, 0x813669c0, 0x0402000b, 0x59cc0001,
+	0x0201f800, 0x00105c9a, 0x02020000, 0x0002077d,
+	0x0201f800, 0x001045a6, 0x02020000, 0x0002077d,
+	0x49366009, 0x4a026406, 0x00000004, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x00103b25, 0x04000023, 0x59cc0806, 0x4807c857,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x04000033, 0x82040580, 0x20000000, 0x04000041,
+	0x82040580, 0x21000000, 0x04000052, 0x82040580,
+	0x24000000, 0x0400004f, 0x82040580, 0x50000000,
+	0x0400004c, 0x82040580, 0x52000000, 0x04000049,
+	0x82040580, 0x05000000, 0x0402000d, 0x59cc0806,
+	0x82040d00, 0xff000000, 0x9c0431c0, 0x42028000,
+	0x00000046, 0x42002800, 0x00000001, 0x0401fcf3,
+	0x0401f93c, 0x02000800, 0x001005d8, 0x42002000,
+	0x00000051, 0x0201f800, 0x00107a4a, 0x59cc0000,
+	0x82000500, 0x00ffffff, 0x82000580, 0x00ffffff,
+	0x04000005, 0x4a026203, 0x00000007, 0x493a6403,
+	0x1c01f000, 0x59325817, 0x812e59c0, 0x02020800,
+	0x001007fd, 0x0201f000, 0x0002077d, 0x813669c0,
+	0x040007df, 0x59340400, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000003, 0x040207d9, 0x0401fc6f,
+	0x040207d7, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x0000000e, 0x4a02621a, 0x00001900, 0x0401f7a2,
+	0x813669c0, 0x0400000c, 0x59340c00, 0x82040500,
+	0x000000ff, 0x82000580, 0x00000009, 0x04000794,
+	0x82040500, 0x0000ff00, 0x82000580, 0x00000700,
+	0x040207c3, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001e00, 0x0401f78e,
+	0x813669c0, 0x040007f8, 0x59340c00, 0x82040500,
+	0x0000ff00, 0x82000580, 0x00000700, 0x040007f2,
+	0x0401f7b3, 0x4d2c0000, 0x4c580000, 0x4c500000,
+	0x4c540000, 0x41385000, 0x83380580, 0x00000054,
+	0x02020800, 0x001005d8, 0x59325808, 0x592c0c0b,
+	0x82040d00, 0x0000e000, 0x82040580, 0x00002000,
+	0x04020076, 0x59300817, 0x800409c0, 0x04000014,
+	0x58041404, 0x41cca800, 0x8204a400, 0x00000005,
+	0x82080480, 0x00000010, 0x04021004, 0x4008b000,
+	0x0401fb6b, 0x0401f00a, 0x40001000, 0x4200b000,
+	0x0000000f, 0x0401fb66, 0x58040801, 0x800409c0,
+	0x040207f2, 0x0201f800, 0x001005d8, 0x813669c0,
+	0x0400005e, 0x59344c00, 0x592c0c09, 0x4807c857,
+	0x4827c857, 0x82040d00, 0x000000ff, 0x82040580,
+	0x00000003, 0x0400002a, 0x82040580, 0x00000005,
+	0x04000032, 0x82040580, 0x00000020, 0x04000036,
+	0x82040580, 0x00000052, 0x04000042, 0x82040580,
+	0x00000050, 0x04000042, 0x82040580, 0x00000021,
+	0x04000004, 0x82040580, 0x00000024, 0x04020043,
+	0x82240500, 0x0000ff00, 0x82000580, 0x00000007,
+	0x04000008, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x42005000, 0x0000000c, 0x0401f037,
+	0x4a025a06, 0x00000031, 0x4a02580d, 0x00000009,
+	0x59340400, 0x4802580e, 0x0201f800, 0x000202da,
+	0x0201f800, 0x00107911, 0x0401f03d, 0x0201f800,
+	0x001042b4, 0x0201f800, 0x0010462a, 0x42000800,
+	0x00000003, 0x0201f800, 0x00104571, 0x42005000,
+	0x00000008, 0x0401f021, 0x59cc0007, 0x0201f800,
+	0x00105eec, 0x0402001d, 0x0201f800, 0x001042b4,
+	0x0401f01a, 0x82240500, 0x0000ff00, 0x82000580,
+	0x00000007, 0x040007df, 0x82240500, 0x000000ff,
+	0x82000580, 0x00000009, 0x040007da, 0x0201f800,
+	0x0010468d, 0x42005000, 0x0000000a, 0x0401f00b,
+	0x42005000, 0x0000000e, 0x0401f003, 0x42005000,
+	0x00000010, 0x82240500, 0x0000ff00, 0x82000580,
+	0x00000007, 0x040007cb, 0x482a6403, 0x4a026203,
+	0x00000001, 0x592c000d, 0x48026011, 0x497a6013,
+	0x59a80038, 0x48026206, 0x417a7800, 0x0201f800,
+	0x0010672b, 0x59325817, 0x812e59c0, 0x04000004,
+	0x0201f800, 0x001007fd, 0x497a6017, 0x5c00a800,
+	0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+	0x4d2c0000, 0x59325808, 0x83380580, 0x00000013,
+	0x04020029, 0x59300c03, 0x82040580, 0x00000054,
+	0x0400001e, 0x82040580, 0x00000010, 0x04000018,
+	0x82040580, 0x0000000e, 0x04000015, 0x82040580,
+	0x00000008, 0x0400000d, 0x82040580, 0x0000000c,
+	0x0400000a, 0x82040580, 0x0000000a, 0x02020800,
+	0x001005d8, 0x42000800, 0x00000006, 0x0201f800,
+	0x00104571, 0x0401f009, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0401f004, 0x59340200,
+	0x8400051a, 0x48026a00, 0x4a025a06, 0x00000000,
+	0x0201f800, 0x000202da, 0x0201f800, 0x0002077d,
+	0x0401f022, 0x83380580, 0x00000027, 0x0400000e,
+	0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x42028000, 0x00000031,
+	0x42000800, 0x00000004, 0x42001000, 0x000000ff,
+	0x0401f009, 0x0201f800, 0x00106bbf, 0x42028000,
+	0x00000031, 0x42000800, 0x00000004, 0x42001000,
+	0x00000010, 0x49425a06, 0x4806580d, 0x480a580e,
+	0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+	0x0201f800, 0x00107911, 0x5c025800, 0x1c01f000,
+	0x42007000, 0x0010b7f8, 0x58380807, 0x800409c0,
+	0x04020005, 0x492c7008, 0x492c7007, 0x0201f000,
+	0x00100875, 0x492c0800, 0x492c7007, 0x1c01f000,
+	0x4d2c0000, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4933c857, 0x4937c857, 0x59cc0806, 0x4807c857,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x0400000d, 0x82040580, 0x05000000, 0x0400000a,
+	0x82040580, 0x21000000, 0x04000030, 0x82040580,
+	0x24000000, 0x0400002d, 0x82040580, 0x20000000,
+	0x0402002f, 0x0201f800, 0x001007e4, 0x0400002c,
+	0x492fc857, 0x492e6017, 0x59a8b016, 0x8258b400,
+	0x0000001b, 0x8258b500, 0xfffffffc, 0x8058b104,
+	0x485a5c04, 0x412c7800, 0x41cca000, 0x82580480,
+	0x00000010, 0x04021005, 0x832cac00, 0x00000005,
+	0x0401fa63, 0x0401f015, 0x40580800, 0x4200b000,
+	0x0000000f, 0x832cac00, 0x00000005, 0x0401fa5c,
+	0x8204b480, 0x0000000f, 0x0201f800, 0x001007e4,
+	0x04000004, 0x492c7801, 0x412c7800, 0x0401f7ec,
+	0x59325817, 0x0201f800, 0x001007fd, 0x497a6017,
+	0x80000580, 0x0401f006, 0x59340200, 0x84000554,
+	0x48026a00, 0x82000540, 0x00000001, 0x5c00a800,
+	0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x492fc857, 0x4d2c0000, 0x59300a03,
+	0x82040580, 0x00000007, 0x04000036, 0x82040580,
+	0x00000001, 0x02020800, 0x001005d8, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x598c000d, 0x81300580,
+	0x04020016, 0x59300004, 0x8c000520, 0x04000004,
+	0x84000520, 0x48026004, 0x0401f016, 0x42001000,
+	0x0010b7f6, 0x50081000, 0x58080002, 0x82000580,
+	0x00000100, 0x04000006, 0x5808000c, 0x81300580,
+	0x02020800, 0x001005d8, 0x0401f00a, 0x0201f800,
+	0x00106e8e, 0x04020020, 0x59300004, 0x8c000520,
+	0x04000004, 0x84000520, 0x48026004, 0x0401f003,
+	0x0201f800, 0x001068d3, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x0201f800, 0x00109037, 0x02000800,
+	0x001005d8, 0x59325808, 0x4a025a06, 0x00000005,
+	0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+	0x59325817, 0x812e59c0, 0x02020800, 0x001007fd,
+	0x0201f800, 0x00107911, 0x80000580, 0x5c025800,
+	0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x59300406, 0x82000580, 0x00000011, 0x040007b8,
+	0x0401f7f7, 0x4c040000, 0x59340200, 0x4803c857,
+	0x8c00051c, 0x04000009, 0x59cc0805, 0x591c0019,
+	0x4803c857, 0x80040580, 0x04000004, 0x80000580,
+	0x4803c856, 0x0401f003, 0x82000540, 0x00000001,
+	0x5c000800, 0x1c01f000, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x42001800, 0x0000ffff, 0x42002000,
+	0x00000004, 0x0401f010, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+	0x00000004, 0x0401f008, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+	0x00000007, 0x480fc857, 0x4813c857, 0x481bc857,
+	0x0201f800, 0x00103aae, 0x5c002000, 0x5c001800,
+	0x5c000000, 0x1c01f000, 0x83380580, 0x00000092,
+	0x02020800, 0x001005d8, 0x42000800, 0x80000040,
+	0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+	0x00020721, 0x4d400000, 0x0201f800, 0x00103b25,
+	0x04000008, 0x59a80005, 0x84000544, 0x48035005,
+	0x42028000, 0x0000002a, 0x0201f800, 0x0010a449,
+	0x5c028000, 0x1c01f000, 0x59a80026, 0x8c000508,
+	0x04000005, 0x599c0017, 0x8c00050a, 0x04020002,
+	0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59300420, 0x84000540, 0x48026420, 0x1c01f000,
+	0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+	0x04000004, 0x598800b8, 0x80000000, 0x480310b8,
+	0x8c142d2e, 0x04000004, 0x598800b9, 0x80000000,
+	0x480310b9, 0x8c142d2c, 0x04000013, 0x40140000,
+	0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+	0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+	0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+	0x80000000, 0x48031005, 0x598800ba, 0x80000000,
+	0x480310ba, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+	0x04000004, 0x598800bb, 0x80000000, 0x480310bb,
+	0x8c142d2e, 0x04000004, 0x598800bc, 0x80000000,
+	0x480310bc, 0x8c142d2c, 0x04000013, 0x40140000,
+	0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+	0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+	0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+	0x80000000, 0x48031005, 0x598800bd, 0x80000000,
+	0x480310bd, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59880001, 0x80000000, 0x4803c857,
+	0x48031001, 0x5c000000, 0x1c01f000, 0x4c000000,
+	0x59880000, 0x80000000, 0x4803c857, 0x48031000,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59880002,
+	0x80000000, 0x4803c857, 0x48031002, 0x5c000000,
+	0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d2c,
+	0x04000004, 0x598800a6, 0x80000000, 0x480310a6,
+	0x8c040d2a, 0x04000004, 0x598800a7, 0x80000000,
+	0x480310a7, 0x8c040d28, 0x04000004, 0x598800a8,
+	0x80000000, 0x480310a8, 0x8c040d26, 0x04000004,
+	0x598800a9, 0x80000000, 0x480310a9, 0x8c040d24,
+	0x04000004, 0x598800aa, 0x80000000, 0x480310aa,
+	0x8c040d22, 0x04000004, 0x598800ab, 0x80000000,
+	0x480310ab, 0x8c040d20, 0x04000004, 0x598800ac,
+	0x80000000, 0x480310ac, 0x5c000000, 0x1c01f000,
+	0x4807c857, 0x4c000000, 0x598800ad, 0x80000000,
+	0x480310ad, 0x5c000000, 0x1c01f000, 0x4807c857,
+	0x4c000000, 0x8c040d1c, 0x04000004, 0x598800ae,
+	0x80000000, 0x480310ae, 0x8c040d1a, 0x04000004,
+	0x598800af, 0x80000000, 0x480310af, 0x5c000000,
+	0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d18,
+	0x04000004, 0x598800b0, 0x80000000, 0x480310b0,
+	0x8c040d16, 0x04000004, 0x598800b1, 0x80000000,
+	0x480310b1, 0x8c040d14, 0x04000004, 0x598800b2,
+	0x80000000, 0x480310b2, 0x5c000000, 0x1c01f000,
+	0x4807c857, 0x4c000000, 0x8c040d10, 0x04000004,
+	0x598800b3, 0x80000000, 0x480310b3, 0x8c040d0c,
+	0x04000004, 0x598800b4, 0x80000000, 0x480310b4,
+	0x5c000000, 0x1c01f000, 0x4807c857, 0x4c000000,
+	0x8c040d08, 0x04000004, 0x598800b5, 0x80000000,
+	0x480310b5, 0x8c040d04, 0x04000004, 0x598800b6,
+	0x80000000, 0x480310b6, 0x5c000000, 0x1c01f000,
+	0x4807c856, 0x4c000000, 0x5988007f, 0x80000000,
+	0x4803107f, 0x5c000000, 0x1c01f000, 0x4803c857,
+	0x4c040000, 0x50000800, 0x80040800, 0x4807c857,
+	0x44040000, 0x5c000800, 0x1c01f000, 0x480fc857,
+	0x4c000000, 0x820c0580, 0x00000000, 0x04020004,
+	0x42000000, 0x0010b819, 0x0401f014, 0x820c0580,
+	0x00001001, 0x04020004, 0x42000000, 0x0010b81a,
+	0x0401f00e, 0x820c0580, 0x00001002, 0x04020004,
+	0x42000000, 0x0010b81b, 0x0401f008, 0x820c0c80,
+	0x0000201c, 0x02021800, 0x001005d8, 0x820c0500,
+	0x0000001f, 0x0c01f804, 0x0401ffdd, 0x5c000000,
+	0x1c01f000, 0x0010aa89, 0x0010aa8c, 0x0010aa8f,
+	0x0010aa92, 0x0010aa95, 0x0010aa98, 0x0010aa9b,
+	0x0010aa9e, 0x0010aaa1, 0x0010aaa4, 0x0010aaa7,
+	0x0010aaaa, 0x0010aaad, 0x0010aab0, 0x0010aab3,
+	0x0010aab6, 0x0010aab9, 0x0010aabc, 0x0010aabf,
+	0x0010aac2, 0x0010aac5, 0x0010aac8, 0x0010aacb,
+	0x0010aace, 0x0010aad1, 0x0010aad4, 0x0010aad7,
+	0x0010aada, 0x42000000, 0x0010b81c, 0x1c01f000,
+	0x42000000, 0x0010b81d, 0x1c01f000, 0x42000000,
+	0x0010b81e, 0x1c01f000, 0x42000000, 0x0010b81f,
+	0x1c01f000, 0x42000000, 0x0010b820, 0x1c01f000,
+	0x42000000, 0x0010b821, 0x1c01f000, 0x42000000,
+	0x0010b822, 0x1c01f000, 0x42000000, 0x0010b823,
+	0x1c01f000, 0x42000000, 0x0010b824, 0x1c01f000,
+	0x42000000, 0x0010b825, 0x1c01f000, 0x42000000,
+	0x0010b826, 0x1c01f000, 0x42000000, 0x0010b827,
+	0x1c01f000, 0x42000000, 0x0010b828, 0x1c01f000,
+	0x42000000, 0x0010b829, 0x1c01f000, 0x42000000,
+	0x0010b82a, 0x1c01f000, 0x42000000, 0x0010b82b,
+	0x1c01f000, 0x42000000, 0x0010b82c, 0x1c01f000,
+	0x42000000, 0x0010b82d, 0x1c01f000, 0x42000000,
+	0x0010b82e, 0x1c01f000, 0x42000000, 0x0010b82f,
+	0x1c01f000, 0x42000000, 0x0010b830, 0x1c01f000,
+	0x42000000, 0x0010b831, 0x1c01f000, 0x42000000,
+	0x0010b832, 0x1c01f000, 0x42000000, 0x0010b833,
+	0x1c01f000, 0x42000000, 0x0010b834, 0x1c01f000,
+	0x42000000, 0x0010b835, 0x1c01f000, 0x42000000,
+	0x0010b836, 0x1c01f000, 0x42000000, 0x0010b837,
+	0x1c01f000, 0x480fc857, 0x4c000000, 0x820c0580,
+	0x00000001, 0x04020004, 0x42000000, 0x0010b80e,
+	0x0401f012, 0x820c0580, 0x00000002, 0x04020004,
+	0x42000000, 0x0010b80f, 0x0401f00c, 0x820c0580,
+	0x00000003, 0x04020004, 0x42000000, 0x0010b810,
+	0x0401f006, 0x820c0580, 0x00000004, 0x04020004,
+	0x42000000, 0x0010b811, 0x0401ff51, 0x5c000000,
+	0x1c01f000, 0x4c000000, 0x59a80026, 0x4803c857,
+	0x8c000502, 0x04000010, 0x8c000506, 0x04000004,
+	0x42000000, 0x0010b841, 0x0401f012, 0x8c00050a,
+	0x04000004, 0x42000000, 0x0010b840, 0x0401f00d,
+	0x8c000508, 0x04000004, 0x42000000, 0x0010b843,
+	0x0401f008, 0x0201f800, 0x0010513b, 0x04000006,
+	0x8c000506, 0x04020004, 0x42000000, 0x0010b842,
+	0x0401ff33, 0x5c000000, 0x1c01f000, 0x8058b1c0,
+	0x02000800, 0x001005d8, 0x5450a800, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207fc, 0x1c01f000,
+	0x8058b1c0, 0x02000800, 0x001005d8, 0x4450a800,
+	0x8054a800, 0x8058b040, 0x040207fd, 0x1c01f000,
+	0x8058b1c0, 0x02000800, 0x001005d8, 0x50500000,
+	0x9c0001c0, 0x4400a800, 0x8050a000, 0x8054a800,
+	0x8058b040, 0x040207fa, 0x1c01f000, 0x4c000000,
+	0x59a80008, 0x8c00051c, 0x5c000000, 0x1c01f000,
+	0x00000001, 0x00000002, 0x00000004, 0x00000008,
+	0x00000010, 0x00000020, 0x00000040, 0x00000080,
+	0x00000100, 0x00000200, 0x00000400, 0x00000800,
+	0x00001000, 0x00002000, 0x00004000, 0x00008000,
+	0x00010000, 0xa5f2b3ac
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length01 = 0x0000ab4a ;
+#else
+uint32_t risc_code_length01 = 0x0000ab4a ;
+#endif
+
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr02 = 0x0010e000  ;
+#else
+uint32_t risc_code_addr02 = 0x0010e000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code02[] = {
+#else
+uint32_t risc_code02[] = {
+#endif
+	0x00000000, 0x00000000, 0x0010e000, 0x000014ff,
+	0x00000000, 0x00000000, 0x00020000, 0x000008c0,
+	0x836c0580, 0x00000003, 0x02020000, 0x001002e3,
+	0x42000000, 0x0010b4bb, 0x50000000, 0x800001c0,
+	0x04020956, 0x0401f923, 0x0401fbe3, 0x0401fb5c,
+	0x0201f800, 0x00020718, 0x0201f800, 0x0002057b,
+	0x0401f7f0, 0x59b800ea, 0x82000d00, 0xf0000038,
+	0x02020000, 0x00100a7a, 0x8c000510, 0x02000000,
+	0x00100a79, 0x59ba60e0, 0x81300182, 0x0402104e,
+	0x04002030, 0x8532653e, 0x59300406, 0x82000580,
+	0x00000003, 0x04020028, 0x59300203, 0x82000580,
+	0x00000004, 0x04020024, 0x59325808, 0x59300402,
+	0x4a025a04, 0x00000103, 0x900001c0, 0x48025806,
+	0x497a5807, 0x497a5c09, 0x5930001f, 0x80000540,
+	0x02020800, 0x00100d56, 0x59300004, 0x8c00053e,
+	0x04020010, 0x0401fa88, 0x59326809, 0x0201f800,
+	0x0002077d, 0x5934000f, 0x5934140b, 0x80081040,
+	0x04001002, 0x480a6c0b, 0x80000540, 0x04020a10,
+	0x59b800ea, 0x8c000510, 0x040207d7, 0x1c01f000,
+	0x0201f800, 0x00106f60, 0x040007ef, 0x0201f000,
+	0x00100a65, 0x42027000, 0x00000055, 0x0401f027,
+	0x83326500, 0x3fffffff, 0x59300406, 0x82000580,
+	0x00000003, 0x04020015, 0x59325808, 0x59326809,
+	0x59301402, 0x4a025a04, 0x00000103, 0x900811c0,
+	0x480a5806, 0x497a5c09, 0x497a5807, 0x0401fa62,
+	0x0201f800, 0x0002077d, 0x5934000f, 0x5934140b,
+	0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+	0x040209eb, 0x0401f7db, 0x42027000, 0x00000054,
+	0x0401f00a, 0x83300500, 0x60000000, 0x02000000,
+	0x00100a68, 0x81326580, 0x8000013a, 0x82000400,
+	0x00100a80, 0x50027000, 0x59300c06, 0x82040580,
+	0x00000002, 0x02000000, 0x00100a65, 0x59300004,
+	0x8c00053e, 0x04020004, 0x0201f800, 0x000207a1,
+	0x0401f7c4, 0x0201f800, 0x00106f60, 0x040007fb,
+	0x0201f000, 0x00100a65, 0x59325808, 0x412c7000,
+	0x58380a04, 0x82040500, 0x0000000f, 0x82000c00,
+	0x001010bd, 0x50044000, 0x0c01f001, 0x00100dd9,
+	0x00100dd9, 0x0002009f, 0x00100dd9, 0x00100dd9,
+	0x00100dd9, 0x00100dd9, 0x00100dd9, 0x000200af,
+	0x00100ded, 0x00100dd9, 0x00100dd9, 0x00100ddb,
+	0x00100dd9, 0x00100dd9, 0x00100dd9, 0x5838040a,
+	0x8c000500, 0x02000800, 0x001005d8, 0x50200000,
+	0x80387c00, 0x583c1002, 0x583c2800, 0x583c2001,
+	0x58380a07, 0x5838300f, 0x59303807, 0x58384c08,
+	0x5838000d, 0x48026012, 0x0401f010, 0x5838020a,
+	0x8c000502, 0x02000000, 0x00100dd9, 0x50200000,
+	0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+	0x592c0a07, 0x592c4c08, 0x592c300f, 0x59303807,
+	0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+	0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+	0x02020000, 0x00100e1a, 0x841c3d40, 0x481e6007,
+	0x1c01f000, 0x41787800, 0x59325808, 0x592c0c0a,
+	0x8c040d02, 0x02000000, 0x00100f8c, 0x592c000d,
+	0x592c100f, 0x592c0a04, 0x480a6011, 0x48026012,
+	0x48026013, 0x412c3000, 0x82040500, 0x0000000f,
+	0x82000400, 0x001010bd, 0x50003800, 0x501c0000,
+	0x401c1000, 0x592c1a07, 0x4802600a, 0x481a600b,
+	0x480a600c, 0x480e600d, 0x843c7d4a, 0x403c1000,
+	0x1c01f000, 0x41787800, 0x497a6012, 0x592c0a04,
+	0x412c3000, 0x592c1a07, 0x82040500, 0x0000000f,
+	0x82000400, 0x001010bd, 0x50004000, 0x50200000,
+	0x40201000, 0x4802600a, 0x481a600b, 0x480a600c,
+	0x480e600d, 0x80000580, 0x483e6004, 0x1c01f000,
+	0x4c000000, 0x4df00000, 0x0201f800, 0x00020729,
+	0x0401f005, 0x4c000000, 0x4df00000, 0x0401ff16,
+	0x0401f001, 0x5c03e000, 0x5c000000, 0x1801f000,
+	0x4203e000, 0xb0100000, 0x41fc0000, 0x82000500,
+	0x00000011, 0x0c01f001, 0x0002012a, 0x00020697,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0010115a, 0x0002012c,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00020697, 0x0201f000, 0x0010115a,
+	0x42000000, 0x0010b4c1, 0x50000000, 0x8c000504,
+	0x04000014, 0x42000000, 0x0010b4c1, 0x50000000,
+	0x8c000502, 0x04020002, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x42034000, 0x0010b4a4,
+	0x59a0001d, 0x59a1d81e, 0x84000502, 0x4803401d,
+	0x58ec0009, 0x0801f800, 0x5c03e000, 0x1c01f000,
+	0x04027002, 0x04026002, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x0201f800, 0x001007e4,
+	0x04000010, 0x412dd800, 0x48efc857, 0x0201f800,
+	0x00103b28, 0x42034000, 0x0010b4a4, 0x49a1d80b,
+	0x48ef401e, 0x59a0001d, 0x84000544, 0x4803401d,
+	0x0201f800, 0x00102214, 0x0201f800, 0x00102233,
+	0x5c03e000, 0x1c01f000, 0x4da00000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x04006051, 0x40001000,
+	0x42034000, 0x0010b4a4, 0x59a01818, 0x800c19c0,
+	0x04020008, 0x59a0381b, 0x801c39c0, 0x02000800,
+	0x001005d8, 0x59a0041c, 0x801c3c00, 0x0401f00c,
+	0x59a00419, 0x82000400, 0x00000002, 0x48034419,
+	0x82000c80, 0x00000013, 0x04001003, 0x497b4419,
+	0x41780000, 0x59a03816, 0x801c3c00, 0x80081040,
+	0x480b4017, 0x581c0200, 0x4803c021, 0x581c0401,
+	0x4803c022, 0x581c0201, 0x4803c023, 0x581c0400,
+	0x4803c020, 0x900001c0, 0x82000540, 0x00000012,
+	0x4803c011, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+	0x800c19c0, 0x04000007, 0x800c1840, 0x480f4018,
+	0x0402001f, 0x497b4419, 0x497b4219, 0x0401f01c,
+	0x800811c0, 0x0402000b, 0x4d2c0000, 0x59a2581b,
+	0x0201f800, 0x001007f4, 0x5c025800, 0x497b401b,
+	0x497b401a, 0x497b441c, 0x497b421c, 0x0401f010,
+	0x59a0041c, 0x82000400, 0x00000002, 0x82000c80,
+	0x00000012, 0x4803441c, 0x04001009, 0x4d2c0000,
+	0x59a2581b, 0x592c3813, 0x481f401b, 0x497b441c,
+	0x0201f800, 0x001007f4, 0x5c025800, 0x5c03e000,
+	0x5c034000, 0x1c01f000, 0x59a80005, 0x82000500,
+	0x00000003, 0x02020000, 0x00104315, 0x59340400,
+	0x82000580, 0x00000606, 0x02020000, 0x001042e6,
+	0x5934000d, 0x80027d40, 0x02020000, 0x00104321,
+	0x0401f803, 0x80000580, 0x1c01f000, 0x5934000f,
+	0x59341203, 0x80080540, 0x0402006f, 0x5934020b,
+	0x5934140b, 0x80080480, 0x0402106b, 0x0201f800,
+	0x0002075a, 0x04000064, 0x80081000, 0x592c0406,
+	0x480a6c0b, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000003, 0x4a026403, 0x00000040, 0x800000c2,
+	0x800018c4, 0x800c0400, 0x48026206, 0x592c0808,
+	0x592c1809, 0x592c020a, 0x48066017, 0x480e6018,
+	0x8c000502, 0x04000030, 0x4a026203, 0x00000004,
+	0x592c0207, 0x80000040, 0x04020020, 0x59a80005,
+	0x8c000514, 0x42000000, 0x00000055, 0x04020003,
+	0x42000000, 0x00000033, 0x80000040, 0x040207ff,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000018, 0x04020011, 0x592c180f, 0x59300007,
+	0x82000540, 0x00000091, 0x480e6011, 0x48026007,
+	0x42000000, 0x80000004, 0x48026004, 0x59bc00ea,
+	0x8c000516, 0x040207fe, 0x83300400, 0x20000000,
+	0x480378e1, 0x1c01f000, 0x0401fe78, 0x59300007,
+	0x8400054e, 0x48026007, 0x592c1a04, 0x820c1d00,
+	0x000000ff, 0x820c0580, 0x00000048, 0x04000017,
+	0x0401f7ec, 0x8c000500, 0x04020ecb, 0x4a026203,
+	0x00000002, 0x59a80805, 0x82040500, 0x00000600,
+	0x04020012, 0x42000000, 0x00000030, 0x80000040,
+	0x040207ff, 0x592c1a04, 0x820c1d00, 0x000000ff,
+	0x820c0580, 0x00000018, 0x040007da, 0x820c0580,
+	0x00000048, 0x040207d7, 0x42000800, 0x80000804,
+	0x0201f000, 0x00106721, 0x8c040d12, 0x42000000,
+	0x00000010, 0x040207ee, 0x42000000, 0x00000051,
+	0x0401f7eb, 0x800811c0, 0x04020003, 0x4a026a03,
+	0x00000001, 0x59340010, 0x492e6810, 0x80000d40,
+	0x04020003, 0x492e680f, 0x1c01f000, 0x492c0800,
+	0x1c01f000, 0x83440c80, 0x00000800, 0x04021009,
+	0x83440400, 0x0010ac00, 0x50000000, 0x80000540,
+	0x04000004, 0x40026800, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x59340203,
+	0x80000540, 0x0402004b, 0x4d300000, 0x4d2c0000,
+	0x5934000f, 0x80025d40, 0x04000044, 0x0201f800,
+	0x0002075a, 0x0400003f, 0x592c0000, 0x4802680f,
+	0x80000540, 0x04020002, 0x48026810, 0x592c2a04,
+	0x80081000, 0x480a6c0b, 0x49366009, 0x492e6008,
+	0x82142d00, 0x000000ff, 0x82140580, 0x00000012,
+	0x04000035, 0x4a026406, 0x00000003, 0x4a026403,
+	0x00000040, 0x592c0406, 0x800000c2, 0x800018c4,
+	0x800c0400, 0x48026206, 0x592c0808, 0x592c1809,
+	0x592c020a, 0x48066017, 0x480e6018, 0x8c000502,
+	0x02000000, 0x0010474d, 0x4a026203, 0x00000004,
+	0x592c0207, 0x80000040, 0x02020000, 0x00104740,
+	0x82140580, 0x00000018, 0x02020000, 0x00104740,
+	0x592c180f, 0x59300007, 0x82000540, 0x00000091,
+	0x480e6011, 0x48026007, 0x42000000, 0x80000004,
+	0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe,
+	0x83300400, 0x20000000, 0x480378e1, 0x5934020b,
+	0x5934140b, 0x80080480, 0x040017be, 0x0401f003,
+	0x4a026a03, 0x00000001, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x497a5800, 0x49325809, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x0401f802,
+	0x0401f7ef, 0x59a80021, 0x800001c0, 0x02020000,
+	0x0010476f, 0x59a80005, 0x8c000504, 0x02020000,
+	0x0010476b, 0x59340200, 0x8c000518, 0x02020000,
+	0x00104767, 0x592c0a0c, 0x48066202, 0x4a025a06,
+	0x00000000, 0x8c000508, 0x02020000, 0x00104763,
+	0x4d3c0000, 0x417a7800, 0x0401fbdf, 0x5c027800,
+	0x1c01f000, 0x592c0404, 0x8c00051e, 0x02020000,
+	0x00104ce4, 0x59980022, 0x80000540, 0x04000017,
+	0x592c0a06, 0x592c0409, 0x80040540, 0x04020013,
+	0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+	0x02020000, 0x00104cf3, 0x59980022, 0x80000540,
+	0x0400000a, 0x82040580, 0x00000001, 0x04020007,
+	0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+	0x02020000, 0x00104dca, 0x59980026, 0x497a5800,
+	0x80000540, 0x02020000, 0x00104e1d, 0x59d80105,
+	0x82000d00, 0x00018780, 0x02020000, 0x00104edb,
+	0x80000106, 0x82000500, 0x00000003, 0x0c01f001,
+	0x000202f0, 0x00104e1d, 0x000202f6, 0x00020341,
+	0x592c0001, 0x492fb107, 0x80000d40, 0x02020000,
+	0x00104ddb, 0x1c01f000, 0x592c0001, 0x492fb107,
+	0x80000d40, 0x02020000, 0x00104de8, 0x59da5908,
+	0x835c0480, 0x00000020, 0x0400102c, 0x0402b034,
+	0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x0400601f,
+	0x59d8010a, 0x59d8090a, 0x80040580, 0x040207fd,
+	0x800408e0, 0x599c1017, 0x8c081508, 0x04020028,
+	0x82040d40, 0x00000013, 0x5998002b, 0x4807c011,
+	0x84000500, 0x4803302b, 0x59e00017, 0x8c000508,
+	0x04020004, 0x4203e000, 0x30000001, 0x1c01f000,
+	0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+	0x82000580, 0x0000001d, 0x040207f7, 0x4a03c017,
+	0x0000000d, 0x0401f7f4, 0x5998082b, 0x84040d40,
+	0x4807302b, 0x1c01f000, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0400e7ca, 0x0401f7d0, 0x0402f7f7,
+	0x492fa807, 0x0400e7c6, 0x0401f7cc, 0x59e0000f,
+	0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+	0x040007d4, 0x40025000, 0x82040d40, 0x0000001d,
+	0x0401f7d2, 0x59d80908, 0x45680800, 0x4006d000,
+	0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+	0x00001200, 0x48039000, 0x02006000, 0x00104df8,
+	0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+	0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+	0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x0202d000,
+	0x00104dfd, 0x592c0001, 0x492fb107, 0x80000d40,
+	0x02020000, 0x00104e10, 0x1c01f000, 0x59980020,
+	0x0c01f001, 0x00020370, 0x00020371, 0x00104e88,
+	0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+	0x0402681e, 0x04006004, 0x599c0017, 0x8c000508,
+	0x04020865, 0x59980029, 0x80025d40, 0x0400000a,
+	0x0402d00b, 0x59980026, 0x80000040, 0x48033026,
+	0x592c0000, 0x492fb107, 0x48033029, 0x04020002,
+	0x48033028, 0x5c03e000, 0x1c01f000, 0x59d80105,
+	0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+	0x42000000, 0x0010b855, 0x0201f800, 0x0010aa47,
+	0x5c03e000, 0x1c01f000, 0x5998002b, 0x8c000500,
+	0x0402003b, 0x0400e007, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x1c01f000,
+	0x59da5908, 0x835c0c80, 0x00000020, 0x04001003,
+	0x0400b029, 0x0400f02b, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0400e7f3, 0x59d8010a, 0x59d8090a,
+	0x80040580, 0x040207fd, 0x800408e0, 0x599c1017,
+	0x8c081508, 0x04020022, 0x82040d40, 0x00000013,
+	0x4807c011, 0x59e00017, 0x8c000508, 0x0400000a,
+	0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+	0x82000580, 0x0000001d, 0x04020003, 0x4a03c017,
+	0x0000000d, 0x4203e000, 0x30000001, 0x59d80105,
+	0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+	0x1c01f000, 0x492fb007, 0x0400e7d2, 0x0401f7df,
+	0x492fa807, 0x0400e7cf, 0x0401f7dc, 0x84000500,
+	0x4803302b, 0x0400e7cb, 0x0401f7d8, 0x59e0000f,
+	0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+	0x040007da, 0x40025000, 0x82040d40, 0x0000001d,
+	0x0401f7d8, 0x59e0000f, 0x59e0100f, 0x80080d80,
+	0x040207fd, 0x81280580, 0x04020002, 0x1c01f000,
+	0x400a5000, 0x900811c0, 0x82081540, 0x0000001c,
+	0x480bc011, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x0000000c, 0x4203e000, 0x30000001,
+	0x1c01f000, 0x41700000, 0x0c01f001, 0x00105420,
+	0x000203fc, 0x00105420, 0x00105421, 0x0010541e,
+	0x0010541e, 0x0010541e, 0x0010541e, 0x001058b0,
+	0x04010037, 0x59980006, 0x80000540, 0x0402003c,
+	0x0402c01c, 0x4202f800, 0x00000010, 0x4df00000,
+	0x4203e000, 0x50000000, 0x49db3005, 0x59da5808,
+	0x592c0204, 0x497a5800, 0x497a5801, 0x82000500,
+	0x000000ff, 0x82000c80, 0x00000079, 0x04021036,
+	0x0c01f839, 0x5c03e000, 0x817ef840, 0x04000009,
+	0x836c0580, 0x00000003, 0x04020006, 0x83700580,
+	0x00000001, 0x04020010, 0x0401001b, 0x0400c7e8,
+	0x0400f94a, 0x0400b134, 0x59d40005, 0x82000500,
+	0x43018780, 0x02020000, 0x0010583f, 0x59d80005,
+	0x82000500, 0x43018780, 0x02020000, 0x00105846,
+	0x1c01f000, 0x83700580, 0x00000003, 0x02000800,
+	0x00105421, 0x83700580, 0x00000001, 0x040207ed,
+	0x04010005, 0x0400c7d2, 0x0401f7ea, 0x4202f800,
+	0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+	0x49d73005, 0x59d65808, 0x0401f7ce, 0x4df00000,
+	0x4203e000, 0x50000000, 0x40025800, 0x592c0204,
+	0x497b3005, 0x497b3006, 0x4202f800, 0x00000010,
+	0x0401f7c7, 0x0201f800, 0x00105491, 0x5c03e000,
+	0x0401f7d4, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105527, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x001054a1,
+	0x00105491, 0x00105491, 0x00105491, 0x00105551,
+	0x00105491, 0x00105491, 0x00105491, 0x000204ef,
+	0x00105491, 0x001056b4, 0x00105491, 0x00105491,
+	0x00105491, 0x000204c2, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x001054c9, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x001057d3, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x0010581e, 0x00105491,
+	0x001054bb, 0x00105491, 0x00105797, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105765, 0x00105491,
+	0x00105765, 0x00105872, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105725,
+	0x00105855, 0x00105491, 0x00105865, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x592c0204, 0x80000110,
+	0x02000000, 0x00105499, 0x80000040, 0x04000009,
+	0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+	0x000204d0, 0x4202e000, 0x00000003, 0x1c01f000,
+	0x592c0406, 0x82000c80, 0x0000199a, 0x02021000,
+	0x001054a9, 0x59a80021, 0x80000540, 0x02020000,
+	0x001054d7, 0x592e8a06, 0x83440c80, 0x000007f0,
+	0x02021000, 0x001054a9, 0x83440400, 0x0010ac00,
+	0x50000000, 0x80026d40, 0x02000000, 0x001054db,
+	0x59340002, 0x592c0810, 0x80040580, 0x82000500,
+	0x00ffffff, 0x02020000, 0x001054a9, 0x0401fccf,
+	0x02020000, 0x001054de, 0x1c01f000, 0x592c0204,
+	0x80000110, 0x02000000, 0x00105499, 0x80000040,
+	0x0402000b, 0x592c040a, 0x8c000504, 0x04000010,
+	0x592c0207, 0x82000c80, 0x00001001, 0x02021000,
+	0x001054a9, 0x0201f000, 0x0010588a, 0x48033002,
+	0x492f3003, 0x492f3004, 0x4a033008, 0x00020507,
+	0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406,
+	0x82000c80, 0x0000199a, 0x02021000, 0x001054a9,
+	0x592e8a06, 0x417a7800, 0x0401fd37, 0x02020000,
+	0x00105658, 0x59340002, 0x592c0808, 0x80040580,
+	0x82000500, 0x00ffffff, 0x02020000, 0x001054a9,
+	0x497a5808, 0x592e6009, 0x83300580, 0xffffffff,
+	0x02000000, 0x00105618, 0x83300480, 0x0010d1c0,
+	0x02001000, 0x00105675, 0x59a8000b, 0x81300480,
+	0x02021000, 0x00105675, 0x592c240a, 0x49366009,
+	0x8c10251c, 0x02020000, 0x00105606, 0x59a80068,
+	0x8c000510, 0x02020000, 0x0010568e, 0x59a80821,
+	0x800409c0, 0x02020000, 0x001055ec, 0x59a80805,
+	0x8c040d04, 0x02020000, 0x0010567f, 0x59340200,
+	0x8c000518, 0x02020000, 0x00105670, 0x59300c06,
+	0x82040580, 0x00000006, 0x02020000, 0x00105610,
+	0x59300414, 0x8c000516, 0x02020000, 0x0010567a,
+	0x8c102508, 0x02020000, 0x0010a5b8, 0x59300808,
+	0x4a025a06, 0x00000000, 0x800409c0, 0x02020000,
+	0x001055e7, 0x592c0a0c, 0x48066202, 0x492e6008,
+	0x0401f14d, 0x4df00000, 0x4203e000, 0x50000000,
+	0x0402b00b, 0x835c0480, 0x00000020, 0x0400100d,
+	0x815eb840, 0x416a5800, 0x592ed000, 0x492fb007,
+	0x497a5800, 0x497a5801, 0x0400b7f7, 0x59d80005,
+	0x82000500, 0x43018780, 0x02020000, 0x00105846,
+	0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000,
+	0x50000000, 0x0402f00b, 0x835c0480, 0x00000020,
+	0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000,
+	0x492fa807, 0x497a5800, 0x497a5801, 0x0400f7f7,
+	0x59d40005, 0x82000500, 0x43018780, 0x02020000,
+	0x0010583f, 0x5c03e000, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x59940024, 0x80000540,
+	0x04000112, 0x4c000000, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24320001, 0x04020015,
+	0x42000800, 0x00000064, 0x80040840, 0x04000007,
+	0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+	0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+	0x00007a01, 0x50040000, 0x8c000510, 0x04000003,
+	0x84000510, 0x44000800, 0x4a030000, 0x00000000,
+	0x59e00002, 0x8c00051e, 0x0402001b, 0x42000000,
+	0x00001000, 0x50000000, 0x82000480, 0x24320002,
+	0x04020015, 0x42000800, 0x00000064, 0x80040840,
+	0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+	0x59800000, 0x8c000500, 0x040007f9, 0x04000008,
+	0x42000800, 0x00007a17, 0x50040000, 0x8c00050e,
+	0x04020003, 0x8400054e, 0x44000800, 0x4a030000,
+	0x00000000, 0x5c000000, 0x5994781a, 0x48032825,
+	0x803c0480, 0x04001004, 0x04000003, 0x4803281a,
+	0x0401f022, 0x41787800, 0x803c7800, 0x82000400,
+	0x000003e8, 0x040027fd, 0x4803281a, 0x59a80024,
+	0x803c1400, 0x480b5024, 0x803c0040, 0x04000002,
+	0x483fc857, 0x59e40852, 0x59a80025, 0x80040580,
+	0x04000004, 0x480bc857, 0x59e40052, 0x48035025,
+	0x59940026, 0x803c0400, 0x48032826, 0x0201f800,
+	0x00106021, 0x59940000, 0x82000580, 0x00000000,
+	0x04020006, 0x59940026, 0x48032827, 0x497b2826,
+	0x4a032800, 0x00000001, 0x4c0c0000, 0x59940007,
+	0x80000d40, 0x0400001d, 0x59941006, 0x59940025,
+	0x80081c80, 0x04001004, 0x04000003, 0x480f2806,
+	0x0401f016, 0x80040840, 0x48072807, 0x82040580,
+	0x000003e8, 0x04020007, 0x4c040000, 0x4c0c0000,
+	0x59940008, 0x0801f800, 0x5c001800, 0x5c000800,
+	0x800409c0, 0x04020004, 0x59940008, 0x0801f800,
+	0x0401f006, 0x400c0000, 0x820c1c00, 0x0000000a,
+	0x040027ed, 0x480f2806, 0x5c001800, 0x4d180000,
+	0x59c40008, 0x8c000534, 0x04020025, 0x417a3000,
+	0x83947c00, 0x00000009, 0x583c0001, 0x80000d40,
+	0x04020008, 0x823c7c00, 0x00000003, 0x811a3000,
+	0x83180580, 0x00000005, 0x040207f8, 0x0401f018,
+	0x583c1000, 0x59940025, 0x80080480, 0x04001005,
+	0x04000004, 0x48007800, 0x80000040, 0x04021010,
+	0x80040840, 0x48047801, 0x04000008, 0x82000400,
+	0x0000000a, 0x48007800, 0x040027fa, 0x82040500,
+	0x0000007f, 0x0401f7e8, 0x583c0002, 0x4c3c0000,
+	0x0801f800, 0x5c007800, 0x0401f7e3, 0x5c023000,
+	0x59940019, 0x80001540, 0x04000008, 0x04002007,
+	0x59940025, 0x80080480, 0x497b2819, 0x04001003,
+	0x04000002, 0x48032819, 0x59940004, 0x80000d40,
+	0x0400002a, 0x4c040000, 0x5994001c, 0x80000d40,
+	0x04000013, 0x5994101b, 0x59940025, 0x80080480,
+	0x04001005, 0x04000004, 0x4803281b, 0x80000040,
+	0x0402100b, 0x80040840, 0x4807281c, 0x04020004,
+	0x5994001d, 0x0801f800, 0x0401f005, 0x82000400,
+	0x0000000a, 0x4803281b, 0x040027f7, 0x5c000800,
+	0x59941003, 0x59940025, 0x80080480, 0x04001005,
+	0x04000004, 0x48032803, 0x80000040, 0x0402100b,
+	0x80040840, 0x48072804, 0x04020004, 0x59940005,
+	0x0801f800, 0x0401f005, 0x82000400, 0x0000000a,
+	0x48032803, 0x040027f7, 0x5994001f, 0x80000d40,
+	0x04000013, 0x5994101e, 0x59940025, 0x80080480,
+	0x04001005, 0x04000004, 0x4803281e, 0x80000040,
+	0x0402100b, 0x80040840, 0x4807281f, 0x04020004,
+	0x59940020, 0x0801f800, 0x0401f005, 0x82000400,
+	0x00000001, 0x4803281e, 0x040027f7, 0x59940022,
+	0x80000d40, 0x04000013, 0x59941021, 0x59940025,
+	0x80080480, 0x04001005, 0x04000004, 0x48032821,
+	0x80000040, 0x0402100b, 0x80040840, 0x48072822,
+	0x04020004, 0x59940023, 0x0801f800, 0x0401f005,
+	0x82000400, 0x0000000a, 0x48032821, 0x040027f7,
+	0x59940824, 0x59940025, 0x80040480, 0x02001800,
+	0x001005d8, 0x48032824, 0x59940000, 0x0c01f001,
+	0x00105fb5, 0x00105fb7, 0x00105fdd, 0x59940024,
+	0x80000000, 0x48032824, 0x4203e000, 0x70000000,
+	0x1c01f000, 0x592c0406, 0x800000c2, 0x800008c4,
+	0x80040c00, 0x592c040a, 0x48066206, 0x82000d00,
+	0x00000003, 0x02000000, 0x0010615e, 0x8c000500,
+	0x04020029, 0x8c00051e, 0x02000000, 0x00106139,
+	0x82000d00, 0x000000c0, 0x02020000, 0x0010612f,
+	0x82000d00, 0x00002020, 0x02020000, 0x0010612c,
+	0x813e79c0, 0x02020000, 0x0010612c, 0x592c0c0c,
+	0x800409c0, 0x02020000, 0x0010612c, 0x59300a03,
+	0x82040d80, 0x00000007, 0x02020000, 0x0010612c,
+	0x4a026203, 0x00000003, 0x4a026403, 0x00000043,
+	0x0201f800, 0x000200c9, 0x82080d40, 0x80003465,
+	0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516,
+	0x040207fe, 0x83300400, 0xa0000000, 0x480378e1,
+	0x1c01f000, 0x8c000502, 0x02020000, 0x00106181,
+	0x8c00051e, 0x0400000e, 0x82000d00, 0x000000c0,
+	0x04000005, 0x82040d80, 0x000000c0, 0x02020000,
+	0x00106186, 0x82000d00, 0x00002020, 0x82040d80,
+	0x00002020, 0x02000000, 0x0010614d, 0x592c0207,
+	0x80000040, 0x02020000, 0x00106157, 0x592c180d,
+	0x800c19c0, 0x02020000, 0x00106157, 0x592c180f,
+	0x59300007, 0x82000540, 0x00000011, 0x480e6011,
+	0x48026007, 0x4a026203, 0x00000004, 0x4a026403,
+	0x00000042, 0x42000800, 0x80002001, 0x0401f02a,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x4807c857,
+	0x0401f003, 0x42000800, 0x00000001, 0x59325808,
+	0x832c0500, 0x00ff0000, 0x0400000d, 0x592c0000,
+	0x48065a06, 0x48026008, 0x592c040a, 0x8c000510,
+	0x04020008, 0x0201f800, 0x000202ce, 0x417a7800,
+	0x59300008, 0x80025d40, 0x0402078f, 0x1c01f000,
+	0x456a5800, 0x412ed000, 0x815eb800, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x0401f7f4,
+	0x59840000, 0x80000540, 0x04020002, 0x1c01f000,
+	0x59840003, 0x80000540, 0x02020000, 0x001061fe,
+	0x1c01f000, 0x48066004, 0x59bc00ea, 0x8c000516,
+	0x040207fe, 0x83300400, 0x40000000, 0x480378e1,
+	0x1c01f000, 0x59bc00ea, 0x82001500, 0xb0000018,
+	0x02020000, 0x00106c81, 0x8c000510, 0x0400002a,
+	0x59bc10e0, 0x82080500, 0xfffff000, 0x0402000a,
+	0x80080108, 0x820a3500, 0x0000000f, 0x4803c857,
+	0x1201f000, 0x00106c87, 0x84000510, 0x48026004,
+	0x0401f016, 0x840a653e, 0x59300004, 0x8c000520,
+	0x040007fa, 0x82000500, 0xfffefeff, 0x48026004,
+	0x8c08153e, 0x04020005, 0x42027000, 0x00000013,
+	0x0401f859, 0x0401f009, 0x59300004, 0x8c000514,
+	0x04000003, 0x0401ffb0, 0x0401f02f, 0x42027000,
+	0x00000049, 0x0401f850, 0x59bc00ea, 0x82001500,
+	0xb0000018, 0x02020000, 0x00106c81, 0x8c000510,
+	0x040207d8, 0x1c01f000, 0x83640480, 0x00000010,
+	0x0400101a, 0x41626000, 0x41580000, 0x59300a03,
+	0x82040d80, 0x00000000, 0x04000008, 0x83326400,
+	0x00000024, 0x81300c80, 0x040017f9, 0x42026000,
+	0x0010d1c0, 0x0401f7f6, 0x8166c840, 0x83300c00,
+	0x00000024, 0x80040480, 0x04021005, 0x4006c000,
+	0x4a026203, 0x00000008, 0x1c01f000, 0x837ac540,
+	0x0010d1c0, 0x0401f7fb, 0x42000000, 0x0010b854,
+	0x0201f800, 0x0010aa47, 0x4967c857, 0x80026580,
+	0x1c01f000, 0x83300480, 0x0010d1c0, 0x02001800,
+	0x001005d8, 0x41580000, 0x81300480, 0x0402100c,
+	0x04011000, 0x457a6000, 0x4a026202, 0x0000ffff,
+	0x83300400, 0x00000003, 0x4803c840, 0x4a03c842,
+	0x00000021, 0x8166c800, 0x1c01f000, 0x41540000,
+	0x81300480, 0x02021800, 0x001005d8, 0x04011000,
+	0x457a6000, 0x4a026202, 0x0000ffff, 0x83300400,
+	0x00000003, 0x4803c840, 0x4a03c842, 0x00000021,
+	0x59a80066, 0x49335065, 0x80000000, 0x48035066,
+	0x1c01f000, 0x4d340000, 0x59326809, 0x59300406,
+	0x82000500, 0x0000001f, 0x0c01f803, 0x5c026800,
+	0x1c01f000, 0x00107966, 0x00107979, 0x00107993,
+	0x000207c9, 0x001098f1, 0x0010990c, 0x0002083e,
+	0x00107966, 0x00107979, 0x001064ee, 0x001079ac,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x001095a1, 0x0010a6c2, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x001079aa,
+	0x00108592, 0x000207dd, 0x00108720, 0x001087b9,
+	0x001079aa, 0x001079aa, 0x001079aa, 0x00108577,
+	0x001079aa, 0x001079aa, 0x001079aa, 0x001079aa,
+	0x00108985, 0x83380480, 0x00000058, 0x04021007,
+	0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861d, 0x001086bd, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x001086c1, 0x000207ff,
+	0x0010861b, 0x001086c0, 0x001086c2, 0x59325808,
+	0x59300811, 0x59301402, 0x59340200, 0x8c00050e,
+	0x0402001c, 0x0401f826, 0x04000005, 0x4a025a04,
+	0x00000103, 0x497a5c09, 0x0401f009, 0x4a025a04,
+	0x00000103, 0x4a025a06, 0x00000000, 0x497a5c09,
+	0x800409c0, 0x02020800, 0x00108785, 0x48065807,
+	0x480a5c06, 0x0201f800, 0x000202c1, 0x5934000f,
+	0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b,
+	0x80000540, 0x02020800, 0x00020253, 0x0401f75e,
+	0x592c020a, 0x8c000502, 0x040007e9, 0x800409c0,
+	0x040007e7, 0x592c0208, 0x8c00050e, 0x040207e4,
+	0x4933c857, 0x0201f000, 0x0010920f, 0x592c020a,
+	0x8c000500, 0x04000010, 0x59300015, 0x592c380f,
+	0x801c3c80, 0x0400000c, 0x4a025a06, 0x00000015,
+	0x8c1c3d3e, 0x04000005, 0x4a025a06, 0x00000007,
+	0x801c3880, 0x801c3800, 0x481fc857, 0x821c0d40,
+	0x00000000, 0x1c01f000, 0x59300203, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+	0x0010992b, 0x00020852, 0x00109fba, 0x00109fc8,
+	0x0002086e, 0x0010992b, 0x0010a0a8, 0x0002088d,
+	0x0010992b, 0x0010992b, 0x0010992b, 0x0010992b,
+	0x0010992b, 0x0010992b, 0x83380580, 0x00000013,
+	0x02020000, 0x00109f42, 0x59300403, 0x82027480,
+	0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x00109f9e, 0x00020864, 0x00109fa0, 0x00109fb2,
+	0x59325808, 0x832c0500, 0x00ff0000, 0x04000005,
+	0x592c0c0a, 0x8c040d1a, 0x02020000, 0x00109fad,
+	0x0401fe91, 0x0401f710, 0x83380580, 0x00000048,
+	0x04000007, 0x83380580, 0x00000053, 0x02000000,
+	0x0010a04a, 0x0201f800, 0x001005d8, 0x5930001f,
+	0x59301011, 0x59300809, 0x58040a00, 0x8c040d0e,
+	0x02020000, 0x0010a026, 0x800811c0, 0x02020000,
+	0x0010a033, 0x5930001f, 0x80000540, 0x02020000,
+	0x0010a041, 0x59325808, 0x592c040a, 0x8c00051e,
+	0x02000000, 0x0010a01c, 0x42027000, 0x00000041,
+	0x0401f001, 0x83380480, 0x00000054, 0x02021800,
+	0x001005d8, 0x83380480, 0x00000040, 0x02001000,
+	0x0010a067, 0x0c01f001, 0x0010a073, 0x000208aa,
+	0x0010a07f, 0x0010a086, 0x0010a073, 0x0010a073,
+	0x0010a073, 0x0010a073, 0x0010a075, 0x0010a07a,
+	0x0010a07a, 0x0010a073, 0x0010a073, 0x0010a073,
+	0x0010a073, 0x0010a07a, 0x0010a073, 0x0010a07a,
+	0x0010a073, 0x0010a075, 0x4a026203, 0x00000001,
+	0x493a6403, 0x42000800, 0x80002042, 0x0401f672,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x14aa62b1,
+	0x00000000, 0x00000000, 0x00000000, 0x00000005,
+	0xfffffffb, 0x02800004, 0x00000000, 0x0000c000,
+	0x0000071d, 0x073fca5a, 0x0705a5a5, 0x01928009,
+	0x070ff0e1, 0x03800006, 0x04958010, 0x05308000,
+	0x05008000, 0x0600902f, 0x04a004dc, 0x0202f051,
+	0x042e4020, 0x018f021b, 0x033e5000, 0x03020000,
+	0x078d0018, 0x0493041a, 0x0092041c, 0x038a0305,
+	0x078b0303, 0x048e8010, 0x0678aae5, 0x06000001,
+	0x07818174, 0x040010e6, 0x0448e0e6, 0x04818010,
+	0x002fb008, 0x0448e0e6, 0x04818010, 0x060ff0e6,
+	0x00580401, 0x054880ff, 0x04818010, 0x022a5001,
+	0x030430d4, 0x06780043, 0x030e0000, 0x030450ff,
+	0x06780043, 0x03019000, 0x058185c6, 0x027c0045,
+	0x03020000, 0x06810037, 0x027c0045, 0x03040000,
+	0x068100c7, 0x027c0045, 0x03080000, 0x0781061e,
+	0x04908037, 0x029105c4, 0x010410a6, 0x0379ff41,
+	0x037fffff, 0x072d6000, 0x07601241, 0x050f80ff,
+	0x032fa009, 0x05600400, 0x050f80ff, 0x056c04ff,
+	0x068105dc, 0x073fa009, 0x06000001, 0x0279ff02,
+	0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+	0x045c0402, 0x048185dc, 0x060ff0d0, 0x0179feff,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x078105be,
+	0x05600e41, 0x050f80ff, 0x032fa069, 0x07480000,
+	0x068105d0, 0x06780043, 0x070000f0, 0x0781005f,
+	0x037c00ff, 0x06000010, 0x0781005f, 0x038005cc,
+	0x0379ff00, 0x070fffff, 0x06780043, 0x07f00000,
+	0x075a0000, 0x020ef001, 0x028605ce, 0x05484000,
+	0x02a1819e, 0x062d6001, 0x002fb001, 0x070ff069,
+	0x01868072, 0x060ff079, 0x055c0441, 0x06810010,
+	0x012fb000, 0x060560fb, 0x03800078, 0x060ff079,
+	0x02868198, 0x070ff069, 0x055c0441, 0x06810010,
+	0x060560fb, 0x0400d0d0, 0x062d6002, 0x0648300d,
+	0x06810086, 0x070ff0d1, 0x062d6001, 0x045c040b,
+	0x06810089, 0x05488000, 0x04818086, 0x072e500c,
+	0x00208001, 0x05a004e1, 0x02800010, 0x062d6001,
+	0x07f00000, 0x07f00000, 0x070ff0d1, 0x0179feff,
+	0x070000ff, 0x055c040c, 0x058180bb, 0x0007b001,
+	0x03079041, 0x0307a000, 0x06600a79, 0x050f80ff,
+	0x053fa80a, 0x06000010, 0x072d5003, 0x078d0096,
+	0x0307c003, 0x0007d004, 0x0107e005, 0x0307f006,
+	0x02080007, 0x00081008, 0x01082009, 0x0308300a,
+	0x0008400b, 0x0308500c, 0x068d00a1, 0x0678007a,
+	0x07f00000, 0x010880ff, 0x03386000, 0x03010000,
+	0x072e6300, 0x020ef07f, 0x02860010, 0x070ff07d,
+	0x0450047c, 0x050f80ff, 0x002fa819, 0x068d00ae,
+	0x02080001, 0x00081002, 0x0448807a, 0x068100b5,
+	0x0379ff03, 0x070000ff, 0x01082003, 0x068d00b6,
+	0x02386004, 0x03010000, 0x072e6c00, 0x02800010,
+	0x06780043, 0x070000f0, 0x078105d7, 0x050020ff,
+	0x027c0002, 0x06000010, 0x078100c3, 0x038005d7,
+	0x0700c0d1, 0x0379ff0c, 0x070000ff, 0x0380008e,
+	0x0204a051, 0x06780043, 0x070000f0, 0x037c00ff,
+	0x06000010, 0x0781816a, 0x072d6000, 0x019485c0,
+	0x050fb056, 0x044880e6, 0x04818010, 0x060ff0d0,
+	0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+	0x078105be, 0x05a00212, 0x0349c0e4, 0x0781811d,
+	0x070ff093, 0x050010ff, 0x070ff093, 0x045c0401,
+	0x058180db, 0x02046092, 0x04002046, 0x04600202,
+	0x00540401, 0x048280e6, 0x04500425, 0x070060ff,
+	0x0730ffff, 0x0700000f, 0x0742000f, 0x05810190,
+	0x07a005a6, 0x0648a002, 0x048180e9, 0x00047089,
+	0x070ff047, 0x045c0443, 0x077800ff, 0x07f00000,
+	0x0781818e, 0x07780047, 0x0500e000, 0x048185ad,
+	0x070ff006, 0x01860117, 0x0179fe47, 0x0700000f,
+	0x010480ff, 0x056c7048, 0x06818102, 0x007a0d4a,
+	0x04003801, 0x0220f001, 0x0180010f, 0x07608e48,
+	0x034a60ff, 0x0700f0ff, 0x074b88ff, 0x037000ff,
+	0x07000600, 0x05500448, 0x074d00ff, 0x045a044a,
+	0x0304a0ff, 0x070ff00f, 0x01540406, 0x05820117,
+	0x04950120, 0x05a001bd, 0x02868123, 0x0134bfff,
+	0x070fffff, 0x0104102e, 0x050fd041, 0x00800126,
+	0x0595011d, 0x05a001bd, 0x0186011d, 0x0202f00e,
+	0x052e4030, 0x040fd02f, 0x070fc0ff, 0x05a00218,
+	0x02800010, 0x0400e02f, 0x042e4020, 0x0202f051,
+	0x0004100e, 0x0004b00e, 0x050fd041, 0x024a6c46,
+	0x04500423, 0x050070ff, 0x03620024, 0x050080ff,
+	0x04004046, 0x0700500f, 0x03206000, 0x05601048,
+	0x0700a0ff, 0x0700900a, 0x070ff005, 0x04500446,
+	0x00540425, 0x04820157, 0x05601622, 0x050f80ff,
+	0x063fa032, 0x06000002, 0x03203000, 0x01204000,
+	0x03205000, 0x0120b000, 0x0320c000, 0x07601441,
+	0x050f80ff, 0x043fa852, 0x06000001, 0x070ff056,
+	0x056c02ff, 0x050fb0ff, 0x070560ff, 0x03079041,
+	0x05600e41, 0x050f80ff, 0x073fa011, 0x0600003d,
+	0x06780043, 0x07f00000, 0x065a007a, 0x010880ff,
+	0x04a001b6, 0x058d0150, 0x0208a04a, 0x0108b04b,
+	0x02386001, 0x03010000, 0x072e6300, 0x028000a8,
+	0x0500d00a, 0x05500405, 0x014a68ff, 0x070090ff,
+	0x0154040a, 0x0700c0ff, 0x0600a023, 0x0500b024,
+	0x02206001, 0x05601622, 0x050f80ff, 0x063fa04a,
+	0x06000002, 0x05601022, 0x050f80ff, 0x043fa819,
+	0x06000001, 0x0600a00d, 0x0180013c, 0x06780043,
+	0x070000f0, 0x050010ff, 0x027c0001, 0x07000030,
+	0x078105b4, 0x027c0001, 0x06000020, 0x078105b4,
+	0x038005cc, 0x054880ff, 0x06810010, 0x070ff056,
+	0x050fb0ff, 0x044880e5, 0x0581017d, 0x044880e6,
+	0x04818010, 0x00800183, 0x056c02ff, 0x050fb0ff,
+	0x070560ff, 0x072e5300, 0x044880e6, 0x04818010,
+	0x072d5003, 0x06780043, 0x07f00000, 0x010880ff,
+	0x058d0187, 0x03386005, 0x03010000, 0x033e6000,
+	0x0700000c, 0x052e5200, 0x02800010, 0x0120918e,
+	0x018004e4, 0x01209190, 0x018004e4, 0x00209192,
+	0x018004e4, 0x03209000, 0x018004e4, 0x01209196,
+	0x018004e4, 0x00209198, 0x018004e4, 0x02493075,
+	0x06810510, 0x0120919a, 0x018004e4, 0x06601e01,
+	0x050f80ff, 0x063fa029, 0x06000008, 0x02015010,
+	0x02016051, 0x00017051, 0x00011051, 0x05601a41,
+	0x050f80ff, 0x053fa83a, 0x06000008, 0x05600e41,
+	0x050f80ff, 0x01464000, 0x032fa00a, 0x07006011,
+	0x05007012, 0x04008013, 0x07009014, 0x0600a015,
+	0x0400b016, 0x0700c017, 0x07c00000, 0x072d5003,
+	0x06601479, 0x050f80ff, 0x048d01b9, 0x063fa051,
+	0x0600003e, 0x07c00000, 0x06005051, 0x0400e02c,
+	0x0660060e, 0x050f80ff, 0x032fa009, 0x0379ff00,
+	0x070000ff, 0x076c0000, 0x058101dd, 0x0660480e,
+	0x0500e0ff, 0x034000ff, 0x01540427, 0x0582020a,
+	0x03400005, 0x070ff005, 0x055c0428, 0x0481020e,
+	0x01680e05, 0x056c0405, 0x068181bf, 0x040f8029,
+	0x053fa809, 0x07000024, 0x06600649, 0x050f80ff,
+	0x032fa009, 0x0379ff00, 0x070000ff, 0x076c0000,
+	0x068181bf, 0x0400e049, 0x0340002d, 0x050f802b,
+	0x053fa80a, 0x06000016, 0x0660480e, 0x0302c0ff,
+	0x034000ff, 0x01540427, 0x0582020c, 0x072d6000,
+	0x0460040e, 0x050f80ff, 0x0104e0d1, 0x0379ff4e,
+	0x0700ffff, 0x062d6002, 0x032fa009, 0x0004d0d0,
+	0x074b004d, 0x07780000, 0x07ffff00, 0x055a044d,
+	0x070000ff, 0x00201008, 0x04002051, 0x06003051,
+	0x05304000, 0x07000060, 0x03205009, 0x07006022,
+	0x0460040e, 0x050f80ff, 0x032fa03a, 0x06603c0e,
+	0x050f80ff, 0x073fa00a, 0x07000027, 0x050010d1,
+	0x0460320e, 0x050f80ff, 0x012fa80a, 0x060ff00e,
+	0x055c042e, 0x04810210, 0x07c00000, 0x0400e026,
+	0x008001cb, 0x0202c026, 0x008001e6, 0x0500e02e,
+	0x008001e6, 0x0400e051, 0x01800209, 0x0349c0e4,
+	0x04810215, 0x07c00000, 0x013e4000, 0x070c0000,
+	0x07c00000, 0x013e4000, 0x03080000, 0x07c00000,
+	0x009702f4, 0x022a5002, 0x0790821d, 0x00910291,
+	0x030400a6, 0x0678aae5, 0x06000001, 0x00a1860e,
+	0x06600c40, 0x050f80ff, 0x032fa021, 0x074b0000,
+	0x076c0600, 0x07818293, 0x05600403, 0x050f80ff,
+	0x073fa009, 0x06000002, 0x0279ff04, 0x0700ffff,
+	0x010440d7, 0x0179fe44, 0x0700ffff, 0x045c0404,
+	0x07818295, 0x0349f044, 0x0681829e, 0x02495001,
+	0x06818297, 0x060ff079, 0x045c0440, 0x0781823c,
+	0x0644f07a, 0x002fb008, 0x060ff079, 0x045c0440,
+	0x07818241, 0x0644f07a, 0x002fb008, 0x0648f001,
+	0x07818288, 0x04600e40, 0x050f80ff, 0x06480001,
+	0x04810257, 0x0448e001, 0x04810273, 0x02460001,
+	0x0644f001, 0x012fa80a, 0x04008040, 0x05a004ee,
+	0x0286828c, 0x05a004d8, 0x062da001, 0x013e4000,
+	0x06000080, 0x06930013, 0x02920013, 0x02800010,
+	0x0644f001, 0x012fa80a, 0x020ef002, 0x00860275,
+	0x04600840, 0x050f80ff, 0x053fa809, 0x06000002,
+	0x05780105, 0x00800440, 0x017c0105, 0x05000400,
+	0x06818275, 0x06601e02, 0x050f80ff, 0x053fa809,
+	0x06000002, 0x04602a40, 0x050f80ff, 0x070ff005,
+	0x053fa809, 0x06000002, 0x055c0405, 0x06818275,
+	0x04008040, 0x0045e008, 0x05a004d8, 0x00800251,
+	0x0644f001, 0x012fa80a, 0x050020d8, 0x04600440,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x06480001,
+	0x07818281, 0x05308000, 0x03040000, 0x06009040,
+	0x04a004dc, 0x00800251, 0x06a0060e, 0x054b0800,
+	0x056a0700, 0x06600c40, 0x050f80ff, 0x032fa00a,
+	0x00800251, 0x013e4000, 0x06000080, 0x01209288,
+	0x018004e4, 0x06009008, 0x05308000, 0x05004000,
+	0x04a004dc, 0x00800251, 0x02209002, 0x008002e5,
+	0x03209000, 0x008002e5, 0x02209004, 0x008002e5,
+	0x04a002fd, 0x062da001, 0x05308000, 0x05002000,
+	0x06009040, 0x04a004dc, 0x02800013, 0x013e4000,
+	0x06000080, 0x02495001, 0x078182db, 0x04600840,
+	0x050f80ff, 0x053fa809, 0x06000001, 0x0721f000,
+	0x0349f003, 0x058102aa, 0x0245f01f, 0x06000002,
+	0x018602db, 0x07601400, 0x050f80ff, 0x012fa809,
+	0x06480001, 0x058102db, 0x06602440, 0x050f80ff,
+	0x012fa809, 0x020ef001, 0x038682db, 0x019b02db,
+	0x050020d8, 0x062da001, 0x06303002, 0x05000430,
+	0x04600440, 0x050f80ff, 0x073fa012, 0x06000001,
+	0x028f82bf, 0x050040d8, 0x062da001, 0x07601e00,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x060ff004,
+	0x00540402, 0x048202d9, 0x06005051, 0x06006051,
+	0x06602240, 0x050f80ff, 0x063fa01a, 0x06000002,
+	0x06600a40, 0x050f80ff, 0x073fa00a, 0x07000003,
+	0x060ff040, 0x045a041f, 0x010eb0ff, 0x06930013,
+	0x02920013, 0x02800010, 0x04004002, 0x018002c9,
+	0x04a002fd, 0x062da001, 0x05308000, 0x07005000,
+	0x06009040, 0x04a004dc, 0x050080d8, 0x05a004e1,
+	0x062da001, 0x02800013, 0x050fd009, 0x050fd041,
+	0x013e4000, 0x06000080, 0x05308000, 0x03013000,
+	0x04a004dc, 0x010440d7, 0x0349f044, 0x048102f2,
+	0x062da001, 0x008f02f2, 0x03e00000, 0x062da001,
+	0x02800013, 0x0249c0e5, 0x06810013, 0x062da001,
+	0x07f00000, 0x07f00000, 0x033e5000, 0x070c0000,
+	0x018f02f6, 0x03800011, 0x050020d8, 0x04600440,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x07c00000,
+	0x002fb001, 0x03800306, 0x012fb000, 0x03075087,
+	0x068d0307, 0x03386000, 0x03020000, 0x04482075,
+	0x06810352, 0x0648a0e6, 0x07810347, 0x0642007f,
+	0x06810345, 0x0340007e, 0x060ff038, 0x0154047e,
+	0x02d00334, 0x0560027d, 0x050f80ff, 0x032fa009,
+	0x030ef000, 0x02860504, 0x0107d000, 0x05600800,
+	0x050f80ff, 0x032fa009, 0x03681e00, 0x04500420,
+	0x050f80ff, 0x073fa009, 0x0700003f, 0x03800311,
+	0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819,
+	0x078d0327, 0x02080001, 0x00081002, 0x0448807a,
+	0x0781032e, 0x0379ff03, 0x070000ff, 0x01082003,
+	0x068d032f, 0x02386004, 0x03010000, 0x072e6c00,
+	0x02800352, 0x0380033a, 0x0380033c, 0x0280033e,
+	0x02800340, 0x03800342, 0x03800344, 0x0727c005,
+	0x02800323, 0x0627c008, 0x02800323, 0x0627c00b,
+	0x02800323, 0x0627c00e, 0x02800323, 0x0727c011,
+	0x02800323, 0x03800314, 0x052e6800, 0x02800352,
+	0x044880e6, 0x07810533, 0x052e6200, 0x070ff088,
+	0x0179feff, 0x070fffff, 0x04818501, 0x060ff083,
+	0x0086836d, 0x033e6000, 0x07000003, 0x068d0352,
+	0x07286000, 0x07f00000, 0x078d0355, 0x038c0306,
+	0x0648c0e6, 0x05818372, 0x0448e0e6, 0x0781036a,
+	0x004920e6, 0x07810365, 0x07a0056f, 0x05001088,
+	0x00700101, 0x03100000, 0x00088001, 0x033e6000,
+	0x07000088, 0x03800560, 0x02386001, 0x07030000,
+	0x033e6000, 0x06000008, 0x028003f1, 0x02799075,
+	0x0500040f, 0x06810010, 0x06601479, 0x050080ff,
+	0x06309052, 0x0600003e, 0x02800376, 0x06602279,
+	0x050080ff, 0x05309812, 0x07000041, 0x0648007a,
+	0x0781037e, 0x04488075, 0x0581837e, 0x040f8008,
+	0x070fa009, 0x0049107a, 0x01a183f3, 0x00798075,
+	0x06000507, 0x05818521, 0x0448b075, 0x06810385,
+	0x02493075, 0x0681050e, 0x0249c0e6, 0x048183e0,
+	0x0648c0e6, 0x0581839a, 0x068d0389, 0x02386001,
+	0x07030000, 0x0049107a, 0x07810390, 0x020ef083,
+	0x0386039a, 0x06483075, 0x068103ef, 0x0678007a,
+	0x07000035, 0x03a184cf, 0x05308000, 0x07060000,
+	0x06009079, 0x04a004dc, 0x028003ef, 0x0448807a,
+	0x0681039e, 0x06483075, 0x058104f9, 0x0448d07a,
+	0x068103a2, 0x06483075, 0x058104f9, 0x068d03a2,
+	0x02386001, 0x07030000, 0x0444e07a, 0x0648307a,
+	0x048183c7, 0x0448707a, 0x068103ea, 0x0648f07a,
+	0x078103b2, 0x05a004cf, 0x04008079, 0x05a004ee,
+	0x008683c2, 0x05a004d8, 0x028003ef, 0x0560107b,
+	0x050f80ff, 0x032fa009, 0x0349c000, 0x058183c0,
+	0x04600e79, 0x050f80ff, 0x073fa00a, 0x0600003d,
+	0x06600a79, 0x050f80ff, 0x053fa80a, 0x06000010,
+	0x028003ef, 0x0046e07a, 0x028003ea, 0x06009008,
+	0x05308000, 0x05004000, 0x04a004dc, 0x028003ef,
+	0x0560167b, 0x050f80ff, 0x032fa011, 0x070ff000,
+	0x04500401, 0x030460ff, 0x060ff025, 0x00540446,
+	0x078203d1, 0x030460ff, 0x04092046, 0x05a00218,
+	0x06600679, 0x050f80ff, 0x00201007, 0x012fa80a,
+	0x0046047a, 0x034630ff, 0x050020ff, 0x06003051,
+	0x04600e79, 0x050f80ff, 0x073fa012, 0x06000001,
+	0x028003ef, 0x033e6a00, 0x0202000e, 0x02079051,
+	0x07000088, 0x078d03e4, 0x0744c000, 0x01088000,
+	0x03386006, 0x03010000, 0x02800010, 0x05a004cf,
+	0x05308000, 0x03020000, 0x06009079, 0x04a004dc,
+	0x033e6a00, 0x0302000a, 0x02079051, 0x02800010,
+	0x04603e79, 0x050f80ff, 0x032fa009, 0x070ff000,
+	0x0186040c, 0x057dfeff, 0x07ffffff, 0x0581040c,
+	0x050f8000, 0x012fa811, 0x0079fe02, 0x070000ff,
+	0x077d66ff, 0x060000dc, 0x0781840c, 0x060ff001,
+	0x0286840d, 0x064b0002, 0x06420002, 0x060ff002,
+	0x05500400, 0x050f80ff, 0x05004084, 0x073fa00a,
+	0x06000002, 0x07c00000, 0x04600201, 0x050f80ff,
+	0x073fa009, 0x06000001, 0x0079fe02, 0x070000ff,
+	0x077d72ff, 0x070000dd, 0x0781840c, 0x064b0002,
+	0x06420002, 0x06000001, 0x01800406, 0x0605004c,
+	0x0180041e, 0x0493041a, 0x04a004d5, 0x054bc450,
+	0x05810421, 0x01d00422, 0x01800421, 0x00800432,
+	0x00800434, 0x00800432, 0x008004a7, 0x0180043f,
+	0x00800434, 0x01800471, 0x00800432, 0x00800432,
+	0x008004ab, 0x00800432, 0x018004af, 0x008004c4,
+	0x01800488, 0x00800432, 0x00800432, 0x00209432,
+	0x018004e4, 0x0379ff50, 0x070fffff, 0x060ff079,
+	0x055c0450, 0x048104a4, 0x002fb008, 0x060ff079,
+	0x055c0450, 0x058104a3, 0x04a004c7, 0x0180049c,
+	0x0179fe50, 0x070fffff, 0x070050ff, 0x060ff079,
+	0x055c0405, 0x04810449, 0x002fb008, 0x060ff079,
+	0x055c0405, 0x078184a0, 0x070ff087, 0x017980ff,
+	0x06000507, 0x06818451, 0x02203040, 0x05002087,
+	0x0049d002, 0x0481046b, 0x04930458, 0x01257000,
+	0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+	0x0304c050, 0x02400057, 0x06740057, 0x06000002,
+	0x06820016, 0x04002083, 0x07003084, 0x04004085,
+	0x06602279, 0x050f80ff, 0x063fa01a, 0x06000001,
+	0x05a004cf, 0x07a00578, 0x033e6a00, 0x0302000a,
+	0x062e5020, 0x003e4002, 0x07000a00, 0x028003f1,
+	0x07420003, 0x0781844e, 0x00798002, 0x06000507,
+	0x06818451, 0x0180045c, 0x05930478, 0x01257000,
+	0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+	0x0304c050, 0x067800e6, 0x07000041, 0x0581047d,
+	0x07a00581, 0x04818016, 0x002fb008, 0x067800e6,
+	0x07000041, 0x04810483, 0x07a00581, 0x04818016,
+	0x062e5020, 0x003e4002, 0x07000a00, 0x03e00000,
+	0x02800010, 0x0379ff50, 0x070fffff, 0x060ff079,
+	0x055c0450, 0x0781848e, 0x0245507a, 0x002fb008,
+	0x060ff079, 0x055c0450, 0x07818493, 0x0245507a,
+	0x002fb008, 0x05600e50, 0x050f80ff, 0x012fa809,
+	0x02455001, 0x05600e50, 0x050f80ff, 0x012fa80a,
+	0x0080049d, 0x002fb008, 0x003e4002, 0x07000a00,
+	0x02800016, 0x079384a3, 0x062e5020, 0x042e4002,
+	0x002fb008, 0x013e4000, 0x05000e00, 0x02800016,
+	0x0179fe50, 0x070fffff, 0x010210ff, 0x02800016,
+	0x0179fe50, 0x070fffff, 0x050340ff, 0x0080049d,
+	0x0179fe50, 0x070fffff, 0x0102e0ff, 0x0760282e,
+	0x050f80ff, 0x05222000, 0x07223000, 0x05224000,
+	0x07225000, 0x07226000, 0x05227000, 0x05228000,
+	0x07229000, 0x0722a000, 0x0522b000, 0x063fa051,
+	0x07000011, 0x0202c026, 0x0522d000, 0x052e400c,
+	0x02800016, 0x030430d4, 0x062e5008, 0x00800176,
+	0x05600e50, 0x050f80ff, 0x032fa009, 0x03460000,
+	0x018004d2, 0x0246007a, 0x0045207a, 0x008004d0,
+	0x0246007a, 0x0600007a, 0x04600e79, 0x050f80ff,
+	0x032fa00a, 0x07c00000, 0x029284d5, 0x070500e1,
+	0x07c00000, 0x0245f008, 0x048404d9, 0x020e0008,
+	0x07c00000, 0x070ff009, 0x065a0008, 0x058404de,
+	0x020e0008, 0x07c00000, 0x058404e1, 0x020e0008,
+	0x07c00000, 0x05308000, 0x0500d000, 0x04a004dc,
+	0x04a004e9, 0x02800010, 0x052e4300, 0x072e500c,
+	0x073c3fff, 0x0700000f, 0x07c00000, 0x06602208,
+	0x050f80ff, 0x032fa011, 0x076a0000, 0x068184f7,
+	0x066a0001, 0x048104f7, 0x04002051, 0x07c00000,
+	0x00202001, 0x07c00000, 0x0648307a, 0x00a18608,
+	0x05a004cc, 0x05308000, 0x05001000, 0x06009079,
+	0x04a004dc, 0x03800560, 0x0249c0e6, 0x058104f9,
+	0x0280036d, 0x0648307a, 0x07818196, 0x05a004cf,
+	0x05308000, 0x03013000, 0x03209006, 0x04a004dc,
+	0x033e6000, 0x07030000, 0x02800345, 0x02490075,
+	0x0781051e, 0x04002089, 0x04780102, 0x07f00000,
+	0x05001088, 0x07a0056f, 0x04740101, 0x03100000,
+	0x060ff002, 0x045c0401, 0x0481851f, 0x00088001,
+	0x033e6000, 0x070000c0, 0x0380055c, 0x07f00000,
+	0x0220951f, 0x018004e4, 0x0648307a, 0x07810527,
+	0x06780075, 0x06000007, 0x0581852e, 0x06a00608,
+	0x06486075, 0x06818194, 0x02490075, 0x0781819a,
+	0x04487075, 0x05818536, 0x0280053d, 0x05308000,
+	0x03010000, 0x06009079, 0x04a004dc, 0x02800010,
+	0x0448e0e6, 0x04818352, 0x00800192, 0x05308000,
+	0x0500e000, 0x06009079, 0x04a004dc, 0x04008089,
+	0x05a004e1, 0x0380055c, 0x05a004cc, 0x05308000,
+	0x0700f000, 0x06009079, 0x07000088, 0x06a00545,
+	0x04a004dc, 0x02800010, 0x03386000, 0x07030000,
+	0x07f00000, 0x078d0548, 0x033e6a00, 0x0202000e,
+	0x02079051, 0x0448b075, 0x07810553, 0x02493075,
+	0x07810553, 0x05301005, 0x03010000, 0x03800555,
+	0x05301006, 0x03010000, 0x05002087, 0x06485002,
+	0x05818555, 0x0744c000, 0x01088000, 0x02086001,
+	0x07c00000, 0x05001088, 0x07a0056f, 0x0644c001,
+	0x00088001, 0x033e6a00, 0x0202000e, 0x004920e6,
+	0x05818565, 0x02079051, 0x078d0565, 0x060ff089,
+	0x034990ff, 0x0781056c, 0x03386005, 0x03010000,
+	0x02800010, 0x03386006, 0x03010000, 0x02800010,
+	0x078d056f, 0x03386000, 0x07030000, 0x07f00000,
+	0x068d0573, 0x070ff087, 0x074850ff, 0x05818574,
+	0x07c00000, 0x078d0578, 0x02386001, 0x07030000,
+	0x07f00000, 0x068d057c, 0x070ff087, 0x074850ff,
+	0x0581857d, 0x07c00000, 0x05002087, 0x0049d002,
+	0x05818590, 0x002fb008, 0x067800e6, 0x07000041,
+	0x002fb008, 0x05818590, 0x07a005a6, 0x0448e002,
+	0x07810593, 0x0648a002, 0x0481859d, 0x06486002,
+	0x06810597, 0x02400057, 0x056a02ff, 0x07c00000,
+	0x07a005a6, 0x06788102, 0x06000004, 0x05818590,
+	0x04002089, 0x070ff0d4, 0x045c0402, 0x077800ff,
+	0x07f00000, 0x05818590, 0x00202010, 0x038c0590,
+	0x07f00000, 0x06420002, 0x0481859e, 0x07a00578,
+	0x033e6a00, 0x0302000a, 0x07c00000, 0x07f00000,
+	0x060ff0a2, 0x050020ff, 0x060ff0a2, 0x045c0402,
+	0x048185a7, 0x07c00000, 0x05a00218, 0x03495047,
+	0x078105b2, 0x0320901d, 0x02800604, 0x0220901f,
+	0x02800604, 0x014980e4, 0x04818010, 0x013e4000,
+	0x07003000, 0x05600e35, 0x050f80ff, 0x07a006fc,
+	0x01208003, 0x05a004e1, 0x038005cc, 0x03209009,
+	0x02800604, 0x03209011, 0x02800604, 0x02209007,
+	0x02800604, 0x03209003, 0x02800604, 0x00498043,
+	0x058185be, 0x00497043, 0x048185c2, 0x02209001,
+	0x02800604, 0x0220900d, 0x02800604, 0x0320900f,
+	0x02800604, 0x03493000, 0x068105d5, 0x027c0045,
+	0x070a0000, 0x078105de, 0x0220900b, 0x02800604,
+	0x02209013, 0x05308000, 0x01012000, 0x04a004dc,
+	0x00800183, 0x03209005, 0x02800604, 0x072e500c,
+	0x00208002, 0x05a004e1, 0x02800010, 0x02209015,
+	0x02800604, 0x072d6000, 0x05308000, 0x05007000,
+	0x07f00000, 0x070090d1, 0x0379ff09, 0x0700ffff,
+	0x04a004dc, 0x03209017, 0x02800604, 0x033e5000,
+	0x06000080, 0x02209019, 0x02800604, 0x072d6000,
+	0x033e5000, 0x06000080, 0x07f00000, 0x060ff0d0,
+	0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+	0x04818010, 0x02400058, 0x00642058, 0x06820010,
+	0x033e5000, 0x06000080, 0x04058051, 0x0320901b,
+	0x02800604, 0x05308000, 0x01012000, 0x04a004dc,
+	0x00800176, 0x05a00218, 0x05308000, 0x05008000,
+	0x06009079, 0x04a004dc, 0x07c00000, 0x034900e4,
+	0x05818618, 0x013e4000, 0x070000c0, 0x07f00000,
+	0x034900e4, 0x04818616, 0x07c00000, 0x013e4000,
+	0x06000080, 0x07f00000, 0x07f00000, 0x07f00000,
+	0x034900e4, 0x06810610, 0x03800618, 0x072d6000,
+	0x00498043, 0x06810632, 0x060ff0d0, 0x0179feff,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x058185e2,
+	0x050f8030, 0x032fa009, 0x0379ff00, 0x0700ffff,
+	0x070ff0d1, 0x0179feff, 0x0700ffff, 0x055c0400,
+	0x078105e2, 0x04004051, 0x0280067a, 0x06a006dc,
+	0x062d6001, 0x020ef004, 0x038605e4, 0x06600004,
+	0x050f80ff, 0x032fa009, 0x074b0000, 0x05002000,
+	0x0769ff00, 0x01640800, 0x078205e4, 0x01640e00,
+	0x058285e4, 0x070ff036, 0x045c0404, 0x0581864d,
+	0x072d6000, 0x050f8030, 0x032fa009, 0x0379ff00,
+	0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+	0x055c0400, 0x078105e2, 0x04482034, 0x078105ff,
+	0x06483034, 0x058185ff, 0x070ff0d4, 0x077800ff,
+	0x070000f0, 0x037c00ff, 0x06000010, 0x0681067a,
+	0x06a006d6, 0x024900e5, 0x0681065d, 0x033e5000,
+	0x06000080, 0x02800010, 0x04601c04, 0x050f80ff,
+	0x053fa809, 0x06000020, 0x030ef041, 0x038605ee,
+	0x062d6002, 0x05602a41, 0x050f80ff, 0x012fa809,
+	0x060ff0d0, 0x074b00ff, 0x045c0401, 0x05818678,
+	0x062d6001, 0x07602841, 0x050f80ff, 0x053fa809,
+	0x06000001, 0x070ff0d1, 0x054b80ff, 0x074b0003,
+	0x055c0403, 0x05818678, 0x033e5000, 0x06000080,
+	0x0080070e, 0x07600041, 0x0280065e, 0x06a006d6,
+	0x024900e5, 0x06810680, 0x033e5000, 0x06000080,
+	0x02800010, 0x06a006c2, 0x030ef041, 0x028605f2,
+	0x04058051, 0x072d6000, 0x05601041, 0x050f80ff,
+	0x012fa809, 0x0600a0d0, 0x0500b0d1, 0x062d6001,
+	0x07f00000, 0x07f00000, 0x0600c0d0, 0x0500d0d1,
+	0x062d6002, 0x0279ff0d, 0x07ff0000, 0x044d800d,
+	0x060ff0d0, 0x074b00ff, 0x065a000d, 0x06601201,
+	0x050f80ff, 0x073fa022, 0x07000005, 0x0079fe0d,
+	0x070000ff, 0x050020ff, 0x05602a41, 0x050f80ff,
+	0x073fa00a, 0x06000001, 0x020ef004, 0x028606bf,
+	0x04601c04, 0x050f80ff, 0x053fa809, 0x06000001,
+	0x050f80ff, 0x053fa80a, 0x06000020, 0x07602841,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x0279ff02,
+	0x070000ff, 0x0678000d, 0x0700ff00, 0x065a0002,
+	0x07602841, 0x050f80ff, 0x073fa00a, 0x06000001,
+	0x07600041, 0x050f80ff, 0x053fa80a, 0x06000001,
+	0x07601241, 0x050f80ff, 0x073fa00a, 0x06000002,
+	0x033e5000, 0x06000080, 0x0080070e, 0x040f8032,
+	0x073fa011, 0x06000001, 0x060ff002, 0x055c0403,
+	0x058186ca, 0x00041051, 0x07c00000, 0x04600402,
+	0x04500432, 0x050f80ff, 0x053fa809, 0x06000020,
+	0x00400402, 0x01680eff, 0x070030ff, 0x040f8032,
+	0x053fa80a, 0x06000001, 0x07c00000, 0x024900e5,
+	0x068106d9, 0x07c00000, 0x033e5000, 0x070000c0,
+	0x07c00000, 0x05004036, 0x060000d0, 0x0179fe00,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068106fb,
+	0x070000d1, 0x0379ff00, 0x0700ffff, 0x06005051,
+	0x060ff031, 0x05500405, 0x050f80ff, 0x073fa009,
+	0x06000002, 0x020ef004, 0x038606f5, 0x04600404,
+	0x050f80ff, 0x012fa809, 0x0079fe01, 0x0700ffff,
+	0x055c0400, 0x068106fb, 0x01400405, 0x070050ff,
+	0x057de0ff, 0x06000007, 0x058186e7, 0x04004051,
+	0x07c00000, 0x072d6000, 0x07f00000, 0x07f00000,
+	0x000110d0, 0x010120d1, 0x062d6001, 0x07f00000,
+	0x07f00000, 0x020130d0, 0x010140d1, 0x062d6002,
+	0x010170d4, 0x07f00000, 0x020150d0, 0x030160d1,
+	0x053fa83a, 0x06000008, 0x07c00000, 0x07600c41,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x04780102,
+	0x07ffff00, 0x046a0702, 0x050f80ff, 0x073fa00a,
+	0x06000001, 0x05600e41, 0x050f80ff, 0x032fa069,
+	0x03800053, 0xba6b4e34, 0x02800004, 0x00000000,
+	0x00008000, 0x00000518, 0x040f801f, 0x012fa8c9,
+	0x040f801f, 0x073fa081, 0x06000010, 0x03200005,
+	0x07420000, 0x050fb000, 0x040f801f, 0x073fa011,
+	0x06000038, 0x040f801f, 0x053fa859, 0x0700003a,
+	0x050fe000, 0x0581800a, 0x0684003d, 0x04958019,
+	0x030e0011, 0x072e4200, 0x03800014, 0x0291001f,
+	0x050010c0, 0x04482001, 0x058180e8, 0x06483001,
+	0x0781814b, 0x02920029, 0x068b0029, 0x018a0150,
+	0x050010c0, 0x06780001, 0x050007c0, 0x06818223,
+	0x06780001, 0x0500f800, 0x07818263, 0x03910030,
+	0x040fe029, 0x03860030, 0x076c001d, 0x04810294,
+	0x076c0a1d, 0x048102b9, 0x0292003d, 0x040fe02f,
+	0x0286003d, 0x06000013, 0x050fb000, 0x066c0073,
+	0x068103c2, 0x0297003d, 0x014920e4, 0x0481803d,
+	0x03400000, 0x076c0a00, 0x04818034, 0x0796003f,
+	0x03b900b8, 0x05908014, 0x010170e1, 0x07780017,
+	0x03e00000, 0x06810092, 0x050010ff, 0x0179fe17,
+	0x031fffff, 0x070000ff, 0x05600800, 0x050f80ff,
+	0x073fa009, 0x06000001, 0x06780002, 0x02800040,
+	0x037c00ff, 0x03800000, 0x0681005e, 0x0249f002,
+	0x068100ab, 0x0448e002, 0x0681005e, 0x07600c00,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x06780002,
+	0x07ffff00, 0x037c00ff, 0x05000200, 0x048180ab,
+	0x064bd401, 0x03d00060, 0x038000a9, 0x02800068,
+	0x03800072, 0x0280007c, 0x02800086, 0x03800090,
+	0x038000a9, 0x038000a9, 0x050fe027, 0x0186806c,
+	0x01028000, 0x0380006f, 0x07600027, 0x050f80ff,
+	0x032fa00a, 0x01027000, 0x02400029, 0x028000ab,
+	0x040fe025, 0x00868076, 0x03026000, 0x02800079,
+	0x06600025, 0x050f80ff, 0x032fa00a, 0x03025000,
+	0x02400029, 0x028000ab, 0x050fe021, 0x00868080,
+	0x01022000, 0x02800083, 0x07600021, 0x050f80ff,
+	0x032fa00a, 0x01021000, 0x02400029, 0x028000ab,
+	0x040fe023, 0x0086808a, 0x01024000, 0x0380008d,
+	0x06600023, 0x050f80ff, 0x032fa00a, 0x03023000,
+	0x02400029, 0x028000ab, 0x06a000c8, 0x028000ab,
+	0x01640817, 0x058280a9, 0x070ff017, 0x03d00096,
+	0x0280009e, 0x038000a0, 0x038000a3, 0x038000a6,
+	0x038000a9, 0x038000a9, 0x038000a9, 0x038000a9,
+	0x03e00000, 0x03800014, 0x059080a0, 0x030160e1,
+	0x028000ab, 0x059080a3, 0x030150e1, 0x028000ab,
+	0x059080a6, 0x010140e1, 0x028000ab, 0x060fc013,
+	0x06a00510, 0x03800014, 0x072e4800, 0x07000012,
+	0x038000bb, 0x0747f000, 0x05600800, 0x050f80ff,
+	0x012fa809, 0x0249f001, 0x078100bb, 0x01012000,
+	0x052e4c00, 0x07c00000, 0x070000eb, 0x0349f000,
+	0x058180af, 0x05600800, 0x050f80ff, 0x012fa809,
+	0x0448e001, 0x068100c1, 0x07c00000, 0x0079c101,
+	0x07ffffff, 0x027a4b01, 0x03800000, 0x05600800,
+	0x050f80ff, 0x012fa80a, 0x07600c00, 0x050f80ff,
+	0x012fa821, 0x06780001, 0x07ffff00, 0x037c00ff,
+	0x05000700, 0x078100dd, 0x06601804, 0x070030ff,
+	0x050f80ff, 0x012fa809, 0x05002000, 0x050f8003,
+	0x073fa00a, 0x06000001, 0x040fe001, 0x038600de,
+	0x04600201, 0x050f80ff, 0x032fa00a, 0x07c00000,
+	0x050fe02e, 0x008680e3, 0x0102e000, 0x0302f000,
+	0x038000e7, 0x0760002e, 0x050f80ff, 0x032fa00a,
+	0x0102e000, 0x07c00000, 0x022c0004, 0x056c041d,
+	0x078100fc, 0x056c021d, 0x04810113, 0x056c081d,
+	0x04810125, 0x076c061d, 0x0581013f, 0x0521d000,
+	0x0202c013, 0x0202a013, 0x02020013, 0x0460021a,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x03b600ac,
+	0x0484801f, 0x0280003d, 0x040fe02a, 0x028600f2,
+	0x06000013, 0x04001013, 0x0560102b, 0x050f80ff,
+	0x032fa012, 0x06420029, 0x0660002a, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x050fe003, 0x00860110,
+	0x01028003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+	0x07000009, 0x00800140, 0x00028013, 0x00027013,
+	0x00800140, 0x040fe02a, 0x028600f1, 0x06420029,
+	0x0660002a, 0x050f80ff, 0x053fa809, 0x06000001,
+	0x050fe003, 0x01860122, 0x03026003, 0x0660002a,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x00800140,
+	0x02026013, 0x02025013, 0x00800140, 0x040fe02a,
+	0x028600f1, 0x06420029, 0x0660002a, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x050fe003, 0x00860134,
+	0x01022003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+	0x07000009, 0x01800136, 0x00022013, 0x00021013,
+	0x0647f020, 0x007a0120, 0x04000101, 0x04a00285,
+	0x0400802a, 0x05a004f5, 0x009480f1, 0x0521d005,
+	0x028000f2, 0x038000fa, 0x0647f020, 0x06486020,
+	0x06818145, 0x04a00285, 0x028000f1, 0x007a0120,
+	0x04000101, 0x04a00285, 0x0400802a, 0x05a004f5,
+	0x028000f1, 0x040fd02a, 0x052e4003, 0x00208010,
+	0x05a004f5, 0x038000fa, 0x00018098, 0x07480018,
+	0x06818161, 0x05481018, 0x0781815f, 0x05482018,
+	0x0681815d, 0x07483018, 0x0681815b, 0x002fb004,
+	0x00800162, 0x012fb003, 0x00800162, 0x002fb002,
+	0x00800162, 0x002fb001, 0x00800162, 0x012fb000,
+	0x0179fe78, 0x070000ff, 0x030190ff, 0x00017086,
+	0x058b0166, 0x03385000, 0x03020000, 0x07780017,
+	0x00430407, 0x078181ee, 0x046c0419, 0x048101a2,
+	0x046c0219, 0x05810172, 0x07219000, 0x00800186,
+	0x07219000, 0x07483017, 0x0481018c, 0x05482017,
+	0x05810193, 0x0448b075, 0x06818186, 0x06601476,
+	0x050f80ff, 0x073fa022, 0x0600003e, 0x06000080,
+	0x05001081, 0x05002082, 0x06003083, 0x05004084,
+	0x04601c76, 0x050f80ff, 0x022fa02a, 0x07219000,
+	0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+	0x0484801f, 0x0280003d, 0x040fe07f, 0x0086019b,
+	0x05a001bb, 0x00920186, 0x040fe07f, 0x07a681bb,
+	0x00800186, 0x0560107b, 0x050f80ff, 0x032fa009,
+	0x0744f000, 0x0560107b, 0x050f80ff, 0x032fa00a,
+	0x00800179, 0x052e400c, 0x040080fb, 0x046aa108,
+	0x06009076, 0x04002075, 0x05a004fc, 0x00800186,
+	0x06219001, 0x05482017, 0x058101af, 0x058b01a5,
+	0x060ff086, 0x0349f0ff, 0x07818165, 0x07483017,
+	0x058101ac, 0x050fd0ff, 0x040fe07f, 0x07a681bb,
+	0x00800186, 0x05004084, 0x05a00205, 0x00920186,
+	0x070ff07d, 0x0450047c, 0x056004ff, 0x050f80ff,
+	0x032fa009, 0x070ff000, 0x00540479, 0x030790ff,
+	0x01800193, 0x060ff079, 0x0054047a, 0x058201e7,
+	0x058101e7, 0x070ff07d, 0x0450047c, 0x050f80ff,
+	0x002fa819, 0x058b01c3, 0x02080001, 0x00081002,
+	0x01082003, 0x048b01c7, 0x03385000, 0x03010000,
+	0x02400019, 0x070ff003, 0x04500479, 0x030790ff,
+	0x0340007e, 0x0642007f, 0x058101e7, 0x070ff07e,
+	0x050f80ff, 0x032fa009, 0x050fe000, 0x028681e6,
+	0x070ff07d, 0x056002ff, 0x050f80ff, 0x032fa009,
+	0x0107d000, 0x018601e8, 0x0560087d, 0x050f80ff,
+	0x032fa009, 0x0569fe00, 0x0550041b, 0x050f80ff,
+	0x032fa009, 0x0107e000, 0x070ff07e, 0x018001d2,
+	0x0307c000, 0x07c00000, 0x052e400c, 0x040080fb,
+	0x046aa108, 0x06009076, 0x04002075, 0x018004fc,
+	0x040fd076, 0x050fd017, 0x060ff086, 0x077800ff,
+	0x07000060, 0x037c00ff, 0x07000060, 0x078181f0,
+	0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+	0x06601476, 0x050f80ff, 0x073fa022, 0x0600003e,
+	0x052e400c, 0x040080fb, 0x066a8108, 0x06009076,
+	0x04002075, 0x05a004fc, 0x02800029, 0x0240007f,
+	0x0742007e, 0x050f807e, 0x032fa009, 0x050fe000,
+	0x0286821f, 0x070ff07d, 0x055c047b, 0x05810214,
+	0x0760007d, 0x050f80ff, 0x032fa009, 0x050fe000,
+	0x03868214, 0x070ff07b, 0x0107d0ff, 0x0560087d,
+	0x050f80ff, 0x032fa009, 0x03681e00, 0x0450041c,
+	0x0107e0ff, 0x050f80ff, 0x032fa009, 0x050fe000,
+	0x01860221, 0x0307c000, 0x07c00000, 0x040fd076,
+	0x02800510, 0x010180c0, 0x0548e018, 0x0781823c,
+	0x0748f018, 0x06818238, 0x03490018, 0x06818234,
+	0x01491018, 0x07818230, 0x073c0000, 0x06000040,
+	0x02200004, 0x0180023f, 0x073c0000, 0x06000020,
+	0x03200003, 0x0180023f, 0x073c0000, 0x06000010,
+	0x02200002, 0x0180023f, 0x073c0000, 0x06000008,
+	0x02200001, 0x0180023f, 0x073c0000, 0x06000004,
+	0x06000013, 0x050fb000, 0x040fe076, 0x00860258,
+	0x046c0273, 0x04810268, 0x066c0073, 0x04810249,
+	0x040fd076, 0x06a00510, 0x03800014, 0x040fd076,
+	0x0080024c, 0x00452075, 0x00077013, 0x0647f075,
+	0x06486075, 0x06818252, 0x05a0028b, 0x00800258,
+	0x007a0175, 0x04000101, 0x05a0028b, 0x04008076,
+	0x0245f008, 0x05a004f5, 0x07273000, 0x05600272,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x0379ff78,
+	0x070000ff, 0x02076013, 0x02075013, 0x0484801f,
+	0x0280003d, 0x070fc0ff, 0x052e400c, 0x00208020,
+	0x05a004f5, 0x00800261, 0x04600276, 0x050010ff,
+	0x040f8001, 0x032fa009, 0x040f8001, 0x053fa80a,
+	0x07000009, 0x070ff000, 0x0286827a, 0x06601276,
+	0x050f80ff, 0x073fa009, 0x0700000c, 0x07601818,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x0180027b,
+	0x07a000de, 0x0448b075, 0x0581024b, 0x06000013,
+	0x04001013, 0x0560107b, 0x050f80ff, 0x032fa012,
+	0x0046b075, 0x03b600ac, 0x0080024c, 0x06000020,
+	0x04001016, 0x0460082a, 0x050f80ff, 0x032fa012,
+	0x07c00000, 0x06000075, 0x040010a2, 0x044b0801,
+	0x060ff016, 0x065a0001, 0x04600876, 0x050f80ff,
+	0x032fa012, 0x07c00000, 0x050fe022, 0x0186029a,
+	0x0421d004, 0x0302a022, 0x04a002c1, 0x018002b1,
+	0x040fe026, 0x008602b3, 0x0421d001, 0x0202a026,
+	0x04a002c1, 0x0202c013, 0x00683e20, 0x070060ff,
+	0x056c0206, 0x048102f4, 0x056c0406, 0x0781030a,
+	0x076c0606, 0x06810379, 0x056c1606, 0x078182b1,
+	0x04488020, 0x07810387, 0x040fd02a, 0x0521d000,
+	0x0202a013, 0x02020013, 0x008002b3, 0x04a004ec,
+	0x008002bf, 0x050fe028, 0x008602bf, 0x0302a028,
+	0x0421d002, 0x04a002c1, 0x008002c8, 0x050fe022,
+	0x008602bf, 0x0421d004, 0x0302a022, 0x04a002c1,
+	0x04a004ec, 0x05848030, 0x0280003d, 0x0460082a,
+	0x050f80ff, 0x022fa031, 0x03020000, 0x0002b004,
+	0x01018005, 0x07c00000, 0x0400702a, 0x06a003ba,
+	0x007a0101, 0x07060000, 0x07303000, 0x07008290,
+	0x07600018, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x0448e007, 0x068182d6, 0x06006013, 0x018002dd,
+	0x02400010, 0x048102d6, 0x06006010, 0x0460322a,
+	0x050f80ff, 0x073fa00a, 0x07000003, 0x050f801e,
+	0x032fa03a, 0x063aa020, 0x06000002, 0x013e4000,
+	0x07000030, 0x009802e3, 0x070ff0f6, 0x036830ff,
+	0x078182e4, 0x070f001e, 0x0560102b, 0x050f10ff,
+	0x063f3c08, 0x0600000d, 0x013e4000, 0x06000020,
+	0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+	0x0202c013, 0x008002bf, 0x04007013, 0x06a003ba,
+	0x007a0101, 0x07050000, 0x07303000, 0x07008890,
+	0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x05601a2b, 0x050f80ff, 0x022fa019, 0x04001002,
+	0x04002013, 0x040f801f, 0x022fa01a, 0x073aa00c,
+	0x06000002, 0x07300c03, 0x0600000d, 0x028003a7,
+	0x04007013, 0x06a003ba, 0x007a0101, 0x03070000,
+	0x0660282a, 0x050f80ff, 0x073fa009, 0x06000004,
+	0x02499008, 0x07810317, 0x07303000, 0x07008890,
+	0x02800319, 0x07303000, 0x04008980, 0x05007003,
+	0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x0760142b, 0x050f80ff, 0x032fa021, 0x064b0002,
+	0x02499008, 0x06810325, 0x0644c002, 0x054b0400,
+	0x050040ff, 0x06698104, 0x0581833a, 0x06000013,
+	0x04001013, 0x04780102, 0x06000010, 0x06003013,
+	0x04004013, 0x06005013, 0x06006013, 0x04007013,
+	0x00644015, 0x07820336, 0x04448002, 0x02205008,
+	0x040f801f, 0x032fa042, 0x04008015, 0x03800371,
+	0x046c8004, 0x05818348, 0x01208018, 0x06780002,
+	0x07000003, 0x0581834b, 0x06003001, 0x06000013,
+	0x04001013, 0x04004013, 0x06005013, 0x040f801f,
+	0x022fa032, 0x03800371, 0x040fd02a, 0x06a00510,
+	0x03800014, 0x04488002, 0x07810350, 0x070ff003,
+	0x04500408, 0x050080ff, 0x06489002, 0x06810357,
+	0x0379ff00, 0x070000ff, 0x070ff000, 0x04500408,
+	0x050080ff, 0x07005003, 0x05004000, 0x06003001,
+	0x06000013, 0x04001013, 0x040f801f, 0x022fa032,
+	0x05601c2b, 0x050f80ff, 0x022fa031, 0x06600c1f,
+	0x050f80ff, 0x022fa032, 0x02680608, 0x07810371,
+	0x016408ff, 0x057dfeff, 0x07ffffff, 0x034000ff,
+	0x045a0407, 0x070000ff, 0x0760061e, 0x050f80ff,
+	0x032fa00a, 0x06600908, 0x0669f908, 0x027a0008,
+	0x06000020, 0x070aa0ff, 0x014a20ff, 0x037a00ff,
+	0x060000dc, 0x070000ff, 0x028003a7, 0x04007013,
+	0x06a003ba, 0x007a0101, 0x07030000, 0x07303000,
+	0x07008190, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x073aa000, 0x06000002, 0x07300c00, 0x07000005,
+	0x028003a7, 0x04007013, 0x06a003ba, 0x007a0101,
+	0x07810000, 0x07303000, 0x07000090, 0x06006013,
+	0x06600c2a, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x04780107, 0x07ffff00, 0x007c0107, 0x07000500,
+	0x0581839a, 0x07303000, 0x05000890, 0x074d0005,
+	0x0660282a, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x0049d007, 0x068103a1, 0x02206001, 0x050f801e,
+	0x032fa03a, 0x073aa000, 0x06000002, 0x07300c00,
+	0x07000005, 0x013e4000, 0x07000030, 0x039803a9,
+	0x070ff0f6, 0x036830ff, 0x058183aa, 0x070f001e,
+	0x040f101f, 0x070f3000, 0x013e4000, 0x06000020,
+	0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+	0x008002bf, 0x03200000, 0x06006076, 0x028003bc,
+	0x03200011, 0x0600602a, 0x05a00441, 0x05600406,
+	0x050f80ff, 0x053fa809, 0x06000002, 0x07c00000,
+	0x0207602f, 0x04600876, 0x050f80ff, 0x022fa031,
+	0x03075000, 0x0007b004, 0x01018005, 0x06600076,
+	0x050020ff, 0x050f80ff, 0x012fa809, 0x0202f001,
+	0x008683d0, 0x0002e013, 0x040f8002, 0x053fa80a,
+	0x07000009, 0x06273001, 0x0448b075, 0x048183da,
+	0x04602076, 0x050f80ff, 0x053fa811, 0x0700003c,
+	0x0179fe78, 0x070000ff, 0x030190ff, 0x018683e2,
+	0x07a003f6, 0x00078019, 0x039203f5, 0x0180043a,
+	0x040fd076, 0x040fd019, 0x04600276, 0x050020ff,
+	0x050f80ff, 0x032fa009, 0x040f8002, 0x053fa80a,
+	0x07000009, 0x050fe000, 0x008683f2, 0x07601818,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x038003f3,
+	0x07a000de, 0x07273000, 0x02076013, 0x0280003d,
+	0x078b03f6, 0x03385000, 0x07030000, 0x05600818,
+	0x050f80ff, 0x032fa009, 0x054b0400, 0x0308a0ff,
+	0x0179fe00, 0x070000ff, 0x010880ff, 0x0448b075,
+	0x04810410, 0x0760147b, 0x050f80ff, 0x002fa819,
+	0x064b0001, 0x02080002, 0x01081003, 0x00082001,
+	0x02083001, 0x02079001, 0x0207a001, 0x00084013,
+	0x0207f013, 0x00800432, 0x06485075, 0x05810428,
+	0x02465075, 0x06601476, 0x050f80ff, 0x073fa021,
+	0x0600003e, 0x070ff07d, 0x0450047c, 0x050f80ff,
+	0x002fa819, 0x058b041b, 0x02080001, 0x00081002,
+	0x01082003, 0x03079003, 0x0208307a, 0x0340007e,
+	0x0642007f, 0x0581042d, 0x070ff07e, 0x05a001d2,
+	0x0392842d, 0x01800439, 0x058b0428, 0x06601476,
+	0x050f80ff, 0x073fa041, 0x0600003e, 0x06602476,
+	0x050f80ff, 0x073fa009, 0x06000007, 0x0008400e,
+	0x048b0432, 0x03385000, 0x03010000, 0x06219001,
+	0x040fe07f, 0x01860439, 0x018001bb, 0x07c00000,
+	0x00683e75, 0x0581043f, 0x0448d075, 0x05810465,
+	0x01800493, 0x05a004f0, 0x038003f5, 0x0297844c,
+	0x07602418, 0x050f80ff, 0x012fa809, 0x06780001,
+	0x070000ff, 0x075a0000, 0x070ff014, 0x0569feff,
+	0x054b08ff, 0x075a0000, 0x05600418, 0x050f80ff,
+	0x012fa809, 0x040fe007, 0x03868453, 0x01204000,
+	0x00800461, 0x00700101, 0x03010000, 0x06780001,
+	0x07ff0000, 0x076c00ff, 0x0681845b, 0x00700101,
+	0x03010000, 0x05600418, 0x050f80ff, 0x012fa80a,
+	0x06780001, 0x07ff0000, 0x050040ff, 0x0279ff01,
+	0x0700ffff, 0x05002014, 0x07c00000, 0x04007076,
+	0x0448b075, 0x0481047f, 0x03200011, 0x06006076,
+	0x06a003bc, 0x007a0101, 0x07060000, 0x07303000,
+	0x07008290, 0x07600018, 0x050f80ff, 0x053fa809,
+	0x07000003, 0x0448e007, 0x07818477, 0x06006013,
+	0x0180048e, 0x02400010, 0x05810477, 0x06006010,
+	0x04603276, 0x050f80ff, 0x073fa00a, 0x07000003,
+	0x0180048e, 0x04602a76, 0x050f80ff, 0x032fa009,
+	0x060ff07a, 0x05500400, 0x070000ff, 0x04602a76,
+	0x050f80ff, 0x032fa00a, 0x07a003b7, 0x007a0101,
+	0x03010000, 0x06303008, 0x05008000, 0x0600600e,
+	0x050f8074, 0x032fa03a, 0x053079a0, 0x0700000c,
+	0x008004d3, 0x00683e75, 0x076c0aff, 0x058104b2,
+	0x04007013, 0x03200011, 0x06006076, 0x06a003bc,
+	0x007a0101, 0x03070000, 0x06602876, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x03499003, 0x048104a7,
+	0x07303000, 0x07008890, 0x053079a0, 0x0700000c,
+	0x008004ab, 0x07303000, 0x04008980, 0x04307920,
+	0x0700000c, 0x074d0005, 0x06006013, 0x050f8074,
+	0x032fa03a, 0x04307920, 0x0700000c, 0x008004d3,
+	0x04602a76, 0x050f80ff, 0x032fa009, 0x060ff07a,
+	0x05500400, 0x070000ff, 0x04602a76, 0x050f80ff,
+	0x032fa00a, 0x04007076, 0x07a003b7, 0x007a0101,
+	0x03010000, 0x06303008, 0x07008800, 0x074d0005,
+	0x06600a76, 0x050f80ff, 0x073fa009, 0x07000003,
+	0x054b0406, 0x045a0404, 0x050040ff, 0x0600600e,
+	0x050f8074, 0x032fa03a, 0x0648c075, 0x058104d1,
+	0x06307d20, 0x0700000c, 0x008004d3, 0x04307920,
+	0x0700000c, 0x013e4000, 0x07000030, 0x009804d5,
+	0x070ff0f6, 0x074850ff, 0x068184d6, 0x050f2074,
+	0x060a0007, 0x040070fb, 0x046a7007, 0x050f40ff,
+	0x013e4000, 0x06000020, 0x0678007a, 0x07fff000,
+	0x068184e6, 0x0320000a, 0x022017d0, 0x008004e9,
+	0x0320000a, 0x06301b58, 0x06000001, 0x050f8072,
+	0x032fa012, 0x038003f5, 0x01208060, 0x0600902a,
+	0x04002020, 0x018004fc, 0x040080fb, 0x066ae108,
+	0x06009076, 0x04002075, 0x018004fc, 0x03201100,
+	0x078484fa, 0x06420001, 0x078184f6, 0x02800513,
+	0x020e0008, 0x07c00000, 0x050fd009, 0x040fd008,
+	0x03201100, 0x05848503, 0x06420001, 0x078184ff,
+	0x02800513, 0x007a0102, 0x04000101, 0x05600809,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x020e0008,
+	0x0684050d, 0x030e0009, 0x07c00000, 0x01011009,
+	0x052e4300, 0x07c00000, 0x052e400f, 0x01208090,
+	0x018004f5, 0x070fc0ff, 0x040f8013, 0x032fa009,
+	0x02800516, 0x15416ea9, 0xffef0b01
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length02 = 0x000014ff ;
+#else
+uint32_t risc_code_length02 = 0x000014ff ;
+#endif
+
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 48e460e..2efca52 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -232,7 +232,7 @@
 qla2x00_isp_name_show(struct class_device *cdev, char *buf)
 {
 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
-	return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
+	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);
 }
 
 static ssize_t
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7b3efd5..79d8a91 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -22,6 +22,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/firmware.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -29,6 +30,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
 #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
 #define IS_QLA2100(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
 #else
@@ -79,9 +81,23 @@
 #define IS_QLA2522(ha)	0
 #endif
 
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+#define IS_QLA2100(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
+#define IS_QLA2200(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200)
+#define IS_QLA2300(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300)
+#define IS_QLA2312(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312)
+#define IS_QLA2322(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322)
+#define IS_QLA6312(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
+#define IS_QLA6322(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
+#define IS_QLA2422(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
+#define IS_QLA2432(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+#define IS_QLA2512(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
+#define IS_QLA2522(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
+#endif
+
 #define IS_QLA23XX(ha)	(IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
     			 IS_QLA6312(ha) || IS_QLA6322(ha))
-
 #define IS_QLA24XX(ha)	(IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA25XX(ha)	(IS_QLA2512(ha) || IS_QLA2522(ha))
 
@@ -2124,6 +2140,12 @@
 	struct scsi_host_template *sht;
 };
 
+struct fw_blob {
+	char *name;
+	uint32_t segs[4];
+	const struct firmware *fw;
+};
+
 /* Return data from MBC_GET_ID_LIST call. */
 struct gid_list_info {
 	uint8_t	al_pa;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fedcb0d..bec81ad 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -33,8 +33,8 @@
 extern void qla2x00_update_fw_options(struct scsi_qla_host *);
 extern void qla24xx_update_fw_options(scsi_qla_host_t *);
 extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
+extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
 extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
-extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
 
 extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
 
@@ -76,6 +76,8 @@
 
 extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
 
+extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_iocb.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c46d246..7d973bd 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
-#include <linux/firmware.h>
 #include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
@@ -3484,17 +3483,16 @@
 	return (rval);
 }
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
 int
 qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
-	int		rval;
-	uint16_t	cnt;
-	uint16_t	*risc_code;
-	unsigned long	risc_address;
-	unsigned long	risc_code_size;
-	int		num;
-	int		i;
-	uint16_t	*req_ring;
+	int	rval, num, i;
+	uint32_t cnt;
+	uint16_t *risc_code;
+	uint32_t risc_addr, risc_size;
+	uint16_t *req_ring;
 	struct qla_fw_info *fw_iter;
 
 	rval = QLA_SUCCESS;
@@ -3504,37 +3502,29 @@
 	*srisc_addr = *ha->brd_info->fw_info->fwstart;
 	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
 		risc_code = fw_iter->fwcode;
-		risc_code_size = *fw_iter->fwlen;
-
-		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-			risc_address = *fw_iter->fwstart;
-		} else {
-			/* Extended address */
-			risc_address = *fw_iter->lfwstart;
-		}
+		risc_size = *fw_iter->fwlen;
+		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL)
+			risc_addr = *fw_iter->fwstart;
+		else
+			risc_addr = *fw_iter->lfwstart;
 
 		num = 0;
 		rval = 0;
-		while (risc_code_size > 0 && !rval) {
+		while (risc_size > 0 && !rval) {
 			cnt = (uint16_t)(ha->fw_transfer_size >> 1);
-			if (cnt > risc_code_size)
-				cnt = risc_code_size;
+			if (cnt > risc_size)
+				cnt = risc_size;
 
 			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
 			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
-			    ha->host_no, risc_code, cnt, risc_address));
+			    ha->host_no, risc_code, cnt, risc_addr));
 
 			req_ring = (uint16_t *)ha->request_ring;
 			for (i = 0; i < cnt; i++)
 				req_ring[i] = cpu_to_le16(risc_code[i]);
 
-			if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-				rval = qla2x00_load_ram(ha, ha->request_dma,
-				    risc_address, cnt);
-			} else {
-				rval = qla2x00_load_ram_ext(ha,
-				    ha->request_dma, risc_address, cnt);
-			}
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    cnt);
 			if (rval) {
 				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
 				    "load segment %d of firmware\n",
@@ -3548,16 +3538,76 @@
 			}
 
 			risc_code += cnt;
-			risc_address += cnt;
-			risc_code_size -= cnt;
+			risc_addr += cnt;
+			risc_size -= cnt;
 			num++;
 		}
 
 		/* Next firmware sequence */
 		fw_iter++;
 	}
+	return rval;
+}
 
-	return (rval);
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval, num, i;
+	uint32_t cnt;
+	uint32_t *risc_code;
+	uint32_t risc_addr, risc_size;
+	uint32_t *req_ring;
+	struct qla_fw_info *fw_iter;
+
+	rval = QLA_SUCCESS;
+
+	/* Load firmware sequences */
+	fw_iter = ha->brd_info->fw_info;
+	*srisc_addr = *((uint32_t *)fw_iter->lfwstart);
+	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
+		risc_code = (uint32_t *)fw_iter->fwcode;
+		risc_size = *((uint32_t *)fw_iter->fwlen);
+		risc_addr = *((uint32_t *)fw_iter->lfwstart);
+
+		num = 0;
+		rval = 0;
+		while (risc_size > 0 && !rval) {
+			cnt = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (cnt > risc_size)
+				cnt = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
+			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
+			    ha->host_no, risc_code, cnt, risc_addr));
+
+			req_ring = (uint32_t *)ha->request_ring;
+			for (i = 0; i < cnt; i++)
+				req_ring[i] = cpu_to_le32(risc_code[i]);
+
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    cnt);
+			if (rval) {
+				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
+				    "load segment %d of firmware\n",
+				    ha->host_no, num));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", num);
+
+				qla2x00_dump_regs(ha);
+				break;
+			}
+
+			risc_code += cnt;
+			risc_addr += cnt;
+			risc_size -= cnt;
+			num++;
+		}
+
+		/* Next firmware sequence */
+		fw_iter++;
+	}
+	return rval;
 }
 
 int
@@ -3642,8 +3692,108 @@
 	return rval;
 }
 
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
 int
-qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval;
+	int	i, fragment;
+	uint16_t *wcode, *fwcode;
+	uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
+	struct fw_blob *blob;
+
+	/* Load firmware blob. */
+	blob = qla2x00_request_firmware(ha);
+	if (!blob) {
+		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
+		return QLA_FUNCTION_FAILED;
+	}
+
+	rval = QLA_SUCCESS;
+
+	wcode = (uint16_t *)ha->request_ring;
+	*srisc_addr = 0;
+	fwcode = (uint16_t *)blob->fw->data;
+	fwclen = 0;
+
+	/* Validate firmware image by checking version. */
+	if (blob->fw->size < 8 * sizeof(uint16_t)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of firmware image (%Zd)!\n",
+		    blob->fw->size);
+		goto fail_fw_integrity;
+	}
+	for (i = 0; i < 4; i++)
+		wcode[i] = be16_to_cpu(fwcode[i + 4]);
+	if ((wcode[0] == 0xffff && wcode[1] == 0xffff && wcode[2] == 0xffff &&
+	    wcode[3] == 0xffff) || (wcode[0] == 0 && wcode[1] == 0 &&
+		wcode[2] == 0 && wcode[3] == 0)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of firmware image!\n");
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware data: %04x %04x %04x %04x!\n", wcode[0],
+		    wcode[1], wcode[2], wcode[3]);
+		goto fail_fw_integrity;
+	}
+
+	seg = blob->segs;
+	while (*seg && rval == QLA_SUCCESS) {
+		risc_addr = *seg;
+		*srisc_addr = *srisc_addr == 0 ? *seg : *srisc_addr;
+		risc_size = be16_to_cpu(fwcode[3]);
+
+		/* Validate firmware image size. */
+		fwclen += risc_size * sizeof(uint16_t);
+		if (blob->fw->size < fwclen) {
+			qla_printk(KERN_WARNING, ha,
+			    "Unable to verify integrity of firmware image "
+			    "(%Zd)!\n", blob->fw->size);
+			goto fail_fw_integrity;
+		}
+
+		fragment = 0;
+		while (risc_size > 0 && rval == QLA_SUCCESS) {
+			wlen = (uint16_t)(ha->fw_transfer_size >> 1);
+			if (wlen > risc_size)
+				wlen = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+			    "addr %x, number of words 0x%x.\n", ha->host_no,
+			    risc_addr, wlen));
+
+			for (i = 0; i < wlen; i++)
+				wcode[i] = swab16(fwcode[i]);
+
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    wlen);
+			if (rval) {
+				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+				    "segment %d of firmware\n", ha->host_no,
+				    fragment));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", fragment);
+				break;
+			}
+
+			fwcode += wlen;
+			risc_addr += wlen;
+			risc_size -= wlen;
+			fragment++;
+		}
+
+		/* Next segment. */
+		seg++;
+	}
+	return rval;
+
+fail_fw_integrity:
+	return QLA_FUNCTION_FAILED;
+}
+
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
 	int	rval;
 	int	segments, fragment;
@@ -3651,14 +3801,13 @@
 	uint32_t risc_addr;
 	uint32_t risc_size;
 	uint32_t i;
-	const struct firmware *fw_entry;
+	struct fw_blob *blob;
 	uint32_t *fwcode, fwclen;
 
-	if (request_firmware(&fw_entry, ha->brd_info->fw_fname,
-	    &ha->pdev->dev)) {
-		qla_printk(KERN_ERR, ha,
-		    "Firmware image file not available: '%s'\n",
-		    ha->brd_info->fw_fname);
+	/* Load firmware blob. */
+	blob = qla2x00_request_firmware(ha);
+	if (!blob) {
+		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
 		return QLA_FUNCTION_FAILED;
 	}
 
@@ -3667,14 +3816,14 @@
 	segments = FA_RISC_CODE_SEGMENTS;
 	dcode = (uint32_t *)ha->request_ring;
 	*srisc_addr = 0;
-	fwcode = (uint32_t *)fw_entry->data;
+	fwcode = (uint32_t *)blob->fw->data;
 	fwclen = 0;
 
 	/* Validate firmware image by checking version. */
-	if (fw_entry->size < 8 * sizeof(uint32_t)) {
+	if (blob->fw->size < 8 * sizeof(uint32_t)) {
 		qla_printk(KERN_WARNING, ha,
-		    "Unable to verify integrity of flash firmware image "
-		    "(%Zd)!\n", fw_entry->size);
+		    "Unable to verify integrity of firmware image (%Zd)!\n",
+		    blob->fw->size);
 		goto fail_fw_integrity;
 	}
 	for (i = 0; i < 4; i++)
@@ -3684,7 +3833,7 @@
 	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
 		dcode[3] == 0)) {
 		qla_printk(KERN_WARNING, ha,
-		    "Unable to verify integrity of flash firmware image!\n");
+		    "Unable to verify integrity of firmware image!\n");
 		qla_printk(KERN_WARNING, ha,
 		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
 		    dcode[1], dcode[2], dcode[3]);
@@ -3698,10 +3847,11 @@
 
 		/* Validate firmware image size. */
 		fwclen += risc_size * sizeof(uint32_t);
-		if (fw_entry->size < fwclen) {
+		if (blob->fw->size < fwclen) {
 			qla_printk(KERN_WARNING, ha,
-			    "Unable to verify integrity of flash firmware "
-			    "image (%Zd)!\n", fw_entry->size);
+			    "Unable to verify integrity of firmware image "
+			    "(%Zd)!\n", blob->fw->size);
+
 			goto fail_fw_integrity;
 		}
 
@@ -3739,13 +3889,9 @@
 		/* Next segment. */
 		segments--;
 	}
-
-	release_firmware(fw_entry);
 	return rval;
 
 fail_fw_integrity:
-
-	release_firmware(fw_entry);
 	return QLA_FUNCTION_FAILED;
-
 }
+#endif
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c58c9d9..2430430 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -54,10 +54,12 @@
 MODULE_PARM_DESC(ql2xloginretrycount,
 		"Specify an alternate value for the NVRAM login retry count.");
 
-int ql2xfwloadbin=1;
-module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xfwloadbin,
-		"Load ISP2xxx firmware image via hotplug.");
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+int ql2xfwloadflash;
+module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadflash,
+		"Load ISP24xx firmware image from FLASH (onboard memory).");
+#endif
 
 static void qla2x00_free_device(scsi_qla_host_t *);
 
@@ -1261,12 +1263,16 @@
 	char pci_info[20];
 	char fw_str[30];
 	fc_port_t *fcport;
+	struct scsi_host_template *sht;
 
 	if (pci_enable_device(pdev))
 		goto probe_out;
 
-	host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
-	    &qla2x00_driver_template, sizeof(scsi_qla_host_t));
+	sht = &qla2x00_driver_template;
+	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+		sht = &qla24xx_driver_template;
+	host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
 	if (host == NULL) {
 		printk(KERN_WARNING
 		    "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1291,8 +1297,8 @@
 		goto probe_failed;
 
 	qla_printk(KERN_INFO, ha,
-	    "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
-	    pdev->irq, ha->iobase);
+	    "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
+	    ha->iobase);
 
 	spin_lock_init(&ha->hardware_lock);
 
@@ -1368,9 +1374,11 @@
 		ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
 		ha->isp_ops.nvram_config = qla24xx_nvram_config;
 		ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-		ha->isp_ops.load_risc = qla24xx_load_risc_flash;
-		if (ql2xfwloadbin)
-			ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
+		ha->isp_ops.load_risc = qla24xx_load_risc;
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+		if (ql2xfwloadflash)
+			ha->isp_ops.load_risc = qla24xx_load_risc_flash;
+#endif
 		ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
 		ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
 		ha->isp_ops.intr_handler = qla24xx_intr_handler;
@@ -1531,11 +1539,12 @@
 	qla_printk(KERN_INFO, ha, "\n"
 	    " QLogic Fibre Channel HBA Driver: %s\n"
 	    "  QLogic %s - %s\n"
-	    "  %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
-	    ha->model_number, ha->model_desc ? ha->model_desc: "",
-	    ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
-	    pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
-	    ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
+	    "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
+	    qla2x00_version_str, ha->model_number,
+	    ha->model_desc ? ha->model_desc: "", pdev->device,
+	    ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
+	    ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
+	    ha->isp_ops.fw_version_str(ha, fw_str));
 
 	/* Go with fc_rport registration. */
 	list_for_each_entry(fcport, &ha->fcports, list)
@@ -2483,45 +2492,115 @@
 	return -ETIMEDOUT;
 }
 
-static struct qla_board_info qla_board_tbl[] = {
-	{
-		.drv_name	= "qla2400",
-		.isp_name	= "ISP2422",
-		.fw_fname	= "ql2400_fw.bin",
-		.sht		= &qla24xx_driver_template,
-	},
-	{
-		.drv_name	= "qla2400",
-		.isp_name	= "ISP2432",
-		.fw_fname	= "ql2400_fw.bin",
-		.sht		= &qla24xx_driver_template,
-	},
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
+#define qla2x00_release_firmware()	do { } while (0)
+#define qla2x00_pci_module_init()	(0)
+#define qla2x00_pci_module_exit()	do { } while (0)
+
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+/* Firmware interface routines. */
+
+#define FW_BLOBS	6
+#define FW_ISP21XX	0
+#define FW_ISP22XX	1
+#define FW_ISP2300	2
+#define FW_ISP2322	3
+#define FW_ISP63XX	4
+#define FW_ISP24XX	5
+
+static DECLARE_MUTEX(qla_fw_lock);
+
+static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
+	{ .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
+	{ .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
+	{ .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
+	{ .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
+	{ .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
+	{ .name = "ql2400_fw.bin", },
+};
+
+struct fw_blob *
+qla2x00_request_firmware(scsi_qla_host_t *ha)
+{
+	struct fw_blob *blob;
+
+	blob = NULL;
+	if (IS_QLA2100(ha)) {
+		blob = &qla_fw_blobs[FW_ISP21XX];
+	} else if (IS_QLA2200(ha)) {
+		blob = &qla_fw_blobs[FW_ISP22XX];
+	} else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
+		blob = &qla_fw_blobs[FW_ISP2300];
+	} else if (IS_QLA2322(ha)) {
+		blob = &qla_fw_blobs[FW_ISP2322];
+	} else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
+		blob = &qla_fw_blobs[FW_ISP63XX];
+	} else if (IS_QLA24XX(ha)) {
+		blob = &qla_fw_blobs[FW_ISP24XX];
+	}
+
+	down(&qla_fw_lock);
+	if (blob->fw)
+		goto out;
+
+	if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
+		DEBUG2(printk("scsi(%ld): Failed to load firmware image "
+		    "(%s).\n", ha->host_no, blob->name));
+		blob->fw = NULL;
+		blob = NULL;
+		goto out;
+	}
+
+out:
+	up(&qla_fw_lock);
+	return blob;
+}
+
+static void
+qla2x00_release_firmware(void)
+{
+	int idx;
+
+	down(&qla_fw_lock);
+	for (idx = 0; idx < FW_BLOBS; idx++)
+		if (qla_fw_blobs[idx].fw)
+			release_firmware(qla_fw_blobs[idx].fw);
+	up(&qla_fw_lock);
+}
+
+static struct qla_board_info qla_board_tbl = {
+	.drv_name       = "qla2xxx",
 };
 
 static struct pci_device_id qla2xxx_pci_tbl[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_QLOGIC,
-		.device		= PCI_DEVICE_ID_QLOGIC_ISP2422,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= (unsigned long)&qla_board_tbl[0],
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_QLOGIC,
-		.device		= PCI_DEVICE_ID_QLOGIC_ISP2432,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= (unsigned long)&qla_board_tbl[1],
-	},
-	{0, 0},
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
 
 static int __devinit
 qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	return qla2x00_probe_one(pdev,
-	    (struct qla_board_info *)id->driver_data);
+	return qla2x00_probe_one(pdev, &qla_board_tbl);
 }
 
 static void __devexit
@@ -2532,11 +2611,28 @@
 
 static struct pci_driver qla2xxx_pci_driver = {
 	.name		= "qla2xxx",
+	.driver		= {
+		.owner		= THIS_MODULE,
+	},
 	.id_table	= qla2xxx_pci_tbl,
 	.probe		= qla2xxx_probe_one,
 	.remove		= __devexit_p(qla2xxx_remove_one),
 };
 
+static inline int
+qla2x00_pci_module_init(void)
+{
+	return pci_module_init(&qla2xxx_pci_driver);
+}
+
+static inline void
+qla2x00_pci_module_exit(void)
+{
+	pci_unregister_driver(&qla2xxx_pci_driver);
+}
+
+#endif
+
 /**
  * qla2x00_module_init - Module initialization.
  **/
@@ -2556,6 +2652,9 @@
 
 	/* Derive version string. */
 	strcpy(qla2x00_version_str, QLA2XXX_VERSION);
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+	strcat(qla2x00_version_str, "-fw");
+#endif
 #if DEBUG_QLA2100
 	strcat(qla2x00_version_str, "-debug");
 #endif
@@ -2565,7 +2664,7 @@
 		return -ENODEV;
 
 	printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
-	ret = pci_module_init(&qla2xxx_pci_driver);
+	ret = qla2x00_pci_module_init();
 	if (ret) {
 		kmem_cache_destroy(srb_cachep);
 		fc_release_transport(qla2xxx_transport_template);
@@ -2579,7 +2678,8 @@
 static void __exit
 qla2x00_module_exit(void)
 {
-	pci_unregister_driver(&qla2xxx_pci_driver);
+	qla2x00_pci_module_exit();
+	qla2x00_release_firmware();
 	kmem_cache_destroy(srb_cachep);
 	fc_release_transport(qla2xxx_transport_template);
 }
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index 5b1c120..5ec5f44 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -115,7 +115,7 @@
 			       raid_remove,
 			       NULL);
 
-static struct {
+static const struct {
 	enum raid_state	value;
 	char		*name;
 } raid_states[] = {
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 9321cdf..b2bf16a 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -431,7 +431,7 @@
 	.host_stop		= mv_host_stop,
 };
 
-static struct ata_port_info mv_port_info[] = {
+static const struct ata_port_info mv_port_info[] = {
 	{  /* chip_504x */
 		.sht		= &mv_sht,
 		.host_flags	= MV_COMMON_FLAGS,
@@ -1243,8 +1243,10 @@
 				VPRINTK("port %u IRQ found for qc, "
 					"ata_status 0x%x\n", port,ata_status);
 				/* mark qc status appropriately */
-				if (!(qc->tf.ctl & ATA_NIEN))
-					ata_qc_complete(qc, err_mask);
+				if (!(qc->tf.ctl & ATA_NIEN)) {
+					qc->err_mask |= err_mask;
+					ata_qc_complete(qc);
+				}
 			}
 		}
 	}
@@ -1865,7 +1867,8 @@
 	 	 */
 		spin_lock_irqsave(&ap->host_set->lock, flags);
 		qc->scsidone = scsi_finish_command;
-		ata_qc_complete(qc, AC_ERR_OTHER);
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
 		spin_unlock_irqrestore(&ap->host_set->lock, flags);
 	}
 }
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 2691625..da7fa04 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -161,7 +161,7 @@
 	.host_stop		= ata_pci_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
 	/* board_2037x */
 	{
 		.sht		= &pdc_ata_sht,
@@ -401,7 +401,8 @@
 	case ATA_PROT_NODATA:
 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
 		drv_stat = ata_wait_idle(ap);
-		ata_qc_complete(qc, __ac_err_mask(drv_stat));
+		qc->err_mask |= __ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -410,7 +411,8 @@
 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
 		       ap->id, qc->tf.command, drv_stat);
 
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
@@ -422,21 +424,21 @@
 static inline unsigned int pdc_host_intr( struct ata_port *ap,
                                           struct ata_queued_cmd *qc)
 {
-	unsigned int handled = 0, err_mask = 0;
+	unsigned int handled = 0;
 	u32 tmp;
 	void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
 
 	tmp = readl(mmio);
 	if (tmp & PDC_ERR_MASK) {
-		err_mask = AC_ERR_DEV;
+		qc->err_mask |= AC_ERR_DEV;
 		pdc_reset_port(ap);
 	}
 
 	switch (qc->tf.protocol) {
 	case ATA_PROT_DMA:
 	case ATA_PROT_NODATA:
-		err_mask |= ac_err_mask(ata_wait_idle(ap));
-		ata_qc_complete(qc, err_mask);
+		qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+		ata_qc_complete(qc);
 		handled = 1;
 		break;
 
@@ -703,7 +705,7 @@
 		probe_ent->port[3].scr_addr = base + 0x700;
 		break;
 	case board_2037x:
-       		probe_ent->n_ports = 2;
+		probe_ent->n_ports = 2;
 		break;
 	case board_20619:
 		probe_ent->n_ports = 4;
@@ -713,7 +715,7 @@
 
 		probe_ent->port[2].scr_addr = base + 0x600;
 		probe_ent->port[3].scr_addr = base + 0x700;
-                break;
+		break;
 	default:
 		BUG();
 		break;
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index a8987f5..de05e28 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -170,7 +170,7 @@
 	.bmdma_status		= qs_bmdma_status,
 };
 
-static struct ata_port_info qs_port_info[] = {
+static const struct ata_port_info qs_port_info[] = {
 	/* board_2068_idx */
 	{
 		.sht		= &qs_ata_sht,
@@ -409,8 +409,8 @@
 					case 3: /* device error */
 						pp->state = qs_state_idle;
 						qs_enter_reg_mode(qc->ap);
-						ata_qc_complete(qc,
-							ac_err_mask(sDST));
+						qc->err_mask |= ac_err_mask(sDST);
+						ata_qc_complete(qc);
 						break;
 					default:
 						break;
@@ -447,7 +447,8 @@
 
 				/* complete taskfile transaction */
 				pp->state = qs_state_idle;
-				ata_qc_complete(qc, ac_err_mask(status));
+				qc->err_mask |= ac_err_mask(status);
+				ata_qc_complete(qc);
 				handled = 1;
 			}
 		}
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 3609186..d205348 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -176,7 +176,7 @@
 	.host_stop		= ata_pci_host_stop,
 };
 
-static struct ata_port_info sil_port_info[] = {
+static const struct ata_port_info sil_port_info[] = {
 	/* sil_3112 */
 	{
 		.sht		= &sil_sht,
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index e0d6f19..a0ad3ed 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -654,7 +654,8 @@
 	 */
 	printk(KERN_ERR "ata%u: command timeout\n", ap->id);
 	qc->scsidone = scsi_finish_command;
-	ata_qc_complete(qc, AC_ERR_OTHER);
+	qc->err_mask |= AC_ERR_OTHER;
+	ata_qc_complete(qc);
 
 	sil24_reset_controller(ap);
 }
@@ -711,8 +712,10 @@
 		sil24_reset_controller(ap);
 	}
 
-	if (qc)
-		ata_qc_complete(qc, err_mask);
+	if (qc) {
+		qc->err_mask |= err_mask;
+		ata_qc_complete(qc);
+	}
 }
 
 static inline void sil24_host_intr(struct ata_port *ap)
@@ -734,8 +737,10 @@
 		 */
 		sil24_update_tf(ap);
 
-		if (qc)
-			ata_qc_complete(qc, ac_err_mask(pp->tf.command));
+		if (qc) {
+			qc->err_mask |= ac_err_mask(pp->tf.command);
+			ata_qc_complete(qc);
+		}
 	} else
 		sil24_error_intr(ap, slot_stat);
 }
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index ac7b0d8..94b253b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -215,7 +215,7 @@
 	.host_stop		= pdc20621_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
 	/* board_20621 */
 	{
 		.sht		= &pdc_sata_sht,
@@ -719,7 +719,8 @@
 			VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
 			/* get drive status; clear intr; complete txn */
-			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+			qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+			ata_qc_complete(qc);
 			pdc20621_pop_hdma(qc);
 		}
 
@@ -757,7 +758,8 @@
 			VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
 			/* get drive status; clear intr; complete txn */
-			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+			qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+			ata_qc_complete(qc);
 			pdc20621_pop_hdma(qc);
 		}
 		handled = 1;
@@ -767,7 +769,8 @@
 
 		status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
 		DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
-		ata_qc_complete(qc, ac_err_mask(status));
+		qc->err_mask |= ac_err_mask(status);
+		ata_qc_complete(qc);
 		handled = 1;
 
 	} else {
@@ -882,7 +885,8 @@
 	case ATA_PROT_DMA:
 	case ATA_PROT_NODATA:
 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-		ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
+		qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -891,7 +895,8 @@
 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
 		       ap->id, qc->tf.command, drv_stat);
 
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index e69477d..f01ec0a 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -354,8 +354,9 @@
  *     @model, if found, return the matching flags value, else return
  *     the host or global default settings.
  **/
-int scsi_get_device_flags(struct scsi_device *sdev, unsigned char *vendor,
-			  unsigned char *model)
+int scsi_get_device_flags(struct scsi_device *sdev,
+			  const unsigned char *vendor,
+			  const unsigned char *model)
 {
 	struct scsi_dev_info_list *devinfo;
 	unsigned int bflags;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index c0ae9e9..a2333d2 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1320,23 +1320,6 @@
 }
 
 /**
- * scsi_eh_lock_done - done function for eh door lock request
- * @scmd:	SCSI command block for the door lock request
- *
- * Notes:
- * 	We completed the asynchronous door lock request, and it has either
- * 	locked the door or failed.  We must free the command structures
- * 	associated with this request.
- **/
-static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
-{
-	struct scsi_request *sreq = scmd->sc_request;
-
-	scsi_release_request(sreq);
-}
-
-
-/**
  * scsi_eh_lock_door - Prevent medium removal for the specified device
  * @sdev:	SCSI device to prevent medium removal
  *
@@ -1358,29 +1341,17 @@
  **/
 static void scsi_eh_lock_door(struct scsi_device *sdev)
 {
-	struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 
-	if (unlikely(!sreq)) {
-		printk(KERN_ERR "%s: request allocate failed,"
-		       "prevent media removal cmd not sent\n", __FUNCTION__);
-		return;
-	}
+	cmnd[0] = ALLOW_MEDIUM_REMOVAL;
+	cmnd[1] = 0;
+	cmnd[2] = 0;
+	cmnd[3] = 0;
+	cmnd[4] = SCSI_REMOVAL_PREVENT;
+	cmnd[5] = 0;
 
-	sreq->sr_cmnd[0] = ALLOW_MEDIUM_REMOVAL;
-	sreq->sr_cmnd[1] = 0;
-	sreq->sr_cmnd[2] = 0;
-	sreq->sr_cmnd[3] = 0;
-	sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
-	sreq->sr_cmnd[5] = 0;
-	sreq->sr_data_direction = DMA_NONE;
-	sreq->sr_bufflen = 0;
-	sreq->sr_buffer = NULL;
-	sreq->sr_allowed = 5;
-	sreq->sr_done = scsi_eh_lock_done;
-	sreq->sr_timeout_per_command = 10 * HZ;
-	sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]);
-
-	scsi_insert_special_req(sreq, 1);
+	scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
+			   5, NULL, NULL, GFP_KERNEL);
 }
 
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index dc249cb..a7f3f0c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -63,39 +63,6 @@
 }; 	
 #undef SP
 
-
-/*
- * Function:    scsi_insert_special_req()
- *
- * Purpose:     Insert pre-formed request into request queue.
- *
- * Arguments:   sreq	- request that is ready to be queued.
- *              at_head	- boolean.  True if we should insert at head
- *                        of queue, false if we should insert at tail.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns:     Nothing
- *
- * Notes:       This function is called from character device and from
- *              ioctl types of functions where the caller knows exactly
- *              what SCSI command needs to be issued.   The idea is that
- *              we merely inject the command into the queue (at the head
- *              for now), and then call the queue request function to actually
- *              process it.
- */
-int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
-{
-	/*
-	 * Because users of this function are apt to reuse requests with no
-	 * modification, we have to sanitise the request flags here
-	 */
-	sreq->sr_request->flags &= ~REQ_DONTPREP;
-	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
-		       	   at_head, sreq);
-	return 0;
-}
-
 static void scsi_run_queue(struct request_queue *q);
 
 /*
@@ -249,8 +216,13 @@
 
 	/*
 	 * head injection *required* here otherwise quiesce won't work
+	 *
+	 * Because users of this function are apt to reuse requests with no
+	 * modification, we have to sanitise the request flags here
 	 */
-	scsi_insert_special_req(sreq, 1);
+	sreq->sr_request->flags &= ~REQ_DONTPREP;
+	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
+		       	   1, sreq);
 }
 EXPORT_SYMBOL(scsi_do_req);
 
@@ -287,6 +259,7 @@
 	memcpy(req->cmd, cmd, req->cmd_len);
 	req->sense = sense;
 	req->sense_len = 0;
+	req->retries = retries;
 	req->timeout = timeout;
 	req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
 
@@ -327,6 +300,200 @@
 }
 EXPORT_SYMBOL(scsi_execute_req);
 
+struct scsi_io_context {
+	void *data;
+	void (*done)(void *data, char *sense, int result, int resid);
+	char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+static kmem_cache_t *scsi_io_context_cache;
+
+static void scsi_end_async(struct request *req)
+{
+	struct scsi_io_context *sioc = req->end_io_data;
+
+	if (sioc->done)
+		sioc->done(sioc->data, sioc->sense, req->errors, req->data_len);
+
+	kmem_cache_free(scsi_io_context_cache, sioc);
+	__blk_put_request(req->q, req);
+}
+
+static int scsi_merge_bio(struct request *rq, struct bio *bio)
+{
+	struct request_queue *q = rq->q;
+
+	bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+	if (rq_data_dir(rq) == WRITE)
+		bio->bi_rw |= (1 << BIO_RW);
+	blk_queue_bounce(q, &bio);
+
+	if (!rq->bio)
+		blk_rq_bio_prep(q, rq, bio);
+	else if (!q->back_merge_fn(q, rq, bio))
+		return -EINVAL;
+	else {
+		rq->biotail->bi_next = bio;
+		rq->biotail = bio;
+		rq->hard_nr_sectors += bio_sectors(bio);
+		rq->nr_sectors = rq->hard_nr_sectors;
+	}
+
+	return 0;
+}
+
+static int scsi_bi_endio(struct bio *bio, unsigned int bytes_done, int error)
+{
+	if (bio->bi_size)
+		return 1;
+
+	bio_put(bio);
+	return 0;
+}
+
+/**
+ * scsi_req_map_sg - map a scatterlist into a request
+ * @rq:		request to fill
+ * @sg:		scatterlist
+ * @nsegs:	number of elements
+ * @bufflen:	len of buffer
+ * @gfp:	memory allocation flags
+ *
+ * scsi_req_map_sg maps a scatterlist into a request so that the
+ * request can be sent to the block layer. We do not trust the scatterlist
+ * sent to use, as some ULDs use that struct to only organize the pages.
+ */
+static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
+			   int nsegs, unsigned bufflen, gfp_t gfp)
+{
+	struct request_queue *q = rq->q;
+	int nr_pages = (bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	unsigned int data_len = 0, len, bytes, off;
+	struct page *page;
+	struct bio *bio = NULL;
+	int i, err, nr_vecs = 0;
+
+	for (i = 0; i < nsegs; i++) {
+		page = sgl[i].page;
+		off = sgl[i].offset;
+		len = sgl[i].length;
+		data_len += len;
+
+		while (len > 0) {
+			bytes = min_t(unsigned int, len, PAGE_SIZE - off);
+
+			if (!bio) {
+				nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
+				nr_pages -= nr_vecs;
+
+				bio = bio_alloc(gfp, nr_vecs);
+				if (!bio) {
+					err = -ENOMEM;
+					goto free_bios;
+				}
+				bio->bi_end_io = scsi_bi_endio;
+			}
+
+			if (bio_add_pc_page(q, bio, page, bytes, off) !=
+			    bytes) {
+				bio_put(bio);
+				err = -EINVAL;
+				goto free_bios;
+			}
+
+			if (bio->bi_vcnt >= nr_vecs) {
+				err = scsi_merge_bio(rq, bio);
+				if (err) {
+					bio_endio(bio, bio->bi_size, 0);
+					goto free_bios;
+				}
+				bio = NULL;
+			}
+
+			page++;
+			len -= bytes;
+			off = 0;
+		}
+	}
+
+	rq->buffer = rq->data = NULL;
+	rq->data_len = data_len;
+	return 0;
+
+free_bios:
+	while ((bio = rq->bio) != NULL) {
+		rq->bio = bio->bi_next;
+		/*
+		 * call endio instead of bio_put incase it was bounced
+		 */
+		bio_endio(bio, bio->bi_size, 0);
+	}
+
+	return err;
+}
+
+/**
+ * scsi_execute_async - insert request
+ * @sdev:	scsi device
+ * @cmd:	scsi command
+ * @data_direction: data direction
+ * @buffer:	data buffer (this can be a kernel buffer or scatterlist)
+ * @bufflen:	len of buffer
+ * @use_sg:	if buffer is a scatterlist this is the number of elements
+ * @timeout:	request timeout in seconds
+ * @retries:	number of times to retry request
+ * @flags:	or into request flags
+ **/
+int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
+		       int data_direction, void *buffer, unsigned bufflen,
+		       int use_sg, int timeout, int retries, void *privdata,
+		       void (*done)(void *, char *, int, int), gfp_t gfp)
+{
+	struct request *req;
+	struct scsi_io_context *sioc;
+	int err = 0;
+	int write = (data_direction == DMA_TO_DEVICE);
+
+	sioc = kmem_cache_alloc(scsi_io_context_cache, gfp);
+	if (!sioc)
+		return DRIVER_ERROR << 24;
+	memset(sioc, 0, sizeof(*sioc));
+
+	req = blk_get_request(sdev->request_queue, write, gfp);
+	if (!req)
+		goto free_sense;
+	req->flags |= REQ_BLOCK_PC | REQ_QUIET;
+
+	if (use_sg)
+		err = scsi_req_map_sg(req, buffer, use_sg, bufflen, gfp);
+	else if (bufflen)
+		err = blk_rq_map_kern(req->q, req, buffer, bufflen, gfp);
+
+	if (err)
+		goto free_req;
+
+	req->cmd_len = COMMAND_SIZE(cmd[0]);
+	memcpy(req->cmd, cmd, req->cmd_len);
+	req->sense = sioc->sense;
+	req->sense_len = 0;
+	req->timeout = timeout;
+	req->retries = retries;
+	req->end_io_data = sioc;
+
+	sioc->data = privdata;
+	sioc->done = done;
+
+	blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async);
+	return 0;
+
+free_req:
+	blk_put_request(req);
+free_sense:
+	kfree(sioc);
+	return DRIVER_ERROR << 24;
+}
+EXPORT_SYMBOL_GPL(scsi_execute_async);
+
 /*
  * Function:    scsi_init_cmd_errh()
  *
@@ -884,7 +1051,8 @@
 			* system where READ CAPACITY failed, we may have read
 			* past the end of the disk.
 		 	*/
-			if (cmd->device->use_10_for_rw &&
+			if ((cmd->device->use_10_for_rw &&
+			    sshdr.asc == 0x20 && sshdr.ascq == 0x00) &&
 			    (cmd->cmnd[0] == READ_10 ||
 			     cmd->cmnd[0] == WRITE_10)) {
 				cmd->device->use_10_for_rw = 0;
@@ -1082,10 +1250,16 @@
 static void scsi_generic_done(struct scsi_cmnd *cmd)
 {
 	BUG_ON(!blk_pc_request(cmd->request));
-	scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
+	/*
+	 * This will complete the whole command with uptodate=1 so
+	 * as far as the block layer is concerned the command completed
+	 * successfully. Since this is a REQ_BLOCK_PC command the
+	 * caller should check the request's errors value
+	 */
+	scsi_io_completion(cmd, cmd->bufflen, 0);
 }
 
-void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries)
+void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *req = cmd->request;
 
@@ -1100,7 +1274,7 @@
 		cmd->sc_data_direction = DMA_FROM_DEVICE;
 	
 	cmd->transfersize = req->data_len;
-	cmd->allowed = retries;
+	cmd->allowed = req->retries;
 	cmd->timeout_per_command = req->timeout;
 }
 EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
@@ -1240,7 +1414,7 @@
 				goto kill;
 			}
 		} else {
-			scsi_setup_blk_pc_cmnd(cmd, 3);
+			scsi_setup_blk_pc_cmnd(cmd);
 			cmd->done = scsi_generic_done;
 		}
 	}
@@ -1603,6 +1777,14 @@
 {
 	int i;
 
+	scsi_io_context_cache = kmem_cache_create("scsi_io_context",
+					sizeof(struct scsi_io_context),
+					0, 0, NULL, NULL);
+	if (!scsi_io_context_cache) {
+		printk(KERN_ERR "SCSI: can't init scsi io context cache\n");
+		return -ENOMEM;
+	}
+
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
 		int size = sgp->size * sizeof(struct scatterlist);
@@ -1630,6 +1812,8 @@
 {
 	int i;
 
+	kmem_cache_destroy(scsi_io_context_cache);
+
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
 		mempool_destroy(sgp->pool);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index d632d9e..f04e7e1 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -40,7 +40,6 @@
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern int scsi_insert_special_req(struct scsi_request *sreq, int);
 extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
 		struct scsi_request *sreq);
 extern void __scsi_release_request(struct scsi_request *sreq);
@@ -57,7 +56,8 @@
 
 /* scsi_devinfo.c */
 extern int scsi_get_device_flags(struct scsi_device *sdev,
-				 unsigned char *vendor, unsigned char *model);
+				 const unsigned char *vendor,
+				 const unsigned char *model);
 extern int __init scsi_init_devinfo(void);
 extern void scsi_exit_devinfo(void);
 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 4e6709f..05ebb9c 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -74,7 +74,7 @@
 #define SCSI_SCAN_TARGET_PRESENT	1
 #define SCSI_SCAN_LUN_PRESENT		2
 
-static char *scsi_null_device_strs = "nullnullnullnull";
+static const char *scsi_null_device_strs = "nullnullnullnull";
 
 #define MAX_SCSI_LUNS	512
 
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 4634929..15842b1 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -21,7 +21,7 @@
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
-static struct {
+static const struct {
 	enum scsi_device_state	value;
 	char			*name;
 } sdev_states[] = {
@@ -48,7 +48,7 @@
 	return name;
 }
 
-static struct {
+static const struct {
 	enum scsi_host_state	value;
 	char			*name;
 } shost_states[] = {
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 2a1a99a..685b997 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -112,7 +112,7 @@
 
 
 /* Convert fc_tgtid_binding_type values to ascii string name */
-static struct {
+static const struct {
 	enum fc_tgtid_binding_type	value;
 	char				*name;
 	int				matchlen;
@@ -150,7 +150,7 @@
 
 
 /* Convert FC_COS bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_cos_names[] = {
@@ -164,7 +164,7 @@
 
 
 /* Convert FC_PORTSPEED bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_port_speed_names[] = {
@@ -190,7 +190,7 @@
 
 
 /* Convert FC_RPORT_ROLE bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_remote_port_role_names[] = {
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 38a53b5..46da6fe 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -18,6 +18,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 <linux/config.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -378,9 +379,7 @@
 
 /* Translate the period into ns according to the current spec
  * for SDTR/PPR messages */
-static ssize_t
-show_spi_transport_period_helper(struct class_device *cdev, char *buf,
-				 int period)
+static int period_to_str(char *buf, int period)
 {
 	int len, picosec;
 
@@ -398,6 +397,14 @@
 		len = sprint_frac(buf, picosec, 1000);
 	}
 
+	return len;
+}
+
+static ssize_t
+show_spi_transport_period_helper(struct class_device *cdev, char *buf,
+				 int period)
+{
+	int len = period_to_str(buf, period);
 	buf[len++] = '\n';
 	buf[len] = '\0';
 	return len;
@@ -1041,12 +1048,133 @@
 			 tp->hold_mcs ? " HMCS" : "",
 			 tmp, tp->offset);
 	} else {
-		dev_info(&starget->dev, "%sasynchronous.\n",
+		dev_info(&starget->dev, "%sasynchronous\n",
 				tp->width ? "wide " : "");
 	}
 }
 EXPORT_SYMBOL(spi_display_xfer_agreement);
 
+#ifdef CONFIG_SCSI_CONSTANTS
+static const char * const one_byte_msgs[] = {
+/* 0x00 */ "Command Complete", NULL, "Save Pointers",
+/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
+/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
+/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
+/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
+/* 0x0f */ "Initiate Recovery", "Release Recovery"
+};
+
+static const char * const two_byte_msgs[] = {
+/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag",
+/* 0x23 */ "Ignore Wide Residue"
+};
+
+static const char * const extended_msgs[] = {
+/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
+/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request",
+/* 0x04 */ "Parallel Protocol Request"
+};
+
+void print_nego(const unsigned char *msg, int per, int off, int width)
+{
+	if (per) {
+		char buf[20];
+		period_to_str(buf, msg[per]);
+		printk("period = %s ns ", buf);
+	}
+
+	if (off)
+		printk("offset = %d ", msg[off]);
+	if (width)
+		printk("width = %d ", 8 << msg[width]);
+}
+
+int spi_print_msg(const unsigned char *msg)
+{
+	int len = 0, i;
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		if (msg[2] < ARRAY_SIZE(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:
+			print_nego(msg, 3, 4, 0);
+			break;
+		case EXTENDED_WDTR:
+			print_nego(msg, 0, 0, 3);
+			break;
+		case EXTENDED_PPR:
+			print_nego(msg, 3, 5, 6);
+			break;
+		default:
+		for (i = 2; i < len; ++i) 
+			printk("%02x ", msg[i]);
+		}
+	/* Identify */
+	} 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 (msg[0] < ARRAY_SIZE(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 ((msg[0] - 0x20) < ARRAY_SIZE(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(spi_print_msg);
+
+#else  /* ifndef CONFIG_SCSI_CONSTANTS */
+
+int spi_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(spi_print_msg);
+#endif /* ! CONFIG_SCSI_CONSTANTS */
+
 #define SETUP_ATTRIBUTE(field)						\
 	i->private_attrs[count] = class_device_attr_##field;		\
 	if (!i->f->set_##field) {					\
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 03fcbab..3d3ad7d 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -245,7 +245,7 @@
 	 * SG_IO from block layer already setup, just copy cdb basically
 	 */
 	if (blk_pc_request(rq)) {
-		scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES);
+		scsi_setup_blk_pc_cmnd(SCpnt);
 		if (rq->timeout)
 			timeout = rq->timeout;
 
@@ -1495,9 +1495,7 @@
 	 */
 	if (sdkp->media_present) {
 		sd_read_capacity(sdkp, disk->disk_name, buffer);
-		if (sdp->removable)
-			sd_read_write_protect_flag(sdkp, disk->disk_name,
-						   buffer);
+		sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
 		sd_read_cache_type(sdkp, disk->disk_name, buffer);
 	}
 		
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index b55c2a8..221e96e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -104,8 +104,6 @@
 static int sg_add(struct class_device *, struct class_interface *);
 static void sg_remove(struct class_device *, struct class_interface *);
 
-static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
-
 static DEFINE_RWLOCK(sg_dev_arr_lock);	/* Also used to lock
 							   file descriptor list for device */
 
@@ -119,7 +117,7 @@
 	unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
 	unsigned bufflen;	/* Size of (aggregate) data buffer */
 	unsigned b_malloc_len;	/* actual len malloc'ed in buffer */
-	void *buffer;		/* Data buffer or scatter list (k_use_sg>0) */
+	struct scatterlist *buffer;/* scatter list */
 	char dio_in_use;	/* 0->indirect IO (or mmap), 1->dio */
 	unsigned char cmd_opcode; /* first byte of command */
 } Sg_scatter_hold;
@@ -128,12 +126,11 @@
 struct sg_fd;
 
 typedef struct sg_request {	/* SG_MAX_QUEUE requests outstanding per file */
-	Scsi_Request *my_cmdp;	/* != 0  when request with lower levels */
 	struct sg_request *nextrp;	/* NULL -> tail request (slist) */
 	struct sg_fd *parentfp;	/* NULL -> not in use */
 	Sg_scatter_hold data;	/* hold buffer, perhaps scatter list */
 	sg_io_hdr_t header;	/* scsi command+info, see <scsi/sg.h> */
-	unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
+	unsigned char sense_b[SCSI_SENSE_BUFFERSIZE];
 	char res_used;		/* 1 -> using reserve buffer, 0 -> not ... */
 	char orphan;		/* 1 -> drop on sight, 0 -> normal */
 	char sg_io_owned;	/* 1 -> packet belongs to SG_IO */
@@ -174,7 +171,8 @@
 } Sg_device;
 
 static int sg_fasync(int fd, struct file *filp, int mode);
-static void sg_cmd_done(Scsi_Cmnd * SCpnt);	/* tasklet or soft irq callback */
+/* tasklet or soft irq callback */
+static void sg_cmd_done(void *data, char *sense, int result, int resid);
 static int sg_start_req(Sg_request * srp);
 static void sg_finish_rem_req(Sg_request * srp);
 static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
@@ -195,8 +193,8 @@
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static char *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
-static void sg_page_free(char *buff, int size);
+static struct page *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
+static void sg_page_free(struct page *page, int size);
 static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
 static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
@@ -207,7 +205,6 @@
 static int sg_allow_access(unsigned char opcode, char dev_type);
 static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static Sg_device *sg_get_dev(int dev);
-static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp);
 #ifdef CONFIG_SCSI_PROC_FS
 static int sg_last_dev(void);
 #endif
@@ -226,6 +223,7 @@
 {
 	int dev = iminor(inode);
 	int flags = filp->f_flags;
+	struct request_queue *q;
 	Sg_device *sdp;
 	Sg_fd *sfp;
 	int res;
@@ -287,7 +285,9 @@
 	}
 	if (!sdp->headfp) {	/* no existing opens on this device */
 		sdp->sgdebug = 0;
-		sdp->sg_tablesize = sdp->device->host->sg_tablesize;
+		q = sdp->device->request_queue;
+		sdp->sg_tablesize = min(q->max_hw_segments,
+					q->max_phys_segments);
 	}
 	if ((sfp = sg_add_sfp(sdp, dev)))
 		filp->private_data = sfp;
@@ -340,6 +340,7 @@
 		return -ENXIO;
 	SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
 				   sdp->disk->disk_name, (int) count));
+
 	if (!access_ok(VERIFY_WRITE, buf, count))
 		return -EFAULT;
 	if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
@@ -491,7 +492,7 @@
 	if ((hp->mx_sb_len > 0) && hp->sbp) {
 		if ((CHECK_CONDITION & hp->masked_status) ||
 		    (DRIVER_SENSE & hp->driver_status)) {
-			int sb_len = sizeof (dummy_cmdp->sr_sense_buffer);
+			int sb_len = SCSI_SENSE_BUFFERSIZE;
 			sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
 			len = 8 + (int) srp->sense_b[7];	/* Additional sense length field */
 			len = (len > sb_len) ? sb_len : len;
@@ -525,7 +526,7 @@
 	Sg_request *srp;
 	struct sg_header old_hdr;
 	sg_io_hdr_t *hp;
-	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
@@ -624,7 +625,7 @@
 	int k;
 	Sg_request *srp;
 	sg_io_hdr_t *hp;
-	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 	int timeout;
 	unsigned long ul_timeout;
 
@@ -692,11 +693,9 @@
 sg_common_write(Sg_fd * sfp, Sg_request * srp,
 		unsigned char *cmnd, int timeout, int blocking)
 {
-	int k;
-	Scsi_Request *SRpnt;
+	int k, data_dir;
 	Sg_device *sdp = sfp->parentdp;
 	sg_io_hdr_t *hp = &srp->header;
-	request_queue_t *q;
 
 	srp->data.cmd_opcode = cmnd[0];	/* hold opcode of command */
 	hp->status = 0;
@@ -723,51 +722,36 @@
 		sg_finish_rem_req(srp);
 		return -ENODEV;
 	}
-	SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC);
-	if (SRpnt == NULL) {
-		SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n"));
-		sg_finish_rem_req(srp);
-		return -ENOMEM;
-	}
 
-	srp->my_cmdp = SRpnt;
-	q = SRpnt->sr_device->request_queue;
-	SRpnt->sr_request->rq_disk = sdp->disk;
-	SRpnt->sr_sense_buffer[0] = 0;
-	SRpnt->sr_cmd_len = hp->cmd_len;
-	SRpnt->sr_use_sg = srp->data.k_use_sg;
-	SRpnt->sr_sglist_len = srp->data.sglist_len;
-	SRpnt->sr_bufflen = srp->data.bufflen;
-	SRpnt->sr_underflow = 0;
-	SRpnt->sr_buffer = srp->data.buffer;
 	switch (hp->dxfer_direction) {
 	case SG_DXFER_TO_FROM_DEV:
 	case SG_DXFER_FROM_DEV:
-		SRpnt->sr_data_direction = DMA_FROM_DEVICE;
+		data_dir = DMA_FROM_DEVICE;
 		break;
 	case SG_DXFER_TO_DEV:
-		SRpnt->sr_data_direction = DMA_TO_DEVICE;
+		data_dir = DMA_TO_DEVICE;
 		break;
 	case SG_DXFER_UNKNOWN:
-		SRpnt->sr_data_direction = DMA_BIDIRECTIONAL;
+		data_dir = DMA_BIDIRECTIONAL;
 		break;
 	default:
-		SRpnt->sr_data_direction = DMA_NONE;
+		data_dir = DMA_NONE;
 		break;
 	}
-	SRpnt->upper_private_data = srp;
-	srp->data.k_use_sg = 0;
-	srp->data.sglist_len = 0;
-	srp->data.bufflen = 0;
-	srp->data.buffer = NULL;
 	hp->duration = jiffies_to_msecs(jiffies);
 /* Now send everything of to mid-level. The next time we hear about this
    packet is when sg_cmd_done() is called (i.e. a callback). */
-	scsi_do_req(SRpnt, (void *) cmnd,
-		    (void *) SRpnt->sr_buffer, hp->dxfer_len,
-		    sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
-	/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-	return 0;
+	if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer,
+				hp->dxfer_len, srp->data.k_use_sg, timeout,
+				SG_DEFAULT_RETRIES, srp, sg_cmd_done,
+				GFP_ATOMIC)) {
+		SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n"));
+		/*
+		 * most likely out of mem, but could also be a bad map
+		 */
+		return -ENOMEM;
+	} else
+		return 0;
 }
 
 static int
@@ -1156,45 +1140,22 @@
 	return (retval < 0) ? retval : 0;
 }
 
-static inline unsigned char *
-sg_scatg2virt(const struct scatterlist *sclp)
-{
-	return (sclp && sclp->page) ?
-	    (unsigned char *) page_address(sclp->page) + sclp->offset : NULL;
-}
-
 /* When startFinish==1 increments page counts for pages other than the 
-   first of scatter gather elements obtained from __get_free_pages().
+   first of scatter gather elements obtained from alloc_pages().
    When startFinish==0 decrements ... */
 static void
 sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
 {
-	void *page_ptr;
+	struct scatterlist *sg = rsv_schp->buffer;
 	struct page *page;
 	int k, m;
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", 
 				   startFinish, rsv_schp->k_use_sg));
 	/* N.B. correction _not_ applied to base page of each allocation */
-	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-			for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
-				page_ptr = sg_scatg2virt(sclp) + m;
-				page = virt_to_page(page_ptr);
-				if (startFinish)
-					get_page(page);
-				else {
-					if (page_count(page) > 0)
-						__put_page(page);
-				}
-			}
-		}
-	} else {		/* reserve buffer is just a single allocation */
-		for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
-			page_ptr = (unsigned char *) rsv_schp->buffer + m;
-			page = virt_to_page(page_ptr);
+	for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+		for (m = PAGE_SIZE; m < sg->length; m += PAGE_SIZE) {
+			page = sg->page;
 			if (startFinish)
 				get_page(page);
 			else {
@@ -1210,9 +1171,10 @@
 {
 	Sg_fd *sfp;
 	struct page *page = NOPAGE_SIGBUS;
-	void *page_ptr = NULL;
-	unsigned long offset;
+	unsigned long offset, len, sa;
 	Sg_scatter_hold *rsv_schp;
+	struct scatterlist *sg;
+	int k;
 
 	if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
 		return page;
@@ -1222,30 +1184,21 @@
 		return page;
 	SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
 				   offset, rsv_schp->k_use_sg));
-	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
-		int k;
-		unsigned long sa = vma->vm_start;
-		unsigned long len;
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-		     ++k, ++sclp) {
-			len = vma->vm_end - sa;
-			len = (len < sclp->length) ? len : sclp->length;
-			if (offset < len) {
-				page_ptr = sg_scatg2virt(sclp) + offset;
-				page = virt_to_page(page_ptr);
-				get_page(page);	/* increment page count */
-				break;
-			}
-			sa += len;
-			offset -= len;
+	sg = rsv_schp->buffer;
+	sa = vma->vm_start;
+	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+	     ++k, ++sg) {
+		len = vma->vm_end - sa;
+		len = (len < sg->length) ? len : sg->length;
+		if (offset < len) {
+			page = sg->page;
+			get_page(page);	/* increment page count */
+			break;
 		}
-	} else {		/* reserve buffer is just a single allocation */
-		page_ptr = (unsigned char *) rsv_schp->buffer + offset;
-		page = virt_to_page(page_ptr);
-		get_page(page);	/* increment page count */
+		sa += len;
+		offset -= len;
 	}
+
 	if (type)
 		*type = VM_FAULT_MINOR;
 	return page;
@@ -1259,8 +1212,10 @@
 sg_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	Sg_fd *sfp;
-	unsigned long req_sz;
+	unsigned long req_sz, len, sa;
 	Sg_scatter_hold *rsv_schp;
+	int k;
+	struct scatterlist *sg;
 
 	if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
 		return -ENXIO;
@@ -1273,24 +1228,15 @@
 	if (req_sz > rsv_schp->bufflen)
 		return -ENOMEM;	/* cannot map more than reserved buffer */
 
-	if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
-		int k;
-		unsigned long sa = vma->vm_start;
-		unsigned long len;
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-		     ++k, ++sclp) {
-			if (0 != sclp->offset)
-				return -EFAULT;	/* non page aligned memory ?? */
-			len = vma->vm_end - sa;
-			len = (len < sclp->length) ? len : sclp->length;
-			sa += len;
-		}
-	} else {	/* reserve buffer is just a single allocation */
-		if ((unsigned long) rsv_schp->buffer & (PAGE_SIZE - 1))
-			return -EFAULT;	/* non page aligned memory ?? */
+	sa = vma->vm_start;
+	sg = rsv_schp->buffer;
+	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+	     ++k, ++sg) {
+		len = vma->vm_end - sa;
+		len = (len < sg->length) ? len : sg->length;
+		sa += len;
 	}
+
 	if (0 == sfp->mmap_called) {
 		sg_rb_correct4mmap(rsv_schp, 1);	/* do only once per fd lifetime */
 		sfp->mmap_called = 1;
@@ -1304,21 +1250,16 @@
 /* This function is a "bottom half" handler that is called by the
  * mid level when a command is completed (or has failed). */
 static void
-sg_cmd_done(Scsi_Cmnd * SCpnt)
+sg_cmd_done(void *data, char *sense, int result, int resid)
 {
-	Scsi_Request *SRpnt = NULL;
+	Sg_request *srp = data;
 	Sg_device *sdp = NULL;
 	Sg_fd *sfp;
-	Sg_request *srp = NULL;
 	unsigned long iflags;
 	unsigned int ms;
 
-	if (SCpnt && (SRpnt = SCpnt->sc_request))
-		srp = (Sg_request *) SRpnt->upper_private_data;
 	if (NULL == srp) {
 		printk(KERN_ERR "sg_cmd_done: NULL request\n");
-		if (SRpnt)
-			scsi_release_request(SRpnt);
 		return;
 	}
 	sfp = srp->parentfp;
@@ -1326,49 +1267,34 @@
 		sdp = sfp->parentdp;
 	if ((NULL == sdp) || sdp->detached) {
 		printk(KERN_INFO "sg_cmd_done: device detached\n");
-		scsi_release_request(SRpnt);
 		return;
 	}
 
-	/* First transfer ownership of data buffers to sg_device object. */
-	srp->data.k_use_sg = SRpnt->sr_use_sg;
-	srp->data.sglist_len = SRpnt->sr_sglist_len;
-	srp->data.bufflen = SRpnt->sr_bufflen;
-	srp->data.buffer = SRpnt->sr_buffer;
-	/* now clear out request structure */
-	SRpnt->sr_use_sg = 0;
-	SRpnt->sr_sglist_len = 0;
-	SRpnt->sr_bufflen = 0;
-	SRpnt->sr_buffer = NULL;
-	SRpnt->sr_underflow = 0;
-	SRpnt->sr_request->rq_disk = NULL; /* "sg" _disowns_ request blk */
-
-	srp->my_cmdp = NULL;
 
 	SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
-		sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result));
-	srp->header.resid = SCpnt->resid;
+		sdp->disk->disk_name, srp->header.pack_id, result));
+	srp->header.resid = resid;
 	ms = jiffies_to_msecs(jiffies);
 	srp->header.duration = (ms > srp->header.duration) ?
 				(ms - srp->header.duration) : 0;
-	if (0 != SRpnt->sr_result) {
+	if (0 != 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;
-		srp->header.masked_status = status_byte(SRpnt->sr_result);
-		srp->header.msg_status = msg_byte(SRpnt->sr_result);
-		srp->header.host_status = host_byte(SRpnt->sr_result);
-		srp->header.driver_status = driver_byte(SRpnt->sr_result);
+		memcpy(srp->sense_b, sense, sizeof (srp->sense_b));
+		srp->header.status = 0xff & result;
+		srp->header.masked_status = status_byte(result);
+		srp->header.msg_status = msg_byte(result);
+		srp->header.host_status = host_byte(result);
+		srp->header.driver_status = driver_byte(result);
 		if ((sdp->sgdebug > 0) &&
 		    ((CHECK_CONDITION == srp->header.masked_status) ||
 		     (COMMAND_TERMINATED == srp->header.masked_status)))
-			scsi_print_req_sense("sg_cmd_done", SRpnt);
+			__scsi_print_sense("sg_cmd_done", sense,
+					   SCSI_SENSE_BUFFERSIZE);
 
 		/* Following if statement is a patch supplied by Eric Youngdale */
-		if (driver_byte(SRpnt->sr_result) != 0
-		    && scsi_command_normalize_sense(SCpnt, &sshdr)
+		if (driver_byte(result) != 0
+		    && scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)
 		    && !scsi_sense_is_deferred(&sshdr)
 		    && sshdr.sense_key == UNIT_ATTENTION
 		    && sdp->device->removable) {
@@ -1379,8 +1305,6 @@
 	}
 	/* Rely on write phase to clean out srp status values, so no "else" */
 
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
 	if (sfp->closed) {	/* whoops this fd already released, cleanup */
 		SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n"));
 		sg_finish_rem_req(srp);
@@ -1431,6 +1355,7 @@
 
 static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 {
+	struct request_queue *q = scsidp->request_queue;
 	Sg_device *sdp;
 	unsigned long iflags;
 	void *old_sg_dev_arr = NULL;
@@ -1473,7 +1398,7 @@
 	sdp->disk = disk;
 	sdp->device = scsidp;
 	init_waitqueue_head(&sdp->o_excl_wait);
-	sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
+	sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
 
 	sg_nr_dev++;
 	sg_dev_arr[k] = sdp;
@@ -1753,36 +1678,35 @@
 static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
-	int ret_sz;
-	int elem_sz = sizeof (struct scatterlist);
-	int sg_bufflen = tablesize * elem_sz;
-	int mx_sc_elems = tablesize;
+	int sg_bufflen = tablesize * sizeof(struct scatterlist);
+	unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
-	schp->buffer = sg_page_malloc(sg_bufflen, sfp->low_dma, &ret_sz);
+	/*
+	 * TODO: test without low_dma, we should not need it since
+	 * the block layer will bounce the buffer for us
+	 *
+	 * XXX(hch): we shouldn't need GFP_DMA for the actual S/G list.
+	 */
+	if (sfp->low_dma)
+		 gfp_flags |= GFP_DMA;
+	schp->buffer = kzalloc(sg_bufflen, gfp_flags);
 	if (!schp->buffer)
 		return -ENOMEM;
-	else if (ret_sz != sg_bufflen) {
-		sg_bufflen = ret_sz;
-		mx_sc_elems = sg_bufflen / elem_sz;
-	}
 	schp->sglist_len = sg_bufflen;
-	memset(schp->buffer, 0, sg_bufflen);
-	return mx_sc_elems;	/* number of scat_gath elements allocated */
+	return tablesize;	/* number of scat_gath elements allocated */
 }
 
 #ifdef SG_ALLOW_DIO_CODE
 /* vvvvvvvv  following code borrowed from st driver's direct IO vvvvvvvvv */
-	/* hopefully this generic code will moved to a library */
+	/* TODO: hopefully we can use the generic block layer code */
 
 /* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
    - mapping of all pages not successful
-   - any page is above max_pfn
    (i.e., either completely successful or fails)
 */
 static int 
 st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-	          unsigned long uaddr, size_t count, int rw,
-	          unsigned long max_pfn)
+	          unsigned long uaddr, size_t count, int rw)
 {
 	unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	unsigned long start = uaddr >> PAGE_SHIFT;
@@ -1828,21 +1752,17 @@
                  * probably wrong function for rw==WRITE
                  */
 		flush_dcache_page(pages[i]);
-		if (page_to_pfn(pages[i]) > max_pfn)
-			goto out_unlock;
 		/* ?? Is locking needed? I don't think so */
 		/* if (TestSetPageLocked(pages[i]))
 		   goto out_unlock; */
         }
 
-	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sgl[0].page = pages[0];
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].offset = 0;
 			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
@@ -1855,10 +1775,6 @@
 	kfree(pages);
 	return nr_pages;
 
- out_unlock:
-	/* for (j=0; j < i; j++)
-	   unlock_page(pages[j]); */
-	res = 0;
  out_unmap:
 	if (res > 0) {
 		for (j=0; j < res; j++)
@@ -1904,20 +1820,20 @@
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
 	int sg_tablesize = sfp->parentdp->sg_tablesize;
-	struct scatterlist *sgl;
 	int mx_sc_elems, res;
 	struct scsi_device *sdev = sfp->parentdp->device;
 
 	if (((unsigned long)hp->dxferp &
 			queue_dma_alignment(sdev->request_queue)) != 0)
 		return 1;
+
 	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
         if (mx_sc_elems <= 0) {
                 return 1;
         }
-	sgl = (struct scatterlist *)schp->buffer;
-	res = st_map_user_pages(sgl, mx_sc_elems, (unsigned long)hp->dxferp, dxfer_len, 
-				(SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0, ULONG_MAX);
+	res = st_map_user_pages(schp->buffer, mx_sc_elems,
+				(unsigned long)hp->dxferp, dxfer_len, 
+				(SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0);
 	if (res <= 0)
 		return 1;
 	schp->k_use_sg = res;
@@ -1932,9 +1848,11 @@
 static int
 sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 {
-	int ret_sz;
+	struct scatterlist *sg;
+	int ret_sz = 0, k, rem_sz, num, mx_sc_elems;
+	int sg_tablesize = sfp->parentdp->sg_tablesize;
 	int blk_size = buff_size;
-	unsigned char *p = NULL;
+	struct page *p = NULL;
 
 	if ((blk_size < 0) || (!sfp))
 		return -EFAULT;
@@ -1944,59 +1862,35 @@
 	blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
 	SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
 				   buff_size, blk_size));
-	if (blk_size <= SG_SCATTER_SZ) {
-		p = sg_page_malloc(blk_size, sfp->low_dma, &ret_sz);
+
+	/* N.B. ret_sz carried into this block ... */
+	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
+	if (mx_sc_elems < 0)
+		return mx_sc_elems;	/* most likely -ENOMEM */
+
+	for (k = 0, sg = schp->buffer, rem_sz = blk_size;
+	     (rem_sz > 0) && (k < mx_sc_elems);
+	     ++k, rem_sz -= ret_sz, ++sg) {
+		
+		num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
+		p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
 		if (!p)
 			return -ENOMEM;
-		if (blk_size == ret_sz) {	/* got it on the first attempt */
-			schp->k_use_sg = 0;
-			schp->buffer = p;
-			schp->bufflen = blk_size;
-			schp->b_malloc_len = blk_size;
-			return 0;
-		}
-	} else {
-		p = sg_page_malloc(SG_SCATTER_SZ, sfp->low_dma, &ret_sz);
-		if (!p)
-			return -ENOMEM;
-	}
-/* Want some local declarations, so start new block ... */
-	{			/* lets try and build a scatter gather list */
-		struct scatterlist *sclp;
-		int k, rem_sz, num;
-		int mx_sc_elems;
-		int sg_tablesize = sfp->parentdp->sg_tablesize;
-		int first = 1;
 
-		/* N.B. ret_sz carried into this block ... */
-		mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
-		if (mx_sc_elems < 0)
-			return mx_sc_elems;	/* most likely -ENOMEM */
+		sg->page = p;
+		sg->length = ret_sz;
 
-		for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
-		     (rem_sz > 0) && (k < mx_sc_elems);
-		     ++k, rem_sz -= ret_sz, ++sclp) {
-			if (first)
-				first = 0;
-			else {
-				num =
-				    (rem_sz >
-				     SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
-				p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
-				if (!p)
-					break;
-			}
-			sg_set_buf(sclp, p, ret_sz);
+		SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
+				  k, p, ret_sz));
+	}		/* end of for loop */
 
-			SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
-					  k, sg_scatg2virt(sclp), ret_sz));
-		}		/* end of for loop */
-		schp->k_use_sg = k;
-		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
-		schp->bufflen = blk_size;
-		if (rem_sz > 0)	/* must have failed */
-			return -ENOMEM;
-	}
+	schp->k_use_sg = k;
+	SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
+
+	schp->bufflen = blk_size;
+	if (rem_sz > 0)	/* must have failed */
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -2005,6 +1899,7 @@
 {
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
 	int num_xfer = 0;
 	int j, k, onum, usglen, ksglen, res;
 	int iovec_count = (int) hp->iovec_count;
@@ -2033,63 +1928,45 @@
 	} else
 		onum = 1;
 
-	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
-		for (j = 0, p = schp->buffer; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-			if (res)
-				return res;
-			usglen = (num_xfer > usglen) ? usglen : num_xfer;
-			if (__copy_from_user(p, up, usglen))
-				return -EFAULT;
-			p += usglen;
-			num_xfer -= usglen;
-			if (num_xfer <= 0)
+	ksglen = sg->length;
+	p = page_address(sg->page);
+	for (j = 0, k = 0; j < onum; ++j) {
+		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
+		if (res)
+			return res;
+
+		for (; p; ++sg, ksglen = sg->length,
+		     p = page_address(sg->page)) {
+			if (usglen <= 0)
+				break;
+			if (ksglen > usglen) {
+				if (usglen >= num_xfer) {
+					if (__copy_from_user(p, up, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_from_user(p, up, usglen))
+					return -EFAULT;
+				p += usglen;
+				ksglen -= usglen;
+				break;
+			} else {
+				if (ksglen >= num_xfer) {
+					if (__copy_from_user(p, up, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_from_user(p, up, ksglen))
+					return -EFAULT;
+				up += ksglen;
+				usglen -= ksglen;
+			}
+			++k;
+			if (k >= schp->k_use_sg)
 				return 0;
 		}
-	} else {		/* kernel using scatter gather list */
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-		ksglen = (int) sclp->length;
-		p = sg_scatg2virt(sclp);
-		for (j = 0, k = 0; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-			if (res)
-				return res;
-
-			for (; p; ++sclp, ksglen = (int) sclp->length,
-				  p = sg_scatg2virt(sclp)) {
-				if (usglen <= 0)
-					break;
-				if (ksglen > usglen) {
-					if (usglen >= num_xfer) {
-						if (__copy_from_user
-						    (p, up, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_from_user(p, up, usglen))
-						return -EFAULT;
-					p += usglen;
-					ksglen -= usglen;
-					break;
-				} else {
-					if (ksglen >= num_xfer) {
-						if (__copy_from_user
-						    (p, up, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_from_user(p, up, ksglen))
-						return -EFAULT;
-					up += ksglen;
-					usglen -= ksglen;
-				}
-				++k;
-				if (k >= schp->k_use_sg)
-					return 0;
-			}
-		}
 	}
+
 	return 0;
 }
 
@@ -2127,29 +2004,25 @@
 {
 	SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
 	if (schp->buffer && (schp->sglist_len > 0)) {
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
+		struct scatterlist *sg = schp->buffer;
 
 		if (schp->dio_in_use) {
 #ifdef SG_ALLOW_DIO_CODE
-			st_unmap_user_pages(sclp, schp->k_use_sg, TRUE);
+			st_unmap_user_pages(sg, schp->k_use_sg, TRUE);
 #endif
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-			     ++k, ++sclp) {
+			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			     ++k, ++sg) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, a=0x%p, len=%d\n",
-				    k, sg_scatg2virt(sclp), sclp->length));
-				sg_page_free(sg_scatg2virt(sclp), sclp->length);
-				sclp->page = NULL;
-				sclp->offset = 0;
-				sclp->length = 0;
+				    k, sg->page, sg->length));
+				sg_page_free(sg->page, sg->length);
 			}
 		}
-		sg_page_free(schp->buffer, schp->sglist_len);
-	} else if (schp->buffer)
-		sg_page_free(schp->buffer, schp->b_malloc_len);
+		kfree(schp->buffer);
+	}
 	memset(schp, 0, sizeof (*schp));
 }
 
@@ -2158,6 +2031,7 @@
 {
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
 	int num_xfer = 0;
 	int j, k, onum, usglen, ksglen, res;
 	int iovec_count = (int) hp->iovec_count;
@@ -2186,63 +2060,45 @@
 	} else
 		onum = 1;
 
-	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
-		for (j = 0, p = schp->buffer; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-			if (res)
-				return res;
-			usglen = (num_xfer > usglen) ? usglen : num_xfer;
-			if (__copy_to_user(up, p, usglen))
-				return -EFAULT;
-			p += usglen;
-			num_xfer -= usglen;
-			if (num_xfer <= 0)
+	p = page_address(sg->page);
+	ksglen = sg->length;
+	for (j = 0, k = 0; j < onum; ++j) {
+		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
+		if (res)
+			return res;
+
+		for (; p; ++sg, ksglen = sg->length,
+		     p = page_address(sg->page)) {
+			if (usglen <= 0)
+				break;
+			if (ksglen > usglen) {
+				if (usglen >= num_xfer) {
+					if (__copy_to_user(up, p, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_to_user(up, p, usglen))
+					return -EFAULT;
+				p += usglen;
+				ksglen -= usglen;
+				break;
+			} else {
+				if (ksglen >= num_xfer) {
+					if (__copy_to_user(up, p, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_to_user(up, p, ksglen))
+					return -EFAULT;
+				up += ksglen;
+				usglen -= ksglen;
+			}
+			++k;
+			if (k >= schp->k_use_sg)
 				return 0;
 		}
-	} else {		/* kernel using scatter gather list */
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-		ksglen = (int) sclp->length;
-		p = sg_scatg2virt(sclp);
-		for (j = 0, k = 0; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-			if (res)
-				return res;
-
-			for (; p; ++sclp, ksglen = (int) sclp->length,
-				  p = sg_scatg2virt(sclp)) {
-				if (usglen <= 0)
-					break;
-				if (ksglen > usglen) {
-					if (usglen >= num_xfer) {
-						if (__copy_to_user
-						    (up, p, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_to_user(up, p, usglen))
-						return -EFAULT;
-					p += usglen;
-					ksglen -= usglen;
-					break;
-				} else {
-					if (ksglen >= num_xfer) {
-						if (__copy_to_user
-						    (up, p, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_to_user(up, p, ksglen))
-						return -EFAULT;
-					up += ksglen;
-					usglen -= ksglen;
-				}
-				++k;
-				if (k >= schp->k_use_sg)
-					return 0;
-			}
-		}
 	}
+
 	return 0;
 }
 
@@ -2250,37 +2106,32 @@
 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 {
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
+	int k, num;
 
 	SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
 				   num_read_xfer));
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
-	if (schp->k_use_sg > 0) {
-		int k, num;
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
 
-		for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-		     ++k, ++sclp) {
-			num = (int) sclp->length;
-			if (num > num_read_xfer) {
-				if (__copy_to_user
-				    (outp, sg_scatg2virt(sclp), num_read_xfer))
-					return -EFAULT;
+	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) {
+		num = sg->length;
+		if (num > num_read_xfer) {
+			if (__copy_to_user(outp, page_address(sg->page),
+					   num_read_xfer))
+				return -EFAULT;
+			break;
+		} else {
+			if (__copy_to_user(outp, page_address(sg->page),
+					   num))
+				return -EFAULT;
+			num_read_xfer -= num;
+			if (num_read_xfer <= 0)
 				break;
-			} else {
-				if (__copy_to_user
-				    (outp, sg_scatg2virt(sclp), num))
-					return -EFAULT;
-				num_read_xfer -= num;
-				if (num_read_xfer <= 0)
-					break;
-				outp += num;
-			}
+			outp += num;
 		}
-	} else {
-		if (__copy_to_user(outp, schp->buffer, num_read_xfer))
-			return -EFAULT;
 	}
+
 	return 0;
 }
 
@@ -2306,44 +2157,31 @@
 {
 	Sg_scatter_hold *req_schp = &srp->data;
 	Sg_scatter_hold *rsv_schp = &sfp->reserve;
+	struct scatterlist *sg = rsv_schp->buffer;
+	int k, num, rem;
 
 	srp->res_used = 1;
 	SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
-	size = (size + 1) & (~1);	/* round to even for aha1542 */
-	if (rsv_schp->k_use_sg > 0) {
-		int k, num;
-		int rem = size;
-		struct scatterlist *sclp =
-		    (struct scatterlist *) rsv_schp->buffer;
+	rem = size = (size + 1) & (~1);	/* round to even for aha1542 */
 
-		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-			num = (int) sclp->length;
-			if (rem <= num) {
-				if (0 == k) {
-					req_schp->k_use_sg = 0;
-					req_schp->buffer = sg_scatg2virt(sclp);
-				} else {
-					sfp->save_scat_len = num;
-					sclp->length = (unsigned) rem;
-					req_schp->k_use_sg = k + 1;
-					req_schp->sglist_len =
-					    rsv_schp->sglist_len;
-					req_schp->buffer = rsv_schp->buffer;
-				}
-				req_schp->bufflen = size;
-				req_schp->b_malloc_len = rsv_schp->b_malloc_len;
-				break;
-			} else
-				rem -= num;
-		}
-		if (k >= rsv_schp->k_use_sg)
-			SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
-	} else {
-		req_schp->k_use_sg = 0;
-		req_schp->bufflen = size;
-		req_schp->buffer = rsv_schp->buffer;
-		req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+	for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+		num = sg->length;
+		if (rem <= num) {
+			sfp->save_scat_len = num;
+			sg->length = rem;
+			req_schp->k_use_sg = k + 1;
+			req_schp->sglist_len = rsv_schp->sglist_len;
+			req_schp->buffer = rsv_schp->buffer;
+
+			req_schp->bufflen = size;
+			req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+			break;
+		} else
+			rem -= num;
 	}
+
+	if (k >= rsv_schp->k_use_sg)
+		SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
 }
 
 static void
@@ -2355,11 +2193,10 @@
 	SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
 				   (int) req_schp->k_use_sg));
 	if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
-		struct scatterlist *sclp =
-		    (struct scatterlist *) rsv_schp->buffer;
+		struct scatterlist *sg = rsv_schp->buffer;
 
 		if (sfp->save_scat_len > 0)
-			(sclp + (req_schp->k_use_sg - 1))->length =
+			(sg + (req_schp->k_use_sg - 1))->length =
 			    (unsigned) sfp->save_scat_len;
 		else
 			SCSI_LOG_TIMEOUT(1, printk ("sg_unlink_reserve: BAD save_scat_len\n"));
@@ -2445,7 +2282,6 @@
 	if (resp) {
 		resp->nextrp = NULL;
 		resp->header.duration = jiffies_to_msecs(jiffies);
-		resp->my_cmdp = NULL;
 	}
 	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
 	return resp;
@@ -2463,8 +2299,6 @@
 	if ((!sfp) || (!srp) || (!sfp->headrp))
 		return res;
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
-	if (srp->my_cmdp)
-		srp->my_cmdp->upper_private_data = NULL;
 	prev_rp = sfp->headrp;
 	if (srp == prev_rp) {
 		sfp->headrp = prev_rp->nextrp;
@@ -2507,10 +2341,10 @@
 	Sg_fd *sfp;
 	unsigned long iflags;
 
-	sfp = (Sg_fd *) sg_page_malloc(sizeof (Sg_fd), 0, NULL);
+	sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN);
 	if (!sfp)
 		return NULL;
-	memset(sfp, 0, sizeof (Sg_fd));
+
 	init_waitqueue_head(&sfp->read_wait);
 	rwlock_init(&sfp->rq_list_lock);
 
@@ -2567,7 +2401,7 @@
 	}
 	sfp->parentdp = NULL;
 	SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    sfp=0x%p\n", sfp));
-	sg_page_free((char *) sfp, sizeof (Sg_fd));
+	kfree(sfp);
 }
 
 /* Returns 0 in normal case, 1 when detached and sdp object removed */
@@ -2632,10 +2466,10 @@
 }
 
 /* If retSzp==NULL want exact size or fail */
-static char *
+static struct page *
 sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 {
-	char *resp = NULL;
+	struct page *resp = NULL;
 	gfp_t page_mask;
 	int order, a_size;
 	int resSz = rqSz;
@@ -2650,11 +2484,11 @@
 
 	for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
 	     order++, a_size <<= 1) ;
-	resp = (char *) __get_free_pages(page_mask, order);
+	resp = alloc_pages(page_mask, order);
 	while ((!resp) && order && retSzp) {
 		--order;
 		a_size >>= 1;	/* divide by 2, until PAGE_SIZE */
-		resp = (char *) __get_free_pages(page_mask, order);	/* try half */
+		resp =  alloc_pages(page_mask, order);	/* try half */
 		resSz = a_size;
 	}
 	if (resp) {
@@ -2667,15 +2501,15 @@
 }
 
 static void
-sg_page_free(char *buff, int size)
+sg_page_free(struct page *page, int size)
 {
 	int order, a_size;
 
-	if (!buff)
+	if (!page)
 		return;
 	for (order = 0, a_size = PAGE_SIZE; a_size < size;
 	     order++, a_size <<= 1) ;
-	free_pages((unsigned long) buff, order);
+	__free_pages(page, order);
 }
 
 #ifndef MAINTENANCE_IN_CMD
@@ -3067,13 +2901,11 @@
 					cp = "     ";
 			}
 			seq_printf(s, cp);
-			blen = srp->my_cmdp ? 
-				srp->my_cmdp->sr_bufflen : srp->data.bufflen;
-			usg = srp->my_cmdp ? 
-				srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
+			blen = srp->data.bufflen;
+			usg = srp->data.k_use_sg;
 			seq_printf(s, srp->done ? 
 				   ((1 == srp->done) ?  "rcv:" : "fin:")
-				   : (srp->my_cmdp ? "act:" : "prior:"));
+				   : "act:");
 			seq_printf(s, " id=%d blen=%d",
 				   srp->header.pack_id, blen);
 			if (srp->done)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index fb4012b..a4d9be7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -320,7 +320,7 @@
 	 * these are already setup, just copy cdb basically
 	 */
 	if (SCpnt->request->flags & REQ_BLOCK_PC) {
-		scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES);
+		scsi_setup_blk_pc_cmnd(SCpnt);
 
 		if (SCpnt->timeout_per_command)
 			timeout = SCpnt->timeout_per_command;
@@ -716,7 +716,7 @@
 	unsigned int the_result;
 	int retries, rc, n;
 
-	static char *loadmech[] =
+	static const char *loadmech[] =
 	{
 		"caddy",
 		"tray",
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 78274dc..9dde8df 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -68,8 +68,8 @@
 #ifndef CONFIG_BLK_DEV_SR_VENDOR
 	cd->vendor = VENDOR_SCSI3;
 #else
-	char *vendor = cd->device->vendor;
-	char *model = cd->device->model;
+	const char *vendor = cd->device->vendor;
+	const char *model = cd->device->model;
 	
 	/* default */
 	cd->vendor = VENDOR_SCSI3;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index dd592f6..c4aade8 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20050830";
+static const char *verstr = "20050830";
 
 #include <linux/module.h>
 
@@ -50,7 +50,6 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
-#include <scsi/scsi_request.h>
 #include <scsi/sg.h>
 
 
@@ -134,7 +133,7 @@
 #endif
 /* Bit reversed order to get same names for same minors with all
    mode counts */
-static char *st_formats[] = {
+static const char *st_formats[] = {
 	"",  "r", "k", "s", "l", "t", "o", "u",
 	"m", "v", "p", "x", "a", "y", "q", "z"}; 
 
@@ -188,8 +187,6 @@
 static void move_buffer_data(struct st_buffer *, int);
 static void buf_to_sg(struct st_buffer *, unsigned int);
 
-static int st_map_user_pages(struct scatterlist *, const unsigned int, 
-			     unsigned long, size_t, int, unsigned long);
 static int sgl_map_user_pages(struct scatterlist *, const unsigned int, 
 			      unsigned long, size_t, int);
 static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
@@ -313,12 +310,13 @@
 }
 
 
-static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s)
+static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
 {
 	const u8 *ucp;
-	const u8 *sense = SRpnt->sr_sense_buffer;
+	const u8 *sense = SRpnt->sense;
 
-	s->have_sense = scsi_request_normalize_sense(SRpnt, &s->sense_hdr);
+	s->have_sense = scsi_normalize_sense(SRpnt->sense,
+				SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
 	s->flags = 0;
 
 	if (s->have_sense) {
@@ -345,9 +343,9 @@
 
 
 /* Convert the result to success code */
-static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
+static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
 {
-	int result = SRpnt->sr_result;
+	int result = SRpnt->result;
 	u8 scode;
 	DEB(const char *stp;)
 	char *name = tape_name(STp);
@@ -366,13 +364,12 @@
 
         DEB(
         if (debugging) {
-                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
 		       name, result,
-		       SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
-		       SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
-		       SRpnt->sr_bufflen);
+		       SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
+		       SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
 		if (cmdstatp->have_sense)
-			scsi_print_req_sense("st", SRpnt);
+			 __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
 	} ) /* end DEB */
 	if (!debugging) { /* Abnormal conditions for tape */
 		if (!cmdstatp->have_sense)
@@ -386,20 +383,21 @@
 			 /* scode != UNIT_ATTENTION && */
 			 scode != BLANK_CHECK &&
 			 scode != VOLUME_OVERFLOW &&
-			 SRpnt->sr_cmnd[0] != MODE_SENSE &&
-			 SRpnt->sr_cmnd[0] != TEST_UNIT_READY) {
+			 SRpnt->cmd[0] != MODE_SENSE &&
+			 SRpnt->cmd[0] != TEST_UNIT_READY) {
 				printk(KERN_WARNING "%s: Error with sense data: ", name);
-				scsi_print_req_sense("st", SRpnt);
+				__scsi_print_sense("st", SRpnt->sense,
+						   SCSI_SENSE_BUFFERSIZE);
 		}
 	}
 
 	if (cmdstatp->fixed_format &&
 	    STp->cln_mode >= EXTENDED_SENSE_START) {  /* Only fixed format sense */
 		if (STp->cln_sense_value)
-			STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+			STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
 					       STp->cln_sense_mask) == STp->cln_sense_value);
 		else
-			STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+			STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
 					       STp->cln_sense_mask) != 0);
 	}
 	if (cmdstatp->have_sense &&
@@ -411,8 +409,8 @@
 	if (cmdstatp->have_sense &&
 	    scode == RECOVERED_ERROR
 #if ST_RECOVERED_WRITE_FATAL
-	    && SRpnt->sr_cmnd[0] != WRITE_6
-	    && SRpnt->sr_cmnd[0] != WRITE_FILEMARKS
+	    && SRpnt->cmd[0] != WRITE_6
+	    && SRpnt->cmd[0] != WRITE_FILEMARKS
 #endif
 	    ) {
 		STp->recover_count++;
@@ -420,9 +418,9 @@
 
                 DEB(
 		if (debugging) {
-			if (SRpnt->sr_cmnd[0] == READ_6)
+			if (SRpnt->cmd[0] == READ_6)
 				stp = "read";
-			else if (SRpnt->sr_cmnd[0] == WRITE_6)
+			else if (SRpnt->cmd[0] == WRITE_6)
 				stp = "write";
 			else
 				stp = "ioctl";
@@ -438,28 +436,37 @@
 
 
 /* Wakeup from interrupt */
-static void st_sleep_done(struct scsi_cmnd * SCpnt)
+static void st_sleep_done(void *data, char *sense, int result, int resid)
 {
-	struct scsi_tape *STp = container_of(SCpnt->request->rq_disk->private_data,
-					     struct scsi_tape, driver);
+	struct st_request *SRpnt = data;
+	struct scsi_tape *STp = SRpnt->stp;
 
-	(STp->buffer)->cmdstat.midlevel_result = SCpnt->result;
-	SCpnt->request->rq_status = RQ_SCSI_DONE;
+	memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
+	(STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
 	DEB( STp->write_pending = 0; )
 
-	if (SCpnt->request->waiting)
-		complete(SCpnt->request->waiting);
+	if (SRpnt->waiting)
+		complete(SRpnt->waiting);
+}
+
+static struct st_request *st_allocate_request(void)
+{
+	return kzalloc(sizeof(struct st_request), GFP_KERNEL);
+}
+
+static void st_release_request(struct st_request *streq)
+{
+	kfree(streq);
 }
 
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise write_behind_check() is used to check that the command
    has finished. */
-static struct scsi_request *
-st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
+static struct st_request *
+st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
 	   int bytes, int direction, int timeout, int retries, int do_wait)
 {
 	struct completion *waiting;
-	unsigned char *bp;
 
 	/* if async, make sure there's no command outstanding */
 	if (!do_wait && ((STp->buffer)->last_SRpnt)) {
@@ -473,7 +480,7 @@
 	}
 
 	if (SRpnt == NULL) {
-		SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC);
+		SRpnt = st_allocate_request();
 		if (SRpnt == NULL) {
 			DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
 				     tape_name(STp)); );
@@ -483,6 +490,7 @@
 				(STp->buffer)->syscall_result = (-EBUSY);
 			return NULL;
 		}
+		SRpnt->stp = STp;
 	}
 
 	/* If async IO, set last_SRpnt. This ptr tells write_behind_check
@@ -492,32 +500,28 @@
 
 	waiting = &STp->wait;
 	init_completion(waiting);
-	SRpnt->sr_use_sg = STp->buffer->do_dio || (bytes > (STp->buffer)->frp[0].length);
-	if (SRpnt->sr_use_sg) {
-		if (!STp->buffer->do_dio)
-			buf_to_sg(STp->buffer, bytes);
-		SRpnt->sr_use_sg = (STp->buffer)->sg_segs;
-		bp = (char *) &((STp->buffer)->sg[0]);
-	} else
-		bp = (STp->buffer)->b_data;
-	SRpnt->sr_data_direction = direction;
-	SRpnt->sr_cmd_len = 0;
-	SRpnt->sr_request->waiting = waiting;
-	SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-	SRpnt->sr_request->rq_disk = STp->disk;
-	SRpnt->sr_request->end_io = blk_end_sync_rq;
+	SRpnt->waiting = waiting;
+
+	if (!STp->buffer->do_dio)
+		buf_to_sg(STp->buffer, bytes);
+
+	memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
 	STp->buffer->cmdstat.have_sense = 0;
+	STp->buffer->syscall_result = 0;
 
-	scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
-		    st_sleep_done, timeout, retries);
-
-	if (do_wait) {
+	if (scsi_execute_async(STp->device, cmd, direction,
+			&((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
+			       timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
+		/* could not allocate the buffer or request was too large */
+		(STp->buffer)->syscall_result = (-EBUSY);
+		(STp->buffer)->last_SRpnt = NULL;
+	}
+	else if (do_wait) {
 		wait_for_completion(waiting);
-		SRpnt->sr_request->waiting = NULL;
-		if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-			SRpnt->sr_result |= (DRIVER_ERROR << 24);
+		SRpnt->waiting = NULL;
 		(STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
 	}
+
 	return SRpnt;
 }
 
@@ -532,7 +536,7 @@
 	struct st_buffer *STbuffer;
 	struct st_partstat *STps;
 	struct st_cmdstatus *cmdstatp;
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 
 	STbuffer = STp->buffer;
 	if (!STbuffer->writing)
@@ -548,12 +552,10 @@
 	wait_for_completion(&(STp->wait));
 	SRpnt = STbuffer->last_SRpnt;
 	STbuffer->last_SRpnt = NULL;
-	SRpnt->sr_request->waiting = NULL;
-	if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-		SRpnt->sr_result |= (DRIVER_ERROR << 24);
+	SRpnt->waiting = NULL;
 
 	(STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	STbuffer->buffer_bytes -= STbuffer->writing;
 	STps = &(STp->ps[STp->partition]);
@@ -593,7 +595,7 @@
    it messes up the block number). */
 static int cross_eof(struct scsi_tape * STp, int forward)
 {
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 
 	cmd[0] = SPACE;
@@ -613,7 +615,7 @@
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	if ((STp->buffer)->cmdstat.midlevel_result != 0)
@@ -630,7 +632,7 @@
 	int offset, transfer, blks;
 	int result;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_partstat *STps;
 
 	result = write_behind_check(STp);
@@ -688,7 +690,7 @@
 			STp->dirty = 0;
 			(STp->buffer)->buffer_bytes = 0;
 		}
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 	return result;
@@ -785,7 +787,7 @@
 }
 
 
-/* Lock or unlock the drive door. Don't use when scsi_request allocated. */
+/* Lock or unlock the drive door. Don't use when st_request allocated. */
 static int do_door_lock(struct scsi_tape * STp, int do_lock)
 {
 	int retval, cmd;
@@ -844,7 +846,7 @@
 	int attentions, waits, max_wait, scode;
 	int retval = CHKRES_READY, new_session = 0;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
 
 	max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
@@ -903,7 +905,7 @@
 	}
 
 	if (SRpnt != NULL)
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 	return retval;
 }
 
@@ -918,7 +920,7 @@
 	int i, retval, new_session = 0, do_wait;
 	unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
 	unsigned short st_flags = filp->f_flags;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	char *name = tape_name(STp);
@@ -993,7 +995,7 @@
 			goto err_out;
 		}
 
-		if (!SRpnt->sr_result && !STp->buffer->cmdstat.have_sense) {
+		if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
 			STp->max_block = ((STp->buffer)->b_data[1] << 16) |
 			    ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
 			STp->min_block = ((STp->buffer)->b_data[4] << 8) |
@@ -1045,7 +1047,7 @@
 		}
 		STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
 	}
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
         STp->inited = 1;
 
@@ -1196,7 +1198,7 @@
 {
 	int result = 0, result2;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm = &(STp->modes[STp->current_mode]);
 	struct st_partstat *STps = &(STp->ps[STp->partition]);
@@ -1249,7 +1251,7 @@
 		      cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
 		     (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
 			/* Write successful at EOM */
-			scsi_release_request(SRpnt);
+			st_release_request(SRpnt);
 			SRpnt = NULL;
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
@@ -1259,7 +1261,7 @@
 			STps->eof = ST_FM;
 		}
 		else { /* Write error */
-			scsi_release_request(SRpnt);
+			st_release_request(SRpnt);
 			SRpnt = NULL;
 			printk(KERN_ERR "%s: Error on write filemark.\n", name);
 			if (result == 0)
@@ -1400,11 +1402,11 @@
 		i = STp->try_dio && try_rdio;
 	else
 		i = STp->try_dio && try_wdio;
+
 	if (i && ((unsigned long)buf & queue_dma_alignment(
 					STp->device->request_queue)) == 0) {
-		i = st_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
-				      (unsigned long)buf, count, (is_read ? READ : WRITE),
-				      STp->max_pfn);
+		i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
+				      (unsigned long)buf, count, (is_read ? READ : WRITE));
 		if (i > 0) {
 			STbp->do_dio = i;
 			STbp->buffer_bytes = 0;   /* can be used as transfer counter */
@@ -1449,14 +1451,15 @@
 
 
 /* Can be called more than once after each setup_buffer() */
-static void release_buffering(struct scsi_tape *STp)
+static void release_buffering(struct scsi_tape *STp, int is_read)
 {
 	struct st_buffer *STbp;
 
 	STbp = STp->buffer;
 	if (STbp->do_dio) {
-		sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, 0);
+		sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
 		STbp->do_dio = 0;
+		STbp->sg_segs = 0;
 	}
 }
 
@@ -1472,7 +1475,7 @@
 	int async_write;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	const char __user *b_point;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
@@ -1624,7 +1627,7 @@
 			retval = STbp->syscall_result;
 			goto out;
 		}
-		if (async_write) {
+		if (async_write && !STbp->syscall_result) {
 			STbp->writing = transfer;
 			STp->dirty = !(STbp->writing ==
 				       STbp->buffer_bytes);
@@ -1698,7 +1701,7 @@
 			} else {
 				count += do_count;
 				STps->drv_block = (-1);		/* Too cautious? */
-				retval = (-EIO);
+				retval = STbp->syscall_result;
 			}
 
 		}
@@ -1728,8 +1731,8 @@
 
  out:
 	if (SRpnt != NULL)
-		scsi_release_request(SRpnt);
-	release_buffering(STp);
+		st_release_request(SRpnt);
+	release_buffering(STp, 0);
 	up(&STp->lock);
 
 	return retval;
@@ -1742,11 +1745,11 @@
    Does release user buffer mapping if it is set.
 */
 static long read_tape(struct scsi_tape *STp, long count,
-		      struct scsi_request ** aSRpnt)
+		      struct st_request ** aSRpnt)
 {
 	int transfer, blks, bytes;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	struct st_buffer *STbp;
@@ -1787,7 +1790,7 @@
 	SRpnt = *aSRpnt;
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
 			   STp->device->timeout, MAX_RETRIES, 1);
-	release_buffering(STp);
+	release_buffering(STp, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
 		return STbp->syscall_result;
@@ -1802,10 +1805,10 @@
 		retval = 1;
 		DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
                             name,
-                            SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
-                            SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
-                            SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
-                            SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]));
+                            SRpnt->sense[0], SRpnt->sense[1],
+                            SRpnt->sense[2], SRpnt->sense[3],
+                            SRpnt->sense[4], SRpnt->sense[5],
+                            SRpnt->sense[6], SRpnt->sense[7]));
 		if (cmdstatp->have_sense) {
 
 			if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
@@ -1835,7 +1838,7 @@
 						}
 						STbp->buffer_bytes = bytes - transfer;
 					} else {
-						scsi_release_request(SRpnt);
+						st_release_request(SRpnt);
 						SRpnt = *aSRpnt = NULL;
 						if (transfer == blks) {	/* We did not get anything, error */
 							printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
@@ -1929,7 +1932,7 @@
 	ssize_t retval = 0;
 	ssize_t i, transfer;
 	int special, do_dio = 0;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
@@ -2054,11 +2057,11 @@
 
  out:
 	if (SRpnt != NULL) {
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 	if (do_dio) {
-		release_buffering(STp);
+		release_buffering(STp, 1);
 		STbp->buffer_bytes = 0;
 	}
 	up(&STp->lock);
@@ -2284,7 +2287,7 @@
 static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
 {
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
@@ -2298,7 +2301,7 @@
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	return (STp->buffer)->syscall_result;
 }
@@ -2310,7 +2313,7 @@
 {
 	int pgo;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
@@ -2329,7 +2332,7 @@
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	return (STp->buffer)->syscall_result;
 }
@@ -2412,7 +2415,7 @@
 	DEB( char *name = tape_name(STp); )
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	struct st_partstat *STps;
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 
 	if (STp->ready != ST_READY && !load_code) {
 		if (STp->ready == ST_NO_TAPE)
@@ -2455,7 +2458,7 @@
 		return (STp->buffer)->syscall_result;
 
 	retval = (STp->buffer)->syscall_result;
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	if (!retval) {	/* SCSI command successful */
 
@@ -2503,7 +2506,7 @@
 	int ioctl_result;
 	int chg_eof = 1;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_partstat *STps;
 	int fileno, blkno, at_sm, undone;
 	int datalen = 0, direction = DMA_NONE;
@@ -2757,7 +2760,7 @@
 	ioctl_result = (STp->buffer)->syscall_result;
 
 	if (!ioctl_result) {	/* SCSI command successful */
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 		STps->drv_block = blkno;
 		STps->drv_file = fileno;
@@ -2872,7 +2875,7 @@
 				/* Try the other possible state of Page Format if not
 				   already tried */
 				STp->use_pf = !STp->use_pf | PF_TESTED;
-				scsi_release_request(SRpnt);
+				st_release_request(SRpnt);
 				SRpnt = NULL;
 				return st_int_ioctl(STp, cmd_in, arg);
 			}
@@ -2882,7 +2885,7 @@
 		if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
 			STps->eof = ST_EOD;
 
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 
@@ -2898,7 +2901,7 @@
 {
 	int result;
 	unsigned char scmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
@@ -2944,7 +2947,7 @@
                 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
                             *block, *partition));
 	}
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	return result;
@@ -2961,7 +2964,7 @@
 	unsigned int blk;
 	int timeout;
 	unsigned char scmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
@@ -3047,7 +3050,7 @@
 		result = 0;
 	}
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	return result;
@@ -3577,7 +3580,7 @@
 static struct st_buffer *
  new_tape_buffer(int from_initialization, int need_dma, int max_sg)
 {
-	int i, got = 0, segs = 0;
+	int i, got = 0;
 	gfp_t priority;
 	struct st_buffer *tb;
 
@@ -3594,10 +3597,8 @@
 		return NULL;
 	}
 	memset(tb, 0, i);
-	tb->frp_segs = tb->orig_frp_segs = segs;
+	tb->frp_segs = tb->orig_frp_segs = 0;
 	tb->use_sg = max_sg;
-	if (segs > 0)
-		tb->b_data = page_address(tb->sg[0].page);
 	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
 	tb->in_use = 1;
@@ -3628,7 +3629,7 @@
 	priority = GFP_KERNEL | __GFP_NOWARN;
 	if (need_dma)
 		priority |= GFP_DMA;
-	for (b_size = PAGE_SIZE, order=0;
+	for (b_size = PAGE_SIZE, order=0; order <= 6 &&
 	     b_size < new_size - STbuffer->buffer_size;
 	     order++, b_size *= 2)
 		;  /* empty */
@@ -3670,6 +3671,7 @@
 	}
 	STbuffer->frp_segs = STbuffer->orig_frp_segs;
 	STbuffer->frp_sg_current = 0;
+	STbuffer->sg_segs = 0;
 }
 
 
@@ -3882,7 +3884,6 @@
 	struct st_buffer *buffer;
 	int i, j, mode, dev_num, error;
 	char *stp;
-	u64 bounce_limit;
 
 	if (SDp->type != TYPE_TAPE)
 		return -ENODEV;
@@ -3892,7 +3893,8 @@
 		return -ENODEV;
 	}
 
-	i = SDp->host->sg_tablesize;
+	i = min(SDp->request_queue->max_hw_segments,
+		SDp->request_queue->max_phys_segments);
 	if (st_max_sg_segs < i)
 		i = st_max_sg_segs;
 	buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
@@ -3994,11 +3996,6 @@
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
 	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 
-	bounce_limit = scsi_calculate_bounce_limit(SDp->host) >> PAGE_SHIFT;
-	if (bounce_limit > ULONG_MAX)
-		bounce_limit = ULONG_MAX;
-	tpnt->max_pfn = bounce_limit;
-
 	for (i = 0; i < ST_NBR_MODES; i++) {
 		STm = &(tpnt->modes[i]);
 		STm->defined = 0;
@@ -4077,9 +4074,9 @@
 
 	sdev_printk(KERN_WARNING, SDp,
 		    "Attached scsi tape %s", tape_name(tpnt));
-	printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n",
+	printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
 	       tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
-	       queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn);
+	       queue_dma_alignment(SDp->request_queue) + 1);
 
 	return 0;
 
@@ -4185,7 +4182,11 @@
 
 static void st_intr(struct scsi_cmnd *SCpnt)
 {
-	scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen), 1);
+	/*
+	 * The caller should be checking the request's errors
+	 * value.
+	 */
+	scsi_io_completion(SCpnt, SCpnt->bufflen, 0);
 }
 
 /*
@@ -4197,7 +4198,7 @@
 	if (!(SCpnt->request->flags & REQ_BLOCK_PC))
 		return 0;
 
-	scsi_setup_blk_pc_cmnd(SCpnt, 0);
+	scsi_setup_blk_pc_cmnd(SCpnt);
 	SCpnt->done = st_intr;
 	return 1;
 }
@@ -4390,34 +4391,6 @@
 	return;
 }
 
-
-/* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
-   - mapping of all pages not successful
-   - any page is above max_pfn
-   (i.e., either completely successful or fails)
-*/
-static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-			     unsigned long uaddr, size_t count, int rw,
-			     unsigned long max_pfn)
-{
-	int i, nr_pages;
-
-	nr_pages = sgl_map_user_pages(sgl, max_pages, uaddr, count, rw);
-	if (nr_pages <= 0)
-		return nr_pages;
-
-	for (i=0; i < nr_pages; i++) {
-		if (page_to_pfn(sgl[i].page) > max_pfn)
-			goto out_unmap;
-	}
-	return nr_pages;
-
- out_unmap:
-	sgl_unmap_user_pages(sgl, nr_pages, 0);
-	return 0;
-}
-
-
 /* The following functions may be useful for a larger audience. */
 static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
 			      unsigned long uaddr, size_t count, int rw)
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 790acac..4112090 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -4,6 +4,7 @@
 
 #include <linux/completion.h>
 #include <linux/kref.h>
+#include <scsi/scsi_cmnd.h>
 
 /* Descriptor for analyzed sense data */
 struct st_cmdstatus {
@@ -17,6 +18,17 @@
 	u8 deferred;
 };
 
+struct scsi_tape;
+
+/* scsi tape command */
+struct st_request {
+	unsigned char cmd[MAX_COMMAND_SIZE];
+	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+	int result;
+	struct scsi_tape *stp;
+	struct completion *waiting;
+};
+
 /* The tape buffer descriptor. */
 struct st_buffer {
 	unsigned char in_use;
@@ -28,7 +40,7 @@
 	int read_pointer;
 	int writing;
 	int syscall_result;
-	struct scsi_request *last_SRpnt;
+	struct st_request *last_SRpnt;
 	struct st_cmdstatus cmdstat;
 	unsigned char *b_data;
 	unsigned short use_sg;	/* zero or max number of s/g segments for this adapter */
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index c041bfd..25cced9 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -70,6 +70,7 @@
  *
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 /*
  * Further development / testing that should be done : 
@@ -2378,7 +2379,7 @@
  * 3..length+1	arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 		    extended_msg[0] = EXTENDED_MESSAGE;
 		    /* Accept first byte by clearing ACK */
@@ -2431,7 +2432,7 @@
 		default:
 		    if (!tmp) {
 			printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-			scsi_print_msg (extended_msg);
+			spi_print_msg(extended_msg);
 			printk("\n");
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2566,7 +2567,7 @@
 
     if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-	scsi_print_msg(msg);
+	spi_print_msg(msg);
 	do_abort(instance);
 	return;
     }
diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
index 2d9437d..3659dd7 100644
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h
@@ -40,7 +40,7 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.2.1"
+#define SYM_VERSION "2.2.2"
 #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
 
 /*
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
index fd36cf9..9916a2a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c
@@ -37,11 +37,7 @@
  * 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
 
 /*
  *  Macros used for all firmwares.
@@ -60,19 +56,12 @@
 #define	SYM_FWA_SCR		sym_fw1a_scr
 #define	SYM_FWB_SCR		sym_fw1b_scr
 #define	SYM_FWZ_SCR		sym_fw1z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw1.h>
-#else
 #include "sym_fw1.h"
-#endif
 static struct sym_fwa_ofs sym_fw1a_ofs = {
 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw1b_ofs = {
 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
 };
 static struct sym_fwz_ofs sym_fw1z_ofs = {
 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
@@ -88,19 +77,12 @@
 #define	SYM_FWA_SCR		sym_fw2a_scr
 #define	SYM_FWB_SCR		sym_fw2b_scr
 #define	SYM_FWZ_SCR		sym_fw2z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw2.h>
-#else
 #include "sym_fw2.h"
-#endif
 static struct sym_fwa_ofs sym_fw2a_ofs = {
 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw2b_ofs = {
 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
 	SYM_GEN_B(struct SYM_FWB_SCR, start64)
 	SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
 };
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.h b/drivers/scsi/sym53c8xx_2/sym_fw.h
index 43f6810..66ec35b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.h
@@ -92,9 +92,6 @@
 };
 struct sym_fwb_ofs {
 	SYM_GEN_FW_B(u_short)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(u_short, data_io)
-#endif
 	SYM_GEN_B(u_short, start64)
 	SYM_GEN_B(u_short, pm_handle)
 };
@@ -111,9 +108,6 @@
 };
 struct sym_fwb_ba {
 	SYM_GEN_FW_B(u32)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(u32, data_io)
-#endif
 	SYM_GEN_B(u32, start64);
 	SYM_GEN_B(u32, pm_handle);
 };
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw1.h b/drivers/scsi/sym53c8xx_2/sym_fw1.h
index cdd92d8..7b39f4a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw1.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw1.h
@@ -197,12 +197,6 @@
 	u32 bad_status		[  7];
 	u32 wsr_ma_helper	[  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	/* Unknown direction handling */
-	u32 data_io		[  2];
-	u32 data_io_com		[  8];
-	u32 data_io_out		[  7];
-#endif
 	/* Data area */
 	u32 zero		[  1];
 	u32 scratch		[  1];
@@ -1747,48 +1741,6 @@
 	SCR_JUMP,
 		PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-	/*
-	 *  We jump here if the data direction was unknown at the 
-	 *  time we had to queue the command to the scripts processor.
-	 *  Pointers had been set as follow in this situation:
-	 *    savep   -->   DATA_IO
-	 *    lastp   -->   start pointer when DATA_IN
-	 *    wlastp  -->   start pointer when DATA_OUT
-	 *  This script sets savep and lastp according to the 
-	 *  direction chosen by the target.
-	 */
-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-		PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-	/*
-	 *  Direction is DATA IN.
-	 */
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.lastp),
-		HADDR_1 (ccb_head.savep),
-	/*
-	 *  Jump to the SCRIPTS according to actual direction.
-	 */
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.savep),
-		RADDR_1 (temp),
-	SCR_RETURN,
-		0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-	/*
-	 *  Direction is DATA OUT.
-	 */
-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-		0,
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.wlastp),
-		HADDR_1 (ccb_head.lastp),
-	SCR_JUMP,
-		PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
 	SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
index 7ea7151..851f270 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h
@@ -191,13 +191,6 @@
 	u32 pm_wsr_handle	[ 38];
 	u32 wsr_ma_helper	[  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	/* Unknown direction handling */
-	u32 data_io		[  2];
-	u32 data_io_in		[  2];
-	u32 data_io_com		[  6];
-	u32 data_io_out		[  8];
-#endif
 	/* Data area */
 	u32 zero		[  1];
 	u32 scratch		[  1];
@@ -1838,51 +1831,6 @@
 	SCR_JUMP,
 		PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-	/*
-	 *  We jump here if the data direction was unknown at the 
-	 *  time we had to queue the command to the scripts processor.
-	 *  Pointers had been set as follow in this situation:
-	 *    savep   -->   DATA_IO
-	 *    lastp   -->   start pointer when DATA_IN
-	 *    wlastp  -->   start pointer when DATA_OUT
-	 *  This script sets savep and lastp according to the 
-	 *  direction chosen by the target.
-	 */
-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-		PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_IN >-----------------------*/,{
-	/*
-	 *  Direction is DATA IN.
-	 */
-	SCR_LOAD_REL  (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.lastp),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-	SCR_STORE_REL (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.savep),
-
-	/*
-	 *  Jump to the SCRIPTS according to actual direction.
-	 */
-	SCR_LOAD_REL  (temp, 4),
-		offsetof (struct sym_ccb, phys.head.savep),
-	SCR_RETURN,
-		0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-	/*
-	 *  Direction is DATA OUT.
-	 */
-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-		0,
-	SCR_LOAD_REL  (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.wlastp),
-	SCR_STORE_REL (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.lastp),
-	SCR_JUMP,
-		PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
 	SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 7fc0b97..1fffd2b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -514,9 +514,10 @@
  */
 int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
 {
-	int dir;
 	struct sym_tcb *tp = &np->target[cp->target];
 	struct sym_lcb *lp = sym_lp(tp, cp->lun);
+	u32 lastp, goalp;
+	int dir;
 
 	/*
 	 *  Build the CDB.
@@ -534,15 +535,47 @@
 			sym_set_cam_status(cmd, DID_ERROR);
 			goto out_abort;
 		}
+
+		/*
+		 *  No segments means no data.
+		 */
+		if (!cp->segments)
+			dir = DMA_NONE;
 	} else {
 		cp->data_len = 0;
 		cp->segments = 0;
 	}
 
 	/*
-	 *  Set data pointers.
+	 *  Set the data pointer.
 	 */
-	sym_setup_data_pointers(np, cp, dir);
+	switch (dir) {
+	case DMA_BIDIRECTIONAL:
+		printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np));
+		sym_set_cam_status(cmd, DID_ERROR);
+		goto out_abort;
+	case DMA_TO_DEVICE:
+		goalp = SCRIPTA_BA(np, data_out2) + 8;
+		lastp = goalp - 8 - (cp->segments * (2*4));
+		break;
+	case DMA_FROM_DEVICE:
+		cp->host_flags |= HF_DATA_IN;
+		goalp = SCRIPTA_BA(np, data_in2) + 8;
+		lastp = goalp - 8 - (cp->segments * (2*4));
+		break;
+	case DMA_NONE:
+	default:
+		lastp = goalp = SCRIPTB_BA(np, no_data);
+		break;
+	}
+
+	/*
+	 *  Set all pointers values needed by SCRIPTS.
+	 */
+	cp->phys.head.lastp = cpu_to_scr(lastp);
+	cp->phys.head.savep = cpu_to_scr(lastp);
+	cp->startp	    = cp->phys.head.savep;
+	cp->goalp	    = cpu_to_scr(goalp);
 
 	/*
 	 *  When `#ifed 1', the code below makes the driver 
@@ -563,10 +596,7 @@
 	/*
 	 *	activate this job.
 	 */
-	if (lp)
-		sym_start_next_ccbs(np, lp, 2);
-	else
-		sym_put_start_queue(np, cp);
+	sym_start_next_ccbs(np, lp, 2);
 	return 0;
 
 out_abort:
@@ -981,15 +1011,14 @@
 
 static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
 {
-	struct sym_hcb *np;
-	struct sym_tcb *tp;
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_tcb *tp = &np->target[sdev->id];
+	struct sym_lcb *lp;
 
 	if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
 		return -ENXIO;
 
-	np = sym_get_hcb(sdev->host);
-	tp = &np->target[sdev->id];
-
+	tp->starget = sdev->sdev_target;
 	/*
 	 * Fail the device init if the device is flagged NOSCAN at BOOT in
 	 * the NVRAM.  This may speed up boot and maintain coherency with
@@ -999,35 +1028,41 @@
 	 * lun devices behave badly when asked for a non zero LUN.
 	 */
 
-	if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
-	    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
+	if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) {
 		tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
+		starget_printk(KERN_INFO, tp->starget,
+				"Scan at boot disabled in NVRAM\n");
 		return -ENXIO;
 	}
 
-	tp->starget = sdev->sdev_target;
+	if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) {
+		if (sdev->lun != 0)
+			return -ENXIO;
+		starget_printk(KERN_INFO, tp->starget,
+				"Multiple LUNs disabled in NVRAM\n");
+	}
+
+	lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
+	if (!lp)
+		return -ENOMEM;
+
+	spi_min_period(tp->starget) = tp->usr_period;
+	spi_max_width(tp->starget) = tp->usr_width;
+
 	return 0;
 }
 
 /*
  * Linux entry point for device queue sizing.
  */
-static int sym53c8xx_slave_configure(struct scsi_device *device)
+static int sym53c8xx_slave_configure(struct scsi_device *sdev)
 {
-	struct sym_hcb *np = sym_get_hcb(device->host);
-	struct sym_tcb *tp = &np->target[device->id];
-	struct sym_lcb *lp;
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_tcb *tp = &np->target[sdev->id];
+	struct sym_lcb *lp = sym_lp(tp, sdev->lun);
 	int reqtags, depth_to_use;
 
 	/*
-	 *  Allocate the LCB if not yet.
-	 *  If it fail, we may well be in the sh*t. :)
-	 */
-	lp = sym_alloc_lcb(np, device->id, device->lun);
-	if (!lp)
-		return -ENOMEM;
-
-	/*
 	 *  Get user flags.
 	 */
 	lp->curr_flags = lp->user_flags;
@@ -1038,10 +1073,10 @@
 	 *  Use at least 2.
 	 *  Donnot use more than our maximum.
 	 */
-	reqtags = device_queue_depth(np, device->id, device->lun);
+	reqtags = device_queue_depth(np, sdev->id, sdev->lun);
 	if (reqtags > tp->usrtags)
 		reqtags = tp->usrtags;
-	if (!device->tagged_supported)
+	if (!sdev->tagged_supported)
 		reqtags = 0;
 #if 1 /* Avoid to locally queue commands for no good reasons */
 	if (reqtags > SYM_CONF_MAX_TAG)
@@ -1050,19 +1085,30 @@
 #else
 	depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
 #endif
-	scsi_adjust_queue_depth(device,
-				(device->tagged_supported ?
+	scsi_adjust_queue_depth(sdev,
+				(sdev->tagged_supported ?
 				 MSG_SIMPLE_TAG : 0),
 				depth_to_use);
 	lp->s.scdev_depth = depth_to_use;
-	sym_tune_dev_queuing(tp, device->lun, reqtags);
+	sym_tune_dev_queuing(tp, sdev->lun, reqtags);
 
-	if (!spi_initial_dv(device->sdev_target))
-		spi_dv_device(device);
+	if (!spi_initial_dv(sdev->sdev_target))
+		spi_dv_device(sdev);
 
 	return 0;
 }
 
+static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
+{
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
+
+	if (lp->itlq_tbl)
+		sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
+	kfree(lp->cb_tags);
+	sym_mfree_dma(lp, sizeof(*lp), "LCB");
+}
+
 /*
  *  Linux entry point for info() function
  */
@@ -1497,7 +1543,7 @@
 {
 #if SYM_CONF_DMA_ADDRESSING_MODE > 0
 #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define	DMA_DAC_MASK	0x000000ffffffffffULL /* 40-bit */
+#define	DMA_DAC_MASK	DMA_40BIT_MASK
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
 #define	DMA_DAC_MASK	DMA_64BIT_MASK
 #endif
@@ -1926,6 +1972,7 @@
 	.queuecommand		= sym53c8xx_queue_command,
 	.slave_alloc		= sym53c8xx_slave_alloc,
 	.slave_configure	= sym53c8xx_slave_configure,
+	.slave_destroy		= sym53c8xx_slave_destroy,
 	.eh_abort_handler	= sym53c8xx_eh_abort_handler,
 	.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sym53c8xx_eh_bus_reset_handler,
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index d3d52f1..cc92d0c 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -68,7 +68,6 @@
  */
 #define	SYM_CONF_TIMER_INTERVAL		((HZ+1)/2)
 
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 
@@ -268,6 +267,5 @@
 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, struct sym_ccb *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 --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 1564ca2..8260f04 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -40,6 +40,7 @@
 
 #include <linux/slab.h>
 #include <asm/param.h>		/* for timeouts in units of HZ */
+#include <scsi/scsi_dbg.h>
 
 #include "sym_glue.h"
 #include "sym_nvram.h"
@@ -70,32 +71,12 @@
 	printf (".\n");
 }
 
-/*
- *  Print out the content of a SCSI message.
- */
-static int sym_show_msg (u_char * msg)
-{
-	u_char i;
-	printf ("%x",*msg);
-	if (*msg==M_EXTENDED) {
-		for (i=1;i<8;i++) {
-			if (i-1>msg[1]) break;
-			printf ("-%x",msg[i]);
-		}
-		return (i+1);
-	} else if ((*msg & 0xf0) == 0x20) {
-		printf ("-%x",msg[1]);
-		return (2);
-	}
-	return (1);
-}
-
 static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
 {
 	sym_print_addr(cp->cmd, "%s: ", label);
 
-	sym_show_msg(msg);
-	printf(".\n");
+	spi_print_msg(msg);
+	printf("\n");
 }
 
 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
@@ -103,8 +84,8 @@
 	struct sym_tcb *tp = &np->target[target];
 	dev_info(&tp->starget->dev, "%s: ", label);
 
-	sym_show_msg(msg);
-	printf(".\n");
+	spi_print_msg(msg);
+	printf("\n");
 }
 
 /*
@@ -635,29 +616,6 @@
 	}
 }
 
-
-/*
- * Print out the list of targets that have some flag disabled by user.
- */
-static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
-{
-	int cnt;
-	int i;
-
-	for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
-		if (i == np->myaddr)
-			continue;
-		if (np->target[i].usrflags & mask) {
-			if (!cnt++)
-				printf("%s: %s disabled for targets",
-					sym_name(np), msg);
-			printf(" %d", i);
-		}
-	}
-	if (cnt)
-		printf(".\n");
-}
-
 /*
  *  Save initial settings of some IO registers.
  *  Assumed to have been set by BIOS.
@@ -962,7 +920,7 @@
 		tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
 		tp->usrtags = SYM_SETUP_MAX_TAG;
 
-		sym_nvram_setup_target(np, i, nvram);
+		sym_nvram_setup_target(tp, i, nvram);
 
 		if (!tp->usrtags)
 			tp->usrflags &= ~SYM_TAGS_ENABLED;
@@ -1005,13 +963,6 @@
 			sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
 			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
 	}
-	/*
-	 *  Let user be aware of targets that have some disable flags set.
-	 */
-	sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");
-	if (sym_verbose)
-		sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,
-				       "SCAN FOR LUNS");
 
 	return 0;
 }
@@ -1523,7 +1474,7 @@
 /*
  *  Insert a job into the start queue.
  */
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
+static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
 {
 	u_short	qidx;
 
@@ -3654,7 +3605,7 @@
 	 *  If result is dp_sg = SYM_CONF_MAX_SG, then we are at the 
 	 *  end of the data.
 	 */
-	tmp = scr_to_cpu(sym_goalp(cp));
+	tmp = scr_to_cpu(cp->goalp);
 	dp_sg = SYM_CONF_MAX_SG;
 	if (dp_scr != tmp)
 		dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
@@ -3761,7 +3712,7 @@
 	 *  And our alchemy:) allows to easily calculate the data 
 	 *  script address we want to return for the next data phase.
 	 */
-	dp_ret = cpu_to_scr(sym_goalp(cp));
+	dp_ret = cpu_to_scr(cp->goalp);
 	dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
 
 	/*
@@ -3857,7 +3808,7 @@
 	 *  If all data has been transferred,
 	 *  there is no residual.
 	 */
-	if (cp->phys.head.lastp == sym_goalp(cp))
+	if (cp->phys.head.lastp == cp->goalp)
 		return resid;
 
 	/*
@@ -4664,30 +4615,7 @@
 		goto out;
 	cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
 
-#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
-	/*
-	 *  If the LCB is not yet available and the LUN
-	 *  has been probed ok, try to allocate the LCB.
-	 */
-	if (!lp && sym_is_bit(tp->lun_map, ln)) {
-		lp = sym_alloc_lcb(np, tn, ln);
-		if (!lp)
-			goto out_free;
-	}
-#endif
-
-	/*
-	 *  If the LCB is not available here, then the 
-	 *  logical unit is not yet discovered. For those 
-	 *  ones only accept 1 SCSI IO per logical unit, 
-	 *  since we cannot allow disconnections.
-	 */
-	if (!lp) {
-		if (!sym_is_bit(tp->busy0_map, ln))
-			sym_set_bit(tp->busy0_map, ln);
-		else
-			goto out_free;
-	} else {
+	{
 		/*
 		 *  If we have been asked for a tagged command.
 		 */
@@ -4840,12 +4768,6 @@
 			lp->head.resel_sa =
 				cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
 	}
-	/*
-	 *  Otherwise, we only accept 1 IO per LUN.
-	 *  Clear the bit that keeps track of this IO.
-	 */
-	else
-		sym_clr_bit(tp->busy0_map, cp->lun);
 
 	/*
 	 *  We donnot queue more than 1 ccb per target 
@@ -4997,20 +4919,7 @@
 struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	struct sym_tcb *tp = &np->target[tn];
-	struct sym_lcb *lp = sym_lp(tp, ln);
-
-	/*
-	 *  Already done, just return.
-	 */
-	if (lp)
-		return lp;
-
-	/*
-	 *  Donnot allow LUN control block 
-	 *  allocation for not probed LUNs.
-	 */
-	if (!sym_is_bit(tp->lun_map, ln))
-		return NULL;
+	struct sym_lcb *lp = NULL;
 
 	/*
 	 *  Initialize the target control block if not yet.
@@ -5082,13 +4991,7 @@
 	lp->started_max   = SYM_CONF_MAX_TASK;
 	lp->started_limit = SYM_CONF_MAX_TASK;
 #endif
-	/*
-	 *  If we are busy, count the IO.
-	 */
-	if (sym_is_bit(tp->busy0_map, ln)) {
-		lp->busy_itl = 1;
-		sym_clr_bit(tp->busy0_map, ln);
-	}
+
 fail:
 	return lp;
 }
@@ -5103,12 +5006,6 @@
 	int i;
 
 	/*
-	 *  If LCB not available, try to allocate it.
-	 */
-	if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
-		goto fail;
-
-	/*
 	 *  Allocate the task table and and the tag allocation 
 	 *  circular buffer. We want both or none.
 	 */
@@ -5481,8 +5378,7 @@
 	/*
 	 *  Donnot start more than 1 command after an error.
 	 */
-	if (lp)
-		sym_start_next_ccbs(np, lp, 1);
+	sym_start_next_ccbs(np, lp, 1);
 #endif
 }
 
@@ -5521,17 +5417,11 @@
 	lp = sym_lp(tp, cp->lun);
 
 	/*
-	 *  Assume device discovered on first success.
-	 */
-	if (!lp)
-		sym_set_bit(tp->lun_map, cp->lun);
-
-	/*
 	 *  If all data have been transferred, given than no
 	 *  extended error did occur, there is no residual.
 	 */
 	resid = 0;
-	if (cp->phys.head.lastp != sym_goalp(cp))
+	if (cp->phys.head.lastp != cp->goalp)
 		resid = sym_compute_residual(np, cp);
 
 	/*
@@ -5551,15 +5441,6 @@
 	 */
 	sym_set_cam_result_ok(cp, cmd, resid);
 
-#ifdef	SYM_OPT_SNIFF_INQUIRY
-	/*
-	 *  On standard INQUIRY response (EVPD and CmDt 
-	 *  not set), sniff out device capabilities.
-	 */
-	if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
-		sym_sniff_inquiry(np, cmd, resid);
-#endif
-
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	/*
 	 *  If max number of started ccbs had been reduced,
@@ -5587,7 +5468,7 @@
 	/*
 	 *  Requeue a couple of awaiting scsi commands.
 	 */
-	if (lp && !sym_que_empty(&lp->waiting_ccbq))
+	if (!sym_que_empty(&lp->waiting_ccbq))
 		sym_start_next_ccbs(np, lp, 2);
 #endif
 	/*
@@ -5830,8 +5711,7 @@
 	SYM_QUEHEAD *qp;
 	struct sym_ccb *cp;
 	struct sym_tcb *tp;
-	struct sym_lcb *lp;
-	int target, lun;
+	int target;
 
 	if (np->scriptz0)
 		sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
@@ -5857,16 +5737,6 @@
 
 	for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
 		tp = &np->target[target];
-		for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
-			lp = sym_lp(tp, lun);
-			if (!lp)
-				continue;
-			if (lp->itlq_tbl)
-				sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
-				       "ITLQ_TBL");
-			kfree(lp->cb_tags);
-			sym_mfree_dma(lp, sizeof(*lp), "LCB");
-		}
 #if SYM_CONF_MAX_LUN > 1
 		kfree(tp->lunmp);
 #endif 
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 3a264a4..2456090 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -48,12 +48,6 @@
  *  They may be defined in platform specific headers, if they 
  *  are useful.
  *
- *    SYM_OPT_HANDLE_DIR_UNKNOWN
- *        When this option is set, the SCRIPTS used by the driver 
- *        are able to handle SCSI transfers with direction not 
- *        supplied by user.
- *        (set for Linux-2.0.X)
- *
  *    SYM_OPT_HANDLE_DEVICE_QUEUEING
  *        When this option is set, the driver will use a queue per 
  *        device and handle QUEUE FULL status requeuing internally.
@@ -64,7 +58,6 @@
  *        (set for Linux)
  */
 #if 0
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 #endif
@@ -416,19 +409,6 @@
 	struct sym_lcb **lunmp;		/* Other LCBs [1..MAX_LUN]	*/
 #endif
 
-	/*
-	 *  Bitmap that tells about LUNs that succeeded at least 
-	 *  1 IO and therefore assumed to be a real device.
-	 *  Avoid useless allocation of the LCB structure.
-	 */
-	u32	lun_map[(SYM_CONF_MAX_LUN+31)/32];
-
-	/*
-	 *  Bitmap that tells about LUNs that haven't yet an LCB 
-	 *  allocated (not discovered or LCB allocation failed).
-	 */
-	u32	busy0_map[(SYM_CONF_MAX_LUN+31)/32];
-
 #ifdef	SYM_HAVE_STCB
 	/*
 	 *  O/S specific data structure.
@@ -454,8 +434,10 @@
 	 *  Other user settable limits and options.
 	 *  These limits are read from the NVRAM if present.
 	 */
-	u_char	usrflags;
-	u_short	usrtags;
+	unsigned char	usrflags;
+	unsigned char	usr_period;
+	unsigned char	usr_width;
+	unsigned short	usrtags;
 	struct scsi_target *starget;
 };
 
@@ -672,9 +654,6 @@
 	 */
 	u32	savep;		/* Jump address to saved data pointer	*/
 	u32	lastp;		/* SCRIPTS address at end of data	*/
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	u32	wlastp;
-#endif
 
 	/*
 	 *  Status fields.
@@ -804,9 +783,6 @@
 	SYM_QUEHEAD link_ccbq;	/* Link to free/busy CCB queue	*/
 	u32	startp;		/* Initial data pointer		*/
 	u32	goalp;		/* Expected last data pointer	*/
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	u32	wgoalp;
-#endif
 	int	ext_sg;		/* Extreme data pointer, used	*/
 	int	ext_ofs;	/*  to calculate the residual.	*/
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
@@ -821,12 +797,6 @@
 
 #define CCB_BA(cp,lbl)	cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
 
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-#define	sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
-#else
-#define	sym_goalp(cp) (cp->goalp)
-#endif
-
 typedef struct device *m_pool_ident_t;
 
 /*
@@ -1077,7 +1047,6 @@
 void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
 int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
 struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
 #endif
@@ -1136,71 +1105,6 @@
 #endif
 
 /*
- *  Set up data pointers used by SCRIPTS.
- *  Called from O/S specific code.
- */
-static inline void sym_setup_data_pointers(struct sym_hcb *np,
-		struct sym_ccb *cp, int dir)
-{
-	u32 lastp, goalp;
-
-	/*
-	 *  No segments means no data.
-	 */
-	if (!cp->segments)
-		dir = DMA_NONE;
-
-	/*
-	 *  Set the data pointer.
-	 */
-	switch(dir) {
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	case DMA_BIDIRECTIONAL:
-#endif
-	case DMA_TO_DEVICE:
-		goalp = SCRIPTA_BA(np, data_out2) + 8;
-		lastp = goalp - 8 - (cp->segments * (2*4));
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-		cp->wgoalp = cpu_to_scr(goalp);
-		if (dir != DMA_BIDIRECTIONAL)
-			break;
-		cp->phys.head.wlastp = cpu_to_scr(lastp);
-		/* fall through */
-#else
-		break;
-#endif
-	case DMA_FROM_DEVICE:
-		cp->host_flags |= HF_DATA_IN;
-		goalp = SCRIPTA_BA(np, data_in2) + 8;
-		lastp = goalp - 8 - (cp->segments * (2*4));
-		break;
-	case DMA_NONE:
-	default:
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-		cp->host_flags |= HF_DATA_IN;
-#endif
-		lastp = goalp = SCRIPTB_BA(np, no_data);
-		break;
-	}
-
-	/*
-	 *  Set all pointers values needed by SCRIPTS.
-	 */
-	cp->phys.head.lastp = cpu_to_scr(lastp);
-	cp->phys.head.savep = cpu_to_scr(lastp);
-	cp->startp	    = cp->phys.head.savep;
-	cp->goalp	    = cpu_to_scr(goalp);
-
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	/*
-	 *  If direction is unknown, start at data_io.
-	 */
-	if (dir == DMA_BIDIRECTIONAL)
-		cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
-#endif
-}
-
-/*
  *  MEMORY ALLOCATOR.
  */
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
index a34d403..92bf9b1 100644
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c
@@ -37,11 +37,7 @@
  * 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
 
 /*
  *  Simple power of two buddy-like generic allocator.
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c
index 994b756..15d6929 100644
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.c
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c
@@ -92,29 +92,32 @@
  *  Get target set-up from Symbios format NVRAM.
  */
 static void
-sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
+sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
 {
-	struct sym_tcb *tp = &np->target[target];
 	Symbios_target *tn = &nvram->target[target];
 
-	tp->usrtags =
-		(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
-
+	if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
+		tp->usrtags = 0;
 	if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
 		tp->usrflags &= ~SYM_DISC_ENABLED;
 	if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
 		tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
 	if (!(tn->flags & SYMBIOS_SCAN_LUNS))
 		tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
+	tp->usr_period = (tn->sync_period + 3) / 4;
+	tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
 }
 
+static const unsigned char Tekram_sync[16] = {
+	25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
+};
+
 /*
  *  Get target set-up from Tekram format NVRAM.
  */
 static void
-sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
+sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
 {
-	struct sym_tcb *tp = &np->target[target];
 	struct Tekram_target *tn = &nvram->target[target];
 
 	if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
@@ -124,22 +127,22 @@
 	if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
 		tp->usrflags |= SYM_DISC_ENABLED;
  
-	/* If any device does not support parity, we will not use this option */
-	if (!(tn->flags & TEKRAM_PARITY_CHECK))
-		np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
+	if (tn->flags & TEKRAM_SYNC_NEGO)
+		tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
+	tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
 }
 
 /*
  *  Get target setup from NVRAM.
  */
-void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
+void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
 {
 	switch (nvp->type) {
 	case SYM_SYMBIOS_NVRAM:
-		sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
+		sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
 		break;
 	case SYM_TEKRAM_NVRAM:
-		sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
+		sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
 		break;
 	default:
 		break;
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h
index 1538bed..bdfbbb0 100644
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.h
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h
@@ -194,12 +194,12 @@
 
 #if SYM_CONF_NVRAM_SUPPORT
 void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
-void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
+void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp);
 int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
 char *sym_nvram_type(struct sym_nvram *nvp);
 #else
 static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
-static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
+static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { }
 static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
 {
 	nvp->type = 0;
diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
deleted file mode 100644
index 20ae2b1..0000000
--- a/drivers/scsi/sym53c8xx_comm.h
+++ /dev/null
@@ -1,792 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  This program is free software; you can redistribute it and/or modify
-**  it under the terms of the GNU General Public License as published by
-**  the Free Software Foundation; either version 2 of the License, or
-**  (at your option) any later version.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You 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.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-*******************************************************************************
-*/
-
-/*==========================================================
-**
-**	Debugging tags
-**
-**==========================================================
-*/
-
-#define DEBUG_ALLOC    (0x0001)
-#define DEBUG_PHASE    (0x0002)
-#define DEBUG_QUEUE    (0x0008)
-#define DEBUG_RESULT   (0x0010)
-#define DEBUG_POINTER  (0x0020)
-#define DEBUG_SCRIPT   (0x0040)
-#define DEBUG_TINY     (0x0080)
-#define DEBUG_TIMING   (0x0100)
-#define DEBUG_NEGO     (0x0200)
-#define DEBUG_TAGS     (0x0400)
-#define DEBUG_SCATTER  (0x0800)
-#define DEBUG_IC        (0x1000)
-
-/*
-**    Enable/Disable debug messages.
-**    Can be changed at runtime too.
-*/
-
-#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
-static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
-	#define DEBUG_FLAGS ncr_debug
-#else
-	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
-#endif
-
-static inline struct list_head *ncr_list_pop(struct list_head *head)
-{
-	if (!list_empty(head)) {
-		struct list_head *elem = head->next;
-
-		list_del(elem);
-		return elem;
-	}
-
-	return NULL;
-}
-
-#ifdef __sparc__
-#include <asm/irq.h>
-#endif
-
-/*==========================================================
-**
-**	Simple power of two buddy-like allocator.
-**
-**	This simple code is not intended to be fast, but to 
-**	provide power of 2 aligned memory allocations.
-**	Since the SCRIPTS processor only supplies 8 bit 
-**	arithmetic, this allocator allows simple and fast 
-**	address calculations  from the SCRIPTS code.
-**	In addition, cache line alignment is guaranteed for 
-**	power of 2 cache line size.
-**	Enhanced in linux-2.3.44 to provide a memory pool 
-**	per pcidev to support dynamic dma mapping. (I would 
-**	have preferred a real bus astraction, btw).
-**
-**==========================================================
-*/
-
-#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
-#if PAGE_SIZE >= 8192
-#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
-#else
-#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
-#endif
-#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
-#define MEMO_WARN	1
-#define MEMO_GFP_FLAGS	GFP_ATOMIC
-#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
-#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
-#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
-
-typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
-typedef struct device *m_bush_t;	/* Something that addresses DMAable */
-
-typedef struct m_link {		/* Link between free memory chunks */
-	struct m_link *next;
-} m_link_s;
-
-typedef struct m_vtob {		/* Virtual to Bus address translation */
-	struct m_vtob *next;
-	m_addr_t vaddr;
-	m_addr_t baddr;
-} m_vtob_s;
-#define VTOB_HASH_SHIFT		5
-#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
-#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
-#define VTOB_HASH_CODE(m)	\
-	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
-
-typedef struct m_pool {		/* Memory pool of a given kind */
-	m_bush_t bush;
-	m_addr_t (*getp)(struct m_pool *);
-	void (*freep)(struct m_pool *, m_addr_t);
-	int nump;
-	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
-	struct m_pool *next;
-	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
-} m_pool_s;
-
-static void *___m_alloc(m_pool_s *mp, int size)
-{
-	int i = 0;
-	int s = (1 << MEMO_SHIFT);
-	int j;
-	m_addr_t a;
-	m_link_s *h = mp->h;
-
-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-		return NULL;
-
-	while (size > s) {
-		s <<= 1;
-		++i;
-	}
-
-	j = i;
-	while (!h[j].next) {
-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			h[j].next = (m_link_s *)mp->getp(mp);
-			if (h[j].next)
-				h[j].next->next = NULL;
-			break;
-		}
-		++j;
-		s <<= 1;
-	}
-	a = (m_addr_t) h[j].next;
-	if (a) {
-		h[j].next = h[j].next->next;
-		while (j > i) {
-			j -= 1;
-			s >>= 1;
-			h[j].next = (m_link_s *) (a+s);
-			h[j].next->next = NULL;
-		}
-	}
-#ifdef DEBUG
-	printk("___m_alloc(%d) = %p\n", size, (void *) a);
-#endif
-	return (void *) a;
-}
-
-static void ___m_free(m_pool_s *mp, void *ptr, int size)
-{
-	int i = 0;
-	int s = (1 << MEMO_SHIFT);
-	m_link_s *q;
-	m_addr_t a, b;
-	m_link_s *h = mp->h;
-
-#ifdef DEBUG
-	printk("___m_free(%p, %d)\n", ptr, size);
-#endif
-
-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-		return;
-
-	while (size > s) {
-		s <<= 1;
-		++i;
-	}
-
-	a = (m_addr_t) ptr;
-
-	while (1) {
-#ifdef MEMO_FREE_UNUSED
-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			mp->freep(mp, a);
-			break;
-		}
-#endif
-		b = a ^ s;
-		q = &h[i];
-		while (q->next && q->next != (m_link_s *) b) {
-			q = q->next;
-		}
-		if (!q->next) {
-			((m_link_s *) a)->next = h[i].next;
-			h[i].next = (m_link_s *) a;
-			break;
-		}
-		q->next = q->next->next;
-		a = a & b;
-		s <<= 1;
-		++i;
-	}
-}
-
-static DEFINE_SPINLOCK(ncr53c8xx_lock);
-
-static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
-{
-	void *p;
-
-	p = ___m_alloc(mp, size);
-
-	if (DEBUG_FLAGS & DEBUG_ALLOC)
-		printk ("new %-10s[%4d] @%p.\n", name, size, p);
-
-	if (p)
-		memset(p, 0, size);
-	else if (uflags & MEMO_WARN)
-		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
-
-	return p;
-}
-
-#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
-
-static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
-{
-	if (DEBUG_FLAGS & DEBUG_ALLOC)
-		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
-
-	___m_free(mp, ptr, size);
-
-}
-
-/*
- * With pci bus iommu support, we use a default pool of unmapped memory 
- * for memory we donnot need to DMA from/to and one pool per pcidev for 
- * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
- */
-
-static m_addr_t ___mp0_getp(m_pool_s *mp)
-{
-	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
-	if (m)
-		++mp->nump;
-	return m;
-}
-
-static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
-{
-	free_pages(m, MEMO_PAGE_ORDER);
-	--mp->nump;
-}
-
-static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
-
-/*
- * DMAable pools.
- */
-
-/*
- * With pci bus iommu support, we maintain one pool per pcidev and a 
- * hashed reverse table for virtual to bus physical address translations.
- */
-static m_addr_t ___dma_getp(m_pool_s *mp)
-{
-	m_addr_t vp;
-	m_vtob_s *vbp;
-
-	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
-	if (vbp) {
-		dma_addr_t daddr;
-		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
-						PAGE_SIZE<<MEMO_PAGE_ORDER,
-						&daddr, GFP_ATOMIC);
-		if (vp) {
-			int hc = VTOB_HASH_CODE(vp);
-			vbp->vaddr = vp;
-			vbp->baddr = daddr;
-			vbp->next = mp->vtob[hc];
-			mp->vtob[hc] = vbp;
-			++mp->nump;
-			return vp;
-		}
-	}
-	if (vbp)
-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-	return 0;
-}
-
-static void ___dma_freep(m_pool_s *mp, m_addr_t m)
-{
-	m_vtob_s **vbpp, *vbp;
-	int hc = VTOB_HASH_CODE(m);
-
-	vbpp = &mp->vtob[hc];
-	while (*vbpp && (*vbpp)->vaddr != m)
-		vbpp = &(*vbpp)->next;
-	if (*vbpp) {
-		vbp = *vbpp;
-		*vbpp = (*vbpp)->next;
-		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
-				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-		--mp->nump;
-	}
-}
-
-static inline m_pool_s *___get_dma_pool(m_bush_t bush)
-{
-	m_pool_s *mp;
-	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
-	return mp;
-}
-
-static m_pool_s *___cre_dma_pool(m_bush_t bush)
-{
-	m_pool_s *mp;
-	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
-	if (mp) {
-		memset(mp, 0, sizeof(*mp));
-		mp->bush = bush;
-		mp->getp = ___dma_getp;
-		mp->freep = ___dma_freep;
-		mp->next = mp0.next;
-		mp0.next = mp;
-	}
-	return mp;
-}
-
-static void ___del_dma_pool(m_pool_s *p)
-{
-	struct m_pool **pp = &mp0.next;
-
-	while (*pp && *pp != p)
-		pp = &(*pp)->next;
-	if (*pp) {
-		*pp = (*pp)->next;
-		__m_free(&mp0, p, sizeof(*p), "MPOOL");
-	}
-}
-
-static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
-{
-	u_long flags;
-	struct m_pool *mp;
-	void *m = NULL;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (!mp)
-		mp = ___cre_dma_pool(bush);
-	if (mp)
-		m = __m_calloc(mp, size, name);
-	if (mp && !mp->nump)
-		___del_dma_pool(mp);
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-
-	return m;
-}
-
-static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
-{
-	u_long flags;
-	struct m_pool *mp;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (mp)
-		__m_free(mp, m, size, name);
-	if (mp && !mp->nump)
-		___del_dma_pool(mp);
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-}
-
-static m_addr_t __vtobus(m_bush_t bush, void *m)
-{
-	u_long flags;
-	m_pool_s *mp;
-	int hc = VTOB_HASH_CODE(m);
-	m_vtob_s *vp = NULL;
-	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (mp) {
-		vp = mp->vtob[hc];
-		while (vp && (m_addr_t) vp->vaddr != a)
-			vp = vp->next;
-	}
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
-}
-
-#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
-#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
-#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
-#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
-#define _vtobus(np, p)			__vtobus(np->dev, p)
-#define vtobus(p)			_vtobus(np, p)
-
-/*
- *  Deal with DMA mapping/unmapping.
- */
-
-/* To keep track of the dma mapping (sg/single) that has been set */
-#define __data_mapped	SCp.phase
-#define __data_mapping	SCp.have_data_in
-
-static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	switch(cmd->__data_mapped) {
-	case 2:
-		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
-				cmd->sc_data_direction);
-		break;
-	case 1:
-		dma_unmap_single(dev, cmd->__data_mapping,
-				 cmd->request_bufflen,
-				 cmd->sc_data_direction);
-		break;
-	}
-	cmd->__data_mapped = 0;
-}
-
-static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	dma_addr_t mapping;
-
-	if (cmd->request_bufflen == 0)
-		return 0;
-
-	mapping = dma_map_single(dev, cmd->request_buffer,
-				 cmd->request_bufflen,
-				 cmd->sc_data_direction);
-	cmd->__data_mapped = 1;
-	cmd->__data_mapping = mapping;
-
-	return mapping;
-}
-
-static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	int use_sg;
-
-	if (cmd->use_sg == 0)
-		return 0;
-
-	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
-			cmd->sc_data_direction);
-	cmd->__data_mapped = 2;
-	cmd->__data_mapping = use_sg;
-
-	return use_sg;
-}
-
-#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)
-
-/*==========================================================
-**
-**	Driver setup.
-**
-**	This structure is initialized from linux config 
-**	options. It can be overridden at boot-up by the boot 
-**	command line.
-**
-**==========================================================
-*/
-static struct ncr_driver_setup
-	driver_setup			= SCSI_NCR_DRIVER_SETUP;
-
-#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-static struct ncr_driver_setup
-	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
-#endif
-
-#define initverbose (driver_setup.verbose)
-#define bootverbose (np->verbose)
-
-
-/*===================================================================
-**
-**	Driver setup from the boot command line
-**
-**===================================================================
-*/
-
-#ifdef MODULE
-#define	ARG_SEP	' '
-#else
-#define	ARG_SEP	','
-#endif
-
-#define OPT_TAGS		1
-#define OPT_MASTER_PARITY	2
-#define OPT_SCSI_PARITY		3
-#define OPT_DISCONNECTION	4
-#define OPT_SPECIAL_FEATURES	5
-#define OPT_UNUSED_1		6
-#define OPT_FORCE_SYNC_NEGO	7
-#define OPT_REVERSE_PROBE	8
-#define OPT_DEFAULT_SYNC	9
-#define OPT_VERBOSE		10
-#define OPT_DEBUG		11
-#define OPT_BURST_MAX		12
-#define OPT_LED_PIN		13
-#define OPT_MAX_WIDE		14
-#define OPT_SETTLE_DELAY	15
-#define OPT_DIFF_SUPPORT	16
-#define OPT_IRQM		17
-#define OPT_PCI_FIX_UP		18
-#define OPT_BUS_CHECK		19
-#define OPT_OPTIMIZE		20
-#define OPT_RECOVERY		21
-#define OPT_SAFE_SETUP		22
-#define OPT_USE_NVRAM		23
-#define OPT_EXCLUDE		24
-#define OPT_HOST_ID		25
-
-#ifdef SCSI_NCR_IARB_SUPPORT
-#define OPT_IARB		26
-#endif
-
-static char setup_token[] __initdata = 
-	"tags:"   "mpar:"
-	"spar:"   "disc:"
-	"specf:"  "ultra:"
-	"fsn:"    "revprob:"
-	"sync:"   "verb:"
-	"debug:"  "burst:"
-	"led:"    "wide:"
-	"settle:" "diff:"
-	"irqm:"   "pcifix:"
-	"buschk:" "optim:"
-	"recovery:"
-	"safe:"   "nvram:"
-	"excl:"   "hostid:"
-#ifdef SCSI_NCR_IARB_SUPPORT
-	"iarb:"
-#endif
-	;	/* DONNOT REMOVE THIS ';' */
-
-#ifdef MODULE
-#define	ARG_SEP	' '
-#else
-#define	ARG_SEP	','
-#endif
-
-static int __init get_setup_token(char *p)
-{
-	char *cur = setup_token;
-	char *pc;
-	int i = 0;
-
-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-		++pc;
-		++i;
-		if (!strncmp(p, cur, pc - cur))
-			return i;
-		cur = pc;
-	}
-	return 0;
-}
-
-
-static int __init sym53c8xx__setup(char *str)
-{
-#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-	char *cur = str;
-	char *pc, *pv;
-	int i, val, c;
-	int xi = 0;
-
-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-		char *pe;
-
-		val = 0;
-		pv = pc;
-		c = *++pv;
-
-		if	(c == 'n')
-			val = 0;
-		else if	(c == 'y')
-			val = 1;
-		else
-			val = (int) simple_strtoul(pv, &pe, 0);
-
-		switch (get_setup_token(cur)) {
-		case OPT_TAGS:
-			driver_setup.default_tags = val;
-			if (pe && *pe == '/') {
-				i = 0;
-				while (*pe && *pe != ARG_SEP && 
-					i < sizeof(driver_setup.tag_ctrl)-1) {
-					driver_setup.tag_ctrl[i++] = *pe++;
-				}
-				driver_setup.tag_ctrl[i] = '\0';
-			}
-			break;
-		case OPT_MASTER_PARITY:
-			driver_setup.master_parity = val;
-			break;
-		case OPT_SCSI_PARITY:
-			driver_setup.scsi_parity = val;
-			break;
-		case OPT_DISCONNECTION:
-			driver_setup.disconnection = val;
-			break;
-		case OPT_SPECIAL_FEATURES:
-			driver_setup.special_features = val;
-			break;
-		case OPT_FORCE_SYNC_NEGO:
-			driver_setup.force_sync_nego = val;
-			break;
-		case OPT_REVERSE_PROBE:
-			driver_setup.reverse_probe = val;
-			break;
-		case OPT_DEFAULT_SYNC:
-			driver_setup.default_sync = val;
-			break;
-		case OPT_VERBOSE:
-			driver_setup.verbose = val;
-			break;
-		case OPT_DEBUG:
-			driver_setup.debug = val;
-			break;
-		case OPT_BURST_MAX:
-			driver_setup.burst_max = val;
-			break;
-		case OPT_LED_PIN:
-			driver_setup.led_pin = val;
-			break;
-		case OPT_MAX_WIDE:
-			driver_setup.max_wide = val? 1:0;
-			break;
-		case OPT_SETTLE_DELAY:
-			driver_setup.settle_delay = val;
-			break;
-		case OPT_DIFF_SUPPORT:
-			driver_setup.diff_support = val;
-			break;
-		case OPT_IRQM:
-			driver_setup.irqm = val;
-			break;
-		case OPT_PCI_FIX_UP:
-			driver_setup.pci_fix_up	= val;
-			break;
-		case OPT_BUS_CHECK:
-			driver_setup.bus_check = val;
-			break;
-		case OPT_OPTIMIZE:
-			driver_setup.optimize = val;
-			break;
-		case OPT_RECOVERY:
-			driver_setup.recovery = val;
-			break;
-		case OPT_USE_NVRAM:
-			driver_setup.use_nvram = val;
-			break;
-		case OPT_SAFE_SETUP:
-			memcpy(&driver_setup, &driver_safe_setup,
-				sizeof(driver_setup));
-			break;
-		case OPT_EXCLUDE:
-			if (xi < SCSI_NCR_MAX_EXCLUDES)
-				driver_setup.excludes[xi++] = val;
-			break;
-		case OPT_HOST_ID:
-			driver_setup.host_id = val;
-			break;
-#ifdef SCSI_NCR_IARB_SUPPORT
-		case OPT_IARB:
-			driver_setup.iarb = val;
-			break;
-#endif
-		default:
-			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
-			break;
-		}
-
-		if ((cur = strchr(cur, ARG_SEP)) != NULL)
-			++cur;
-	}
-#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
-	return 1;
-}
-
-/*===================================================================
-**
-**	Get device queue depth from boot command line.
-**
-**===================================================================
-*/
-#define DEF_DEPTH	(driver_setup.default_tags)
-#define ALL_TARGETS	-2
-#define NO_TARGET	-1
-#define ALL_LUNS	-2
-#define NO_LUN		-1
-
-static int device_queue_depth(int unit, int target, int lun)
-{
-	int c, h, t, u, v;
-	char *p = driver_setup.tag_ctrl;
-	char *ep;
-
-	h = -1;
-	t = NO_TARGET;
-	u = NO_LUN;
-	while ((c = *p++) != 0) {
-		v = simple_strtoul(p, &ep, 0);
-		switch(c) {
-		case '/':
-			++h;
-			t = ALL_TARGETS;
-			u = ALL_LUNS;
-			break;
-		case 't':
-			if (t != target)
-				t = (target == v) ? v : NO_TARGET;
-			u = ALL_LUNS;
-			break;
-		case 'u':
-			if (u != lun)
-				u = (lun == v) ? v : NO_LUN;
-			break;
-		case 'q':
-			if (h == unit &&
-				(t == ALL_TARGETS || t == target) &&
-				(u == ALL_LUNS    || u == lun))
-				return v;
-			break;
-		case '-':
-			t = ALL_TARGETS;
-			u = ALL_LUNS;
-			break;
-		default:
-			break;
-		}
-		p = ep;
-	}
-	return DEF_DEPTH;
-}
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
deleted file mode 100644
index 139cd0e..0000000
--- a/drivers/scsi/sym53c8xx_defs.h
+++ /dev/null
@@ -1,1320 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  This program is free software; you can redistribute it and/or modify
-**  it under the terms of the GNU General Public License as published by
-**  the Free Software Foundation; either version 2 of the License, or
-**  (at your option) any later version.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You 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.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-**  Added support for MIPS big endian systems.
-**    Carsten Langgaard, carstenl@mips.com
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-**  Added support for HP PARISC big endian systems.
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-*******************************************************************************
-*/
-
-#ifndef SYM53C8XX_DEFS_H
-#define SYM53C8XX_DEFS_H
-
-#include <linux/config.h>
-
-/*
-**	If you want a driver as small as possible, donnot define the 
-**	following options.
-*/
-#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-#define SCSI_NCR_DEBUG_INFO_SUPPORT
-
-/*
-**	To disable integrity checking, do not define the 
-**	following option.
-*/
-#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
-#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
-#endif
-
-/* ---------------------------------------------------------------------
-** Take into account kernel configured parameters.
-** Most of these options can be overridden at startup by a command line.
-** ---------------------------------------------------------------------
-*/
-
-/*
- * For Ultra2 and Ultra3 SCSI support option, use special features. 
- *
- * Value (default) means:
- *	bit 0 : all features enabled, except:
- *		bit 1 : PCI Write And Invalidate.
- *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
- *
- * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
- * enabled by the driver.
- */
-#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
-
-#define SCSI_NCR_MAX_SYNC			(80)
-
-/*
- * Allow tags from 2 to 256, default 8
- */
-#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
-#define SCSI_NCR_MAX_TAGS	(2)
-#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
-#define SCSI_NCR_MAX_TAGS	(256)
-#else
-#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#endif
-#else
-#define SCSI_NCR_MAX_TAGS	(8)
-#endif
-
-/*
- * Allow tagged command queuing support if configured with default number 
- * of tags set to max (see above).
- */
-#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
-#else
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
-#endif
-
-/*
- * Immediate arbitration
- */
-#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
-#define SCSI_NCR_IARB_SUPPORT
-#endif
-
-/*
- * Sync transfer frequency at startup.
- * Allow from 5Mhz to 80Mhz default 20 Mhz.
- */
-#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
-#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
-#undef	CONFIG_SCSI_NCR53C8XX_SYNC
-#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
-#endif
-
-#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
-#else
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
-#endif
-
-/*
- * Disallow disconnections at boot-up
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
-#define SCSI_NCR_SETUP_DISCONNECTION	(0)
-#else
-#define SCSI_NCR_SETUP_DISCONNECTION	(1)
-#endif
-
-/*
- * Force synchronous negotiation for all targets
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
-#else
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
-#endif
-
-/*
- * Disable master parity checking (flawed hardwares need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
-#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
-#else
-#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
-#endif
-
-/*
- * Disable scsi parity checking (flawed devices may need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
-#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
-#else
-#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
-#endif
-
-/*
- * Settle time after reset at boot-up
- */
-#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
-
-/*
-**	Bridge quirks work-around option defaulted to 1.
-*/
-#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
-#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
-#endif
-
-/*
-**	Work-around common bridge misbehaviour.
-**
-**	- Do not flush posted writes in the opposite 
-**	  direction on read.
-**	- May reorder DMA writes to memory.
-**
-**	This option should not affect performances 
-**	significantly, so it is the default.
-*/
-#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-
-/*
-**	Same as option 1, but also deal with 
-**	misconfigured interrupts.
-**
-**	- Edge triggerred instead of level sensitive.
-**	- No interrupt line connected.
-**	- IRQ number misconfigured.
-**	
-**	If no interrupt is delivered, the driver will 
-**	catch the interrupt conditions 10 times per 
-**	second. No need to say that this option is 
-**	not recommended.
-*/
-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-#define	SCSI_NCR_PCIQ_BROKEN_INTR
-
-/*
-**	Some bridge designers decided to flush 
-**	everything prior to deliver the interrupt.
-**	This option tries to deal with such a 
-**	behaviour.
-*/
-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
-#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
-#endif
-
-/*
-**	Other parameters not configurable with "make config"
-**	Avoid to change these constants, unless you know what you are doing.
-*/
-
-#define SCSI_NCR_ALWAYS_SIMPLE_TAG
-#define SCSI_NCR_MAX_SCATTER	(127)
-#define SCSI_NCR_MAX_TARGET	(16)
-
-/*
-**   Compute some desirable value for CAN_QUEUE 
-**   and CMD_PER_LUN.
-**   The driver will use lower values if these 
-**   ones appear to be too large.
-*/
-#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
-#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
-
-#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
-#define SCSI_NCR_TIMER_INTERVAL	(HZ)
-
-#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
-#define SCSI_NCR_MAX_LUN	(16)
-#else
-#define SCSI_NCR_MAX_LUN	(1)
-#endif
-
-/*
- *  IO functions definition for big/little endian CPU support.
- *  For now, the NCR is only supported in little endian addressing mode, 
- */
-
-#ifdef	__BIG_ENDIAN
-
-#define	inw_l2b		inw
-#define	inl_l2b		inl
-#define	outw_b2l	outw
-#define	outl_b2l	outl
-
-#define	readb_raw	readb
-#define	writeb_raw	writeb
-
-#if defined(SCSI_NCR_BIG_ENDIAN)
-#define	readw_l2b	__raw_readw
-#define	readl_l2b	__raw_readl
-#define	writew_b2l	__raw_writew
-#define	writel_b2l	__raw_writel
-#define	readw_raw	__raw_readw
-#define	readl_raw	__raw_readl
-#define	writew_raw	__raw_writew
-#define	writel_raw	__raw_writel
-#else	/* Other big-endian */
-#define	readw_l2b	readw
-#define	readl_l2b	readl
-#define	writew_b2l	writew
-#define	writel_b2l	writel
-#define	readw_raw	readw
-#define	readl_raw	readl
-#define	writew_raw	writew
-#define	writel_raw	writel
-#endif
-
-#else	/* little endian */
-
-#define	inw_raw		inw
-#define	inl_raw		inl
-#define	outw_raw	outw
-#define	outl_raw	outl
-
-#define	readb_raw	readb
-#define	readw_raw	readw
-#define	readl_raw	readl
-#define	writeb_raw	writeb
-#define	writew_raw	writew
-#define	writel_raw	writel
-
-#endif
-
-#if !defined(__hppa__) && !defined(__mips__)
-#ifdef	SCSI_NCR_BIG_ENDIAN
-#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
-#endif
-#endif
-
-#define MEMORY_BARRIER()	mb()
-
-
-/*
- *  If the NCR uses big endian addressing mode over the 
- *  PCI, actual io register addresses for byte and word 
- *  accesses must be changed according to lane routing.
- *  Btw, ncr_offb() and ncr_offw() macros only apply to 
- *  constants and so donnot generate bloated code.
- */
-
-#if	defined(SCSI_NCR_BIG_ENDIAN)
-
-#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
-#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
-
-#else
-
-#define ncr_offb(o)	(o)
-#define ncr_offw(o)	(o)
-
-#endif
-
-/*
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for script patching.
- *  Macro cpu_to_scr() is to be used for script patching.
- *  Macro scr_to_cpu() is to be used for getting a DWORD 
- *  from the script.
- */
-
-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw)	cpu_to_le32(dw)
-#define scr_to_cpu(dw)	le32_to_cpu(dw)
-
-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw)	cpu_to_be32(dw)
-#define scr_to_cpu(dw)	be32_to_cpu(dw)
-
-#else
-
-#define cpu_to_scr(dw)	(dw)
-#define scr_to_cpu(dw)	(dw)
-
-#endif
-
-/*
- *  Access to the controller chip.
- *
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for accessing chip io 
- *  registers. Functions suffixed by '_raw' are assumed 
- *  to access the chip over the PCI without doing byte 
- *  reordering. Functions suffixed by '_l2b' are 
- *  assumed to perform little-endian to big-endian byte 
- *  reordering, those suffixed by '_b2l' blah, blah,
- *  blah, ...
- */
-
-/*
- *  MEMORY mapped IO input / output
- */
-
-#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
-#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
-
-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
-
-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
-
-#else
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
-#else
-#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
-#else
-#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
-
-#endif
-
-#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
-#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
-#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
-
-#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
-
-/*
- *  Set bit field ON, OFF 
- */
-
-#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
-#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
-#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
-#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
-#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
-#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
-
-/*
- *  We normally want the chip to have a consistent view
- *  of driver internal data structures when we restart it.
- *  Thus these macros.
- */
-#define OUTL_DSP(v)				\
-	do {					\
-		MEMORY_BARRIER();		\
-		OUTL (nc_dsp, (v));		\
-	} while (0)
-
-#define OUTONB_STD()				\
-	do {					\
-		MEMORY_BARRIER();		\
-		OUTONB (nc_dcntl, (STD|NOCOM));	\
-	} while (0)
-
-
-/*
-**   NCR53C8XX devices features table.
-*/
-struct ncr_chip {
-	unsigned short	revision_id;
-	unsigned char	burst_max;	/* log-base-2 of max burst */
-	unsigned char	offset_max;
-	unsigned char	nr_divisor;
-	unsigned int	features;
-#define FE_LED0		(1<<0)
-#define FE_WIDE		(1<<1)    /* Wide data transfers */
-#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
-#define FE_DBLR		(1<<4)	  /* Clock doubler present */
-#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
-#define FE_ERL		(1<<6)    /* Enable read line */
-#define FE_CLSE		(1<<7)    /* Cache line size enable */
-#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
-#define FE_ERMP		(1<<9)    /* Enable read multiple */
-#define FE_BOF		(1<<10)   /* Burst opcode fetch */
-#define FE_DFS		(1<<11)   /* DMA fifo size */
-#define FE_PFEN		(1<<12)   /* Prefetch enable */
-#define FE_LDSTR	(1<<13)   /* Load/Store supported */
-#define FE_RAM		(1<<14)   /* On chip RAM present */
-#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
-#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
-#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
-#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
-#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
-#define FE_LEDC		(1<<20)   /* Hardware control of LED */
-#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
-#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
-#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
-#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
-#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
-#define FE_EHP		(1<<27)   /* 720: Even host parity */
-#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
-#define FE_EA		(1<<29)   /* 720: Enable Ack */
-
-#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
-#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
-#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
-};
-
-
-/*
-**	Driver setup structure.
-**
-**	This structure is initialized from linux config options.
-**	It can be overridden at boot-up by the boot command line.
-*/
-#define SCSI_NCR_MAX_EXCLUDES 8
-struct ncr_driver_setup {
-	u8	master_parity;
-	u8	scsi_parity;
-	u8	disconnection;
-	u8	special_features;
-	u8	force_sync_nego;
-	u8	reverse_probe;
-	u8	pci_fix_up;
-	u8	use_nvram;
-	u8	verbose;
-	u8	default_tags;
-	u16	default_sync;
-	u16	debug;
-	u8	burst_max;
-	u8	led_pin;
-	u8	max_wide;
-	u8	settle_delay;
-	u8	diff_support;
-	u8	irqm;
-	u8	bus_check;
-	u8	optimize;
-	u8	recovery;
-	u8	host_id;
-	u16	iarb;
-	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
-	char	tag_ctrl[100];
-};
-
-/*
-**	Initial setup.
-**	Can be overriden at startup by a command line.
-*/
-#define SCSI_NCR_DRIVER_SETUP			\
-{						\
-	SCSI_NCR_SETUP_MASTER_PARITY,		\
-	SCSI_NCR_SETUP_SCSI_PARITY,		\
-	SCSI_NCR_SETUP_DISCONNECTION,		\
-	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
-	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
-	0,					\
-	0,					\
-	1,					\
-	0,					\
-	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
-	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
-	0x00,					\
-	7,					\
-	0,					\
-	1,					\
-	SCSI_NCR_SETUP_SETTLE_TIME,		\
-	0,					\
-	0,					\
-	1,					\
-	0,					\
-	0,					\
-	255,					\
-	0x00					\
-}
-
-/*
-**	Boot fail safe setup.
-**	Override initial setup from boot command line:
-**	ncr53c8xx=safe:y
-*/
-#define SCSI_NCR_DRIVER_SAFE_SETUP		\
-{						\
-	0,					\
-	1,					\
-	0,					\
-	0,					\
-	0,					\
-	0,					\
-	0,					\
-	1,					\
-	2,					\
-	0,					\
-	255,					\
-	0x00,					\
-	255,					\
-	0,					\
-	0,					\
-	10,					\
-	1,					\
-	1,					\
-	1,					\
-	0,					\
-	0,					\
-	255					\
-}
-
-/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
-
-/*-----------------------------------------------------------------
-**
-**	The ncr 53c810 register structure.
-**
-**-----------------------------------------------------------------
-*/
-
-struct ncr_reg {
-/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
-
-/*01*/  u8	nc_scntl1;    /* no reset                         */
-        #define   ISCON   0x10  /* connected to scsi		    */
-        #define   CRST    0x08  /* force reset                      */
-        #define   IARB    0x02  /* immediate arbitration            */
-
-/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
-	#define   SDU     0x80  /* cmd: disconnect will raise error */
-	#define   CHM     0x40  /* sta: chained mode                */
-	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
-	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
-
-/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
-	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
-	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
-				/* bits 0-2, 7 rsvd for C1010       */
-
-/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
-	#define   RRE     0x40  /* r/w:e enable response to resel.  */
-	#define   SRE     0x20  /* r/w:e enable response to select  */
-
-/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
-				/* bits 6-7 rsvd for C1010          */
-
-/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
-
-/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
-
-/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
-
-/*09*/  u8	nc_socl;
-	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
-	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
-	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
-	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
-	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
-	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
-	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
-	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
-
-/*0a*/  u8	nc_ssid;
-
-/*0b*/  u8	nc_sbcl;
-
-/*0c*/  u8	nc_dstat;
-        #define   DFE     0x80  /* sta: dma fifo empty              */
-        #define   MDPE    0x40  /* int: master data parity error    */
-        #define   BF      0x20  /* int: script: bus fault           */
-        #define   ABRT    0x10  /* int: script: command aborted     */
-        #define   SSI     0x08  /* int: script: single step         */
-        #define   SIR     0x04  /* int: script: interrupt instruct. */
-        #define   IID     0x01  /* int: script: illegal instruct.   */
-
-/*0d*/  u8	nc_sstat0;
-        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
-        #define   ORF     0x40  /* sta: data in SODR register lsb   */
-        #define   OLF     0x20  /* sta: data in SODL register lsb   */
-        #define   AIP     0x10  /* sta: arbitration in progress     */
-        #define   LOA     0x08  /* sta: arbitration lost            */
-        #define   WOA     0x04  /* sta: arbitration won             */
-        #define   IRST    0x02  /* sta: scsi reset signal           */
-        #define   SDP     0x01  /* sta: scsi parity signal          */
-
-/*0e*/  u8	nc_sstat1;
-	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
-
-/*0f*/  u8	nc_sstat2;
-        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
-        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
-        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
-        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
-        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
-
-/*10*/  u8	nc_dsa;	/* --> Base page                    */
-/*11*/  u8	nc_dsa1;
-/*12*/  u8	nc_dsa2;
-/*13*/  u8	nc_dsa3;
-
-/*14*/  u8	nc_istat;	/* --> Main Command and status      */
-        #define   CABRT   0x80  /* cmd: abort current operation     */
-        #define   SRST    0x40  /* mod: reset chip                  */
-        #define   SIGP    0x20  /* r/w: message from host to ncr    */
-        #define   SEM     0x10  /* r/w: message between host + ncr  */
-        #define   CON     0x08  /* sta: connected to scsi           */
-        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
-        #define   SIP     0x02  /* sta: scsi-interrupt              */
-        #define   DIP     0x01  /* sta: host/script interrupt       */
-
-/*15*/  u8	nc_istat1;	/* 896 and later cores only */
-        #define   FLSH    0x04  /* sta: chip is flushing            */
-        #define   SRUN    0x02  /* sta: scripts are running         */
-        #define   SIRQD   0x01  /* r/w: disable INT pin             */
-
-/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
-/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
-
-/*18*/	u8	nc_ctest0;
-	#define   EHP     0x04	/* 720 even host parity             */
-/*19*/  u8	nc_ctest1;
-
-/*1a*/  u8	nc_ctest2;
-	#define   CSIGP   0x40
-				/* bits 0-2,7 rsvd for C1010        */
-
-/*1b*/  u8	nc_ctest3;
-	#define   FLF     0x08  /* cmd: flush dma fifo              */
-	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
-	#define   FM      0x02  /* mod: fetch pin mode              */
-	#define   WRIE    0x01  /* mod: write and invalidate enable */
-				/* bits 4-7 rsvd for C1010          */
-
-/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
-
-/*20*/	u8	nc_dfifo;
-/*21*/  u8	nc_ctest4;
-	#define   MUX     0x80  /* 720 host bus multiplex mode      */
-	#define   BDIS    0x80  /* mod: burst disable               */
-	#define   MPEE    0x08  /* mod: master parity error enable  */
-
-/*22*/  u8	nc_ctest5;
-	#define   DFS     0x20  /* mod: dma fifo size               */
-				/* bits 0-1, 3-7 rsvd for C1010          */
-/*23*/  u8	nc_ctest6;
-
-/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
-/*28*/  u32    nc_dnad;	/* ### Next command register        */
-/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
-/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
-
-/*34*/  u8	nc_scratcha;  /* Temporary register a            */
-/*35*/  u8	nc_scratcha1;
-/*36*/  u8	nc_scratcha2;
-/*37*/  u8	nc_scratcha3;
-
-/*38*/  u8	nc_dmode;
-	#define   BL_2    0x80  /* mod: burst length shift value +2 */
-	#define   BL_1    0x40  /* mod: burst length shift value +1 */
-	#define   ERL     0x08  /* mod: enable read line            */
-	#define   ERMP    0x04  /* mod: enable read multiple        */
-	#define   BOF     0x02  /* mod: burst op code fetch         */
-
-/*39*/  u8	nc_dien;
-/*3a*/  u8	nc_sbr;
-
-/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
-	#define   CLSE    0x80  /* mod: cache line size enable      */
-	#define   PFF     0x40  /* cmd: pre-fetch flush             */
-	#define   PFEN    0x20  /* mod: pre-fetch enable            */
-	#define   EA      0x20  /* mod: 720 enable-ack              */
-	#define   SSM     0x10  /* mod: single step mode            */
-	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
-	#define   STD     0x04  /* cmd: start dma mode              */
-	#define   IRQD    0x02  /* mod: irq disable                 */
- 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
-				/* bits 0-1 rsvd for C1010          */
-
-/*3c*/  u32	nc_adder;
-
-/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
-/*42*/  u16	nc_sist;	/* <--: interrupt status            */
-        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
-        #define   STO     0x0400/* sta: timeout (select)            */
-        #define   GEN     0x0200/* sta: timeout (general)           */
-        #define   HTH     0x0100/* sta: timeout (handshake)         */
-        #define   MA      0x80  /* sta: phase mismatch              */
-        #define   CMP     0x40  /* sta: arbitration complete        */
-        #define   SEL     0x20  /* sta: selected by another device  */
-        #define   RSL     0x10  /* sta: reselected by another device*/
-        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
-        #define   UDC     0x04  /* sta: unexpected disconnect       */
-        #define   RST     0x02  /* sta: scsi bus reset detected     */
-        #define   PAR     0x01  /* sta: scsi parity error           */
-
-/*44*/  u8	nc_slpar;
-/*45*/  u8	nc_swide;
-/*46*/  u8	nc_macntl;
-/*47*/  u8	nc_gpcntl;
-/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
-/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
-/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
-
-/*4c*/  u8	nc_stest0;
-
-/*4d*/  u8	nc_stest1;
-	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
-	#define   DBLEN   0x08	/* clock doubler running		*/
-	#define   DBLSEL  0x04	/* clock doubler selected		*/
-  
-
-/*4e*/  u8	nc_stest2;
-	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
-	#define   DIF     0x20  /* 720 SCSI differential mode             */
-	#define   EXT     0x02  /* extended filtering                     */
-
-/*4f*/  u8	nc_stest3;
-	#define   TE     0x80	/* c: tolerAnt enable */
-	#define   HSC    0x20	/* c: Halt SCSI Clock */
-	#define   CSF    0x02	/* c: clear scsi fifo */
-
-/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
-/*52*/  u8	nc_stest4;
-	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
-	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
-	#define    SMODE_SE  0x80	/* Single Ended                    */
-	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
-	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
-				/* bits 0-5 rsvd for C1010          */
-
-/*53*/  u8	nc_53_;
-/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
-/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
-	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
-	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
-	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
-	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
-	#define   DILS   0x02	/* Disable Internal Load/Store      */
-	#define   DPR    0x01	/* Disable Pipe Req                 */
-
-/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
-	#define   ZMOD   0x80	/* High Impedance Mode              */
-	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
-	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
-	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
-	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
-	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
-
-/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
-/*5a*/  u16	nc_5a_;
-
-/*5c*/  u8	nc_scr0;	/* Working register B               */
-/*5d*/  u8	nc_scr1;	/*                                  */
-/*5e*/  u8	nc_scr2;	/*                                  */
-/*5f*/  u8	nc_scr3;	/*                                  */
-
-/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
-/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
-/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
-/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
-/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
-/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
-/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
-/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
-/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
-	#define   U3EN   0x80	/* Enable Ultra 3                   */
-	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
-	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
-					transfer edge	            */
-	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
-					transfer edge	            */
-
-/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
-/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
-
-/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
-/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
-/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
-/*c9*/	u8	nc_rbc1;	/*                                  */
-/*ca*/	u8	nc_rbc2;	/*                                  */
-/*cb*/	u8	nc_rbc3;	/*                                  */
-
-/*cc*/	u8	nc_ua;		/* Updated Address                  */
-/*cd*/	u8	nc_ua1;		/*                                  */
-/*ce*/	u8	nc_ua2;		/*                                  */
-/*cf*/	u8	nc_ua3;		/*                                  */
-/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
-/*d4*/	u8	nc_ia;		/* Instruction Address              */
-/*d5*/	u8	nc_ia1;
-/*d6*/	u8	nc_ia2;
-/*d7*/	u8	nc_ia3;
-/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
-/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
-
-				/* Following for C1010 only         */
-/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
-/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
-	#define   SNDCRC  0x10	/* Send CRC Request                 */
-/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
-/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
-/*e8*/  u32	nc_e8_;		/* rsvd 			    */
-/*ec*/  u32	nc_ec_;		/* rsvd 			    */
-/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
-
-};
-
-/*-----------------------------------------------------------
-**
-**	Utility macros for the script.
-**
-**-----------------------------------------------------------
-*/
-
-#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
-#define REG(r) REGJ (nc_, r)
-
-typedef u32 ncrcmd;
-
-/*-----------------------------------------------------------
-**
-**	SCSI phases
-**
-**	DT phases illegal for ncr driver.
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_DATA_OUT	0x00000000
-#define	SCR_DATA_IN	0x01000000
-#define	SCR_COMMAND	0x02000000
-#define	SCR_STATUS	0x03000000
-#define SCR_DT_DATA_OUT	0x04000000
-#define SCR_DT_DATA_IN	0x05000000
-#define SCR_MSG_OUT	0x06000000
-#define SCR_MSG_IN      0x07000000
-
-#define SCR_ILG_OUT	0x04000000
-#define SCR_ILG_IN	0x05000000
-
-/*-----------------------------------------------------------
-**
-**	Data transfer via SCSI.
-**
-**-----------------------------------------------------------
-**
-**	MOVE_ABS (LEN)
-**	<<start address>>
-**
-**	MOVE_IND (LEN)
-**	<<dnad_offset>>
-**
-**	MOVE_TBL
-**	<<dnad_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define OPC_MOVE          0x08000000
-
-#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
-
-#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
-#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
-#define SCR_CHMOV_TBL     (0x10000000)
-
-struct scr_tblmove {
-        u32  size;
-        u32  addr;
-};
-
-/*-----------------------------------------------------------
-**
-**	Selection
-**
-**-----------------------------------------------------------
-**
-**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
-**	<<alternate_address>>
-**
-**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
-**	<<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_SEL_ABS	0x40000000
-#define	SCR_SEL_ABS_ATN	0x41000000
-#define	SCR_SEL_TBL	0x42000000
-#define	SCR_SEL_TBL_ATN	0x43000000
-
-
-#ifdef SCSI_NCR_BIG_ENDIAN
-struct scr_tblsel {
-        u8	sel_scntl3;
-        u8	sel_id;
-        u8	sel_sxfer;
-        u8	sel_scntl4;	
-};
-#else
-struct scr_tblsel {
-        u8	sel_scntl4;	
-        u8	sel_sxfer;
-        u8	sel_id;
-        u8	sel_scntl3;
-};
-#endif
-
-#define SCR_JMP_REL     0x04000000
-#define SCR_ID(id)	(((u32)(id)) << 16)
-
-/*-----------------------------------------------------------
-**
-**	Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**	WAIT_DISC
-**	dummy: <<alternate_address>>
-**
-**	WAIT_RESEL
-**	<<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_WAIT_DISC	0x48000000
-#define SCR_WAIT_RESEL  0x50000000
-
-/*-----------------------------------------------------------
-**
-**	Bit Set / Reset
-**
-**-----------------------------------------------------------
-**
-**	SET (flags {|.. })
-**
-**	CLR (flags {|.. })
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_SET(f)     (0x58000000 | (f))
-#define SCR_CLR(f)     (0x60000000 | (f))
-
-#define	SCR_CARRY	0x00000400
-#define	SCR_TRG		0x00000200
-#define	SCR_ACK		0x00000040
-#define	SCR_ATN		0x00000008
-
-
-
-
-/*-----------------------------------------------------------
-**
-**	Memory to memory move
-**
-**-----------------------------------------------------------
-**
-**	COPY (bytecount)
-**	<< source_address >>
-**	<< destination_address >>
-**
-**	SCR_COPY   sets the NO FLUSH option by default.
-**	SCR_COPY_F does not set this option.
-**
-**	For chips which do not support this option,
-**	ncr_copy_and_bind() will remove this bit.
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_FLUSH 0x01000000
-
-#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
-#define SCR_COPY_F(n) (0xc0000000 | (n))
-
-/*-----------------------------------------------------------
-**
-**	Register move and binary operations
-**
-**-----------------------------------------------------------
-**
-**	SFBR_REG (reg, op, data)        reg  = SFBR op data
-**	<< 0 >>
-**
-**	REG_SFBR (reg, op, data)        SFBR = reg op data
-**	<< 0 >>
-**
-**	REG_REG  (reg, op, data)        reg  = reg op data
-**	<< 0 >>
-**
-**-----------------------------------------------------------
-**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
-**	of SFBR register can be used as data (SCR_SFBR_DATA).
-**	The 896 has additionnal IO registers starting at 
-**	offset 0x80. Bit 7 of register offset is stored in 
-**	bit 7 of the SCRIPTS instruction first DWORD.
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
-
-#define SCR_SFBR_REG(reg,op,data) \
-        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_SFBR(reg,op,data) \
-        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_REG(reg,op,data) \
-        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-
-#define      SCR_LOAD   0x00000000
-#define      SCR_SHL    0x01000000
-#define      SCR_OR     0x02000000
-#define      SCR_XOR    0x03000000
-#define      SCR_AND    0x04000000
-#define      SCR_SHR    0x05000000
-#define      SCR_ADD    0x06000000
-#define      SCR_ADDC   0x07000000
-
-#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
-
-/*-----------------------------------------------------------
-**
-**	FROM_REG (reg)		  SFBR = reg
-**	<< 0 >>
-**
-**	TO_REG	 (reg)		  reg  = SFBR
-**	<< 0 >>
-**
-**	LOAD_REG (reg, data)	  reg  = <data>
-**	<< 0 >>
-**
-**	LOAD_SFBR(data) 	  SFBR = <data>
-**	<< 0 >>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_FROM_REG(reg) \
-	SCR_REG_SFBR(reg,SCR_OR,0)
-
-#define	SCR_TO_REG(reg) \
-	SCR_SFBR_REG(reg,SCR_OR,0)
-
-#define	SCR_LOAD_REG(reg,data) \
-	SCR_REG_REG(reg,SCR_LOAD,data)
-
-#define SCR_LOAD_SFBR(data) \
-        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
-
-/*-----------------------------------------------------------
-**
-**	LOAD  from memory   to register.
-**	STORE from register to memory.
-**
-**	Only supported by 810A, 860, 825A, 875, 895 and 896.
-**
-**-----------------------------------------------------------
-**
-**	LOAD_ABS (LEN)
-**	<<start address>>
-**
-**	LOAD_REL (LEN)        (DSA relative)
-**	<<dsa_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
-#define SCR_NO_FLUSH2	0x02000000
-#define SCR_DSA_REL2	0x10000000
-
-#define SCR_LOAD_R(reg, how, n) \
-        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_STORE_R(reg, how, n) \
-        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
-#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
-#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
-
-#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
-#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
-#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
-
-
-/*-----------------------------------------------------------
-**
-**	Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<address>>
-**
-**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<distance>>
-**
-**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<address>>
-**
-**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<distance>>
-**
-**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<dummy>>
-**
-**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<ident>>
-**
-**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<ident>>
-**
-**	Conditions:
-**	     WHEN (phase)
-**	     IF   (phase)
-**	     CARRYSET
-**	     DATA (data, mask)
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_OP       0x80000000
-#define SCR_JUMP        0x80080000
-#define SCR_JUMP64      0x80480000
-#define SCR_JUMPR       0x80880000
-#define SCR_CALL        0x88080000
-#define SCR_CALLR       0x88880000
-#define SCR_RETURN      0x90080000
-#define SCR_INT         0x98080000
-#define SCR_INT_FLY     0x98180000
-
-#define IFFALSE(arg)   (0x00080000 | (arg))
-#define IFTRUE(arg)    (0x00000000 | (arg))
-
-#define WHEN(phase)    (0x00030000 | (phase))
-#define IF(phase)      (0x00020000 | (phase))
-
-#define DATA(D)        (0x00040000 | ((D) & 0xff))
-#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
-
-#define CARRYSET       (0x00200000)
-
-/*-----------------------------------------------------------
-**
-**	SCSI  constants.
-**
-**-----------------------------------------------------------
-*/
-
-/*
-**	Messages
-*/
-
-#define	M_COMPLETE	COMMAND_COMPLETE
-#define	M_EXTENDED	EXTENDED_MESSAGE
-#define	M_SAVE_DP	SAVE_POINTERS
-#define	M_RESTORE_DP	RESTORE_POINTERS
-#define	M_DISCONNECT	DISCONNECT
-#define	M_ID_ERROR	INITIATOR_ERROR
-#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		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	IGNORE_WIDE_RESIDUE
-#define	M_IDENTIFY   	(0x80)
-
-#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	EXTENDED_PPR
-
-/*
-**	Status
-*/
-
-#define	S_GOOD		(0x00)
-#define	S_CHECK_COND	(0x02)
-#define	S_COND_MET	(0x04)
-#define	S_BUSY		(0x08)
-#define	S_INT		(0x10)
-#define	S_INT_COND_MET	(0x14)
-#define	S_CONFLICT	(0x18)
-#define	S_TERMINATED	(0x20)
-#define	S_QUEUE_FULL	(0x28)
-#define	S_ILLEGAL	(0xff)
-#define	S_SENSE		(0x80)
-
-/*
- * End of ncrreg from FreeBSD
- */
-
-#endif /* defined SYM53C8XX_DEFS_H */
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index a50c2bc..3639c3f 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -22,6 +22,7 @@
 obj-$(CONFIG_USB_PRINTER)	+= class/
 
 obj-$(CONFIG_USB_STORAGE)	+= storage/
+obj-$(CONFIG_USB)		+= storage/
 
 obj-$(CONFIG_USB_AIPTEK)	+= input/
 obj-$(CONFIG_USB_ATI_REMOTE)	+= input/
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig
index f429862..550ddfa 100644
--- a/drivers/usb/atm/Kconfig
+++ b/drivers/usb/atm/Kconfig
@@ -44,6 +44,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cxacru.
 
+config USB_UEAGLEATM
+	tristate "ADI 930 and eagle USB DSL modem"
+	depends on USB_ATM
+	select FW_LOADER
+	help
+	  Say Y here if you have an ADSL USB modem based on the ADI 930
+	  or eagle chipset. In order to use your modem you will need to
+	  install firmwares and CMV (Command Management Variables); see
+	  <https://gna.org/projects/ueagleatm/> for details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ueagle-atm.
+
 config USB_XUSBATM
 	tristate "Other USB DSL modem support"
 	depends on USB_ATM
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile
index 8509971..4c4a776 100644
--- a/drivers/usb/atm/Makefile
+++ b/drivers/usb/atm/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_USB_CXACRU)	+= cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= speedtch.o
+obj-$(CONFIG_USB_UEAGLEATM)	+= ueagle-atm.o
 obj-$(CONFIG_USB_ATM)		+= usbatm.o
 obj-$(CONFIG_USB_XUSBATM)	+= xusbatm.o
 
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 9d59dc6..af0a41e 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -853,7 +853,6 @@
 }
 
 static struct usb_driver cxacru_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= cxacru_driver_name,
 	.probe		= cxacru_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index d0cbbb7..b283361 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -659,7 +659,6 @@
 static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *);
 
 static struct usb_driver speedtch_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= speedtch_driver_name,
 	.probe		= speedtch_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
new file mode 100644
index 0000000..7d2a679
--- /dev/null
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -0,0 +1,1820 @@
+/*-
+ * Copyright (c) 2003, 2004
+ *	Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
+ *
+ * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr>
+ *
+ * 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
+ * BSD license below:
+ *
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 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.
+ *
+ * GPL license :
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ *
+ * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
+ * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
+ *
+ * The rest of the code was was rewritten from scratch.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/kthread.h>
+#include <linux/version.h>
+#include <asm/unaligned.h>
+
+#include "usbatm.h"
+
+#define EAGLEUSBVERSION "ueagle 1.1"
+
+
+/*
+ * Debug macros
+ */
+#define uea_dbg(usb_dev, format, args...)	\
+	do { \
+		if (debug >= 1) \
+			dev_dbg(&(usb_dev)->dev, \
+				"[ueagle-atm dbg] %s: " format, \
+					__FUNCTION__, ##args); \
+       } while (0)
+
+#define uea_vdbg(usb_dev, format, args...)	\
+	do { \
+		if (debug >= 2) \
+			dev_dbg(&(usb_dev)->dev, \
+				"[ueagle-atm vdbg]  " format, ##args); \
+       } while (0)
+
+#define uea_enters(usb_dev) \
+	uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
+
+#define uea_leaves(usb_dev) \
+	uea_vdbg(usb_dev, "leaving  %s\n", __FUNCTION__)
+
+#define uea_err(usb_dev, format,args...) \
+	dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
+
+#define uea_warn(usb_dev, format,args...) \
+	dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)
+
+#define uea_info(usb_dev, format,args...) \
+	dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)
+
+struct uea_cmvs {
+	u32 address;
+	u16 offset;
+	u32 data;
+} __attribute__ ((packed));
+
+struct uea_softc {
+	struct usb_device *usb_dev;
+	struct usbatm_data *usbatm;
+
+	int modem_index;
+	unsigned int driver_info;
+
+	int booting;
+	int reset;
+
+	wait_queue_head_t sync_q;
+
+	struct task_struct *kthread;
+	u32 data;
+	wait_queue_head_t cmv_ack_wait;
+	int cmv_ack;
+
+	struct work_struct task;
+	u16 pageno;
+	u16 ovl;
+
+	const struct firmware *dsp_firm;
+	struct urb *urb_int;
+
+	u8 cmv_function;
+	u16 cmv_idx;
+	u32 cmv_address;
+	u16 cmv_offset;
+
+	/* keep in sync with eaglectl */
+	struct uea_stats {
+		struct {
+			u32 state;
+			u32 flags;
+			u32 mflags;
+			u32 vidcpe;
+			u32 vidco;
+			u32 dsrate;
+			u32 usrate;
+			u32 dsunc;
+			u32 usunc;
+			u32 dscorr;
+			u32 uscorr;
+			u32 txflow;
+			u32 rxflow;
+			u32 usattenuation;
+			u32 dsattenuation;
+			u32 dsmargin;
+			u32 usmargin;
+			u32 firmid;
+		} phy;
+	} stats;
+};
+
+/*
+ * Elsa IDs
+ */
+#define ELSA_VID		0x05CC
+#define ELSA_PID_PSTFIRM	0x3350
+#define ELSA_PID_PREFIRM	0x3351
+
+/*
+ * Sagem USB IDs
+ */
+#define EAGLE_VID		0x1110
+#define EAGLE_I_PID_PREFIRM	0x9010	/* Eagle I */
+#define EAGLE_I_PID_PSTFIRM	0x900F	/* Eagle I */
+
+#define EAGLE_IIC_PID_PREFIRM	0x9024	/* Eagle IIC */
+#define EAGLE_IIC_PID_PSTFIRM	0x9023	/* Eagle IIC */
+
+#define EAGLE_II_PID_PREFIRM	0x9022	/* Eagle II */
+#define EAGLE_II_PID_PSTFIRM	0x9021	/* Eagle II */
+
+/*
+ *  Eagle III Pid
+ */
+#define EAGLE_III_PID_PREFIRM	0x9032	/* Eagle III */
+#define EAGLE_III_PID_PSTFIRM	0x9031	/* Eagle III */
+
+/*
+ * USR USB IDs
+ */
+#define USR_VID			0x0BAF
+#define MILLER_A_PID_PREFIRM	0x00F2
+#define MILLER_A_PID_PSTFIRM	0x00F1
+#define MILLER_B_PID_PREFIRM	0x00FA
+#define MILLER_B_PID_PSTFIRM	0x00F9
+#define HEINEKEN_A_PID_PREFIRM	0x00F6
+#define HEINEKEN_A_PID_PSTFIRM	0x00F5
+#define HEINEKEN_B_PID_PREFIRM	0x00F8
+#define HEINEKEN_B_PID_PSTFIRM	0x00F7
+
+#define PREFIRM 0
+#define PSTFIRM (1<<7)
+enum {
+	ADI930 = 0,
+	EAGLE_I,
+	EAGLE_II,
+	EAGLE_III
+};
+
+/* macros for both struct usb_device_id and struct uea_softc */
+#define UEA_IS_PREFIRM(x) \
+	(!((x)->driver_info & PSTFIRM))
+#define UEA_CHIP_VERSION(x) \
+	((x)->driver_info & 0xf)
+
+#define IS_ISDN(sc) \
+	(le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
+
+#define INS_TO_USBDEV(ins) ins->usb_dev
+
+#define GET_STATUS(data) \
+	((data >> 8) & 0xf)
+#define IS_OPERATIONAL(sc) \
+	(GET_STATUS(sc->stats.phy.state) == 2)
+
+/*
+ * Set of macros to handle unaligned data in the firmware blob.
+ * The FW_GET_BYTE() macro is provided only for consistency.
+ */
+
+#define FW_GET_BYTE(p)	*((__u8 *) (p))
+#define FW_GET_WORD(p)	le16_to_cpu(get_unaligned((__le16 *) (p)))
+#define FW_GET_LONG(p)	le32_to_cpu(get_unaligned((__le32 *) (p)))
+
+#define FW_DIR "ueagle-atm/"
+#define NB_MODEM 4
+
+#define BULK_TIMEOUT 300
+#define CTRL_TIMEOUT 1000
+
+#define ACK_TIMEOUT msecs_to_jiffies(1500)
+
+#define UEA_INTR_IFACE_NO 	0
+#define UEA_US_IFACE_NO		1
+#define UEA_DS_IFACE_NO		2
+
+#define FASTEST_ISO_INTF	8
+
+#define UEA_BULK_DATA_PIPE	0x02
+#define UEA_IDMA_PIPE		0x04
+#define UEA_INTR_PIPE		0x04
+#define UEA_ISO_DATA_PIPE	0x08
+
+#define UEA_SET_BLOCK    	0x0001
+#define UEA_SET_MODE     	0x0003
+#define UEA_SET_2183_DATA	0x0004
+#define UEA_SET_TIMEOUT		0x0011
+
+#define UEA_LOOPBACK_OFF	0x0002
+#define UEA_LOOPBACK_ON		0x0003
+#define UEA_BOOT_IDMA		0x0006
+#define UEA_START_RESET		0x0007
+#define UEA_END_RESET		0x0008
+
+#define UEA_SWAP_MAILBOX	(0x3fcd | 0x4000)
+#define UEA_MPTX_START		(0x3fce | 0x4000)
+#define UEA_MPTX_MAILBOX	(0x3fd6 | 0x4000)
+#define UEA_MPRX_MAILBOX	(0x3fdf | 0x4000)
+
+/* structure describing a block within a DSP page */
+struct block_info {
+	__le16 wHdr;
+#define UEA_BIHDR 0xabcd
+	__le16 wAddress;
+	__le16 wSize;
+	__le16 wOvlOffset;
+	__le16 wOvl;		/* overlay */
+	__le16 wLast;
+} __attribute__ ((packed));
+#define BLOCK_INFO_SIZE 12
+
+/* structure representing a CMV (Configuration and Management Variable) */
+struct cmv {
+	__le16 wPreamble;
+#define PREAMBLE 0x535c
+	__u8 bDirection;
+#define MODEMTOHOST 0x01
+#define HOSTTOMODEM 0x10
+	__u8 bFunction;
+#define FUNCTION_TYPE(f)    ((f) >> 4)
+#define MEMACCESS	0x1
+#define ADSLDIRECTIVE	0x7
+
+#define FUNCTION_SUBTYPE(f) ((f) & 0x0f)
+/* for MEMACCESS */
+#define REQUESTREAD	0x0
+#define REQUESTWRITE	0x1
+#define REPLYREAD	0x2
+#define REPLYWRITE	0x3
+/* for ADSLDIRECTIVE */
+#define KERNELREADY	0x0
+#define MODEMREADY	0x1
+
+#define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
+	__le16 wIndex;
+	__le32 dwSymbolicAddress;
+#define MAKESA(a, b, c, d)						\
+	(((c) & 0xff) << 24 |						\
+	 ((d) & 0xff) << 16 |						\
+	 ((a) & 0xff) << 8  |						\
+	 ((b) & 0xff))
+
+#define SA_CNTL MAKESA('C', 'N', 'T', 'L')
+#define SA_DIAG MAKESA('D', 'I', 'A', 'G')
+#define SA_INFO MAKESA('I', 'N', 'F', 'O')
+#define SA_OPTN MAKESA('O', 'P', 'T', 'N')
+#define SA_RATE MAKESA('R', 'A', 'T', 'E')
+#define SA_STAT MAKESA('S', 'T', 'A', 'T')
+	__le16 wOffsetAddress;
+	__le32 dwData;
+} __attribute__ ((packed));
+#define CMV_SIZE 16
+
+/* structure representing swap information */
+struct swap_info {
+	__u8 bSwapPageNo;
+	__u8 bOvl;		/* overlay */
+} __attribute__ ((packed));
+
+/* structure representing interrupt data */
+struct intr_pkt {
+	__u8 bType;
+	__u8 bNotification;
+	__le16 wValue;
+	__le16 wIndex;
+	__le16 wLength;
+	__le16 wInterrupt;
+#define INT_LOADSWAPPAGE 0x0001
+#define INT_INCOMINGCMV  0x0002
+	union {
+		struct {
+			struct swap_info swapinfo;
+			__le16 wDataSize;
+		} __attribute__ ((packed)) s1;
+
+		struct {
+			struct cmv cmv;
+			__le16 wDataSize;
+		} __attribute__ ((packed)) s2;
+	} __attribute__ ((packed)) u;
+#define bSwapPageNo	u.s1.swapinfo.bSwapPageNo
+#define bOvl		u.s1.swapinfo.bOvl
+} __attribute__ ((packed));
+#define INTR_PKT_SIZE 28
+
+static struct usb_driver uea_driver;
+static DECLARE_MUTEX(uea_semaphore);
+static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
+
+static int modem_index;
+static unsigned int debug;
+static int sync_wait[NB_MODEM];
+static char *cmv_file[NB_MODEM];
+
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
+module_param_array(sync_wait, bool, NULL, 0644);
+MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
+module_param_array(cmv_file, charp, NULL, 0644);
+MODULE_PARM_DESC(cmv_file,
+		"file name with configuration and management variables");
+
+#define UPDATE_ATM_STAT(type, val) \
+	do { \
+		if (sc->usbatm->atm_dev) \
+			sc->usbatm->atm_dev->type = val; \
+	} while (0)
+
+/* Firmware loading */
+#define LOAD_INTERNAL     0xA0
+#define F8051_USBCS       0x7f92
+
+/**
+ * uea_send_modem_cmd - Send a command for pre-firmware devices.
+ */
+static int uea_send_modem_cmd(struct usb_device *usb,
+		u16 addr, u16 size, u8 * buff)
+{
+	int ret = -ENOMEM;
+	u8 *xfer_buff;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (xfer_buff) {
+		memcpy(xfer_buff, buff, size);
+		ret = usb_control_msg(usb,
+				      usb_sndctrlpipe(usb, 0),
+				      LOAD_INTERNAL,
+				      USB_DIR_OUT | USB_TYPE_VENDOR |
+				      USB_RECIP_DEVICE, addr, 0, xfer_buff,
+				      size, CTRL_TIMEOUT);
+		kfree(xfer_buff);
+	}
+
+	if (ret < 0)
+		return ret;
+
+	return (ret == size) ? 0 : -EIO;
+}
+
+static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
+{
+	struct usb_device *usb = context;
+	u8 *pfw, value;
+	u32 crc = 0;
+	int ret, size;
+
+	uea_enters(usb);
+	if (!fw_entry) {
+		uea_err(usb, "firmware is not available\n");
+		goto err;
+	}
+
+	pfw = fw_entry->data;
+	size = fw_entry->size;
+	if (size < 4)
+		goto err_fw_corrupted;
+
+	crc = FW_GET_LONG(pfw);
+	pfw += 4;
+	size -= 4;
+	if (crc32_be(0, pfw, size) != crc)
+		goto err_fw_corrupted;
+
+	/*
+	 * Start to upload formware : send reset
+	 */
+	value = 1;
+	ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
+
+	if (ret < 0) {
+		uea_err(usb, "modem reset failed with error %d\n", ret);
+		goto err;
+	}
+
+	while (size > 3) {
+		u8 len = FW_GET_BYTE(pfw);
+		u16 add = FW_GET_WORD(pfw + 1);
+
+		size -= len + 3;
+		if (size < 0)
+			goto err_fw_corrupted;
+
+		ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
+		if (ret < 0) {
+			uea_err(usb, "uploading firmware data failed "
+					"with error %d\n", ret);
+			goto err;
+		}
+		pfw += len + 3;
+	}
+
+	if (size != 0)
+		goto err_fw_corrupted;
+
+	/*
+	 * Tell the modem we finish : de-assert reset
+	 */
+	value = 0;
+	ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
+	if (ret < 0)
+		uea_err(usb, "modem de-assert failed with error %d\n", ret);
+	else
+		uea_info(usb, "firmware uploaded\n");
+
+	uea_leaves(usb);
+	return;
+
+err_fw_corrupted:
+	uea_err(usb, "firmware is corrupted\n");
+err:
+	uea_leaves(usb);
+}
+
+/**
+ * uea_load_firmware - Load usb firmware for pre-firmware devices.
+ */
+static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
+{
+	int ret;
+	char *fw_name = FW_DIR "eagle.fw";
+
+	uea_enters(usb);
+	uea_info(usb, "pre-firmware device, uploading firmware\n");
+
+	switch (ver) {
+	case ADI930:
+		fw_name = FW_DIR "adi930.fw";
+		break;
+	case EAGLE_I:
+		fw_name = FW_DIR "eagleI.fw";
+		break;
+	case EAGLE_II:
+		fw_name = FW_DIR "eagleII.fw";
+		break;
+	case EAGLE_III:
+		fw_name = FW_DIR "eagleIII.fw";
+		break;
+	}
+
+	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+	if (ret)
+		uea_err(usb, "firmware %s is not available\n", fw_name);
+	else
+		uea_info(usb, "loading firmware %s\n", fw_name);
+
+	uea_leaves(usb);
+	return ret;
+}
+
+/* modem management : dsp firmware, send/read CMV, monitoring statistic
+ */
+
+/*
+ * Make sure that the DSP code provided is safe to use.
+ */
+static int check_dsp(u8 *dsp, unsigned int len)
+{
+	u8 pagecount, blockcount;
+	u16 blocksize;
+	u32 pageoffset;
+	unsigned int i, j, p, pp;
+
+	pagecount = FW_GET_BYTE(dsp);
+	p = 1;
+
+	/* enough space for page offsets? */
+	if (p + 4 * pagecount > len)
+		return 1;
+
+	for (i = 0; i < pagecount; i++) {
+
+		pageoffset = FW_GET_LONG(dsp + p);
+		p += 4;
+
+		if (pageoffset == 0)
+			continue;
+
+		/* enough space for blockcount? */
+		if (pageoffset >= len)
+			return 1;
+
+		pp = pageoffset;
+		blockcount = FW_GET_BYTE(dsp + pp);
+		pp += 1;
+
+		for (j = 0; j < blockcount; j++) {
+
+			/* enough space for block header? */
+			if (pp + 4 > len)
+				return 1;
+
+			pp += 2;	/* skip blockaddr */
+			blocksize = FW_GET_WORD(dsp + pp);
+			pp += 2;
+
+			/* enough space for block data? */
+			if (pp + blocksize > len)
+				return 1;
+
+			pp += blocksize;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * send data to the idma pipe
+ * */
+static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
+{
+	int ret = -ENOMEM;
+	u8 *xfer_buff;
+	int bytes_read;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (!xfer_buff) {
+		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+		return ret;
+	}
+
+	memcpy(xfer_buff, data, size);
+
+	ret = usb_bulk_msg(sc->usb_dev,
+			 usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
+			 xfer_buff, size, &bytes_read, BULK_TIMEOUT);
+
+	kfree(xfer_buff);
+	if (ret < 0)
+		return ret;
+	if (size != bytes_read) {
+		uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
+		       bytes_read);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int request_dsp(struct uea_softc *sc)
+{
+	int ret;
+	char *dsp_name;
+
+	if (UEA_CHIP_VERSION(sc) == ADI930) {
+		if (IS_ISDN(sc))
+			dsp_name = FW_DIR "DSP9i.bin";
+		else
+			dsp_name = FW_DIR "DSP9p.bin";
+	} else {
+		if (IS_ISDN(sc))
+			dsp_name = FW_DIR "DSPei.bin";
+		else
+			dsp_name = FW_DIR "DSPep.bin";
+	}
+
+	ret = request_firmware(&sc->dsp_firm,
+				dsp_name, &sc->usb_dev->dev);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "requesting firmware %s failed with error %d\n",
+		       dsp_name, ret);
+		return ret;
+	}
+
+	if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       dsp_name);
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
+		return -EILSEQ;
+	}
+
+	return 0;
+}
+
+/*
+ * The uea_load_page() function must be called within a process context
+ */
+static void uea_load_page(void *xsc)
+{
+	struct uea_softc *sc = xsc;
+	u16 pageno = sc->pageno;
+	u16 ovl = sc->ovl;
+	struct block_info bi;
+
+	u8 *p;
+	u8 pagecount, blockcount;
+	u16 blockaddr, blocksize;
+	u32 pageoffset;
+	int i;
+
+	/* reload firmware when reboot start and it's loaded already */
+	if (ovl == 0 && pageno == 0 && sc->dsp_firm) {
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
+	}
+
+	if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
+		return;
+
+	p = sc->dsp_firm->data;
+	pagecount = FW_GET_BYTE(p);
+	p += 1;
+
+	if (pageno >= pagecount)
+		goto bad1;
+
+	p += 4 * pageno;
+	pageoffset = FW_GET_LONG(p);
+
+	if (pageoffset == 0)
+		goto bad1;
+
+	p = sc->dsp_firm->data + pageoffset;
+	blockcount = FW_GET_BYTE(p);
+	p += 1;
+
+	uea_dbg(INS_TO_USBDEV(sc),
+	       "sending %u blocks for DSP page %u\n", blockcount, pageno);
+
+	bi.wHdr = cpu_to_le16(UEA_BIHDR);
+	bi.wOvl = cpu_to_le16(ovl);
+	bi.wOvlOffset = cpu_to_le16(ovl | 0x8000);
+
+	for (i = 0; i < blockcount; i++) {
+		blockaddr = FW_GET_WORD(p);
+		p += 2;
+
+		blocksize = FW_GET_WORD(p);
+		p += 2;
+
+		bi.wSize = cpu_to_le16(blocksize);
+		bi.wAddress = cpu_to_le16(blockaddr);
+		bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0);
+
+		/* send block info through the IDMA pipe */
+		if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE))
+			goto bad2;
+
+		/* send block data through the IDMA pipe */
+		if (uea_idma_write(sc, p, blocksize))
+			goto bad2;
+
+		p += blocksize;
+	}
+
+	return;
+
+bad2:
+	uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i);
+	return;
+bad1:
+	uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno);
+}
+
+static inline void wake_up_cmv_ack(struct uea_softc *sc)
+{
+	sc->cmv_ack = 1;
+	wake_up(&sc->cmv_ack_wait);
+}
+
+static inline int wait_cmv_ack(struct uea_softc *sc)
+{
+	int ret = wait_event_timeout(sc->cmv_ack_wait,
+						   sc->cmv_ack, ACK_TIMEOUT);
+	sc->cmv_ack = 0;
+
+	if (ret < 0)
+		return ret;
+
+	return (ret == 0) ? -ETIMEDOUT : 0;
+
+}
+
+#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
+
+static int uea_request(struct uea_softc *sc,
+		u16 value, u16 index, u16 size, void *data)
+{
+	u8 *xfer_buff;
+	int ret = -ENOMEM;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (!xfer_buff) {
+		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+		return ret;
+	}
+	memcpy(xfer_buff, data, size);
+
+	ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
+			      UCDC_SEND_ENCAPSULATED_COMMAND,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      value, index, xfer_buff, size, CTRL_TIMEOUT);
+
+	kfree(xfer_buff);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);
+		return ret;
+	}
+
+	if (ret != size) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "usb_control_msg send only %d bytes (instead of %d)\n",
+		       ret, size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int uea_cmv(struct uea_softc *sc,
+		u8 function, u32 address, u16 offset, u32 data)
+{
+	struct cmv cmv;
+	int ret;
+
+	/* we send a request, but we expect a reply */
+	sc->cmv_function = function | 0x2;
+	sc->cmv_idx++;
+	sc->cmv_address = address;
+	sc->cmv_offset = offset;
+
+	cmv.wPreamble = cpu_to_le16(PREAMBLE);
+	cmv.bDirection = HOSTTOMODEM;
+	cmv.bFunction = function;
+	cmv.wIndex = cpu_to_le16(sc->cmv_idx);
+	put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress);
+	cmv.wOffsetAddress = cpu_to_le16(offset);
+	put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData);
+
+	ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv);
+	if (ret < 0)
+		return ret;
+	return wait_cmv_ack(sc);
+}
+
+static inline int uea_read_cmv(struct uea_softc *sc,
+		u32 address, u16 offset, u32 *data)
+{
+	int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD),
+			  address, offset, 0);
+	if (ret < 0)
+		uea_err(INS_TO_USBDEV(sc),
+			"reading cmv failed with error %d\n", ret);
+	else
+	 	*data = sc->data;
+
+	return ret;
+}
+
+static inline int uea_write_cmv(struct uea_softc *sc,
+		u32 address, u16 offset, u32 data)
+{
+	int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE),
+			  address, offset, data);
+	if (ret < 0)
+		uea_err(INS_TO_USBDEV(sc),
+			"writing cmv failed with error %d\n", ret);
+
+	return ret;
+}
+
+/*
+ * Monitor the modem and update the stat
+ * return 0 if everything is ok
+ * return < 0 if an error occurs (-EAGAIN reboot needed)
+ */
+static int uea_stat(struct uea_softc *sc)
+{
+	u32 data;
+	int ret;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	data = sc->stats.phy.state;
+
+	ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state);
+	if (ret < 0)
+		return ret;
+
+	switch (GET_STATUS(sc->stats.phy.state)) {
+	case 0:		/* not yet synchronized */
+		uea_dbg(INS_TO_USBDEV(sc),
+		       "modem not yet synchronized\n");
+		return 0;
+
+	case 1:		/* initialization */
+		uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
+		return 0;
+
+	case 2:		/* operational */
+		uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");
+		break;
+
+	case 3:		/* fail ... */
+		uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n");
+		return -EAGAIN;
+
+	case 4 ... 6:	/* test state */
+		uea_warn(INS_TO_USBDEV(sc),
+				"modem in test mode - not supported\n");
+		return -EAGAIN;
+
+	case 7:		/* fast-retain ... */
+		uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");
+		return 0;
+	default:
+		uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",
+			GET_STATUS(sc->stats.phy.state));
+		return -EAGAIN;
+	}
+
+	if (GET_STATUS(data) != 2) {
+		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
+		uea_info(INS_TO_USBDEV(sc), "modem operational\n");
+
+		/* release the dsp firmware as it is not needed until
+		 * the next failure
+		 */
+		if (sc->dsp_firm) {
+			release_firmware(sc->dsp_firm);
+			sc->dsp_firm = NULL;
+		}
+
+		ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
+		if (ret < 0)
+			return ret;
+		uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
+				sc->stats.phy.firmid);
+	}
+
+	/* always update it as atm layer could not be init when we switch to
+	 * operational state
+	 */
+	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);
+
+	/* wake up processes waiting for synchronization */
+	wake_up(&sc->sync_q);
+
+	ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.mflags |= sc->stats.phy.flags;
+
+	/* in case of a flags ( for example delineation LOSS (& 0x10)),
+	 * we check the status again in order to detect the failure earlier
+	 */
+	if (sc->stats.phy.flags) {
+		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n",
+		       sc->stats.phy.flags);
+		return 0;
+	}
+
+	ret = uea_read_cmv(sc, SA_RATE, 0, &data);
+	if (ret < 0)
+		return ret;
+
+	/* in bulk mode the modem have problem with high rate
+	 * changing internal timing could improve things, but the
+	 * value is misterious.
+	 * ADI930 don't support it (-EPIPE error).
+	 */
+	if (UEA_CHIP_VERSION(sc) != ADI930
+		    && sc->stats.phy.dsrate != (data >> 16) * 32) {
+		/* Original timming from ADI(used in windows driver)
+		 * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits
+		 */
+		u16 timeout = (data <= 0x20ffff) ? 0 : 1;
+		ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);
+		uea_info(INS_TO_USBDEV(sc),
+				"setting new timeout %d%s\n", timeout,
+				ret < 0?" failed":"");
+	}
+	sc->stats.phy.dsrate = (data >> 16) * 32;
+	sc->stats.phy.usrate = (data & 0xffff) * 32;
+	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
+
+	ret = uea_read_cmv(sc, SA_DIAG, 23, &data);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.dsattenuation = (data & 0xff) / 2;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 47, &data);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.usattenuation = (data & 0xff) / 2;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc);
+	if (ret < 0)
+		return ret;
+
+	/* only for atu-c */
+	ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr);
+	if (ret < 0)
+		return ret;
+
+	/* only for atu-c */
+	ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int request_cmvs(struct uea_softc *sc,
+		 struct uea_cmvs **cmvs, const struct firmware **fw)
+{
+	int ret, size;
+	u8 *data;
+	char *file;
+	static char cmv_name[256] = FW_DIR;
+
+	if (cmv_file[sc->modem_index] == NULL) {
+		if (UEA_CHIP_VERSION(sc) == ADI930)
+			file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin";
+		else
+			file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin";
+	} else
+		file = cmv_file[sc->modem_index];
+
+	strcpy(cmv_name, FW_DIR);
+	strlcat(cmv_name, file, sizeof(cmv_name));
+
+	ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "requesting firmware %s failed with error %d\n",
+		       cmv_name, ret);
+		return ret;
+	}
+
+	data = (u8 *) (*fw)->data;
+	size = *data * sizeof(struct uea_cmvs) + 1;
+	if (size != (*fw)->size) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       cmv_name);
+		release_firmware(*fw);
+		return -EILSEQ;
+	}
+
+	*cmvs = (struct uea_cmvs *)(data + 1);
+	return *data;
+}
+
+/* Start boot post firmware modem:
+ * - send reset commands through usb control pipe
+ * - start workqueue for DSP loading
+ * - send CMV options to modem
+ */
+
+static int uea_start_reset(struct uea_softc *sc)
+{
+	u16 zero = 0;	/* ;-) */
+	int i, len, ret;
+	struct uea_cmvs *cmvs;
+	const struct firmware *cmvs_fw;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
+
+	sc->booting = 1;
+	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST);
+
+	/* reset statistics */
+	memset(&sc->stats, 0, sizeof(struct uea_stats));
+
+	/* tell the modem that we want to boot in IDMA mode */
+	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+	uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL);
+
+ 	/* enter reset mode */
+	uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL);
+
+	/* original driver use 200ms, but windows driver use 100ms */
+	msleep(100);
+
+	/* leave reset mode */
+	uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL);
+
+ 	/* clear tx and rx mailboxes */
+	uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero);
+	uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero);
+	uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero);
+
+	msleep(1000);
+	sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY);
+	sc->booting = 0;
+
+	/* start loading DSP */
+	sc->pageno = 0;
+	sc->ovl = 0;
+	schedule_work(&sc->task);
+
+	/* wait for modem ready CMV */
+	ret = wait_cmv_ack(sc);
+	if (ret < 0)
+		return ret;
+
+	/* Enter in R-IDLE (cmv) until instructed otherwise */
+	ret = uea_write_cmv(sc, SA_CNTL, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	/* get options */
+ 	ret = len = request_cmvs(sc, &cmvs, &cmvs_fw);
+	if (ret < 0)
+		return ret;
+
+	/* send options */
+	for (i = 0; i < len; i++) {
+		ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address),
+					FW_GET_WORD(&cmvs[i].offset),
+					FW_GET_LONG(&cmvs[i].data));
+		if (ret < 0)
+			goto out;
+	}
+	/* Enter in R-ACT-REQ */
+	ret = uea_write_cmv(sc, SA_CNTL, 0, 2);
+out:
+	release_firmware(cmvs_fw);
+	sc->reset = 0;
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+/*
+ * In case of an error wait 1s before rebooting the modem
+ * if the modem don't request reboot (-EAGAIN).
+ * Monitor the modem every 1s.
+ */
+
+static int uea_kthread(void *data)
+{
+	struct uea_softc *sc = data;
+	int ret = -EAGAIN;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	while (!kthread_should_stop()) {
+		if (ret < 0 || sc->reset)
+			ret = uea_start_reset(sc);
+		if (!ret)
+			ret = uea_stat(sc);
+		if (ret != -EAGAIN)
+			msleep(1000);
+	}
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+/* Load second usb firmware for ADI930 chip */
+static int load_XILINX_firmware(struct uea_softc *sc)
+{
+	const struct firmware *fw_entry;
+	int ret, size, u, ln;
+	u8 *pfw, value;
+	char *fw_name = FW_DIR "930-fpga.bin";
+
+	uea_enters(INS_TO_USBDEV(sc));
+
+	ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
+	if (ret) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
+		       fw_name);
+		goto err0;
+	}
+
+	pfw = fw_entry->data;
+	size = fw_entry->size;
+	if (size != 0x577B) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       fw_name);
+		ret = -EILSEQ;
+		goto err1;
+	}
+	for (u = 0; u < size; u += ln) {
+		ln = min(size - u, 64);
+		ret = uea_request(sc, 0xe, 0, ln, pfw + u);
+		if (ret < 0) {
+			uea_err(INS_TO_USBDEV(sc),
+			       "elsa download data failed (%d)\n", ret);
+			goto err1;
+		}
+	}
+
+	/* finish to send the fpga
+	 */
+	ret = uea_request(sc, 0xe, 1, 0, NULL);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+				"elsa download data failed (%d)\n", ret);
+		goto err1;
+	}
+
+	/*
+	 * Tell the modem we finish : de-assert reset
+	 */
+	value = 0;
+	ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
+	if (ret < 0)
+		uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret);
+
+
+err1:
+	release_firmware(fw_entry);
+err0:
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv)
+{
+	uea_enters(INS_TO_USBDEV(sc));
+	if (le16_to_cpu(cmv->wPreamble) != PREAMBLE)
+		goto bad1;
+
+	if (cmv->bDirection != MODEMTOHOST)
+		goto bad1;
+
+	/* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
+	 * the first MEMACESS cmv. Ignore it...
+	 */
+	if (cmv->bFunction != sc->cmv_function) {
+		if (UEA_CHIP_VERSION(sc) == ADI930
+				&& cmv->bFunction ==  MAKEFUNCTION(2, 2)) {
+			cmv->wIndex = cpu_to_le16(sc->cmv_idx);
+			put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress);
+			cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset);
+		}
+		else
+			goto bad2;
+	}
+
+	if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) {
+		wake_up_cmv_ack(sc);
+		return;
+	}
+
+	/* in case of MEMACCESS */
+	if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx ||
+	    le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) !=
+	    sc->cmv_address
+	    || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset)
+		goto bad2;
+
+	sc->data = le32_to_cpu(get_unaligned(&cmv->dwData));
+	sc->data = sc->data << 16 | sc->data >> 16;
+
+	wake_up_cmv_ack(sc);
+	return;
+
+bad2:
+	uea_err(INS_TO_USBDEV(sc), "unexpected cmv received,"
+			"Function : %d, Subfunction : %d\n",
+			FUNCTION_TYPE(cmv->bFunction),
+			FUNCTION_SUBTYPE(cmv->bFunction));
+	return;
+
+bad1:
+	uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
+			"wPreamble %d, bDirection %d\n",
+			le16_to_cpu(cmv->wPreamble), cmv->bDirection);
+}
+
+/*
+ * interrupt handler
+ */
+static void uea_intr(struct urb *urb, struct pt_regs *regs)
+{
+	struct uea_softc *sc = (struct uea_softc *)urb->context;
+	struct intr_pkt *intr;
+	uea_enters(INS_TO_USBDEV(sc));
+
+	if (urb->status < 0) {
+		uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
+		       urb->status);
+		return;
+	}
+
+	intr = (struct intr_pkt *) urb->transfer_buffer;
+
+	/* device-to-host interrupt */
+	if (intr->bType != 0x08 || sc->booting) {
+		uea_err(INS_TO_USBDEV(sc), "wrong intr\n");
+		// rebooting ?
+		// sc->reset = 1;
+		goto resubmit;
+	}
+
+	switch (le16_to_cpu(intr->wInterrupt)) {
+	case INT_LOADSWAPPAGE:
+		sc->pageno = intr->bSwapPageNo;
+		sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4;
+		schedule_work(&sc->task);
+		break;
+
+	case INT_INCOMINGCMV:
+		uea_dispatch_cmv(sc, &intr->u.s2.cmv);
+		break;
+
+	default:
+		uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n",
+		       le16_to_cpu(intr->wInterrupt));
+	}
+
+resubmit:
+	usb_submit_urb(sc->urb_int, GFP_ATOMIC);
+}
+
+/*
+ * Start the modem : init the data and start kernel thread
+ */
+static int uea_boot(struct uea_softc *sc)
+{
+	int ret;
+	struct intr_pkt *intr;
+
+	uea_enters(INS_TO_USBDEV(sc));
+
+	INIT_WORK(&sc->task, uea_load_page, sc);
+	init_waitqueue_head(&sc->sync_q);
+	init_waitqueue_head(&sc->cmv_ack_wait);
+
+	if (UEA_CHIP_VERSION(sc) == ADI930)
+		load_XILINX_firmware(sc);
+
+	intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL);
+	if (!intr) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "cannot allocate interrupt package\n");
+		uea_leaves(INS_TO_USBDEV(sc));
+		return -ENOMEM;
+	}
+
+	sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);
+	if (!sc->urb_int) {
+		uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n");
+		goto err;
+	}
+
+	usb_fill_int_urb(sc->urb_int, sc->usb_dev,
+			 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
+			 intr, INTR_PKT_SIZE, uea_intr, sc,
+			 sc->usb_dev->actconfig->interface[0]->altsetting[0].
+			 endpoint[0].desc.bInterval);
+
+	ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "urb submition failed with error %d\n", ret);
+		goto err1;
+	}
+
+	sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
+	if (sc->kthread == ERR_PTR(-ENOMEM)) {
+		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+		goto err2;
+	}
+
+	uea_leaves(INS_TO_USBDEV(sc));
+	return 0;
+
+err2:
+	usb_kill_urb(sc->urb_int);
+err1:
+	kfree(intr);
+err:
+	usb_free_urb(sc->urb_int);
+	uea_leaves(INS_TO_USBDEV(sc));
+	return -ENOMEM;
+}
+
+/*
+ * Stop the modem : kill kernel thread and free data
+ */
+static void uea_stop(struct uea_softc *sc)
+{
+	int ret;
+	uea_enters(INS_TO_USBDEV(sc));
+	ret = kthread_stop(sc->kthread);
+	uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
+
+	/* stop any pending boot process */
+	flush_scheduled_work();
+
+	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+
+	usb_kill_urb(sc->urb_int);
+	kfree(sc->urb_int->transfer_buffer);
+	usb_free_urb(sc->urb_int);
+
+	if (sc->dsp_firm)
+		release_firmware(sc->dsp_firm);
+	uea_leaves(INS_TO_USBDEV(sc));
+}
+
+/* syfs interface */
+static struct uea_softc *dev_to_uea(struct device *dev)
+{
+	struct usb_interface *intf;
+	struct usbatm_data *usbatm;
+
+	intf = to_usb_interface(dev);
+	if (!intf)
+		return NULL;
+
+	usbatm = usb_get_intfdata(intf);
+	if (!usbatm)
+		return NULL;
+
+	return usbatm->driver_data;
+}
+
+static ssize_t read_status(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static ssize_t reboot(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+	sc->reset = 1;
+	ret = count;
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+
+static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+
+	switch (GET_STATUS(sc->stats.phy.state)) {
+	case 0:
+		ret = sprintf(buf, "Modem is booting\n");
+		break;
+	case 1:
+		ret = sprintf(buf, "Modem is initializing\n");
+		break;
+	case 2:
+		ret = sprintf(buf, "Modem is operational\n");
+		break;
+	default:
+		ret = sprintf(buf, "Modem synchronization failed\n");
+		break;
+	}
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);
+
+static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+
+	if (sc->stats.phy.flags & 0x0C00)
+		ret = sprintf(buf, "ERROR\n");
+	else if (sc->stats.phy.flags & 0x0030)
+		ret = sprintf(buf, "LOSS\n");
+	else
+		ret = sprintf(buf, "GOOD\n");
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+
+#define UEA_ATTR(name, reset) 					\
+								\
+static ssize_t read_##name(struct device *dev, 			\
+		struct device_attribute *attr, char *buf)	\
+{ 								\
+	int ret = -ENODEV; 					\
+	struct uea_softc *sc; 					\
+ 								\
+	down(&uea_semaphore); 					\
+	sc = dev_to_uea(dev);					\
+	if (!sc) 						\
+		goto out; 					\
+	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name);	\
+	if (reset)						\
+		sc->stats.phy.name = 0;				\
+out: 								\
+	up(&uea_semaphore); 					\
+	return ret; 						\
+} 								\
+								\
+static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL)
+
+UEA_ATTR(mflags, 1);
+UEA_ATTR(vidcpe, 0);
+UEA_ATTR(usrate, 0);
+UEA_ATTR(dsrate, 0);
+UEA_ATTR(usattenuation, 0);
+UEA_ATTR(dsattenuation, 0);
+UEA_ATTR(usmargin, 0);
+UEA_ATTR(dsmargin, 0);
+UEA_ATTR(txflow, 0);
+UEA_ATTR(rxflow, 0);
+UEA_ATTR(uscorr, 0);
+UEA_ATTR(dscorr, 0);
+UEA_ATTR(usunc, 0);
+UEA_ATTR(dsunc, 0);
+
+/* Retrieve the device End System Identifier (MAC) */
+
+#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)
+static int uea_getesi(struct uea_softc *sc, u_char * esi)
+{
+	unsigned char mac_str[2 * ETH_ALEN + 1];
+	int i;
+	if (usb_string
+	    (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,
+	     sizeof(mac_str)) != 2 * ETH_ALEN)
+		return 1;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);
+
+	return 0;
+}
+
+/* ATM stuff */
+static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	return uea_getesi(sc, atm_dev->esi);
+}
+
+static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	wait_event(sc->sync_q, IS_OPERATIONAL(sc));
+
+	return 0;
+
+}
+
+static int claim_interface(struct usb_device *usb_dev,
+			   struct usbatm_data *usbatm, int ifnum)
+{
+	int ret;
+	struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);
+
+	if (!intf) {
+		uea_err(usb_dev, "interface %d not found\n", ifnum);
+		return -ENODEV;
+	}
+
+	ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);
+	if (ret != 0)
+		uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,
+		       ret);
+	return ret;
+}
+
+static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+	/* sysfs interface */
+	device_create_file(&intf->dev, &dev_attr_stat_status);
+	device_create_file(&intf->dev, &dev_attr_stat_mflags);
+	device_create_file(&intf->dev, &dev_attr_stat_human_status);
+	device_create_file(&intf->dev, &dev_attr_stat_delin);
+	device_create_file(&intf->dev, &dev_attr_stat_vidcpe);
+	device_create_file(&intf->dev, &dev_attr_stat_usrate);
+	device_create_file(&intf->dev, &dev_attr_stat_dsrate);
+	device_create_file(&intf->dev, &dev_attr_stat_usattenuation);
+	device_create_file(&intf->dev, &dev_attr_stat_dsattenuation);
+	device_create_file(&intf->dev, &dev_attr_stat_usmargin);
+	device_create_file(&intf->dev, &dev_attr_stat_dsmargin);
+	device_create_file(&intf->dev, &dev_attr_stat_txflow);
+	device_create_file(&intf->dev, &dev_attr_stat_rxflow);
+	device_create_file(&intf->dev, &dev_attr_stat_uscorr);
+	device_create_file(&intf->dev, &dev_attr_stat_dscorr);
+	device_create_file(&intf->dev, &dev_attr_stat_usunc);
+	device_create_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
+		   const struct usb_device_id *id, int *heavy)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+	struct uea_softc *sc;
+	int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
+
+	uea_enters(usb);
+
+	/* interface 0 is for firmware/monitoring */
+	if (ifnum != UEA_INTR_IFACE_NO)
+		return -ENODEV;
+
+	*heavy = sync_wait[modem_index];
+
+	/* interface 1 is for outbound traffic */
+	ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
+	if (ret < 0)
+		return ret;
+
+	/* ADI930 has only 2 interfaces and inbound traffic
+	 * is on interface 1
+	 */
+	if (UEA_CHIP_VERSION(id) != ADI930) {
+		/* interface 2 is for inbound traffic */
+		ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
+		if (ret < 0)
+			return ret;
+	}
+
+	sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
+	if (!sc) {
+		uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n");
+		return -ENOMEM;
+	}
+
+	sc->usb_dev = usb;
+	usbatm->driver_data = sc;
+	sc->usbatm = usbatm;
+	sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
+	sc->driver_info = id->driver_info;
+
+	ret = uea_boot(sc);
+	if (ret < 0) {
+		kfree(sc);
+		return ret;
+	}
+
+	create_fs_entries(sc, intf);
+	return 0;
+}
+
+static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+	/* sysfs interface */
+	device_remove_file(&intf->dev, &dev_attr_stat_status);
+	device_remove_file(&intf->dev, &dev_attr_stat_mflags);
+	device_remove_file(&intf->dev, &dev_attr_stat_human_status);
+	device_remove_file(&intf->dev, &dev_attr_stat_delin);
+	device_remove_file(&intf->dev, &dev_attr_stat_vidcpe);
+	device_remove_file(&intf->dev, &dev_attr_stat_usrate);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsrate);
+	device_remove_file(&intf->dev, &dev_attr_stat_usattenuation);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation);
+	device_remove_file(&intf->dev, &dev_attr_stat_usmargin);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsmargin);
+	device_remove_file(&intf->dev, &dev_attr_stat_txflow);
+	device_remove_file(&intf->dev, &dev_attr_stat_rxflow);
+	device_remove_file(&intf->dev, &dev_attr_stat_uscorr);
+	device_remove_file(&intf->dev, &dev_attr_stat_dscorr);
+	device_remove_file(&intf->dev, &dev_attr_stat_usunc);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	destroy_fs_entries(sc, intf);
+	uea_stop(sc);
+	kfree(sc);
+}
+
+static struct usbatm_driver uea_usbatm_driver = {
+	.driver_name = "ueagle-atm",
+	.owner = THIS_MODULE,
+	.bind = uea_bind,
+	.atm_start = uea_atm_open,
+	.unbind = uea_unbind,
+	.heavy_init = uea_heavy,
+	.in = UEA_BULK_DATA_PIPE,
+	.out = UEA_BULK_DATA_PIPE,
+};
+
+static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+
+	uea_enters(usb);
+	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n",
+	       le16_to_cpu(usb->descriptor.idVendor),
+	       le16_to_cpu(usb->descriptor.idProduct),
+	       chip_name[UEA_CHIP_VERSION(id)]);
+
+	usb_reset_device(usb);
+
+	if (UEA_IS_PREFIRM(id))
+		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
+
+	return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+}
+
+static void uea_disconnect(struct usb_interface *intf)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	uea_enters(usb);
+
+	/* ADI930 has 2 interfaces and eagle 3 interfaces.
+	 * Pre-firmware device has one interface
+	 */
+	if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
+		down(&uea_semaphore);
+		usbatm_usb_disconnect(intf);
+		up(&uea_semaphore);
+		uea_info(usb, "ADSL device removed\n");
+	}
+
+	uea_leaves(usb);
+}
+
+/*
+ * List of supported VID/PID
+ */
+static const struct usb_device_id uea_ids[] = {
+	{USB_DEVICE(ELSA_VID,	ELSA_PID_PREFIRM),	.driver_info = ADI930 | PREFIRM},
+	{USB_DEVICE(ELSA_VID,	ELSA_PID_PSTFIRM),	.driver_info = ADI930 | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_I_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_I_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_II_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_II_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_IIC_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_IIC_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_III_PID_PREFIRM),	.driver_info = EAGLE_III | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_III_PID_PSTFIRM),	.driver_info = EAGLE_III | PSTFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_A_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_A_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_B_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_B_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+	{}
+};
+
+/*
+ * USB driver descriptor
+ */
+static struct usb_driver uea_driver = {
+	.name = "ueagle-atm",
+	.id_table = uea_ids,
+	.probe = uea_probe,
+	.disconnect = uea_disconnect,
+};
+
+MODULE_DEVICE_TABLE(usb, uea_ids);
+
+/**
+ * uea_init - Initialize the module.
+ *      Register to USB subsystem
+ */
+static int __init uea_init(void)
+{
+	printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n");
+
+	usb_register(&uea_driver);
+
+	return 0;
+}
+
+module_init(uea_init);
+
+/**
+ * uea_exit  -  Destroy module
+ *    Deregister with USB subsystem
+ */
+static void __exit uea_exit(void)
+{
+	/*
+	 * This calls automatically the uea_disconnect method if necessary:
+	 */
+	usb_deregister(&uea_driver);
+
+	printk(KERN_INFO "[ueagle-atm] driver unloaded\n");
+}
+
+module_exit(uea_exit);
+
+MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");
+MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 2e6593e..9baa629 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -646,14 +646,14 @@
 	kfree(instance);
 }
 
-void usbatm_get_instance(struct usbatm_data *instance)
+static void usbatm_get_instance(struct usbatm_data *instance)
 {
 	dbg("%s", __func__);
 
 	kref_get(&instance->refcount);
 }
 
-void usbatm_put_instance(struct usbatm_data *instance)
+static void usbatm_put_instance(struct usbatm_data *instance)
 {
 	dbg("%s", __func__);
 
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 7fe7fb4..5c76e3a 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -140,7 +140,6 @@
 }
 
 static struct usb_driver xusbatm_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= xusbatm_driver_name,
 	.probe		= xusbatm_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
index 5085827..3ad9ee8 100644
--- a/drivers/usb/class/audio.c
+++ b/drivers/usb/class/audio.c
@@ -2732,7 +2732,6 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 1b47514..248279e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -6,6 +6,7 @@
  * Copyright (c) 1999 Johannes Erdfelt	<johannes@erdfelt.com>
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
  * Copyright (c) 2004 Oliver Neukum	<oliver@neukum.name>
+ * Copyright (c) 2005 David Kubicek	<dave@awk.cz>
  *
  * USB Abstract Control Model driver for USB modems and ISDN adapters
  *
@@ -29,6 +30,7 @@
  *		config we want, sysadmin changes bConfigurationValue in sysfs.
  *	v0.23 - use softirq for rx processing, as needed by tty layer
  *	v0.24 - change probe method to evaluate CDC union descriptor
+ *	v0.25 - downstream tasks paralelized to maximize throughput
  */
 
 /*
@@ -63,14 +65,15 @@
 #include <linux/usb_cdc.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
+#include <linux/list.h>
 
 #include "cdc-acm.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.23"
-#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
+#define DRIVER_VERSION "v0.25"
+#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
 static struct usb_driver acm_driver;
@@ -284,7 +287,9 @@
 /* data interface returns incoming bytes, or we got unthrottled */
 static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
 {
-	struct acm *acm = urb->context;
+	struct acm_rb *buf;
+	struct acm_ru *rcv = urb->context;
+	struct acm *acm = rcv->instance;
 	dbg("Entering acm_read_bulk with status %d\n", urb->status);
 
 	if (!ACM_READY(acm))
@@ -293,49 +298,109 @@
 	if (urb->status)
 		dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
 
-	/* calling tty_flip_buffer_push() in_irq() isn't allowed */
-	tasklet_schedule(&acm->bh);
+	buf = rcv->buffer;
+	buf->size = urb->actual_length;
+
+	spin_lock(&acm->read_lock);
+	list_add_tail(&rcv->list, &acm->spare_read_urbs);
+	list_add_tail(&buf->list, &acm->filled_read_bufs);
+	spin_unlock(&acm->read_lock);
+
+	tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_rx_tasklet(unsigned long _acm)
 {
 	struct acm *acm = (void *)_acm;
-	struct urb *urb = acm->readurb;
+	struct acm_rb *buf;
 	struct tty_struct *tty = acm->tty;
-	unsigned char *data = urb->transfer_buffer;
+	struct acm_ru *rcv;
+	//unsigned long flags;
 	int i = 0;
 	dbg("Entering acm_rx_tasklet");
 
-	if (urb->actual_length > 0 && !acm->throttle)  {
-		for (i = 0; i < urb->actual_length && !acm->throttle; 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);
-			}
-			tty_insert_flip_char(tty, data[i], 0);
-		}
-		dbg("Handed %d bytes to tty layer", i+1);
-		tty_flip_buffer_push(tty);
+	if (!ACM_READY(acm) || acm->throttle)
+		return;
+
+next_buffer:
+	spin_lock(&acm->read_lock);
+	if (list_empty(&acm->filled_read_bufs)) {
+		spin_unlock(&acm->read_lock);
+		goto urbs;
 	}
+	buf = list_entry(acm->filled_read_bufs.next,
+			 struct acm_rb, list);
+	list_del(&buf->list);
+	spin_unlock(&acm->read_lock);
+
+	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
+
+	for (i = 0; i < buf->size && !acm->throttle; 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);
+ 		}
+		tty_insert_flip_char(tty, buf->base[i], 0);
+ 	}
+	tty_flip_buffer_push(tty);
 
 	spin_lock(&acm->throttle_lock);
 	if (acm->throttle) {
 		dbg("Throtteling noticed");
-		memmove(data, data + i, urb->actual_length - i);
-		urb->actual_length -= i;
-		acm->resubmit_to_unthrottle = 1;
+		memmove(buf->base, buf->base + i, buf->size - i);
+		buf->size -= i;
 		spin_unlock(&acm->throttle_lock);
+		spin_lock(&acm->read_lock);
+		list_add(&buf->list, &acm->filled_read_bufs);
+		spin_unlock(&acm->read_lock);
 		return;
 	}
 	spin_unlock(&acm->throttle_lock);
 
-	urb->actual_length = 0;
-	urb->dev = acm->dev;
+	spin_lock(&acm->read_lock);
+	list_add(&buf->list, &acm->spare_read_bufs);
+	spin_unlock(&acm->read_lock);
+	goto next_buffer;
 
-	i = usb_submit_urb(urb, GFP_ATOMIC);
-	if (i)
-		dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i);
+urbs:
+	while (!list_empty(&acm->spare_read_bufs)) {
+		spin_lock(&acm->read_lock);
+		if (list_empty(&acm->spare_read_urbs)) {
+			spin_unlock(&acm->read_lock);
+			return;
+		}
+		rcv = list_entry(acm->spare_read_urbs.next,
+				 struct acm_ru, list);
+		list_del(&rcv->list);
+		spin_unlock(&acm->read_lock);
+
+		buf = list_entry(acm->spare_read_bufs.next,
+				 struct acm_rb, list);
+		list_del(&buf->list);
+
+		rcv->buffer = buf;
+
+		usb_fill_bulk_urb(rcv->urb, acm->dev,
+				  acm->rx_endpoint,
+				  buf->base,
+				  acm->readsize,
+				  acm_read_bulk, rcv);
+		rcv->urb->transfer_dma = buf->dma;
+		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+		dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
+
+		/* This shouldn't kill the driver as unsuccessful URBs are returned to the
+		   free-urbs-pool and resubmited ASAP */
+		if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
+			list_add(&buf->list, &acm->spare_read_bufs);
+			spin_lock(&acm->read_lock);
+			list_add(&rcv->list, &acm->spare_read_urbs);
+			spin_unlock(&acm->read_lock);
+			return;
+		}
+	}
 }
 
 /* data interface wrote those outgoing bytes */
@@ -369,6 +434,7 @@
 {
 	struct acm *acm;
 	int rv = -EINVAL;
+	int i;
 	dbg("Entering acm_tty_open.\n");
 	
 	down(&open_sem);
@@ -382,7 +448,9 @@
 	tty->driver_data = acm;
 	acm->tty = tty;
 
-
+	/* force low_latency on so that our tty_push actually forces the data through,
+	   otherwise it is scheduled, and with high data rates data can get lost. */
+	tty->low_latency = 1;
 
 	if (acm->used++) {
 		goto done;
@@ -394,18 +462,20 @@
 		goto bail_out;
 	}
 
-	acm->readurb->dev = acm->dev;
-	if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
-		dbg("usb_submit_urb(read bulk) failed");
-		goto bail_out_and_unlink;
-	}
-
 	if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
 		goto full_bailout;
 
-	/* force low_latency on so that our tty_push actually forces the data through, 
-	   otherwise it is scheduled, and with high data rates data can get lost. */
-	tty->low_latency = 1;
+	INIT_LIST_HEAD(&acm->spare_read_urbs);
+	INIT_LIST_HEAD(&acm->spare_read_bufs);
+	INIT_LIST_HEAD(&acm->filled_read_bufs);
+	for (i = 0; i < ACM_NRU; i++) {
+		list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
+	}
+	for (i = 0; i < ACM_NRB; i++) {
+		list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
+	}
+
+	tasklet_schedule(&acm->urb_task);
 
 done:
 err_out:
@@ -413,8 +483,6 @@
 	return rv;
 
 full_bailout:
-	usb_kill_urb(acm->readurb);
-bail_out_and_unlink:
 	usb_kill_urb(acm->ctrlurb);
 bail_out:
 	acm->used--;
@@ -424,18 +492,22 @@
 
 static void acm_tty_unregister(struct acm *acm)
 {
+	int i;
+
 	tty_unregister_device(acm_tty_driver, acm->minor);
 	usb_put_intf(acm->control);
 	acm_table[acm->minor] = NULL;
 	usb_free_urb(acm->ctrlurb);
-	usb_free_urb(acm->readurb);
 	usb_free_urb(acm->writeurb);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_free_urb(acm->ru[i].urb);
 	kfree(acm);
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct acm *acm = tty->driver_data;
+	int i;
 
 	if (!acm || !acm->used)
 		return;
@@ -446,7 +518,8 @@
 			acm_set_control(acm, acm->ctrlout = 0);
 			usb_kill_urb(acm->ctrlurb);
 			usb_kill_urb(acm->writeurb);
-			usb_kill_urb(acm->readurb);
+			for (i = 0; i < ACM_NRU; i++)
+				usb_kill_urb(acm->ru[i].urb);
 		} else
 			acm_tty_unregister(acm);
 	}
@@ -528,10 +601,7 @@
 	spin_lock_bh(&acm->throttle_lock);
 	acm->throttle = 0;
 	spin_unlock_bh(&acm->throttle_lock);
-	if (acm->resubmit_to_unthrottle) {
-		acm->resubmit_to_unthrottle = 0;
-		acm_read_bulk(acm->readurb, NULL);
-	}
+	tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
@@ -588,7 +658,7 @@
 	return -ENOIOCTLCMD;
 }
 
-static __u32 acm_tty_speed[] = {
+static const __u32 acm_tty_speed[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600,
 	1200, 1800, 2400, 4800, 9600, 19200, 38400,
 	57600, 115200, 230400, 460800, 500000, 576000,
@@ -596,7 +666,7 @@
 	2500000, 3000000, 3500000, 4000000
 };
 
-static __u8 acm_tty_size[] = {
+static const __u8 acm_tty_size[] = {
 	5, 6, 7, 8
 };
 
@@ -694,6 +764,7 @@
 	int call_interface_num = -1;
 	int data_interface_num;
 	unsigned long quirks;
+	int i;
 
 	/* handle quirks deadly to normal probing*/
 	quirks = (unsigned long)id->driver_info;
@@ -833,7 +904,7 @@
 	}
 
 	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
-	readsize = le16_to_cpu(epread->wMaxPacketSize);
+	readsize = le16_to_cpu(epread->wMaxPacketSize)*2;
 	acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
 	acm->control = control_interface;
 	acm->data = data_interface;
@@ -842,12 +913,14 @@
 	acm->ctrl_caps = ac_management_function;
 	acm->ctrlsize = ctrlsize;
 	acm->readsize = readsize;
-	acm->bh.func = acm_rx_tasklet;
-	acm->bh.data = (unsigned long) acm;
+	acm->urb_task.func = acm_rx_tasklet;
+	acm->urb_task.data = (unsigned long) acm;
 	INIT_WORK(&acm->work, acm_softint, acm);
 	spin_lock_init(&acm->throttle_lock);
 	spin_lock_init(&acm->write_lock);
+	spin_lock_init(&acm->read_lock);
 	acm->write_ready = 1;
+	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
 
 	buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
 	if (!buf) {
@@ -856,13 +929,6 @@
 	}
 	acm->ctrl_buffer = buf;
 
-	buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma);
-	if (!buf) {
-		dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n");
-		goto alloc_fail3;
-	}
-	acm->read_buffer = buf;
-
 	if (acm_write_buffers_alloc(acm) < 0) {
 		dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
 		goto alloc_fail4;
@@ -873,10 +939,25 @@
 		dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
 		goto alloc_fail5;
 	}
-	acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!acm->readurb) {
-		dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n");
-		goto alloc_fail6;
+	for (i = 0; i < ACM_NRU; i++) {
+		struct acm_ru *rcv = &(acm->ru[i]);
+
+		if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
+			dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
+			goto alloc_fail7;
+		}
+
+		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+		rcv->instance = acm;
+	}
+	for (i = 0; i < ACM_NRB; i++) {
+		struct acm_rb *buf = &(acm->rb[i]);
+
+		// Using usb_buffer_alloc instead of kmalloc as Oliver suggested
+		if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
+			dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+			goto alloc_fail7;
+		}
 	}
 	acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!acm->writeurb) {
@@ -889,15 +970,9 @@
 	acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	acm->ctrlurb->transfer_dma = acm->ctrl_dma;
 
-	usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
-			  acm->read_buffer, readsize, acm_read_bulk, acm);
-	acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-	acm->readurb->transfer_dma = acm->read_dma;
-
 	usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
 			  NULL, acm->writesize, acm_write_bulk, acm);
 	acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-	/* acm->writeurb->transfer_dma = 0; */
 
 	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
@@ -917,14 +992,14 @@
 	return 0;
 
 alloc_fail7:
-	usb_free_urb(acm->readurb);
-alloc_fail6:
+	for (i = 0; i < ACM_NRB; i++)
+		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_free_urb(acm->ru[i].urb);
 	usb_free_urb(acm->ctrlurb);
 alloc_fail5:
 	acm_write_buffers_free(acm);
 alloc_fail4:
-	usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma);
-alloc_fail3:
 	usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
 alloc_fail2:
 	kfree(acm);
@@ -936,6 +1011,7 @@
 {
 	struct acm *acm = usb_get_intfdata (intf);
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	int i;
 
 	if (!acm || !acm->dev) {
 		dbg("disconnect on nonexisting interface");
@@ -946,15 +1022,24 @@
 	acm->dev = NULL;
 	usb_set_intfdata (intf, NULL);
 
+	tasklet_disable(&acm->urb_task);
+
 	usb_kill_urb(acm->ctrlurb);
-	usb_kill_urb(acm->readurb);
 	usb_kill_urb(acm->writeurb);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_kill_urb(acm->ru[i].urb);
+
+	INIT_LIST_HEAD(&acm->filled_read_bufs);
+	INIT_LIST_HEAD(&acm->spare_read_bufs);
+
+	tasklet_enable(&acm->urb_task);
 
 	flush_scheduled_work(); /* wait for acm_softint */
 
 	acm_write_buffers_free(acm);
-	usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma);
 	usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+	for (i = 0; i < ACM_NRB; i++)
+		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
 
 	usb_driver_release_interface(&acm_driver, acm->data);
 
@@ -1003,7 +1088,6 @@
 MODULE_DEVICE_TABLE (usb, acm_ids);
 
 static struct usb_driver acm_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_acm",
 	.probe =	acm_probe,
 	.disconnect =	acm_disconnect,
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 963a5df..fd2aaccd 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -59,6 +59,9 @@
  * when processing onlcr, so we only need 2 buffers.
  */
 #define ACM_NWB  2
+#define ACM_NRU  16
+#define ACM_NRB  16
+
 struct acm_wb {
 	unsigned char *buf;
 	dma_addr_t dmah;
@@ -66,22 +69,43 @@
 	int use;
 };
 
+struct acm_rb {
+	struct list_head	list;
+	int			size;
+	unsigned char		*base;
+	dma_addr_t		dma;
+};
+
+struct acm_ru {
+	struct list_head	list;
+	struct acm_rb		*buffer;
+	struct urb		*urb;
+	struct acm		*instance;
+};
+
 struct acm {
 	struct usb_device *dev;				/* the corresponding usb device */
 	struct usb_interface *control;			/* control interface */
 	struct usb_interface *data;			/* data interface */
 	struct tty_struct *tty;				/* the corresponding tty */
-	struct urb *ctrlurb, *readurb, *writeurb;	/* urbs */
-	u8 *ctrl_buffer, *read_buffer;			/* buffers of urbs */
-	dma_addr_t ctrl_dma, read_dma;			/* dma handles of buffers */
+	struct urb *ctrlurb, *writeurb;			/* urbs */
+	u8 *ctrl_buffer;				/* buffers of urbs */
+	dma_addr_t ctrl_dma;				/* dma handles of buffers */
 	struct acm_wb wb[ACM_NWB];
+	struct acm_ru ru[ACM_NRU];
+	struct acm_rb rb[ACM_NRB];
+	int rx_endpoint;
+	spinlock_t read_lock;
+	struct list_head spare_read_urbs;
+	struct list_head spare_read_bufs;
+	struct list_head filled_read_bufs;
 	int write_current;				/* current write buffer */
 	int write_used;					/* number of non-empty write buffers */
 	int write_ready;				/* write urb is not running */
 	spinlock_t write_lock;
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
-	struct tasklet_struct bh;			/* rx processing */
+	struct tasklet_struct urb_task;                 /* rx processing */
 	spinlock_t throttle_lock;			/* synchronize throtteling and read callback */
 	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */
 	unsigned int ctrlout;				/* output control lines (DTR, RTS) */
@@ -91,7 +115,6 @@
 	unsigned int minor;				/* acm minor number */
 	unsigned char throttle;				/* throttled by tty layer */
 	unsigned char clocal;				/* termios CLOCAL */
-	unsigned char resubmit_to_unthrottle;		/* throtteling has disabled the read urb */
 	unsigned int ctrl_caps;				/* control capabilities from the class specific header */
 };
 
diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
index 5f8af35..f13f004 100644
--- a/drivers/usb/class/usb-midi.c
+++ b/drivers/usb/class/usb-midi.c
@@ -2027,7 +2027,6 @@
 };
 
 static struct usb_driver usb_midi_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"midi",
 	.probe =	usb_midi_probe,
 	.disconnect =	usb_midi_disconnect,
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 38f905d..dba4cc0 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -199,7 +199,7 @@
 #define USBLP_QUIRK_BIDIR	0x1	/* reports bidir but requires unidirectional mode (no INs/reads) */
 #define USBLP_QUIRK_USB_INIT	0x2	/* needs vendor USB init string */
 
-static struct quirk_printer_struct quirk_printers[] = {
+static const struct quirk_printer_struct quirk_printers[] = {
 	{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
 	{ 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
 	{ 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
@@ -301,7 +301,7 @@
  * Get and print printer errors.
  */
 
-static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
+static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
 
 static int usblp_check_status(struct usblp *usblp, int err)
 {
@@ -438,7 +438,7 @@
  			       | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
 }
 
-static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct usblp *usblp = file->private_data;
 	int length, err, i;
@@ -838,7 +838,8 @@
 	.read =		usblp_read,
 	.write =	usblp_write,
 	.poll =		usblp_poll,
-	.ioctl =	usblp_ioctl,
+	.unlocked_ioctl =	usblp_ioctl,
+	.compat_ioctl =		usblp_ioctl,
 	.open =		usblp_open,
 	.release =	usblp_release,
 };
@@ -849,6 +850,20 @@
 	.minor_base =	USBLP_MINOR_BASE,
 };
 
+static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usblp *usblp = usb_get_intfdata (intf);
+
+	if (usblp->device_id_string[0] == 0 &&
+	    usblp->device_id_string[1] == 0)
+		return 0;
+
+	return sprintf(buf, "%s", usblp->device_id_string+2);
+}
+
+static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL);
+
 static int usblp_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
@@ -933,20 +948,12 @@
 
 	/* Retrieve and store the device ID string. */
 	usblp_cache_device_id_string(usblp);
+	device_create_file(&intf->dev, &dev_attr_ieee1284_id);
 
 #ifdef DEBUG
 	usblp_check_status(usblp, 0);
 #endif
 
-	info("usblp%d: USB %sdirectional printer dev %d "
-		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
-		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
-		usblp->ifnum,
-		usblp->protocol[usblp->current_protocol].alt_setting,
-		usblp->current_protocol,
-		le16_to_cpu(usblp->dev->descriptor.idVendor),
-		le16_to_cpu(usblp->dev->descriptor.idProduct));
-
 	usb_set_intfdata (intf, usblp);
 
 	usblp->present = 1;
@@ -957,11 +964,20 @@
 		goto abort_intfdata;
 	}
 	usblp->minor = intf->minor;
+	info("usblp%d: USB %sdirectional printer dev %d "
+		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
+		usblp->ifnum,
+		usblp->protocol[usblp->current_protocol].alt_setting,
+		usblp->current_protocol,
+		le16_to_cpu(usblp->dev->descriptor.idVendor),
+		le16_to_cpu(usblp->dev->descriptor.idProduct));
 
 	return 0;
 
 abort_intfdata:
 	usb_set_intfdata (intf, NULL);
+	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
 	if (usblp) {
 		if (usblp->writebuf)
@@ -1156,6 +1172,8 @@
 		BUG ();
 	}
 
+	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
+
 	down (&usblp_sem);
 	down (&usblp->sem);
 	usblp->present = 0;
@@ -1186,7 +1204,6 @@
 MODULE_DEVICE_TABLE (usb, usblp_ids);
 
 static struct usb_driver usblp_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usblp",
 	.probe =	usblp_probe,
 	.disconnect =	usblp_disconnect,
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 86d5c38..28329dd 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -2,7 +2,7 @@
 # Makefile for USB Core files and filesystem
 #
 
-usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o \
+usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o driver.o \
 			config.o file.o buffer.o sysfs.o devio.o notify.o
 
 ifeq ($(CONFIG_PCI),y)
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 419c994..ad742ce 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -55,6 +55,9 @@
 	char		name [16];
 	int 		i, size;
 
+	if (!hcd->self.controller->dma_mask)
+		return 0;
+
 	for (i = 0; i < HCD_BUFFER_POOLS; i++) { 
 		if (!(size = pool_max [i]))
 			continue;
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 83e815d..2684e15 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -67,45 +67,45 @@
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
 #define ALLOW_SERIAL_NUMBER
 
-static char *format_topo =
+static const char *format_topo =
 /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
 "\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
 
-static char *format_string_manufacturer =
+static const char *format_string_manufacturer =
 /* S:  Manufacturer=xxxx */
   "S:  Manufacturer=%.100s\n";
 
-static char *format_string_product =
+static const char *format_string_product =
 /* S:  Product=xxxx */
   "S:  Product=%.100s\n";
 
 #ifdef ALLOW_SERIAL_NUMBER
-static char *format_string_serialnumber =
+static const char *format_string_serialnumber =
 /* S:  SerialNumber=xxxx */
   "S:  SerialNumber=%.100s\n";
 #endif
 
-static char *format_bandwidth =
+static const char *format_bandwidth =
 /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
   "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
   
-static char *format_device1 =
+static const char *format_device1 =
 /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
   "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
 
-static char *format_device2 =
+static const char *format_device2 =
 /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */
   "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
 
-static char *format_config =
+static const char *format_config =
 /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
   "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
   
-static char *format_iface =
+static const char *format_iface =
 /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
   "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
 
-static char *format_endpt =
+static const char *format_endpt =
 /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
   "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
 
@@ -545,10 +545,10 @@
 		struct usb_device *childdev = usbdev->children[chix];
 
 		if (childdev) {
-			down(&childdev->serialize);
+			usb_lock_device(childdev);
 			ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev,
 					bus, level + 1, chix, ++cnt);
-			up(&childdev->serialize);
+			usb_unlock_device(childdev);
 			if (ret == -EFAULT)
 				return total_written;
 			total_written += ret;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index b1d6e9a..2b68998 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -402,7 +402,6 @@
 }
 
 struct usb_driver usbfs_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbfs",
 	.probe =	driver_probe,
 	.disconnect =	driver_disconnect,
@@ -1350,9 +1349,7 @@
 	/* let kernel drivers try to (re)bind to the interface */
 	case USBDEVFS_CONNECT:
 		usb_unlock_device(ps->dev);
-		usb_lock_all_devices();
 		bus_rescan_devices(intf->dev.bus);
-		usb_unlock_all_devices();
 		usb_lock_device(ps->dev);
 		break;
 
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
new file mode 100644
index 0000000..076462c
--- /dev/null
+++ b/drivers/usb/core/driver.c
@@ -0,0 +1,472 @@
+/*
+ * drivers/usb/driver.c - most of the driver model stuff for usb
+ *
+ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * based on drivers/usb/usb.c which had the following copyrights:
+ *	(C) Copyright Linus Torvalds 1999
+ *	(C) Copyright Johannes Erdfelt 1999-2001
+ *	(C) Copyright Andreas Gal 1999
+ *	(C) Copyright Gregory P. Smith 1999
+ *	(C) Copyright Deti Fliegl 1999 (new USB architecture)
+ *	(C) Copyright Randy Dunlap 2000
+ *	(C) Copyright David Brownell 2000-2004
+ *	(C) Copyright Yggdrasil Computing, Inc. 2000
+ *		(usb_device_id matching changes by Adam J. Richter)
+ *	(C) Copyright Greg Kroah-Hartman 2002-2003
+ *
+ * NOTE! This is not actually a driver at all, rather this is
+ * just a collection of helper routines that implement the
+ * generic USB things that the real drivers can use..
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/device.h>
+#include <linux/usb.h>
+#include "hcd.h"
+#include "usb.h"
+
+static int usb_match_one_id(struct usb_interface *interface,
+			    const struct usb_device_id *id);
+
+struct usb_dynid {
+	struct list_head node;
+	struct usb_device_id id;
+};
+
+
+static int generic_probe(struct device *dev)
+{
+	return 0;
+}
+static int generic_remove(struct device *dev)
+{
+	struct usb_device *udev = to_usb_device(dev);
+
+	/* if this is only an unbind, not a physical disconnect, then
+	 * unconfigure the device */
+	if (udev->state == USB_STATE_CONFIGURED)
+		usb_set_configuration(udev, 0);
+
+	/* in case the call failed or the device was suspended */
+	if (udev->state >= USB_STATE_CONFIGURED)
+		usb_disable_device(udev, 0);
+	return 0;
+}
+
+struct device_driver usb_generic_driver = {
+	.owner = THIS_MODULE,
+	.name =	"usb",
+	.bus = &usb_bus_type,
+	.probe = generic_probe,
+	.remove = generic_remove,
+};
+
+/* Fun hack to determine if the struct device is a
+ * usb device or a usb interface. */
+int usb_generic_driver_data;
+
+#ifdef CONFIG_HOTPLUG
+
+/*
+ * Adds a new dynamic USBdevice ID to this driver,
+ * and cause the driver to probe for all devices again.
+ */
+static ssize_t store_new_id(struct device_driver *driver,
+			    const char *buf, size_t count)
+{
+	struct usb_driver *usb_drv = to_usb_driver(driver);
+	struct usb_dynid *dynid;
+	u32 idVendor = 0;
+	u32 idProduct = 0;
+	int fields = 0;
+
+	fields = sscanf(buf, "%x %x", &idVendor, &idProduct);
+	if (fields < 2)
+		return -EINVAL;
+
+	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
+	if (!dynid)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&dynid->node);
+	dynid->id.idVendor = idVendor;
+	dynid->id.idProduct = idProduct;
+	dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+
+	spin_lock(&usb_drv->dynids.lock);
+	list_add_tail(&usb_drv->dynids.list, &dynid->node);
+	spin_unlock(&usb_drv->dynids.lock);
+
+	if (get_driver(driver)) {
+		driver_attach(driver);
+		put_driver(driver);
+	}
+
+	return count;
+}
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+
+static int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+	int error = 0;
+
+	if (usb_drv->no_dynamic_id)
+		goto exit;
+
+	if (usb_drv->probe != NULL)
+		error = sysfs_create_file(&usb_drv->driver.kobj,
+					  &driver_attr_new_id.attr);
+exit:
+	return error;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+	if (usb_drv->no_dynamic_id)
+		return;
+
+	if (usb_drv->probe != NULL)
+		sysfs_remove_file(&usb_drv->driver.kobj,
+				  &driver_attr_new_id.attr);
+}
+
+static void usb_free_dynids(struct usb_driver *usb_drv)
+{
+	struct usb_dynid *dynid, *n;
+
+	spin_lock(&usb_drv->dynids.lock);
+	list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) {
+		list_del(&dynid->node);
+		kfree(dynid);
+	}
+	spin_unlock(&usb_drv->dynids.lock);
+}
+#else
+static inline int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+	return 0;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+}
+
+static inline void usb_free_dynids(struct usb_driver *usb_drv)
+{
+}
+#endif
+
+static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
+							struct usb_driver *drv)
+{
+	struct usb_dynid *dynid;
+
+	spin_lock(&drv->dynids.lock);
+	list_for_each_entry(dynid, &drv->dynids.list, node) {
+		if (usb_match_one_id(intf, &dynid->id)) {
+			spin_unlock(&drv->dynids.lock);
+			return &dynid->id;
+		}
+	}
+	spin_unlock(&drv->dynids.lock);
+	return NULL;
+}
+
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_probe_interface(struct device *dev)
+{
+	struct usb_interface * intf = to_usb_interface(dev);
+	struct usb_driver * driver = to_usb_driver(dev->driver);
+	const struct usb_device_id *id;
+	int error = -ENODEV;
+
+	dev_dbg(dev, "%s\n", __FUNCTION__);
+
+	if (!driver->probe)
+		return error;
+	/* FIXME we'd much prefer to just resume it ... */
+	if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
+		return -EHOSTUNREACH;
+
+	id = usb_match_id(intf, driver->id_table);
+	if (!id)
+		id = usb_match_dynamic_id(intf, driver);
+	if (id) {
+		dev_dbg(dev, "%s - got id\n", __FUNCTION__);
+
+		/* Interface "power state" doesn't correspond to any hardware
+		 * state whatsoever.  We use it to record when it's bound to
+		 * a driver that may start I/0:  it's not frozen/quiesced.
+		 */
+		mark_active(intf);
+		intf->condition = USB_INTERFACE_BINDING;
+		error = driver->probe(intf, id);
+		if (error) {
+			mark_quiesced(intf);
+			intf->condition = USB_INTERFACE_UNBOUND;
+		} else
+			intf->condition = USB_INTERFACE_BOUND;
+	}
+
+	return error;
+}
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_unbind_interface(struct device *dev)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usb_driver *driver = to_usb_driver(intf->dev.driver);
+
+	intf->condition = USB_INTERFACE_UNBINDING;
+
+	/* release all urbs for this interface */
+	usb_disable_interface(interface_to_usbdev(intf), intf);
+
+	if (driver && driver->disconnect)
+		driver->disconnect(intf);
+
+	/* reset other interface state */
+	usb_set_interface(interface_to_usbdev(intf),
+			intf->altsetting[0].desc.bInterfaceNumber,
+			0);
+	usb_set_intfdata(intf, NULL);
+	intf->condition = USB_INTERFACE_UNBOUND;
+	mark_quiesced(intf);
+
+	return 0;
+}
+
+/* returns 0 if no match, 1 if match */
+static int usb_match_one_id(struct usb_interface *interface,
+			    const struct usb_device_id *id)
+{
+	struct usb_host_interface *intf;
+	struct usb_device *dev;
+
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return 0;
+
+	intf = interface->cur_altsetting;
+	dev = interface_to_usbdev(interface);
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+	    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+	    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
+		return 0;
+
+	/* 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 > le16_to_cpu(dev->descriptor.bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+	    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+	    (id->bDeviceClass != dev->descriptor.bDeviceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+	    (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+	    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+	    (id->bInterfaceClass != intf->desc.bInterfaceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+	    (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+	    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
+		return 0;
+
+	return 1;
+}
+/**
+ * usb_match_id - find first usb_device_id matching device or interface
+ * @interface: the interface of interest
+ * @id: array of usb_device_id structures, terminated by zero entry
+ *
+ * usb_match_id searches an array of usb_device_id's and returns
+ * the first one matching the device or interface, or null.
+ * This is used when binding (or rebinding) a driver to an interface.
+ * Most USB device drivers will use this indirectly, through the usb core,
+ * but some layered driver frameworks use it directly.
+ * These device tables are exported with MODULE_DEVICE_TABLE, through
+ * modutils, to support the driver loading functionality of USB hotplugging.
+ *
+ * What Matches:
+ *
+ * The "match_flags" element in a usb_device_id controls which
+ * members are used.  If the corresponding bit is set, the
+ * value in the device_id must match its corresponding member
+ * in the device or interface descriptor, or else the device_id
+ * does not match.
+ *
+ * "driver_info" is normally used only by device drivers,
+ * but you can create a wildcard "matches anything" usb_device_id
+ * as a driver's "modules.usbmap" entry if you provide an id with
+ * only a nonzero "driver_info" field.  If you do this, the USB device
+ * driver's probe() routine should use additional intelligence to
+ * decide whether to bind to the specified interface.
+ *
+ * What Makes Good usb_device_id Tables:
+ *
+ * The match algorithm is very simple, so that intelligence in
+ * driver selection must come from smart driver id records.
+ * Unless you have good reasons to use another selection policy,
+ * provide match elements only in related groups, and order match
+ * specifiers from specific to general.  Use the macros provided
+ * for that purpose if you can.
+ *
+ * The most specific match specifiers use device descriptor
+ * data.  These are commonly used with product-specific matches;
+ * the USB_DEVICE macro lets you provide vendor and product IDs,
+ * and you can also match against ranges of product revisions.
+ * These are widely used for devices with application or vendor
+ * specific bDeviceClass values.
+ *
+ * Matches based on device class/subclass/protocol specifications
+ * are slightly more general; use the USB_DEVICE_INFO macro, or
+ * its siblings.  These are used with single-function devices
+ * where bDeviceClass doesn't specify that each interface has
+ * its own class.
+ *
+ * Matches based on interface class/subclass/protocol are the
+ * most general; they let drivers bind to any interface on a
+ * multiple-function device.  Use the USB_INTERFACE_INFO
+ * macro, or its siblings, to match class-per-interface style
+ * devices (as recorded in bDeviceClass).
+ *
+ * Within those groups, remember that not all combinations are
+ * meaningful.  For example, don't give a product version range
+ * without vendor and product IDs; or specify a protocol without
+ * its associated class and subclass.
+ */
+const struct usb_device_id *usb_match_id(struct usb_interface *interface,
+					 const struct usb_device_id *id)
+{
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return NULL;
+
+	/* It is important to check that id->driver_info is nonzero,
+	   since an entry that is all zeroes except for a nonzero
+	   id->driver_info is the way to create an entry that
+	   indicates that the driver want to examine every
+	   device and interface. */
+	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+	       id->driver_info; id++) {
+		if (usb_match_one_id(interface, id))
+			return id;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(usb_match_id);
+
+int usb_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct usb_interface *intf;
+	struct usb_driver *usb_drv;
+	const struct usb_device_id *id;
+
+	/* check for generic driver, which we don't match any device with */
+	if (drv == &usb_generic_driver)
+		return 0;
+
+	intf = to_usb_interface(dev);
+	usb_drv = to_usb_driver(drv);
+
+	id = usb_match_id(intf, usb_drv->id_table);
+	if (id)
+		return 1;
+
+	id = usb_match_dynamic_id(intf, usb_drv);
+	if (id)
+		return 1;
+	return 0;
+}
+
+/**
+ * usb_register_driver - register a USB driver
+ * @new_driver: USB operations for the driver
+ * @owner: module owner of this driver.
+ *
+ * Registers a USB driver with the USB core.  The list of unattached
+ * interfaces will be rescanned whenever a new driver is added, allowing
+ * the new driver to attach to any recognized devices.
+ * Returns a negative error code on failure and 0 on success.
+ *
+ * NOTE: if you want your driver to use the USB major number, you must call
+ * usb_register_dev() to enable that functionality.  This function no longer
+ * takes care of that.
+ */
+int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
+{
+	int retval = 0;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	new_driver->driver.name = (char *)new_driver->name;
+	new_driver->driver.bus = &usb_bus_type;
+	new_driver->driver.probe = usb_probe_interface;
+	new_driver->driver.remove = usb_unbind_interface;
+	new_driver->driver.owner = owner;
+	spin_lock_init(&new_driver->dynids.lock);
+	INIT_LIST_HEAD(&new_driver->dynids.list);
+
+	retval = driver_register(&new_driver->driver);
+
+	if (!retval) {
+		pr_info("%s: registered new driver %s\n",
+			usbcore_name, new_driver->name);
+		usbfs_update_special();
+		usb_create_newid_file(new_driver);
+	} else {
+		printk(KERN_ERR "%s: error %d registering driver %s\n",
+			usbcore_name, retval, new_driver->name);
+	}
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(usb_register_driver);
+
+/**
+ * usb_deregister - unregister a USB driver
+ * @driver: USB operations of the driver to unregister
+ * Context: must be able to sleep
+ *
+ * Unlinks the specified driver from the internal USB driver list.
+ *
+ * NOTE: If you called usb_register_dev(), you still need to call
+ * usb_deregister_dev() to clean up your driver's allocated minor numbers,
+ * this * call will no longer do it for you.
+ */
+void usb_deregister(struct usb_driver *driver)
+{
+	pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
+
+	usb_remove_newid_file(driver);
+	usb_free_dynids(driver);
+	driver_unregister(&driver->driver);
+
+	usbfs_update_special();
+}
+EXPORT_SYMBOL_GPL(usb_deregister);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index da24c31..0018bbc 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -857,9 +857,7 @@
 		return (retval < 0) ? retval : -EMSGSIZE;
 	}
 
-	usb_lock_device (usb_dev);
 	retval = usb_new_device (usb_dev);
-	usb_unlock_device (usb_dev);
 	if (retval) {
 		usb_dev->bus->root_hub = NULL;
 		dev_err (parent_dev, "can't register root hub for %s, %d\n",
@@ -1827,8 +1825,6 @@
 		retval = -ENOMEM;
 		goto err_allocate_root_hub;
 	}
-	rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-			USB_SPEED_FULL;
 
 	/* Although in principle hcd->driver->start() might need to use rhdev,
 	 * none of the current drivers do.
@@ -1846,6 +1842,9 @@
 		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
 	hcd->remote_wakeup = hcd->can_wakeup;
 
+	rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
+			USB_SPEED_FULL;
+	rhdev->bus_mA = min(500u, hcd->power_budget);
 	if ((retval = register_root_hub(rhdev, hcd)) != 0)
 		goto err_register_root_hub;
 
@@ -1891,7 +1890,10 @@
 	spin_lock_irq (&hcd_root_hub_lock);
 	hcd->rh_registered = 0;
 	spin_unlock_irq (&hcd_root_hub_lock);
+
+	down(&usb_bus_list_lock);
 	usb_disconnect(&hcd->self.root_hub);
+	up(&usb_bus_list_lock);
 
 	hcd->poll_rh = 0;
 	del_timer_sync(&hcd->rh_timer);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index c8a1b35..591b5aa 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -380,6 +380,7 @@
 #ifdef CONFIG_PM
 extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd);
 extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
+extern void usb_root_hub_lost_power (struct usb_device *rhdev);
 extern int hcd_bus_suspend (struct usb_bus *bus);
 extern int hcd_bus_resume (struct usb_bus *bus);
 #else
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f78bd12..650d5ee 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -32,7 +32,7 @@
 #include "hub.h"
 
 /* Protect struct usb_device->state and ->children members
- * Note: Both are also protected by ->serialize, except that ->state can
+ * Note: Both are also protected by ->dev.sem, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
 static DEFINE_SPINLOCK(device_state_lock);
 
@@ -515,6 +515,31 @@
 	return ret;
 }
 
+
+/* caller has locked the hub device */
+static void hub_pre_reset(struct usb_hub *hub, int disable_ports)
+{
+	struct usb_device *hdev = hub->hdev;
+	int port1;
+
+	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+		if (hdev->children[port1 - 1]) {
+			usb_disconnect(&hdev->children[port1 - 1]);
+			if (disable_ports)
+				hub_port_disable(hub, port1, 0);
+		}
+	}
+	hub_quiesce(hub);
+}
+
+/* caller has locked the hub device */
+static void hub_post_reset(struct usb_hub *hub)
+{
+	hub_activate(hub);
+	hub_power_on(hub);
+}
+
+
 static int hub_configure(struct usb_hub *hub,
 	struct usb_endpoint_descriptor *endpoint)
 {
@@ -677,26 +702,40 @@
 	 * and battery-powered root hubs (may provide just 8 mA).
 	 */
 	ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);
-	if (ret < 0) {
+	if (ret < 2) {
 		message = "can't get hub status";
 		goto fail;
 	}
 	le16_to_cpus(&hubstatus);
 	if (hdev == hdev->bus->root_hub) {
-		struct usb_hcd *hcd =
-				container_of(hdev->bus, struct usb_hcd, self);
-
-		hub->power_budget = min(500u, hcd->power_budget) / 2;
+		if (hdev->bus_mA == 0 || hdev->bus_mA >= 500)
+			hub->mA_per_port = 500;
+		else {
+			hub->mA_per_port = hdev->bus_mA;
+			hub->limited_power = 1;
+		}
 	} else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
 		dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
 			hub->descriptor->bHubContrCurrent);
-		hub->power_budget = (501 - hub->descriptor->bHubContrCurrent)
-					/ 2;
-	}
-	if (hub->power_budget)
-		dev_dbg(hub_dev, "%dmA bus power budget for children\n",
-			hub->power_budget * 2);
+		hub->limited_power = 1;
+		if (hdev->maxchild > 0) {
+			int remaining = hdev->bus_mA -
+					hub->descriptor->bHubContrCurrent;
 
+			if (remaining < hdev->maxchild * 100)
+				dev_warn(hub_dev,
+					"insufficient power available "
+					"to use all downstream ports\n");
+			hub->mA_per_port = 100;		/* 7.2.1.1 */
+		}
+	} else {	/* Self-powered external hub */
+		/* FIXME: What about battery-powered external hubs that
+		 * provide less current per port? */
+		hub->mA_per_port = 500;
+	}
+	if (hub->mA_per_port < 500)
+		dev_dbg(hub_dev, "%umA bus power budget for each child\n",
+				hub->mA_per_port);
 
 	ret = hub_hub_status(hub, &hubstatus, &hubchange);
 	if (ret < 0) {
@@ -750,29 +789,10 @@
 
 static unsigned highspeed_hubs;
 
-/* Called after the hub driver is unbound from a hub with children */
-static void hub_remove_children_work(void *__hub)
-{
-	struct usb_hub		*hub = __hub;
-	struct usb_device	*hdev = hub->hdev;
-	int			i;
-
-	kfree(hub);
-
-	usb_lock_device(hdev);
-	for (i = 0; i < hdev->maxchild; ++i) {
-		if (hdev->children[i])
-			usb_disconnect(&hdev->children[i]);
-	}
-	usb_unlock_device(hdev);
-	usb_put_dev(hdev);
-}
-
 static void hub_disconnect(struct usb_interface *intf)
 {
 	struct usb_hub *hub = usb_get_intfdata (intf);
 	struct usb_device *hdev;
-	int n, port1;
 
 	usb_set_intfdata (intf, NULL);
 	hdev = hub->hdev;
@@ -780,7 +800,9 @@
 	if (hdev->speed == USB_SPEED_HIGH)
 		highspeed_hubs--;
 
-	hub_quiesce(hub);
+	/* Disconnect all children and quiesce the hub */
+	hub_pre_reset(hub, 1);
+
 	usb_free_urb(hub->urb);
 	hub->urb = NULL;
 
@@ -800,27 +822,7 @@
 		hub->buffer = NULL;
 	}
 
-	/* If there are any children then this is an unbind only, not a
-	 * physical disconnection.  The active ports must be disabled
-	 * and later on we must call usb_disconnect().  We can't call
-	 * it now because we may not hold the hub's device lock.
-	 */
-	n = 0;
-	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-		if (hdev->children[port1 - 1]) {
-			++n;
-			hub_port_disable(hub, port1, 1);
-		}
-	}
-
-	if (n == 0)
-		kfree(hub);
-	else {
-		/* Reuse the hub->leds work_struct for our own purposes */
-		INIT_WORK(&hub->leds, hub_remove_children_work, hub);
-		schedule_work(&hub->leds);
-		usb_get_dev(hdev);
-	}
+	kfree(hub);
 }
 
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -917,26 +919,6 @@
 	}
 }
 
-/* caller has locked the hub device */
-static void hub_pre_reset(struct usb_hub *hub)
-{
-	struct usb_device *hdev = hub->hdev;
-	int i;
-
-	for (i = 0; i < hdev->maxchild; ++i) {
-		if (hdev->children[i])
-			usb_disconnect(&hdev->children[i]);
-	}
-	hub_quiesce(hub);
-}
-
-/* caller has locked the hub device */
-static void hub_post_reset(struct usb_hub *hub)
-{
-	hub_activate(hub);
-	hub_power_on(hub);
-}
-
 
 /* grab device/port lock, returning index of that port (zero based).
  * protects the upstream link used by this device from concurrent
@@ -964,24 +946,21 @@
 	t = locktree(hdev);
 	if (t < 0)
 		return t;
-	for (t = 0; t < hdev->maxchild; t++) {
-		if (hdev->children[t] == udev) {
-			/* everything is fail-fast once disconnect
-			 * processing starts
-			 */
-			if (udev->state == USB_STATE_NOTATTACHED)
-				break;
 
-			/* when everyone grabs locks top->bottom,
-			 * non-overlapping work may be concurrent
-			 */
-			down(&udev->serialize);
-			up(&hdev->serialize);
-			return t + 1;
-		}
+	/* everything is fail-fast once disconnect
+	 * processing starts
+	 */
+	if (udev->state == USB_STATE_NOTATTACHED) {
+		usb_unlock_device(hdev);
+		return -ENODEV;
 	}
+
+	/* when everyone grabs locks top->bottom,
+	 * non-overlapping work may be concurrent
+	 */
+	usb_lock_device(udev);
 	usb_unlock_device(hdev);
-	return -ENODEV;
+	return udev->portnum;
 }
 
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
@@ -1039,6 +1018,39 @@
 EXPORT_SYMBOL(usb_set_device_state);
 
 
+#ifdef CONFIG_PM
+
+/**
+ * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power
+ * @rhdev: struct usb_device for the root hub
+ *
+ * The USB host controller driver calls this function when its root hub
+ * is resumed and Vbus power has been interrupted or the controller
+ * has been reset.  The routine marks all the children of the root hub
+ * as NOTATTACHED and marks logical connect-change events on their ports.
+ */
+void usb_root_hub_lost_power(struct usb_device *rhdev)
+{
+	struct usb_hub *hub;
+	int port1;
+	unsigned long flags;
+
+	dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
+	spin_lock_irqsave(&device_state_lock, flags);
+	hub = hdev_to_hub(rhdev);
+	for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {
+		if (rhdev->children[port1 - 1]) {
+			recursively_mark_NOTATTACHED(
+					rhdev->children[port1 - 1]);
+			set_bit(port1, hub->change_bits);
+		}
+	}
+	spin_unlock_irqrestore(&device_state_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);
+
+#endif
+
 static void choose_address(struct usb_device *udev)
 {
 	int		devnum;
@@ -1099,16 +1111,10 @@
 	 * this quiesces everyting except pending urbs.
 	 */
 	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
-
-	/* lock the bus list on behalf of HCDs unregistering their root hubs */
-	if (!udev->parent) {
-		down(&usb_bus_list_lock);
-		usb_lock_device(udev);
-	} else
-		down(&udev->serialize);
-
 	dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
 
+	usb_lock_device(udev);
+
 	/* Free up all the children before we remove this device */
 	for (i = 0; i < USB_MAXCHILDREN; i++) {
 		if (udev->children[i])
@@ -1136,54 +1142,112 @@
 	*pdev = NULL;
 	spin_unlock_irq(&device_state_lock);
 
-	if (!udev->parent) {
-		usb_unlock_device(udev);
-		up(&usb_bus_list_lock);
-	} else
-		up(&udev->serialize);
+	usb_unlock_device(udev);
 
 	device_unregister(&udev->dev);
 }
 
+static inline const char *plural(int n)
+{
+	return (n == 1 ? "" : "s");
+}
+
 static int choose_configuration(struct usb_device *udev)
 {
-	int c, i;
+	int i;
+	u16 devstatus;
+	int bus_powered;
+	int num_configs;
+	struct usb_host_config *c, *best;
 
-	/* NOTE: this should interact with hub power budgeting */
+	/* If this fails, assume the device is bus-powered */
+	devstatus = 0;
+	usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
+	le16_to_cpus(&devstatus);
+	bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0);
+	dev_dbg(&udev->dev, "device is %s-powered\n",
+			bus_powered ? "bus" : "self");
 
-	c = udev->config[0].desc.bConfigurationValue;
-	if (udev->descriptor.bNumConfigurations != 1) {
-		for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
-			struct usb_interface_descriptor	*desc;
+	best = NULL;
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc =
+				&c->intf_cache[0]->altsetting->desc;
 
-			/* heuristic:  Linux is more likely to have class
-			 * drivers, so avoid vendor-specific interfaces.
-			 */
-			desc = &udev->config[i].intf_cache[0]
-					->altsetting->desc;
-			if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
-				continue;
-			/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS.
-			 * MSFT needs this to be the first config; never use
-			 * it as the default unless Linux has host-side RNDIS.
-			 * A second config would ideally be CDC-Ethernet, but
-			 * may instead be the "vendor specific" CDC subset
-			 * long used by ARM Linux for sa1100 or pxa255.
-			 */
-			if (desc->bInterfaceClass == USB_CLASS_COMM
-					&& desc->bInterfaceSubClass == 2
-					&& desc->bInterfaceProtocol == 0xff) {
-				c = udev->config[1].desc.bConfigurationValue;
-				continue;
-			}
-			c = udev->config[i].desc.bConfigurationValue;
+		/*
+		 * HP's USB bus-powered keyboard has only one configuration
+		 * and it claims to be self-powered; other devices may have
+		 * similar errors in their descriptors.  If the next test
+		 * were allowed to execute, such configurations would always
+		 * be rejected and the devices would not work as expected.
+		 */
+#if 0
+		/* Rule out self-powered configs for a bus-powered device */
+		if (bus_powered && (c->desc.bmAttributes &
+					USB_CONFIG_ATT_SELFPOWER))
+			continue;
+#endif
+
+		/*
+		 * The next test may not be as effective as it should be.
+		 * Some hubs have errors in their descriptor, claiming
+		 * to be self-powered when they are really bus-powered.
+		 * We will overestimate the amount of current such hubs
+		 * make available for each port.
+		 *
+		 * This is a fairly benign sort of failure.  It won't
+		 * cause us to reject configurations that we should have
+		 * accepted.
+		 */
+
+		/* Rule out configs that draw too much bus current */
+		if (c->desc.bMaxPower * 2 > udev->bus_mA)
+			continue;
+
+		/* If the first config's first interface is COMM/2/0xff
+		 * (MSFT RNDIS), rule it out unless Linux has host-side
+		 * RNDIS support. */
+		if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM
+				&& desc->bInterfaceSubClass == 2
+				&& desc->bInterfaceProtocol == 0xff) {
+#ifndef CONFIG_USB_NET_RNDIS
+			continue;
+#else
+			best = c;
+#endif
+		}
+
+		/* From the remaining configs, choose the first one whose
+		 * first interface is for a non-vendor-specific class.
+		 * Reason: Linux is more likely to have a class driver
+		 * than a vendor-specific driver. */
+		else if (udev->descriptor.bDeviceClass !=
+						USB_CLASS_VENDOR_SPEC &&
+				desc->bInterfaceClass !=
+						USB_CLASS_VENDOR_SPEC) {
+			best = c;
 			break;
 		}
-		dev_info(&udev->dev,
-			"configuration #%d chosen from %d choices\n",
-			c, udev->descriptor.bNumConfigurations);
+
+		/* If all the remaining configs are vendor-specific,
+		 * choose the first one. */
+		else if (!best)
+			best = c;
 	}
-	return c;
+
+	if (best) {
+		i = best->desc.bConfigurationValue;
+		dev_info(&udev->dev,
+			"configuration #%d chosen from %d choice%s\n",
+			i, num_configs, plural(num_configs));
+	} else {
+		i = -1;
+		dev_warn(&udev->dev,
+			"no configuration chosen from %d choice%s\n",
+			num_configs, plural(num_configs));
+	}
+	return i;
 }
 
 #ifdef DEBUG
@@ -1210,8 +1274,8 @@
  *
  * This is called with devices which have been enumerated, but not yet
  * configured.  The device descriptor is available, but not descriptors
- * for any device configuration.  The caller must have locked udev and
- * either the parent hub (if udev is a normal device) or else the
+ * for any device configuration.  The caller must have locked either
+ * the parent hub (if udev is a normal device) or else the
  * usb_bus_list_lock (if udev is a root hub).  The parent's pointer to
  * udev has already been installed, but udev is not yet visible through
  * sysfs or other filesystem code.
@@ -1221,8 +1285,7 @@
  *
  * This call is synchronous, and may not be used in an interrupt context.
  *
- * Only the hub driver should ever call this; root hub registration
- * uses it indirectly.
+ * Only the hub driver or root-hub registrar should ever call this.
  */
 int usb_new_device(struct usb_device *udev)
 {
@@ -1269,15 +1332,9 @@
 					le16_to_cpu(udev->config[0].desc.wTotalLength),
 					USB_DT_OTG, (void **) &desc) == 0) {
 			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port1;
+				unsigned		port1 = udev->portnum;
 				struct usb_device	*root = udev->parent;
 				
-				for (port1 = 1; port1 <= root->maxchild;
-						port1++) {
-					if (root->children[port1-1] == udev)
-						break;
-				}
-
 				dev_info(&udev->dev,
 					"Dual-Role OTG device on %sHNP port\n",
 					(port1 == bus->otg_port)
@@ -1331,27 +1388,27 @@
 	}
 	usb_create_sysfs_dev_files (udev);
 
+	usb_lock_device(udev);
+
 	/* choose and set the configuration. that registers the interfaces
 	 * with the driver core, and lets usb device drivers bind to them.
 	 */
 	c = choose_configuration(udev);
-	if (c < 0)
-		dev_warn(&udev->dev,
-				"can't choose an initial configuration\n");
-	else {
+	if (c >= 0) {
 		err = usb_set_configuration(udev, c);
 		if (err) {
 			dev_err(&udev->dev, "can't set config #%d, error %d\n",
 					c, err);
-			usb_remove_sysfs_dev_files(udev);
-			device_del(&udev->dev);
-			goto fail;
+			/* This need not be fatal.  The user can try to
+			 * set other configurations. */
 		}
 	}
 
 	/* USB device state == configured ... usable */
 	usb_notify_add_device(udev);
 
+	usb_unlock_device(udev);
+
 	return 0;
 
 fail:
@@ -1654,15 +1711,9 @@
 int usb_suspend_device(struct usb_device *udev)
 {
 #ifdef	CONFIG_USB_SUSPEND
-	int	port1, status;
-
-	port1 = locktree(udev);
-	if (port1 < 0)
-		return port1;
-
-	status = __usb_suspend_device(udev, port1);
-	usb_unlock_device(udev);
-	return status;
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
+	return __usb_suspend_device(udev, udev->portnum);
 #else
 	/* NOTE:  udev->state unchanged, it's not lying ... */
 	udev->dev.power.power_state = PMSG_SUSPEND;
@@ -1694,13 +1745,14 @@
 	usb_set_device_state(udev, udev->actconfig
 			? USB_STATE_CONFIGURED
 			: USB_STATE_ADDRESS);
+	udev->dev.power.power_state = PMSG_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,
 	 * and device drivers will know about any resume quirks.
 	 */
 	status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
-	if (status < 0)
+	if (status < 2)
 		dev_dbg(&udev->dev,
 			"gone after usb resume? status %d\n",
 			status);
@@ -1709,7 +1761,7 @@
 		int		(*resume)(struct device *);
 
 		le16_to_cpus(&devstatus);
-		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)
+		if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
 				&& udev->parent) {
 			status = usb_control_msg(udev,
 					usb_sndctrlpipe(udev, 0),
@@ -1729,8 +1781,14 @@
 		 * may have a child resume event to deal with soon
 		 */
 		resume = udev->dev.bus->resume;
-		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++)
-			(void) resume(&udev->actconfig->interface[i]->dev);
+		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+			struct device *dev =
+					&udev->actconfig->interface[i]->dev;
+
+			down(&dev->sem);
+			(void) resume(dev);
+			up(&dev->sem);
+		}
 		status = 0;
 
 	} else if (udev->devnum <= 0) {
@@ -1813,11 +1871,10 @@
  */
 int usb_resume_device(struct usb_device *udev)
 {
-	int	port1, status;
+	int	status;
 
-	port1 = locktree(udev);
-	if (port1 < 0)
-		return port1;
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
 
 #ifdef	CONFIG_USB_SUSPEND
 	/* selective resume of one downstream hub-to-device port */
@@ -1826,7 +1883,7 @@
 			// NOTE swsusp may bork us, device state being wrong...
 			// NOTE this fails if parent is also suspended...
 			status = hub_port_resume(hdev_to_hub(udev->parent),
-					port1, udev);
+					udev->portnum, udev);
 		} else
 			status = 0;
 	} else
@@ -1836,13 +1893,11 @@
 		dev_dbg(&udev->dev, "can't resume, status %d\n",
 			status);
 
-	usb_unlock_device(udev);
-
 	/* rebind drivers that had no suspend() */
 	if (status == 0) {
-		usb_lock_all_devices();
+		usb_unlock_device(udev);
 		bus_rescan_devices(&usb_bus_type);
-		usb_unlock_all_devices();
+		usb_lock_device(udev);
 	}
 	return status;
 }
@@ -1856,14 +1911,14 @@
 	/* don't repeat RESUME sequence if this device
 	 * was already woken up by some other task
 	 */
-	down(&udev->serialize);
+	usb_lock_device(udev);
 	if (udev->state == USB_STATE_SUSPENDED) {
 		dev_dbg(&udev->dev, "RESUME (wakeup)\n");
 		/* TRSMRCY = 10 msec */
 		msleep(10);
 		status = finish_device_resume(udev);
 	}
-	up(&udev->serialize);
+	usb_unlock_device(udev);
 #endif
 	return status;
 }
@@ -1964,7 +2019,7 @@
 
 		if (!udev || status < 0)
 			continue;
-		down (&udev->serialize);
+		usb_lock_device(udev);
 		if (portstat & USB_PORT_STAT_SUSPEND)
 			status = hub_port_resume(hub, port1, udev);
 		else {
@@ -1975,7 +2030,7 @@
 				hub_port_logical_disconnect(hub, port1);
 			}
 		}
-		up(&udev->serialize);
+		usb_unlock_device(udev);
 	}
 	}
 #endif
@@ -2359,39 +2414,36 @@
 {
 	struct usb_device *hdev = hub->hdev;
 	int remaining;
-	unsigned i;
+	int port1;
 
-	remaining = hub->power_budget;
-	if (!remaining)		/* self-powered */
+	if (!hub->limited_power)
 		return 0;
 
-	for (i = 0; i < hdev->maxchild; i++) {
-		struct usb_device	*udev = hdev->children[i];
-		int			delta, ceiling;
+	remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
+	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+		struct usb_device	*udev = hdev->children[port1 - 1];
+		int			delta;
 
 		if (!udev)
 			continue;
 
-		/* 100mA per-port ceiling, or 8mA for OTG ports */
-		if (i != (udev->bus->otg_port - 1) || hdev->parent)
-			ceiling = 50;
-		else
-			ceiling = 4;
-
+		/* Unconfigured devices may not use more than 100mA,
+		 * or 8mA for OTG ports */
 		if (udev->actconfig)
-			delta = udev->actconfig->desc.bMaxPower;
+			delta = udev->actconfig->desc.bMaxPower * 2;
+		else if (port1 != udev->bus->otg_port || hdev->parent)
+			delta = 100;
 		else
-			delta = ceiling;
-		// dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta);
-		if (delta > ceiling)
-			dev_warn(&udev->dev, "%dmA over %dmA budget!\n",
-				2 * (delta - ceiling), 2 * ceiling);
+			delta = 8;
+		if (delta > hub->mA_per_port)
+			dev_warn(&udev->dev, "%dmA is over %umA budget "
+					"for port %d!\n",
+					delta, hub->mA_per_port, port1);
 		remaining -= delta;
 	}
 	if (remaining < 0) {
-		dev_warn(hub->intfdev,
-			"%dmA over power budget!\n",
-			-2 * remaining);
+		dev_warn(hub->intfdev, "%dmA over power budget!\n",
+			- remaining);
 		remaining = 0;
 	}
 	return remaining;
@@ -2486,7 +2538,8 @@
 
 		usb_set_device_state(udev, USB_STATE_POWERED);
 		udev->speed = USB_SPEED_UNKNOWN;
- 
+ 		udev->bus_mA = hub->mA_per_port;
+
 		/* set the address */
 		choose_address(udev);
 		if (udev->devnum <= 0) {
@@ -2506,16 +2559,16 @@
 		 * on the parent.
 		 */
 		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB
-				&& hub->power_budget) {
+				&& udev->bus_mA <= 100) {
 			u16	devstat;
 
 			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,
 					&devstat);
-			if (status < 0) {
+			if (status < 2) {
 				dev_dbg(&udev->dev, "get status %d ?\n", status);
 				goto loop_disable;
 			}
-			cpu_to_le16s(&devstat);
+			le16_to_cpus(&devstat);
 			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
 				dev_err(&udev->dev,
 					"can't connect bus-powered hub "
@@ -2540,7 +2593,6 @@
 		 * udev becomes globally accessible, although presumably
 		 * no one will look at it until hdev is unlocked.
 		 */
-		down (&udev->serialize);
 		status = 0;
 
 		/* We mustn't add new devices if the parent hub has
@@ -2564,15 +2616,12 @@
 			}
 		}
 
-		up (&udev->serialize);
 		if (status)
 			goto loop_disable;
 
 		status = hub_power_remaining(hub);
 		if (status)
-			dev_dbg(hub_dev,
-				"%dmA power budget left\n",
-				2 * status);
+			dev_dbg(hub_dev, "%dmA power budget left\n", status);
 
 		return;
 
@@ -2648,6 +2697,8 @@
 		if (i) {
 			dpm_runtime_resume(&hdev->dev);
 			dpm_runtime_resume(&intf->dev);
+			usb_put_intf(intf);
+			continue;
 		}
 
 		/* Lock the device, then check to see if we were
@@ -2661,7 +2712,7 @@
 
 		/* If the hub has died, clean up after it */
 		if (hdev->state == USB_STATE_NOTATTACHED) {
-			hub_pre_reset(hub);
+			hub_pre_reset(hub, 0);
 			goto loop;
 		}
 
@@ -2784,6 +2835,11 @@
 			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
 				dev_dbg (hub_dev, "power change\n");
 				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
+				if (hubstatus & HUB_STATUS_LOCAL_POWER)
+					/* FIXME: Is this always true? */
+					hub->limited_power = 0;
+				else
+					hub->limited_power = 1;
 			}
 			if (hubchange & HUB_CHANGE_OVERCURRENT) {
 				dev_dbg (hub_dev, "overcurrent change\n");
@@ -2832,7 +2888,6 @@
 MODULE_DEVICE_TABLE (usb, hub_id_table);
 
 static struct usb_driver hub_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hub",
 	.probe =	hub_probe,
 	.disconnect =	hub_disconnect,
@@ -2944,7 +2999,8 @@
 	struct usb_hub			*parent_hub;
 	struct usb_device_descriptor	descriptor = udev->descriptor;
 	struct usb_hub			*hub = NULL;
-	int 				i, ret = 0, port1 = -1;
+	int 				i, ret = 0;
+	int				port1 = udev->portnum;
 
 	if (udev->state == USB_STATE_NOTATTACHED ||
 			udev->state == USB_STATE_SUSPENDED) {
@@ -2958,18 +3014,6 @@
 		dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
 		return -EISDIR;
 	}
-
-	for (i = 0; i < parent_hdev->maxchild; i++)
-		if (parent_hdev->children[i] == udev) {
-			port1 = i + 1;
-			break;
-		}
-
-	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 */
@@ -2977,7 +3021,7 @@
 			udev->actconfig->interface[0]->dev.driver ==
 				&hub_driver.driver &&
 			(hub = hdev_to_hub(udev)) != NULL) {
-		hub_pre_reset(hub);
+		hub_pre_reset(hub, 0);
 	}
 
 	set_bit(port1, parent_hub->busy_bits);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index bf23f89..29d5f45 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -220,8 +220,9 @@
 	struct usb_hub_descriptor *descriptor;	/* class descriptor */
 	struct usb_tt		tt;		/* Transaction Translator */
 
-	u8			power_budget;	/* in 2mA units; or zero */
+	unsigned		mA_per_port;	/* current for each child */
 
+	unsigned		limited_power:1;
 	unsigned		quiescing:1;
 	unsigned		activating:1;
 	unsigned		resume_root_hub:1;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index fe74f99..319de03 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1387,6 +1387,12 @@
 	if (dev->state != USB_STATE_ADDRESS)
 		usb_disable_device (dev, 1);	// Skip ep0
 
+	i = dev->bus_mA - cp->desc.bMaxPower * 2;
+	if (i < 0)
+		dev_warn(&dev->dev, "new config #%d exceeds power "
+				"limit by %dmA\n",
+				configuration, -i);
+
 	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
 			NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e80ef94..56a3520 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -32,7 +32,6 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
-#include <linux/rwsem.h>
 #include <linux/usb.h>
 
 #include <asm/io.h>
@@ -47,165 +46,7 @@
 const char *usbcore_name = "usbcore";
 
 static int nousb;	/* Disable USB when built into kernel image */
-			/* Not honored on modular build */
 
-static DECLARE_RWSEM(usb_all_devices_rwsem);
-
-
-static int generic_probe (struct device *dev)
-{
-	return 0;
-}
-static int generic_remove (struct device *dev)
-{
-	struct usb_device *udev = to_usb_device(dev);
-
-	/* if this is only an unbind, not a physical disconnect, then
-	 * unconfigure the device */
-	if (udev->state == USB_STATE_CONFIGURED)
-		usb_set_configuration(udev, 0);
-
-	/* in case the call failed or the device was suspended */
-	if (udev->state >= USB_STATE_CONFIGURED)
-		usb_disable_device(udev, 0);
-	return 0;
-}
-
-static struct device_driver usb_generic_driver = {
-	.owner = THIS_MODULE,
-	.name =	"usb",
-	.bus = &usb_bus_type,
-	.probe = generic_probe,
-	.remove = generic_remove,
-};
-
-static int usb_generic_driver_data;
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_probe_interface(struct device *dev)
-{
-	struct usb_interface * intf = to_usb_interface(dev);
-	struct usb_driver * driver = to_usb_driver(dev->driver);
-	const struct usb_device_id *id;
-	int error = -ENODEV;
-
-	dev_dbg(dev, "%s\n", __FUNCTION__);
-
-	if (!driver->probe)
-		return error;
-	/* FIXME we'd much prefer to just resume it ... */
-	if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
-		return -EHOSTUNREACH;
-
-	id = usb_match_id (intf, driver->id_table);
-	if (id) {
-		dev_dbg (dev, "%s - got id\n", __FUNCTION__);
-
-		/* Interface "power state" doesn't correspond to any hardware
-		 * state whatsoever.  We use it to record when it's bound to
-		 * a driver that may start I/0:  it's not frozen/quiesced.
-		 */
-		mark_active(intf);
-		intf->condition = USB_INTERFACE_BINDING;
-		error = driver->probe (intf, id);
-		if (error) {
-			mark_quiesced(intf);
-			intf->condition = USB_INTERFACE_UNBOUND;
-		} else
-			intf->condition = USB_INTERFACE_BOUND;
-	}
-
-	return error;
-}
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_unbind_interface(struct device *dev)
-{
-	struct usb_interface *intf = to_usb_interface(dev);
-	struct usb_driver *driver = to_usb_driver(intf->dev.driver);
-
-	intf->condition = USB_INTERFACE_UNBINDING;
-
-	/* release all urbs for this interface */
-	usb_disable_interface(interface_to_usbdev(intf), intf);
-
-	if (driver && driver->disconnect)
-		driver->disconnect(intf);
-
-	/* reset other interface state */
-	usb_set_interface(interface_to_usbdev(intf),
-			intf->altsetting[0].desc.bInterfaceNumber,
-			0);
-	usb_set_intfdata(intf, NULL);
-	intf->condition = USB_INTERFACE_UNBOUND;
-	mark_quiesced(intf);
-
-	return 0;
-}
-
-/**
- * usb_register - register a USB driver
- * @new_driver: USB operations for the driver
- *
- * Registers a USB driver with the USB core.  The list of unattached
- * interfaces will be rescanned whenever a new driver is added, allowing
- * the new driver to attach to any recognized devices.
- * Returns a negative error code on failure and 0 on success.
- * 
- * NOTE: if you want your driver to use the USB major number, you must call
- * usb_register_dev() to enable that functionality.  This function no longer
- * takes care of that.
- */
-int usb_register(struct usb_driver *new_driver)
-{
-	int retval = 0;
-
-	if (nousb)
-		return -ENODEV;
-
-	new_driver->driver.name = (char *)new_driver->name;
-	new_driver->driver.bus = &usb_bus_type;
-	new_driver->driver.probe = usb_probe_interface;
-	new_driver->driver.remove = usb_unbind_interface;
-	new_driver->driver.owner = new_driver->owner;
-
-	usb_lock_all_devices();
-	retval = driver_register(&new_driver->driver);
-	usb_unlock_all_devices();
-
-	if (!retval) {
-		pr_info("%s: registered new driver %s\n",
-			usbcore_name, new_driver->name);
-		usbfs_update_special();
-	} else {
-		printk(KERN_ERR "%s: error %d registering driver %s\n",
-			usbcore_name, retval, new_driver->name);
-	}
-
-	return retval;
-}
-
-/**
- * usb_deregister - unregister a USB driver
- * @driver: USB operations of the driver to unregister
- * Context: must be able to sleep
- *
- * Unlinks the specified driver from the internal USB driver list.
- * 
- * NOTE: If you called usb_register_dev(), you still need to call
- * usb_deregister_dev() to clean up your driver's allocated minor numbers,
- * this * call will no longer do it for you.
- */
-void usb_deregister(struct usb_driver *driver)
-{
-	pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
-
-	usb_lock_all_devices();
-	driver_unregister (&driver->driver);
-	usb_unlock_all_devices();
-
-	usbfs_update_special();
-}
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -351,152 +192,23 @@
 	iface->condition = USB_INTERFACE_UNBOUND;
 	mark_quiesced(iface);
 }
-
-/**
- * usb_match_id - find first usb_device_id matching device or interface
- * @interface: the interface of interest
- * @id: array of usb_device_id structures, terminated by zero entry
- *
- * usb_match_id searches an array of usb_device_id's and returns
- * the first one matching the device or interface, or null.
- * This is used when binding (or rebinding) a driver to an interface.
- * Most USB device drivers will use this indirectly, through the usb core,
- * but some layered driver frameworks use it directly.
- * These device tables are exported with MODULE_DEVICE_TABLE, through
- * modutils and "modules.usbmap", to support the driver loading
- * functionality of USB hotplugging.
- *
- * What Matches:
- *
- * The "match_flags" element in a usb_device_id controls which
- * members are used.  If the corresponding bit is set, the
- * value in the device_id must match its corresponding member
- * in the device or interface descriptor, or else the device_id
- * does not match.
- *
- * "driver_info" is normally used only by device drivers,
- * but you can create a wildcard "matches anything" usb_device_id
- * as a driver's "modules.usbmap" entry if you provide an id with
- * only a nonzero "driver_info" field.  If you do this, the USB device
- * driver's probe() routine should use additional intelligence to
- * decide whether to bind to the specified interface.
- * 
- * What Makes Good usb_device_id Tables:
- *
- * The match algorithm is very simple, so that intelligence in
- * driver selection must come from smart driver id records.
- * Unless you have good reasons to use another selection policy,
- * provide match elements only in related groups, and order match
- * specifiers from specific to general.  Use the macros provided
- * for that purpose if you can.
- *
- * The most specific match specifiers use device descriptor
- * data.  These are commonly used with product-specific matches;
- * the USB_DEVICE macro lets you provide vendor and product IDs,
- * and you can also match against ranges of product revisions.
- * These are widely used for devices with application or vendor
- * specific bDeviceClass values.
- *
- * Matches based on device class/subclass/protocol specifications
- * are slightly more general; use the USB_DEVICE_INFO macro, or
- * its siblings.  These are used with single-function devices
- * where bDeviceClass doesn't specify that each interface has
- * its own class. 
- *
- * Matches based on interface class/subclass/protocol are the
- * most general; they let drivers bind to any interface on a
- * multiple-function device.  Use the USB_INTERFACE_INFO
- * macro, or its siblings, to match class-per-interface style 
- * devices (as recorded in bDeviceClass).
- *  
- * Within those groups, remember that not all combinations are
- * meaningful.  For example, don't give a product version range
- * without vendor and product IDs; or specify a protocol without
- * its associated class and subclass.
- */   
-const struct usb_device_id *
-usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_host_interface *intf;
-	struct usb_device *dev;
-
-	/* proc_connectinfo in devio.c may call us with id == NULL. */
-	if (id == NULL)
-		return NULL;
-
-	intf = interface->cur_altsetting;
-	dev = interface_to_usbdev(interface);
-
-	/* It is important to check that id->driver_info is nonzero,
-	   since an entry that is all zeroes except for a nonzero
-	   id->driver_info is the way to create an entry that
-	   indicates that the driver want to examine every
-	   device and interface. */
-	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
-	       id->driver_info; id++) {
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-		    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-		    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 > le16_to_cpu(dev->descriptor.bcdDevice)))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-		    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
-		    (id->bDeviceClass != dev->descriptor.bDeviceClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
-		    (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
-		    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
-		    (id->bInterfaceClass != intf->desc.bInterfaceClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
-		    (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
-		    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
-			continue;
-
-		return id;
-	}
-
-	return NULL;
-}
-
+struct find_interface_arg {
+	int minor;
+	struct usb_interface *interface;
+};
 
 static int __find_interface(struct device * dev, void * data)
 {
-	struct usb_interface ** ret = (struct usb_interface **)data;
-	struct usb_interface * intf = *ret;
-	int *minor = (int *)data;
+	struct find_interface_arg *arg = data;
+	struct usb_interface *intf;
 
 	/* can't look at usb devices, only interfaces */
 	if (dev->driver == &usb_generic_driver)
 		return 0;
 
 	intf = to_usb_interface(dev);
-	if (intf->minor != -1 && intf->minor == *minor) {
-		*ret = intf;
+	if (intf->minor != -1 && intf->minor == arg->minor) {
+		arg->interface = intf;
 		return 1;
 	}
 	return 0;
@@ -513,35 +225,14 @@
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-	struct usb_interface *intf = (struct usb_interface *)(long)minor;
-	int ret;
+	struct find_interface_arg argb;
 
-	ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
-
-	return ret ? intf : NULL;
+	argb.minor = minor;
+	argb.interface = NULL;
+	driver_for_each_device(&drv->driver, NULL, &argb, __find_interface);
+	return argb.interface;
 }
 
-static int usb_device_match (struct device *dev, struct device_driver *drv)
-{
-	struct usb_interface *intf;
-	struct usb_driver *usb_drv;
-	const struct usb_device_id *id;
-
-	/* check for generic driver, which we don't match any device with */
-	if (drv == &usb_generic_driver)
-		return 0;
-
-	intf = to_usb_interface(dev);
-	usb_drv = to_usb_driver(drv);
-	
-	id = usb_match_id (intf, usb_drv->id_table);
-	if (id)
-		return 1;
-
-	return 0;
-}
-
-
 #ifdef	CONFIG_HOTPLUG
 
 /*
@@ -750,12 +441,11 @@
 		/* hub driver sets up TT records */
 	}
 
+	dev->portnum = port1;
 	dev->bus = bus;
 	dev->parent = parent;
 	INIT_LIST_HEAD(&dev->filelist);
 
-	init_MUTEX(&dev->serialize);
-
 	return dev;
 }
 
@@ -828,76 +518,21 @@
 
 /*			USB device locking
  *
- * Although locking USB devices should be straightforward, it is
- * complicated by the way the driver-model core works.  When a new USB
- * driver is registered or unregistered, the core will automatically
- * probe or disconnect all matching interfaces on all USB devices while
- * holding the USB subsystem writelock.  There's no good way for us to
- * tell which devices will be used or to lock them beforehand; our only
- * option is to effectively lock all the USB devices.
- *
- * We do that by using a private rw-semaphore, usb_all_devices_rwsem.
- * When locking an individual device you must first acquire the rwsem's
- * readlock.  When a driver is registered or unregistered the writelock
- * must be held.  These actions are encapsulated in the subroutines
- * below, so all a driver needs to do is call usb_lock_device() and
- * usb_unlock_device().
+ * USB devices and interfaces are locked using the semaphore in their
+ * embedded struct device.  The hub driver guarantees that whenever a
+ * device is connected or disconnected, drivers are called with the
+ * USB device locked as well as their particular interface.
  *
  * Complications arise when several devices are to be locked at the same
  * time.  Only hub-aware drivers that are part of usbcore ever have to
- * do this; nobody else needs to worry about it.  The problem is that
- * usb_lock_device() must not be called to lock a second device since it
- * would acquire the rwsem's readlock reentrantly, leading to deadlock if
- * another thread was waiting for the writelock.  The solution is simple:
- *
- *	When locking more than one device, call usb_lock_device()
- *	to lock the first one.  Lock the others by calling
- *	down(&udev->serialize) directly.
- *
- *	When unlocking multiple devices, use up(&udev->serialize)
- *	to unlock all but the last one.  Unlock the last one by
- *	calling usb_unlock_device().
+ * do this; nobody else needs to worry about it.  The rule for locking
+ * is simple:
  *
  *	When locking both a device and its parent, always lock the
  *	the parent first.
  */
 
 /**
- * usb_lock_device - acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Use this routine when you don't hold any other device locks;
- * to acquire nested inner locks call down(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_lock_device(struct usb_device *udev)
-{
-	down_read(&usb_all_devices_rwsem);
-	down(&udev->serialize);
-}
-
-/**
- * usb_trylock_device - attempt to acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Don't use this routine if you already hold a device lock;
- * use down_trylock(&udev->serialize) instead.
- * This is necessary for proper interaction with usb_lock_all_devices().
- *
- * Returns 1 if successful, 0 if contention.
- */
-int usb_trylock_device(struct usb_device *udev)
-{
-	if (!down_read_trylock(&usb_all_devices_rwsem))
-		return 0;
-	if (down_trylock(&udev->serialize)) {
-		up_read(&usb_all_devices_rwsem);
-		return 0;
-	}
-	return 1;
-}
-
-/**
  * usb_lock_device_for_reset - cautiously acquire the lock for a
  *	usb device structure
  * @udev: device that's being locked
@@ -935,7 +570,7 @@
 		}
 	}
 
-	while (!usb_trylock_device(udev)) {
+	while (usb_trylock_device(udev) != 0) {
 
 		/* If we can't acquire the lock after waiting one second,
 		 * we're probably deadlocked */
@@ -953,39 +588,6 @@
 	return 1;
 }
 
-/**
- * usb_unlock_device - release the lock for a usb device structure
- * @udev: device that's being unlocked
- *
- * Use this routine when releasing the only device lock you hold;
- * to release inner nested locks call up(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_unlock_device(struct usb_device *udev)
-{
-	up(&udev->serialize);
-	up_read(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_lock_all_devices - acquire the lock for all usb device structures
- *
- * This is necessary when registering a new driver or probing a bus,
- * since the driver-model core may try to use any usb_device.
- */
-void usb_lock_all_devices(void)
-{
-	down_write(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_unlock_all_devices - release the lock for all usb device structures
- */
-void usb_unlock_all_devices(void)
-{
-	up_write(&usb_all_devices_rwsem);
-}
-
 
 static struct usb_device *match_device(struct usb_device *dev,
 				       u16 vendor_id, u16 product_id)
@@ -1008,10 +610,10 @@
 	/* look through all of the children of this device */
 	for (child = 0; child < dev->maxchild; ++child) {
 		if (dev->children[child]) {
-			down(&dev->children[child]->serialize);
+			usb_lock_device(dev->children[child]);
 			ret_dev = match_device(dev->children[child],
 					       vendor_id, product_id);
-			up(&dev->children[child]->serialize);
+			usb_unlock_device(dev->children[child]);
 			if (ret_dev)
 				goto exit;
 		}
@@ -1496,18 +1098,8 @@
 	.resume =	usb_generic_resume,
 };
 
-#ifndef MODULE
-
-static int __init usb_setup_disable(char *str)
-{
-	nousb = 1;
-	return 1;
-}
-
 /* format to disable USB on kernel command line is: nousb */
-__setup("nousb", usb_setup_disable);
-
-#endif
+__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
 
 /*
  * for external read access to <nousb>
@@ -1598,8 +1190,6 @@
  * driver modules to use.
  */
 
-EXPORT_SYMBOL(usb_register);
-EXPORT_SYMBOL(usb_deregister);
 EXPORT_SYMBOL(usb_disabled);
 
 EXPORT_SYMBOL_GPL(usb_get_intf);
@@ -1610,14 +1200,10 @@
 EXPORT_SYMBOL(usb_get_dev);
 EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
-EXPORT_SYMBOL(usb_lock_device);
-EXPORT_SYMBOL(usb_trylock_device);
 EXPORT_SYMBOL(usb_lock_device_for_reset);
-EXPORT_SYMBOL(usb_unlock_device);
 
 EXPORT_SYMBOL(usb_driver_claim_interface);
 EXPORT_SYMBOL(usb_driver_release_interface);
-EXPORT_SYMBOL(usb_match_id);
 EXPORT_SYMBOL(usb_find_interface);
 EXPORT_SYMBOL(usb_ifnum_to_if);
 EXPORT_SYMBOL(usb_altnum_to_altsetting);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1c4a684..4647e1e 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -16,9 +16,6 @@
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 
-extern void usb_lock_all_devices(void);
-extern void usb_unlock_all_devices(void);
-
 extern void usb_kick_khubd(struct usb_device *dev);
 extern void usb_suspend_root_hub(struct usb_device *hdev);
 extern void usb_resume_root_hub(struct usb_device *dev);
@@ -33,6 +30,9 @@
 extern int usb_suspend_device(struct usb_device *dev);
 extern int usb_resume_device(struct usb_device *dev);
 
+extern struct device_driver usb_generic_driver;
+extern int usb_generic_driver_data;
+extern int usb_device_match(struct device *dev, struct device_driver *drv);
 
 /* Interfaces and their "power state" are owned by usbcore */
 
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index c655d46..9734cb7 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -138,7 +138,7 @@
 	/* or like sa1100: two fixed function endpoints */
 	"ep1out-bulk", "ep2in-bulk",
 };
-#define DUMMY_ENDPOINTS	(sizeof(ep_name)/sizeof(char *))
+#define DUMMY_ENDPOINTS	ARRAY_SIZE(ep_name)
 
 /*-------------------------------------------------------------------------*/
 
@@ -896,7 +896,7 @@
 #endif
 }
 
-static int dummy_udc_probe (struct platform_device *dev)
+static int dummy_udc_probe (struct platform_device *pdev)
 {
 	struct dummy	*dum = the_controller;
 	int		rc;
@@ -909,7 +909,7 @@
 	dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
 
 	strcpy (dum->gadget.dev.bus_id, "gadget");
-	dum->gadget.dev.parent = &dev->dev;
+	dum->gadget.dev.parent = &pdev->dev;
 	dum->gadget.dev.release = dummy_gadget_release;
 	rc = device_register (&dum->gadget.dev);
 	if (rc < 0)
@@ -919,47 +919,47 @@
 	usb_bus_get (&dummy_to_hcd (dum)->self);
 #endif
 
-	platform_set_drvdata (dev, dum);
+	platform_set_drvdata (pdev, dum);
 	device_create_file (&dum->gadget.dev, &dev_attr_function);
 	return rc;
 }
 
-static int dummy_udc_remove (struct platform_device *dev)
+static int dummy_udc_remove (struct platform_device *pdev)
 {
-	struct dummy	*dum = platform_get_drvdata (dev);
+	struct dummy	*dum = platform_get_drvdata (pdev);
 
-	platform_set_drvdata (dev, NULL);
+	platform_set_drvdata (pdev, NULL);
 	device_remove_file (&dum->gadget.dev, &dev_attr_function);
 	device_unregister (&dum->gadget.dev);
 	return 0;
 }
 
-static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state)
 {
-	struct dummy	*dum = platform_get_drvdata(dev);
+	struct dummy	*dum = platform_get_drvdata(pdev);
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 1;
 	set_link_state (dum);
 	spin_unlock_irq (&dum->lock);
 
-	dev->dev.power.power_state = state;
+	pdev->dev.power.power_state = state;
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
 
-static int dummy_udc_resume (struct platform_device *dev)
+static int dummy_udc_resume (struct platform_device *pdev)
 {
-	struct dummy	*dum = platform_get_drvdata(dev);
+	struct dummy	*dum = platform_get_drvdata(pdev);
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 0;
 	set_link_state (dum);
 	spin_unlock_irq (&dum->lock);
 
-	dev->dev.power.power_state = PMSG_ON;
+	pdev->dev.power.power_state = PMSG_ON;
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
@@ -1576,7 +1576,7 @@
 	dum = hcd_to_dummy (hcd);
 
 	spin_lock_irqsave (&dum->lock, flags);
-	if (hcd->state != HC_STATE_RUNNING)
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
 		goto done;
 
 	if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) {
@@ -1623,7 +1623,7 @@
 	int		retval = 0;
 	unsigned long	flags;
 
-	if (hcd->state != HC_STATE_RUNNING)
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
 		return -ETIMEDOUT;
 
 	dum = hcd_to_dummy (hcd);
@@ -1756,9 +1756,12 @@
 {
 	struct dummy *dum = hcd_to_dummy (hcd);
 
+	dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
+
 	spin_lock_irq (&dum->lock);
 	dum->rh_state = DUMMY_RH_SUSPENDED;
 	set_link_state (dum);
+	hcd->state = HC_STATE_SUSPENDED;
 	spin_unlock_irq (&dum->lock);
 	return 0;
 }
@@ -1766,14 +1769,23 @@
 static int dummy_bus_resume (struct usb_hcd *hcd)
 {
 	struct dummy *dum = hcd_to_dummy (hcd);
+	int rc = 0;
+
+	dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
 
 	spin_lock_irq (&dum->lock);
-	dum->rh_state = DUMMY_RH_RUNNING;
-	set_link_state (dum);
-	if (!list_empty(&dum->urbp_list))
-		mod_timer (&dum->timer, jiffies);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+		dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n");
+		rc = -ENODEV;
+	} else {
+		dum->rh_state = DUMMY_RH_RUNNING;
+		set_link_state (dum);
+		if (!list_empty(&dum->urbp_list))
+			mod_timer (&dum->timer, jiffies);
+		hcd->state = HC_STATE_RUNNING;
+	}
 	spin_unlock_irq (&dum->lock);
-	return 0;
+	return rc;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1899,14 +1911,14 @@
 	.bus_resume =		dummy_bus_resume,
 };
 
-static int dummy_hcd_probe (struct platform_device *dev)
+static int dummy_hcd_probe(struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 	int			retval;
 
-	dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
+	dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 
-	hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id);
+	hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id);
 	if (!hcd)
 		return -ENOMEM;
 	the_controller = hcd_to_dummy (hcd);
@@ -1919,36 +1931,43 @@
 	return retval;
 }
 
-static int dummy_hcd_remove (struct platform_device *dev)
+static int dummy_hcd_remove (struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 
-	hcd = platform_get_drvdata (dev);
+	hcd = platform_get_drvdata (pdev);
 	usb_remove_hcd (hcd);
 	usb_put_hcd (hcd);
 	the_controller = NULL;
 	return 0;
 }
 
-static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state)
 {
 	struct usb_hcd		*hcd;
+	struct dummy		*dum;
+	int			rc = 0;
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-	hcd = platform_get_drvdata (dev);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
-	hcd->state = HC_STATE_SUSPENDED;
-	return 0;
+	hcd = platform_get_drvdata (pdev);
+	dum = hcd_to_dummy (hcd);
+	if (dum->rh_state == DUMMY_RH_RUNNING) {
+		dev_warn(&pdev->dev, "Root hub isn't suspended!\n");
+		rc = -EBUSY;
+	} else
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+	return rc;
 }
 
-static int dummy_hcd_resume (struct platform_device *dev)
+static int dummy_hcd_resume (struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-	hcd = platform_get_drvdata (dev);
-	hcd->state = HC_STATE_RUNNING;
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
+	hcd = platform_get_drvdata (pdev);
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	usb_hcd_poll_rh_status (hcd);
 	return 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ea09aaa..0cea978 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -224,6 +224,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/kthread.h>
 #include <linux/limits.h>
 #include <linux/list.h>
@@ -238,7 +239,6 @@
 #include <linux/string.h>
 #include <linux/suspend.h>
 #include <linux/utsname.h>
-#include <linux/wait.h>
 
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
@@ -250,7 +250,7 @@
 
 #define DRIVER_DESC		"File-backed Storage Gadget"
 #define DRIVER_NAME		"g_file_storage"
-#define DRIVER_VERSION		"20 October 2004"
+#define DRIVER_VERSION		"28 November 2005"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -335,8 +335,8 @@
 #define MAX_LUNS	8
 
 	/* Arggh!  There should be a module_param_array_named macro! */
-static char		*file[MAX_LUNS] = {NULL, };
-static int		ro[MAX_LUNS] = {0, };
+static char		*file[MAX_LUNS];
+static int		ro[MAX_LUNS];
 
 static struct {
 	int		num_filenames;
@@ -587,7 +587,7 @@
 struct fsg_buffhd {
 	void				*buf;
 	dma_addr_t			dma;
-	volatile enum fsg_buffer_state	state;
+	enum fsg_buffer_state		state;
 	struct fsg_buffhd		*next;
 
 	/* The NetChip 2280 is faster, and handles some protocol faults
@@ -596,9 +596,9 @@
 	unsigned int			bulk_out_intended_length;
 
 	struct usb_request		*inreq;
-	volatile int			inreq_busy;
+	int				inreq_busy;
 	struct usb_request		*outreq;
-	volatile int			outreq_busy;
+	int				outreq_busy;
 };
 
 enum fsg_state {
@@ -631,13 +631,16 @@
 	/* filesem protects: backing files in use */
 	struct rw_semaphore	filesem;
 
+	/* reference counting: wait until all LUNs are released */
+	struct kref		ref;
+
 	struct usb_ep		*ep0;		// Handy copy of gadget->ep0
 	struct usb_request	*ep0req;	// For control responses
-	volatile unsigned int	ep0_req_tag;
+	unsigned int		ep0_req_tag;
 	const char		*ep0req_name;
 
 	struct usb_request	*intreq;	// For interrupt responses
-	volatile int		intreq_busy;
+	int			intreq_busy;
 	struct fsg_buffhd	*intr_buffhd;
 
  	unsigned int		bulk_out_maxpacket;
@@ -667,7 +670,6 @@
 	struct fsg_buffhd	*next_buffhd_to_drain;
 	struct fsg_buffhd	buffhds[NUM_BUFFERS];
 
-	wait_queue_head_t	thread_wqh;
 	int			thread_wakeup_needed;
 	struct completion	thread_notifier;
 	struct task_struct	*thread_task;
@@ -694,7 +696,6 @@
 	unsigned int		nluns;
 	struct lun		*luns;
 	struct lun		*curlun;
-	struct completion	lun_released;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -1073,11 +1074,13 @@
 
 /* These routines may be called in process context or in_irq */
 
+/* Caller must hold fsg->lock */
 static void wakeup_thread(struct fsg_dev *fsg)
 {
 	/* Tell the main thread that something has happened */
 	fsg->thread_wakeup_needed = 1;
-	wake_up_all(&fsg->thread_wqh);
+	if (fsg->thread_task)
+		wake_up_process(fsg->thread_task);
 }
 
 
@@ -1164,11 +1167,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	bh->inreq_busy = 0;
 	bh->state = BUF_STATE_EMPTY;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
@@ -1185,11 +1189,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	bh->outreq_busy = 0;
 	bh->state = BUF_STATE_FULL;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 
@@ -1206,11 +1211,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	fsg->intreq_busy = 0;
 	bh->state = BUF_STATE_EMPTY;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1261,8 +1267,8 @@
 	fsg->cbbuf_cmnd_size = req->actual;
 	memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
 
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1514,8 +1520,8 @@
 
 /* Use this for bulk or interrupt transfers, not ep0 */
 static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
-		struct usb_request *req, volatile int *pbusy,
-		volatile enum fsg_buffer_state *state)
+		struct usb_request *req, int *pbusy,
+		enum fsg_buffer_state *state)
 {
 	int	rc;
 
@@ -1523,8 +1529,11 @@
 		dump_msg(fsg, "bulk-in", req->buf, req->length);
 	else if (ep == fsg->intr_in)
 		dump_msg(fsg, "intr-in", req->buf, req->length);
+
+	spin_lock_irq(&fsg->lock);
 	*pbusy = 1;
 	*state = BUF_STATE_BUSY;
+	spin_unlock_irq(&fsg->lock);
 	rc = usb_ep_queue(ep, req, GFP_KERNEL);
 	if (rc != 0) {
 		*pbusy = 0;
@@ -1544,14 +1553,23 @@
 
 static int sleep_thread(struct fsg_dev *fsg)
 {
-	int	rc;
+	int	rc = 0;
 
 	/* Wait until a signal arrives or we are woken up */
-	rc = wait_event_interruptible(fsg->thread_wqh,
-			fsg->thread_wakeup_needed);
+	for (;;) {
+		try_to_freeze();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (signal_pending(current)) {
+			rc = -EINTR;
+			break;
+		}
+		if (fsg->thread_wakeup_needed)
+			break;
+		schedule();
+	}
+	__set_current_state(TASK_RUNNING);
 	fsg->thread_wakeup_needed = 0;
-	try_to_freeze();
-	return (rc ? -EINTR : 0);
+	return rc;
 }
 
 
@@ -1788,6 +1806,7 @@
 		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
 			break;			// We stopped early
 		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
 			fsg->next_buffhd_to_drain = bh->next;
 			bh->state = BUF_STATE_EMPTY;
 
@@ -2356,6 +2375,7 @@
 
 		/* Throw away the data in a filled buffer */
 		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
 			bh->state = BUF_STATE_EMPTY;
 			fsg->next_buffhd_to_drain = bh->next;
 
@@ -3021,6 +3041,7 @@
 			if ((rc = sleep_thread(fsg)) != 0)
 				return rc;
 			}
+		smp_rmb();
 		rc = received_cbw(fsg, bh);
 		bh->state = BUF_STATE_EMPTY;
 
@@ -3642,11 +3663,19 @@
 
 /*-------------------------------------------------------------------------*/
 
+static void fsg_release(struct kref *ref)
+{
+	struct fsg_dev	*fsg = container_of(ref, struct fsg_dev, ref);
+
+	kfree(fsg->luns);
+	kfree(fsg);
+}
+
 static void lun_release(struct device *dev)
 {
 	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
 
-	complete(&fsg->lun_released);
+	kref_put(&fsg->ref, fsg_release);
 }
 
 static void fsg_unbind(struct usb_gadget *gadget)
@@ -3660,14 +3689,12 @@
 	clear_bit(REGISTERED, &fsg->atomic_bitflags);
 
 	/* Unregister the sysfs attribute files and the LUNs */
-	init_completion(&fsg->lun_released);
 	for (i = 0; i < fsg->nluns; ++i) {
 		curlun = &fsg->luns[i];
 		if (curlun->registered) {
 			device_remove_file(&curlun->dev, &dev_attr_ro);
 			device_remove_file(&curlun->dev, &dev_attr_file);
 			device_unregister(&curlun->dev);
-			wait_for_completion(&fsg->lun_released);
 			curlun->registered = 0;
 		}
 	}
@@ -3846,6 +3873,7 @@
 			curlun->dev.release = lun_release;
 			device_create_file(&curlun->dev, &dev_attr_ro);
 			device_create_file(&curlun->dev, &dev_attr_file);
+			kref_get(&fsg->ref);
 		}
 
 		if (file[i] && *file[i]) {
@@ -4061,7 +4089,7 @@
 		return -ENOMEM;
 	spin_lock_init(&fsg->lock);
 	init_rwsem(&fsg->filesem);
-	init_waitqueue_head(&fsg->thread_wqh);
+	kref_init(&fsg->ref);
 	init_completion(&fsg->thread_notifier);
 
 	the_fsg = fsg;
@@ -4069,13 +4097,6 @@
 }
 
 
-static void fsg_free(struct fsg_dev *fsg)
-{
-	kfree(fsg->luns);
-	kfree(fsg);
-}
-
-
 static int __init fsg_init(void)
 {
 	int		rc;
@@ -4085,7 +4106,7 @@
 		return rc;
 	fsg = the_fsg;
 	if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
-		fsg_free(fsg);
+		kref_put(&fsg->ref, fsg_release);
 	return rc;
 }
 module_init(fsg_init);
@@ -4103,6 +4124,6 @@
 	wait_for_completion(&fsg->thread_notifier);
 
 	close_all_backing_files(fsg);
-	fsg_free(fsg);
+	kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b35ac6d..65e084a 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -890,10 +890,12 @@
 	/* wait for write buffer to drain, or */
 	/* at most GS_CLOSE_TIMEOUT seconds */
 	if (gs_buf_data_avail(port->port_write_buf) > 0) {
+		spin_unlock_irqrestore(&port->port_lock, flags);
 		wait_cond_interruptible_timeout(port->port_write_wait,
 		port->port_dev == NULL
 		|| gs_buf_data_avail(port->port_write_buf) == 0,
 		&port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+		spin_lock_irqsave(&port->port_lock, flags);
 	}
 
 	/* free disconnected port on final close */
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 58321d3..e3020f4b 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -2,6 +2,10 @@
 # Makefile for USB Host Controller Drivers
 #
 
+ifeq ($(CONFIG_USB_DEBUG),y)
+	EXTRA_CFLAGS		+= -DDEBUG
+endif
+
 obj-$(CONFIG_PCI)		+= pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 29f52a4..9dd3d14 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -17,13 +17,6 @@
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-	#define DEBUG
-#else
-	#undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dmapool.h>
@@ -624,7 +617,7 @@
 	}
 
 	/* remote wakeup [4.3.1] */
-	if ((status & STS_PCD) && hcd->remote_wakeup) {
+	if (status & STS_PCD) {
 		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
 
 		/* resume root hub? */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 82caf33..69b0b9b 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -59,7 +59,7 @@
 
 		if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
 			t2 |= PORT_SUSPEND;
-		if (hcd->remote_wakeup)
+		if (device_may_wakeup(&hcd->self.root_hub->dev))
 			t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
 		else
 			t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -517,7 +517,7 @@
 			if ((temp & PORT_PE) == 0
 					|| (temp & PORT_RESET) != 0)
 				goto error;
-			if (hcd->remote_wakeup)
+			if (device_may_wakeup(&hcd->self.root_hub->dev))
 				temp |= PORT_WAKE_BITS;
 			writel (temp | PORT_SUSPEND,
 				&ehci->regs->port_status [wIndex]);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 13f73a8..08ca0f8 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -210,7 +210,16 @@
 	/* Serial Bus Release Number is at PCI 0x60 offset */
 	pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
 
-	/* REVISIT:  per-port wake capability (PCI 0x62) currently unused */
+	/* Workaround current PCI init glitch:  wakeup bits aren't
+	 * being set from PCI PM capability.
+	 */
+	if (!device_can_wakeup(&pdev->dev)) {
+		u16	port_wake;
+
+		pci_read_config_word(pdev, 0x62, &port_wake);
+		if (port_wake & 0x0001)
+			device_init_wakeup(&pdev->dev, 1);
+	}
 
 	retval = ehci_pci_reinit(ehci, pdev);
 done:
@@ -269,7 +278,6 @@
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 	unsigned		port;
-	struct usb_device	*root = hcd->self.root_hub;
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	int			retval = -EINVAL;
 
@@ -303,13 +311,7 @@
 
 restart:
 	ehci_dbg(ehci, "lost power, restarting\n");
-	for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
-		port--;
-		if (!root->children [port])
-			continue;
-		usb_set_device_state(root->children[port],
-					USB_STATE_NOTATTACHED);
-	}
+	usb_root_hub_lost_power(hcd->self.root_hub);
 
 	/* Else reset, to cope with power loss or flush-to-storage
 	 * style "resume" having let BIOS kick in during reboot.
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index bf03ec0..9b13bf2 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -514,18 +514,18 @@
 		qtd->urb = urb;
 		qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
 		list_add_tail (&qtd->qtd_list, head);
+
+		/* for zero length DATA stages, STATUS is always IN */
+		if (len == 0)
+			token |= (1 /* "in" */ << 8);
 	} 
 
 	/*
 	 * data transfer stage:  buffer setup
 	 */
-	if (likely (len > 0))
-		buf = urb->transfer_dma;
-	else
-		buf = 0;
+	buf = urb->transfer_dma;
 
-	/* for zero length DATA stages, STATUS is always IN */
-	if (!buf || is_input)
+	if (is_input)
 		token |= (1 /* "in" */ << 8);
 	/* else it's already initted to "out" pid (0 << 8) */
 
@@ -572,7 +572,7 @@
 	 * control requests may need a terminating data "status" ack;
 	 * bulk ones may need a terminating short packet (zero length).
 	 */
-	if (likely (buf != 0)) {
+	if (likely (urb->transfer_buffer_length != 0)) {
 		int	one_more = 0;
 
 		if (usb_pipecontrol (urb->pipe)) {
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 82f6498..584b8dc 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -55,19 +55,13 @@
 /* enqueuing/finishing log of urbs */
 //#define URB_TRACE
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/usb_isp116x.h>
 #include <linux/platform_device.h>
@@ -77,14 +71,10 @@
 #include <asm/system.h>
 #include <asm/byteorder.h>
 
-#ifndef DEBUG
-#	define	STUB_DEBUG_FILE
-#endif
-
 #include "../core/hcd.h"
 #include "isp116x.h"
 
-#define DRIVER_VERSION	"05 Aug 2005"
+#define DRIVER_VERSION	"03 Nov 2005"
 #define DRIVER_DESC	"ISP116x USB Host Controller Driver"
 
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -164,13 +154,11 @@
 	struct ptd *ptd;
 	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
 	    ? isp116x->atl_bufshrt : isp116x->atl_buflen;
-	int ptd_count = 0;
 
 	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
 	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
 	isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
 	for (ep = isp116x->atl_active; ep; ep = ep->active) {
-		++ptd_count;
 		ptd = &ep->ptd;
 		dump_ptd(ptd);
 		dump_ptd_out_data(ptd, ep->data);
@@ -305,9 +293,8 @@
 		udev = urb->dev;
 		ptd = &ep->ptd;
 		cc = PTD_GET_CC(ptd);
-
-		spin_lock(&urb->lock);
 		short_not_ok = 1;
+		spin_lock(&urb->lock);
 
 		/* Data underrun is special. For allowed underrun
 		   we clear the error and continue as normal. For
@@ -420,7 +407,7 @@
 			ep->nextpid = 0;
 			break;
 		default:
-			BUG_ON(1);
+			BUG();
 		}
 		spin_unlock(&urb->lock);
 	}
@@ -628,8 +615,12 @@
 		u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
 		isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
 		if (intstat & HCINT_UE) {
-			ERR("Unrecoverable error\n");
-			/* What should we do here? Reset?  */
+			ERR("Unrecoverable error, HC is dead!\n");
+			/* IRQ's are off, we do no DMA,
+			   perfectly ready to die ... */
+			hcd->state = HC_STATE_HALT;
+			ret = IRQ_HANDLED;
+			goto done;
 		}
 		if (intstat & HCINT_RHSC)
 			/* When root hub or any of its ports is going
@@ -640,7 +631,6 @@
 		if (intstat & HCINT_RD) {
 			DBG("---- remote wakeup\n");
 			usb_hcd_resume_root_hub(hcd);
-			ret = IRQ_HANDLED;
 		}
 		irqstat &= ~HCuPINT_OPR;
 		ret = IRQ_HANDLED;
@@ -651,6 +641,7 @@
 	}
 
 	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
+      done:
 	spin_unlock(&isp116x->lock);
 	return ret;
 }
@@ -724,6 +715,7 @@
 
 	spin_lock_irqsave(&isp116x->lock, flags);
 	if (!HC_IS_RUNNING(hcd->state)) {
+		kfree(ep);
 		ret = -ENODEV;
 		goto fail;
 	}
@@ -888,7 +880,7 @@
 				     struct usb_host_endpoint *hep)
 {
 	int i;
-	struct isp116x_ep *ep = hep->hcpriv;;
+	struct isp116x_ep *ep = hep->hcpriv;
 
 	if (!ep)
 		return;
@@ -916,8 +908,6 @@
 	return (int)fmnum;
 }
 
-/*----------------------------------------------------------------*/
-
 /*
   Adapted from ohci-hub.c. Currently we don't support autosuspend.
 */
@@ -968,11 +958,10 @@
 	desc->bHubContrCurrent = 0;
 	desc->bNbrPorts = (u8) (reg & 0x3);
 	/* Power switching, device type, overcurrent. */
-	desc->wHubCharacteristics =
-	    (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f));
+	desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
 	desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
 	/* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
-	desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
+	desc->bitmap[0] = 0;
 	desc->bitmap[1] = ~0;
 }
 
@@ -1159,135 +1148,9 @@
 	return ret;
 }
 
-#ifdef	CONFIG_PM
-
-static int isp116x_bus_suspend(struct usb_hcd *hcd)
-{
-	struct isp116x *isp116x = hcd_to_isp116x(hcd);
-	unsigned long flags;
-	u32 val;
-	int ret = 0;
-
-	spin_lock_irqsave(&isp116x->lock, flags);
-
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	switch (val & HCCONTROL_HCFS) {
-	case HCCONTROL_USB_OPER:
-		hcd->state = HC_STATE_QUIESCING;
-		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
-		val |= HCCONTROL_USB_SUSPEND;
-		if (hcd->remote_wakeup)
-			val |= HCCONTROL_RWE;
-		/* Wait for usb transfers to finish */
-		mdelay(2);
-		isp116x_write_reg32(isp116x, HCCONTROL, val);
-		hcd->state = HC_STATE_SUSPENDED;
-		/* Wait for devices to suspend */
-		mdelay(5);
-	case HCCONTROL_USB_SUSPEND:
-		break;
-	case HCCONTROL_USB_RESUME:
-		isp116x_write_reg32(isp116x, HCCONTROL,
-				    (val & ~HCCONTROL_HCFS) |
-				    HCCONTROL_USB_RESET);
-	case HCCONTROL_USB_RESET:
-		ret = -EBUSY;
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	spin_unlock_irqrestore(&isp116x->lock, flags);
-	return ret;
-}
-
-static int isp116x_bus_resume(struct usb_hcd *hcd)
-{
-	struct isp116x *isp116x = hcd_to_isp116x(hcd);
-	u32 val;
-	int ret = -EINPROGRESS;
-
-	msleep(5);
-	spin_lock_irq(&isp116x->lock);
-
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	switch (val & HCCONTROL_HCFS) {
-	case HCCONTROL_USB_SUSPEND:
-		val &= ~HCCONTROL_HCFS;
-		val |= HCCONTROL_USB_RESUME;
-		isp116x_write_reg32(isp116x, HCCONTROL, val);
-	case HCCONTROL_USB_RESUME:
-		break;
-	case HCCONTROL_USB_OPER:
-		/* Without setting power_state here the
-		   SUSPENDED state won't be removed from
-		   sysfs/usbN/power.state as a response to remote
-		   wakeup. Maybe in the future. */
-		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-		ret = 0;
-		break;
-	default:
-		ret = -EBUSY;
-	}
-
-	if (ret != -EINPROGRESS) {
-		spin_unlock_irq(&isp116x->lock);
-		return ret;
-	}
-
-	val = isp116x->rhdesca & RH_A_NDP;
-	while (val--) {
-		u32 stat =
-		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
-		/* force global, not selective, resume */
-		if (!(stat & RH_PS_PSS))
-			continue;
-		DBG("%s: Resuming port %d\n", __func__, val);
-		isp116x_write_reg32(isp116x, RH_PS_POCI, val
-				    ? HCRHPORT2 : HCRHPORT1);
-	}
-	spin_unlock_irq(&isp116x->lock);
-
-	hcd->state = HC_STATE_RESUMING;
-	mdelay(20);
-
-	/* Go operational */
-	spin_lock_irq(&isp116x->lock);
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	isp116x_write_reg32(isp116x, HCCONTROL,
-			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
-	spin_unlock_irq(&isp116x->lock);
-	/* see analogous comment above */
-	hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-	hcd->state = HC_STATE_RUNNING;
-
-	return 0;
-}
-
-
-#else
-
-#define	isp116x_bus_suspend	NULL
-#define	isp116x_bus_resume	NULL
-
-#endif
-
 /*-----------------------------------------------------------------*/
 
-#ifdef STUB_DEBUG_FILE
-
-static inline void create_debug_file(struct isp116x *isp116x)
-{
-}
-
-static inline void remove_debug_file(struct isp116x *isp116x)
-{
-}
-
-#else
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#ifdef CONFIG_DEBUG_FS
 
 static void dump_irq(struct seq_file *s, char *label, u16 mask)
 {
@@ -1311,13 +1174,9 @@
 		   mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : "");
 }
 
-static int proc_isp116x_show(struct seq_file *s, void *unused)
+static int isp116x_show_dbg(struct seq_file *s, void *unused)
 {
 	struct isp116x *isp116x = s->private;
-	struct isp116x_ep *ep;
-	struct urb *urb;
-	unsigned i;
-	char *str;
 
 	seq_printf(s, "%s\n%s version %s\n",
 		   isp116x_to_hcd(isp116x)->product_desc, hcd_name,
@@ -1333,105 +1192,50 @@
 	}
 
 	spin_lock_irq(&isp116x->lock);
-
 	dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB));
 	dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT));
 	dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB));
 	dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT));
-
-	list_for_each_entry(ep, &isp116x->async, schedule) {
-
-		switch (ep->nextpid) {
-		case USB_PID_IN:
-			str = "in";
-			break;
-		case USB_PID_OUT:
-			str = "out";
-			break;
-		case USB_PID_SETUP:
-			str = "setup";
-			break;
-		case USB_PID_ACK:
-			str = "status";
-			break;
-		default:
-			str = "?";
-			break;
-		};
-		seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep,
-			   ep->epnum, str, ep->maxpacket);
-		list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
-			seq_printf(s, "  urb%p, %d/%d\n", urb,
-				   urb->actual_length,
-				   urb->transfer_buffer_length);
-		}
-	}
-	if (!list_empty(&isp116x->async))
-		seq_printf(s, "\n");
-
-	seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE);
-
-	for (i = 0; i < PERIODIC_SIZE; i++) {
-		ep = isp116x->periodic[i];
-		if (!ep)
-			continue;
-		seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]);
-
-		/* DUMB: prints shared entries multiple times */
-		do {
-			seq_printf(s, "   %d/%p (%sdev%d ep%d%s max %d)\n",
-				   ep->period, ep,
-				   (ep->udev->speed ==
-				    USB_SPEED_FULL) ? "" : "ls ",
-				   ep->udev->devnum, ep->epnum,
-				   (ep->epnum ==
-				    0) ? "" : ((ep->nextpid ==
-						USB_PID_IN) ? "in" : "out"),
-				   ep->maxpacket);
-			ep = ep->next;
-		} while (ep);
-	}
+	isp116x_show_regs_seq(isp116x, s);
 	spin_unlock_irq(&isp116x->lock);
 	seq_printf(s, "\n");
 
 	return 0;
 }
 
-static int proc_isp116x_open(struct inode *inode, struct file *file)
+static int isp116x_open_seq(struct inode *inode, struct file *file)
 {
-	return single_open(file, proc_isp116x_show, PDE(inode)->data);
+	return single_open(file, isp116x_show_dbg, inode->u.generic_ip);
 }
 
-static struct file_operations proc_ops = {
-	.open = proc_isp116x_open,
+static struct file_operations isp116x_debug_fops = {
+	.open = isp116x_open_seq,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
-/* expect just one isp116x per system */
-static const char proc_filename[] = "driver/isp116x";
-
-static void create_debug_file(struct isp116x *isp116x)
+static int create_debug_file(struct isp116x *isp116x)
 {
-	struct proc_dir_entry *pde;
-
-	pde = create_proc_entry(proc_filename, 0, NULL);
-	if (pde == NULL)
-		return;
-
-	pde->proc_fops = &proc_ops;
-	pde->data = isp116x;
-	isp116x->pde = pde;
+	isp116x->dentry = debugfs_create_file(hcd_name,
+					      S_IRUGO, NULL, isp116x,
+					      &isp116x_debug_fops);
+	if (!isp116x->dentry)
+		return -ENOMEM;
+	return 0;
 }
 
 static void remove_debug_file(struct isp116x *isp116x)
 {
-	if (isp116x->pde)
-		remove_proc_entry(proc_filename, NULL);
+	debugfs_remove(isp116x->dentry);
 }
 
-#endif
+#else
+
+#define	create_debug_file(d)	0
+#define	remove_debug_file(d)	do{}while(0)
+
+#endif				/* CONFIG_DEBUG_FS */
 
 /*-----------------------------------------------------------------*/
 
@@ -1466,7 +1270,7 @@
 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
 	unsigned long t;
 	u16 clkrdy = 0;
-	int ret = 0, timeout = 15 /* ms */ ;
+	int ret, timeout = 15 /* ms */ ;
 
 	ret = isp116x_sw_reset(isp116x);
 	if (ret)
@@ -1482,7 +1286,7 @@
 			break;
 	}
 	if (!clkrdy) {
-		ERR("Clock not ready after 20ms\n");
+		ERR("Clock not ready after %dms\n", timeout);
 		/* After sw_reset the clock won't report to be ready, if
 		   H_WAKEUP pin is high. */
 		ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
@@ -1572,7 +1376,8 @@
 
 	val = 0;
 	if (board->remote_wakeup_enable) {
-		hcd->can_wakeup = 1;
+		if (!device_can_wakeup(hcd->self.controller))
+			device_init_wakeup(hcd->self.controller, 1);
 		val |= RH_HS_DRWE;
 	}
 	isp116x_write_reg32(isp116x, HCRHSTATUS, val);
@@ -1600,12 +1405,126 @@
 	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
 	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
 
-	isp116x_show_regs(isp116x);
+	isp116x_show_regs_log(isp116x);
 	spin_unlock_irqrestore(&isp116x->lock, flags);
 	return 0;
 }
 
-/*-----------------------------------------------------------------*/
+#ifdef	CONFIG_PM
+
+static int isp116x_bus_suspend(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	unsigned long flags;
+	u32 val;
+	int ret = 0;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_OPER:
+		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
+		val |= HCCONTROL_USB_SUSPEND;
+		if (device_may_wakeup(&hcd->self.root_hub->dev))
+			val |= HCCONTROL_RWE;
+		/* Wait for usb transfers to finish */
+		mdelay(2);
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+		/* Wait for devices to suspend */
+		mdelay(5);
+	case HCCONTROL_USB_SUSPEND:
+		break;
+	case HCCONTROL_USB_RESUME:
+		isp116x_write_reg32(isp116x, HCCONTROL,
+				    (val & ~HCCONTROL_HCFS) |
+				    HCCONTROL_USB_RESET);
+	case HCCONTROL_USB_RESET:
+		ret = -EBUSY;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return ret;
+}
+
+static int isp116x_bus_resume(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	u32 val;
+
+	msleep(5);
+	spin_lock_irq(&isp116x->lock);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_SUSPEND:
+		val &= ~HCCONTROL_HCFS;
+		val |= HCCONTROL_USB_RESUME;
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+	case HCCONTROL_USB_RESUME:
+		break;
+	case HCCONTROL_USB_OPER:
+		spin_unlock_irq(&isp116x->lock);
+		/* Without setting power_state here the
+		   SUSPENDED state won't be removed from
+		   sysfs/usbN/power.state as a response to remote
+		   wakeup. Maybe in the future. */
+		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+		return 0;
+	default:
+		/* HCCONTROL_USB_RESET: this may happen, when during
+		   suspension the HC lost power. Reinitialize completely */
+		spin_unlock_irq(&isp116x->lock);
+		DBG("Chip has been reset while suspended. Reinit from scratch.\n");
+		isp116x_reset(hcd);
+		isp116x_start(hcd);
+		isp116x_hub_control(hcd, SetPortFeature,
+				    USB_PORT_FEAT_POWER, 1, NULL, 0);
+		if ((isp116x->rhdesca & RH_A_NDP) == 2)
+			isp116x_hub_control(hcd, SetPortFeature,
+					    USB_PORT_FEAT_POWER, 2, NULL, 0);
+		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+		return 0;
+	}
+
+	val = isp116x->rhdesca & RH_A_NDP;
+	while (val--) {
+		u32 stat =
+		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
+		/* force global, not selective, resume */
+		if (!(stat & RH_PS_PSS))
+			continue;
+		DBG("%s: Resuming port %d\n", __func__, val);
+		isp116x_write_reg32(isp116x, RH_PS_POCI, val
+				    ? HCRHPORT2 : HCRHPORT1);
+	}
+	spin_unlock_irq(&isp116x->lock);
+
+	hcd->state = HC_STATE_RESUMING;
+	msleep(20);
+
+	/* Go operational */
+	spin_lock_irq(&isp116x->lock);
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	isp116x_write_reg32(isp116x, HCCONTROL,
+			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
+	spin_unlock_irq(&isp116x->lock);
+	/* see analogous comment above */
+	hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+	hcd->state = HC_STATE_RUNNING;
+
+	return 0;
+}
+
+#else
+
+#define	isp116x_bus_suspend	NULL
+#define	isp116x_bus_resume	NULL
+
+#endif
 
 static struct hc_driver isp116x_hc_driver = {
 	.description = hcd_name,
@@ -1735,12 +1654,19 @@
 	}
 
 	ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);
-	if (ret != 0)
+	if (ret)
 		goto err6;
 
-	create_debug_file(isp116x);
+	ret = create_debug_file(isp116x);
+	if (ret) {
+		ERR("Couldn't create debugfs entry\n");
+		goto err7;
+	}
+
 	return 0;
 
+      err7:
+	usb_remove_hcd(hcd);
       err6:
 	usb_put_hcd(hcd);
       err5:
@@ -1762,13 +1688,9 @@
 */
 static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 {
-	int ret = 0;
-
-	VDBG("%s: state %x\n", __func__, state);
-
+	VDBG("%s: state %x\n", __func__, state.event);
 	dev->dev.power.power_state = state;
-
-	return ret;
+	return 0;
 }
 
 /*
@@ -1776,13 +1698,9 @@
 */
 static int isp116x_resume(struct platform_device *dev)
 {
-	int ret = 0;
-
-	VDBG("%s:  state %x\n", __func__, dev->dev.power.power_state);
-
+	VDBG("%s:  state %x\n", __func__, dev->power.power_state.event);
 	dev->dev.power.power_state = PMSG_ON;
-
-	return ret;
+	return 0;
 }
 
 #else
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index c6fec96..a1b7c38 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -259,7 +259,7 @@
 
 	struct isp116x_platform_data *board;
 
-	struct proc_dir_entry *pde;
+	struct dentry *dentry;
 	unsigned long stat1, stat2, stat4, stat8, stat16;
 
 	/* HC registers */
@@ -450,7 +450,7 @@
 	isp116x_write_data32(isp116x, (u32) val);
 }
 
-#define isp116x_show_reg(d,r) {					\
+#define isp116x_show_reg_log(d,r,s) {				\
 	if ((r) < 0x20) {			                \
 		DBG("%-12s[%02x]: %08x\n", #r,			\
 			r, isp116x_read_reg32(d, r));		\
@@ -459,35 +459,60 @@
 			r, isp116x_read_reg16(d, r));	    	\
 	}							\
 }
+#define isp116x_show_reg_seq(d,r,s) {				\
+	if ((r) < 0x20) {					\
+		seq_printf(s, "%-12s[%02x]: %08x\n", #r,	\
+			r, isp116x_read_reg32(d, r));		\
+	} else {						\
+		seq_printf(s, "%-12s[%02x]:     %04x\n", #r,	\
+			r, isp116x_read_reg16(d, r));		\
+	}							\
+}
 
-static inline void isp116x_show_regs(struct isp116x *isp116x)
+#define isp116x_show_regs(d,type,s) {			\
+	isp116x_show_reg_##type(d, HCREVISION, s);	\
+	isp116x_show_reg_##type(d, HCCONTROL, s);	\
+	isp116x_show_reg_##type(d, HCCMDSTAT, s);	\
+	isp116x_show_reg_##type(d, HCINTSTAT, s);	\
+	isp116x_show_reg_##type(d, HCINTENB, s);	\
+	isp116x_show_reg_##type(d, HCFMINTVL, s);	\
+	isp116x_show_reg_##type(d, HCFMREM, s);		\
+	isp116x_show_reg_##type(d, HCFMNUM, s);		\
+	isp116x_show_reg_##type(d, HCLSTHRESH, s);	\
+	isp116x_show_reg_##type(d, HCRHDESCA, s);	\
+	isp116x_show_reg_##type(d, HCRHDESCB, s);	\
+	isp116x_show_reg_##type(d, HCRHSTATUS, s);	\
+	isp116x_show_reg_##type(d, HCRHPORT1, s);	\
+	isp116x_show_reg_##type(d, HCRHPORT2, s);	\
+	isp116x_show_reg_##type(d, HCHWCFG, s);		\
+	isp116x_show_reg_##type(d, HCDMACFG, s);	\
+	isp116x_show_reg_##type(d, HCXFERCTR, s);	\
+	isp116x_show_reg_##type(d, HCuPINT, s);		\
+	isp116x_show_reg_##type(d, HCuPINTENB, s);	\
+	isp116x_show_reg_##type(d, HCCHIPID, s);	\
+	isp116x_show_reg_##type(d, HCSCRATCH, s);	\
+	isp116x_show_reg_##type(d, HCITLBUFLEN, s);	\
+	isp116x_show_reg_##type(d, HCATLBUFLEN, s);	\
+	isp116x_show_reg_##type(d, HCBUFSTAT, s);	\
+	isp116x_show_reg_##type(d, HCRDITL0LEN, s);	\
+	isp116x_show_reg_##type(d, HCRDITL1LEN, s);	\
+}
+
+/*
+   Dump registers for debugfs.
+*/
+static inline void isp116x_show_regs_seq(struct isp116x *isp116x,
+					  struct seq_file *s)
 {
-	isp116x_show_reg(isp116x, HCREVISION);
-	isp116x_show_reg(isp116x, HCCONTROL);
-	isp116x_show_reg(isp116x, HCCMDSTAT);
-	isp116x_show_reg(isp116x, HCINTSTAT);
-	isp116x_show_reg(isp116x, HCINTENB);
-	isp116x_show_reg(isp116x, HCFMINTVL);
-	isp116x_show_reg(isp116x, HCFMREM);
-	isp116x_show_reg(isp116x, HCFMNUM);
-	isp116x_show_reg(isp116x, HCLSTHRESH);
-	isp116x_show_reg(isp116x, HCRHDESCA);
-	isp116x_show_reg(isp116x, HCRHDESCB);
-	isp116x_show_reg(isp116x, HCRHSTATUS);
-	isp116x_show_reg(isp116x, HCRHPORT1);
-	isp116x_show_reg(isp116x, HCRHPORT2);
-	isp116x_show_reg(isp116x, HCHWCFG);
-	isp116x_show_reg(isp116x, HCDMACFG);
-	isp116x_show_reg(isp116x, HCXFERCTR);
-	isp116x_show_reg(isp116x, HCuPINT);
-	isp116x_show_reg(isp116x, HCuPINTENB);
-	isp116x_show_reg(isp116x, HCCHIPID);
-	isp116x_show_reg(isp116x, HCSCRATCH);
-	isp116x_show_reg(isp116x, HCITLBUFLEN);
-	isp116x_show_reg(isp116x, HCATLBUFLEN);
-	isp116x_show_reg(isp116x, HCBUFSTAT);
-	isp116x_show_reg(isp116x, HCRDITL0LEN);
-	isp116x_show_reg(isp116x, HCRDITL1LEN);
+	isp116x_show_regs(isp116x, seq, s);
+}
+
+/*
+   Dump registers to syslog.
+*/
+static inline void isp116x_show_regs_log(struct isp116x *isp116x)
+{
+	isp116x_show_regs(isp116x, log, NULL);
 }
 
 #if defined(URB_TRACE)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index bf1d9ab..a4b1240 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -75,13 +75,6 @@
  */
  
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#	define DEBUG
-#else
-#	undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -802,7 +795,6 @@
 	int temp;
 	int i;
 	struct urb_priv *priv;
-	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.
@@ -811,11 +803,7 @@
 	 */ 
 	spin_lock_irq(&ohci->lock);
 	disable (ohci);
-	for (i = 0; i < root->maxchild; i++) {
-		if (root->children [i])
-			usb_set_device_state (root->children[i],
-				USB_STATE_NOTATTACHED);
-	}
+	usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
 	if (!list_empty (&ohci->pending))
 		ohci_dbg(ohci, "abort schedule...\n");
 	list_for_each_entry (priv, &ohci->pending, pending) {
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 72e3b12..4b2226d 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -372,7 +372,7 @@
 					& ohci->hc_control)
 				== OHCI_USB_OPER
 			&& time_after (jiffies, ohci->next_statechange)
-			&& usb_trylock_device (hcd->self.root_hub)
+			&& usb_trylock_device (hcd->self.root_hub) == 0
 			) {
 		ohci_vdbg (ohci, "autosuspend\n");
 		(void) ohci_bus_suspend (hcd);
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 9d65ec3..acde886 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -26,18 +26,12 @@
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
-
-
-#define PMM_NPS_MODE           1
-#define PMM_GLOBAL_MODE        2
-#define PMM_PERPORT_MODE       3
+#include <asm/arch/ohci.h>
 
 #define PXA_UHC_MAX_PORTNUM    3
 
 #define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
 
-static int pxa27x_ohci_pmm_state;
-
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
       Ports are powered continuously.
@@ -50,8 +44,6 @@
  */
 static int pxa27x_ohci_select_pmm( int mode )
 {
-	pxa27x_ohci_pmm_state = mode;
-
 	switch ( mode ) {
 	case PMM_NPS_MODE:
 		UHCRHDA |= RH_A_NPS;
@@ -71,7 +63,6 @@
 			"Invalid mode %d, set to non-power switch mode.\n", 
 			mode );
 
-		pxa27x_ohci_pmm_state = PMM_NPS_MODE;
 		UHCRHDA |= RH_A_NPS;
 	}
 
@@ -82,8 +73,13 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void pxa27x_start_hc(struct platform_device *dev)
+static int pxa27x_start_hc(struct device *dev)
 {
+	int retval = 0;
+	struct pxaohci_platform_data *inf;
+
+	inf = dev->platform_data;
+
 	pxa_set_cken(CKEN10_USBHOST, 1);
 
 	UHCHR |= UHCHR_FHR;
@@ -94,21 +90,11 @@
 	while (UHCHR & UHCHR_FSBIR)
 		cpu_relax();
 
-	/* This could be properly abstracted away through the
-	   device data the day more machines are supported and
-	   their differences can be figured out correctly. */
-	if (machine_is_mainstone()) {
-		/* setup Port1 GPIO pin. */
-		pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
-		pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+	if (inf->init)
+		retval = inf->init(dev);
 
-		/* Set the Power Control Polarity Low and Power Sense
-		   Polarity Low to active low. Supply power to USB ports. */
-		UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-			~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
-		pxa27x_ohci_pmm_state = PMM_PERPORT_MODE;
-	}
+	if (retval < 0)
+		return retval;
 
 	UHCHR &= ~UHCHR_SSE;
 
@@ -117,10 +103,19 @@
 	/* Clear any OTG Pin Hold */
 	if (PSSR & PSSR_OTGPH)
 		PSSR |= PSSR_OTGPH;
+
+	return 0;
 }
 
-static void pxa27x_stop_hc(struct platform_device *dev)
+static void pxa27x_stop_hc(struct device *dev)
 {
+	struct pxaohci_platform_data *inf;
+
+	inf = dev->platform_data;
+
+	if (inf->exit)
+		inf->exit(dev);
+
 	UHCHR |= UHCHR_FHR;
 	udelay(11);
 	UHCHR &= ~UHCHR_FHR;
@@ -147,22 +142,27 @@
  * through the hotplug entry's driver_data.
  *
  */
-int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
-			  struct platform_device *dev)
+int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
 {
 	int retval;
 	struct usb_hcd *hcd;
+	struct pxaohci_platform_data *inf;
 
-	if (dev->resource[1].flags != IORESOURCE_IRQ) {
+	inf = pdev->dev.platform_data;
+
+	if (!inf)
+		return -ENODEV;
+
+	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
 		pr_debug ("resource[1] is not IORESOURCE_IRQ");
 		return -ENOMEM;
 	}
 
-	hcd = usb_create_hcd (driver, &dev->dev, "pxa27x");
+	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
 	if (!hcd)
 		return -ENOMEM;
-	hcd->rsrc_start = dev->resource[0].start;
-	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+	hcd->rsrc_start = pdev->resource[0].start;
+	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		pr_debug("request_mem_region failed");
@@ -177,18 +177,22 @@
 		goto err2;
 	}
 
-	pxa27x_start_hc(dev);
+	if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
+		pr_debug("pxa27x_start_hc failed");
+		goto err3;
+	}
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state);
+	pxa27x_ohci_select_pmm(inf->port_mode);
 
 	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+	retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
 	if (retval == 0)
 		return retval;
 
-	pxa27x_stop_hc(dev);
+	pxa27x_stop_hc(&pdev->dev);
+ err3:
 	iounmap(hcd->regs);
  err2:
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -211,10 +215,10 @@
  * context, normally "rmmod", "apmd", or something similar.
  *
  */
-void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
+void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
 	usb_remove_hcd(hcd);
-	pxa27x_stop_hc(dev);
+	pxa27x_stop_hc(&pdev->dev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
@@ -292,15 +296,12 @@
 
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
-	int ret;
-
 	pr_debug ("In ohci_hcd_pxa27x_drv_probe");
 
 	if (usb_disabled())
 		return -ENODEV;
 
-	ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
-	return ret;
+	return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
 }
 
 static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
@@ -308,31 +309,55 @@
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	usb_hcd_pxa27x_remove(hcd, pdev);
+	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef	CONFIG_PM
+static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
-//	struct usb_hcd *hcd = platform_get_drvdata(dev);
-	printk("%s: not implemented yet\n", __FUNCTION__);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	pxa27x_stop_hc(&pdev->dev);
+	hcd->state = HC_STATE_SUSPENDED;
+	pdev->dev.power.power_state = PMSG_SUSPEND;
 
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev)
+static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
 {
-//	struct usb_hcd *hcd = platform_get_drvdata(dev);
-	printk("%s: not implemented yet\n", __FUNCTION__);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int status;
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
+		return status;
+
+	pdev->dev.power.power_state = PMSG_ON;
+	usb_hcd_resume_root_hub(hcd);
 
 	return 0;
 }
+#endif
 
 
 static struct platform_driver ohci_hcd_pxa27x_driver = {
 	.probe		= ohci_hcd_pxa27x_drv_probe,
 	.remove		= ohci_hcd_pxa27x_drv_remove,
+#ifdef CONFIG_PM
 	.suspend	= ohci_hcd_pxa27x_drv_suspend, 
 	.resume		= ohci_hcd_pxa27x_drv_resume,
+#endif
 	.driver		= {
 		.name	= "pxa27x-ohci",
 	},
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index e46528c..3ef2c0c 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -9,12 +9,6 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
-
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index a7722a6..517360b 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -32,13 +32,6 @@
 #undef	PACKET_TRACE
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#	define DEBUG
-#else
-#	undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -1581,7 +1574,9 @@
 	hcd->state = HC_STATE_RUNNING;
 
 	if (sl811->board) {
-		hcd->can_wakeup = sl811->board->can_wakeup;
+		if (!device_can_wakeup(hcd->self.controller))
+			device_init_wakeup(hcd->self.controller,
+				sl811->board->can_wakeup);
 		hcd->power_budget = sl811->board->power * 2;
 	}
 
@@ -1805,9 +1800,10 @@
 	 * let's assume it'd only be powered to enable remote wakeup.
 	 */
 	if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND
-			|| !hcd->can_wakeup) {
+			|| !device_can_wakeup(&hcd->self.root_hub->dev)) {
 		sl811->port1 = 0;
 		port_power(sl811, 1);
+		usb_root_hub_lost_power(hcd->self.root_hub);
 		return 0;
 	}
 
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index e73faf8..5056b74 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -38,7 +38,7 @@
 /* MACROS                                                             */
 /*====================================================================*/
 
-#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG)
+#if defined(DEBUG) || defined(PCMCIA_DEBUG)
 
 static int pc_debug = 0;
 module_param(pc_debug, int, 0644);
@@ -129,7 +129,8 @@
 	resources[2].end   = base_addr + 1;
 
 	/* The driver core will probe for us.  We know sl811-hcd has been
-	 * initialized already because of the link order dependency.
+	 * initialized already because of the link order dependency created
+	 * by referencing "sl811h_driver".
 	 */
 	platform_dev.name = sl811h_driver.name;
 	return platform_device_register(&platform_dev);
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 151154d..5832953 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -2,8 +2,8 @@
  * UHCI-specific debugging code. Invaluable when something
  * goes wrong, but don't get in my face.
  *
- * Kernel visible pointers are surrounded in []'s and bus
- * visible pointers are surrounded in ()'s
+ * Kernel visible pointers are surrounded in []s and bus
+ * visible pointers are surrounded in ()s
  *
  * (C) Copyright 1999 Linus Torvalds
  * (C) Copyright 1999-2001 Johannes Erdfelt
@@ -19,7 +19,7 @@
 
 static struct dentry *uhci_debugfs_root = NULL;
 
-/* Handle REALLY large printk's so we don't overflow buffers */
+/* Handle REALLY large printks so we don't overflow buffers */
 static inline void lprintk(char *buf)
 {
 	char *p;
@@ -160,7 +160,7 @@
 			}
 
 			if (active && ni > i) {
-				out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i);
+				out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i);
 				tmp = ntmp;
 				td = ntd;
 				i = ni;
@@ -173,7 +173,7 @@
 	if (list_empty(&urbp->queue_list) || urbp->queued)
 		goto out;
 
-	out += sprintf(out, "%*sQueued QH's:\n", -space, "--");
+	out += sprintf(out, "%*sQueued QHs:\n", -space, "--");
 
 	head = &urbp->queue_list;
 	tmp = head->next;
@@ -197,7 +197,7 @@
 	}
 
 #ifdef CONFIG_PROC_FS
-static const char *qh_names[] = {
+static const char * const qh_names[] = {
   "skel_int128_qh", "skel_int64_qh",
   "skel_int32_qh", "skel_int16_qh",
   "skel_int8_qh", "skel_int4_qh",
@@ -464,7 +464,7 @@
 		} while (tmp != head);
 	}
 
-	out += sprintf(out, "Skeleton QH's\n");
+	out += sprintf(out, "Skeleton QHs\n");
 
 	for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
 		int shown = 0;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 79efaf7..dfe121d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -23,11 +23,6 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -67,10 +62,10 @@
 
 /*
  * debug = 0, no debugging messages
- * debug = 1, dump failed URB's except for stalls
- * debug = 2, dump all failed URB's (including stalls)
+ * debug = 1, dump failed URBs except for stalls
+ * debug = 2, dump all failed URBs (including stalls)
  *            show all queues in /debug/uhci/[pci_addr]
- * debug = 3, show all TD's in URB's when dumping
+ * debug = 3, show all TDs in URBs when dumping
  */
 #ifdef DEBUG
 static int debug = 1;
@@ -93,7 +88,7 @@
 #define FSBR_DELAY	msecs_to_jiffies(50)
 
 /* When we timeout an idle transfer for FSBR, we'll switch it over to */
-/* depth first traversal. We'll do it in groups of this number of TD's */
+/* depth first traversal. We'll do it in groups of this number of TDs */
 /* to make sure it doesn't hog all of the bandwidth */
 #define DEPTH_INTERVAL 5
 
@@ -478,8 +473,6 @@
 	struct dentry *dentry;
 
 	hcd->uses_new_polling = 1;
-	if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
-		hcd->can_wakeup = 1;		/* Assume it supports PME# */
 
 	dentry = debugfs_create_file(hcd->self.bus_name,
 			S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
@@ -573,7 +566,7 @@
 	uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH;
 
 	/* This dummy TD is to work around a bug in Intel PIIX controllers */
-	uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) |
+	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
 		(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
 	uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
 
@@ -735,8 +728,9 @@
 
 	dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
 
-	/* We aren't in D3 state anymore, we do that even if dead as I
-	 * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0
+	/* Since we aren't in D3 any more, it's safe to set this flag
+	 * even if the controller was dead.  It might not even be dead
+	 * any more, if the firmware or quirks code has reset it.
 	 */
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	mb();
@@ -755,8 +749,12 @@
 	check_and_reset_hc(uhci);
 	configure_hc(uhci);
 
-	if (uhci->rh_state == UHCI_RH_RESET)
+	if (uhci->rh_state == UHCI_RH_RESET) {
+
+		/* The controller had to be reset */
+		usb_root_hub_lost_power(hcd->self.root_hub);
 		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+	}
 
 	spin_unlock_irq(&uhci->lock);
 
@@ -882,7 +880,7 @@
 
 init_failed:
 	if (kmem_cache_destroy(uhci_up_cachep))
-		warn("not all urb_priv's were freed!");
+		warn("not all urb_privs were freed!");
 
 up_failed:
 	debugfs_remove(uhci_debugfs_root);
@@ -900,7 +898,7 @@
 	pci_unregister_driver(&uhci_pci_driver);
 	
 	if (kmem_cache_destroy(uhci_up_cachep))
-		warn("not all urb_priv's were freed!");
+		warn("not all urb_privs were freed!");
 
 	debugfs_remove(uhci_debugfs_root);
 	kfree(errbuf);
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index e576db5..8b4b887 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -71,8 +71,6 @@
 #define   USBLEGSUP_RWC		0x8f00	/* the R/WC bits */
 #define   USBLEGSUP_RO		0x5040	/* R/O and reserved bits */
 
-#define UHCI_NULL_DATA_SIZE	0x7FF	/* for UHCI controller TD */
-
 #define UHCI_PTR_BITS		cpu_to_le32(0x000F)
 #define UHCI_PTR_TERM		cpu_to_le32(0x0001)
 #define UHCI_PTR_QH		cpu_to_le32(0x0002)
@@ -168,9 +166,11 @@
 #define TD_TOKEN_EXPLEN_MASK	0x7FF		/* expected length, encoded as n - 1 */
 #define TD_TOKEN_PID_MASK	0xFF
 
-#define uhci_explen(len)	((len) << TD_TOKEN_EXPLEN_SHIFT)
+#define uhci_explen(len)	((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
+					TD_TOKEN_EXPLEN_SHIFT)
 
-#define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK)
+#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \
+					1) & TD_TOKEN_EXPLEN_MASK)
 #define uhci_toggle(token)	(((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1)
 #define uhci_endpoint(token)	(((token) >> 15) & 0xf)
 #define uhci_devaddr(token)	(((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f)
@@ -223,10 +223,10 @@
  */
 
 /*
- * 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
- * a skeleton of QH's for each predefined Interrupt latency, low-speed
+ * The UHCI driver places Interrupt, Control and Bulk into QHs both
+ * to group together TDs for one transfer, and also to facilitate queuing
+ * of URBs. To make it easy to insert entries into the schedule, we have
+ * a skeleton of QHs for each predefined Interrupt latency, low-speed
  * control, full-speed control and terminating QH (see explanation for
  * the terminating QH below).
  *
@@ -257,8 +257,8 @@
  *   reclamation.
  *
  * Isochronous transfers are stored before the start of the skeleton
- * schedule and don't use QH's. While the UHCI spec doesn't forbid the
- * use of QH's for Isochronous, it doesn't use them either. And the spec
+ * schedule and don't use QHs. While the UHCI spec doesn't forbid the
+ * use of QHs for Isochronous, it doesn't use them either. And the spec
  * says that queues never advance on an error completion status, which
  * makes them totally unsuitable for Isochronous transfers.
  */
@@ -359,7 +359,7 @@
 	struct dma_pool *td_pool;
 
 	struct uhci_td *term_td;	/* Terminating TD, see UHCI bug */
-	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QH's */
+	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QHs */
 
 	spinlock_t lock;
 
@@ -389,22 +389,22 @@
 	unsigned long resuming_ports;
 	unsigned long ports_timeout;		/* Time to stop signalling */
 
-	/* Main list of URB's currently controlled by this HC */
+	/* Main list of URBs currently controlled by this HC */
 	struct list_head urb_list;
 
-	/* List of QH's that are done, but waiting to be unlinked (race) */
+	/* List of QHs that are done, but waiting to be unlinked (race) */
 	struct list_head qh_remove_list;
 	unsigned int qh_remove_age;		/* Age in frames */
 
-	/* List of TD's that are done, but waiting to be freed (race) */
+	/* List of TDs that are done, but waiting to be freed (race) */
 	struct list_head td_remove_list;
 	unsigned int td_remove_age;		/* Age in frames */
 
-	/* List of asynchronously unlinked URB's */
+	/* List of asynchronously unlinked URBs */
 	struct list_head urb_remove_list;
 	unsigned int urb_remove_age;		/* Age in frames */
 
-	/* List of URB's awaiting completion callback */
+	/* List of URBs awaiting completion callback */
 	struct list_head complete_list;
 
 	int rh_numports;			/* Number of root-hub ports */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 7e46887..b607600 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -80,7 +80,7 @@
 }
 
 /*
- * We insert Isochronous URB's directly into the frame list at the beginning
+ * We insert Isochronous URBs directly into the frame list at the beginning
  */
 static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum)
 {
@@ -369,7 +369,7 @@
 				uhci_fixup_toggle(urb,
 					uhci_toggle(td_token(lltd)) ^ 1));
 
-	/* All qh's in the queue need to link to the next queue */
+	/* All qhs in the queue need to link to the next queue */
 	urbp->qh->link = eurbp->qh->link;
 
 	wmb();			/* Make sure we flush everything */
@@ -502,7 +502,7 @@
 	}
 
 	/* Check to see if the remove list is empty. Set the IOC bit */
-	/* to force an interrupt so we can remove the TD's*/
+	/* to force an interrupt so we can remove the TDs*/
 	if (list_empty(&uhci->td_remove_list))
 		uhci_set_next_interrupt(uhci);
 
@@ -596,7 +596,7 @@
 		return -ENOMEM;
 
 	uhci_add_td_to_urb(urb, td);
-	uhci_fill_td(td, status, destination | uhci_explen(7),
+	uhci_fill_td(td, status, destination | uhci_explen(8),
 		urb->setup_dma);
 
 	/*
@@ -612,7 +612,7 @@
 	}
 
 	/*
-	 * Build the DATA TD's
+	 * Build the DATA TDs
 	 */
 	while (len > 0) {
 		int pktsze = len;
@@ -628,7 +628,7 @@
 		destination ^= TD_TOKEN_TOGGLE;
 	
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1),
+		uhci_fill_td(td, status, destination | uhci_explen(pktsze),
 			data);
 
 		data += pktsze;
@@ -658,7 +658,7 @@
 
 	uhci_add_td_to_urb(urb, td);
 	uhci_fill_td(td, status | TD_CTRL_IOC,
-		destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0);
+		destination | uhci_explen(0), 0);
 
 	qh = uhci_alloc_qh(uhci);
 	if (!qh)
@@ -744,7 +744,7 @@
 
 	urb->actual_length = 0;
 
-	/* The rest of the TD's (but the last) are data */
+	/* The rest of the TDs (but the last) are data */
 	tmp = tmp->next;
 	while (tmp != head && tmp->next != head) {
 		unsigned int ctrlstat;
@@ -848,7 +848,7 @@
 		status |= TD_CTRL_SPD;
 
 	/*
-	 * Build the DATA TD's
+	 * Build the DATA TDs
 	 */
 	do {	/* Allow zero length packets */
 		int pktsze = maxsze;
@@ -864,7 +864,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) |
+		uhci_fill_td(td, status, destination | uhci_explen(pktsze) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
 			data);
@@ -890,7 +890,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) |
+		uhci_fill_td(td, status, destination | uhci_explen(0) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
 			data);
@@ -1025,7 +1025,7 @@
 	list_for_each_entry(up, &uhci->urb_list, urb_list) {
 		struct urb *u = up->urb;
 
-		/* look for pending URB's with identical pipe handle */
+		/* look for pending URBs with identical pipe handle */
 		if ((urb->pipe == u->pipe) && (urb->dev == u->dev) &&
 		    (u->status == -EINPROGRESS) && (u != urb)) {
 			if (!last_urb)
@@ -1092,7 +1092,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1),
+		uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length),
 			urb->transfer_dma + urb->iso_frame_desc[i].offset);
 
 		if (i + 1 >= urb->number_of_packets)
@@ -1355,7 +1355,7 @@
 
 	uhci_delete_queued_urb(uhci, urb);
 
-	/* The interrupt loop will reclaim the QH's */
+	/* The interrupt loop will reclaim the QHs */
 	uhci_remove_qh(uhci, urbp->qh);
 	urbp->qh = NULL;
 }
@@ -1413,7 +1413,7 @@
 	list_for_each_entry(td, head, list) {
 		/*
 		 * Make sure we don't do the last one (since it'll have the
-		 * TERM bit set) as well as we skip every so many TD's to
+		 * TERM bit set) as well as we skip every so many TDs to
 		 * make sure it doesn't hog the bandwidth
 		 */
 		if (td->list.next != head && (count % DEPTH_INTERVAL) ==
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 1d973bc..0498711 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -962,7 +962,6 @@
  */
 static struct usb_driver mdc800_usb_driver =
 {
-	.owner =	THIS_MODULE,
 	.name =		"mdc800",
 	.probe =	mdc800_usb_probe,
 	.disconnect =	mdc800_usb_disconnect,
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 950543a..458f2ac 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -160,7 +160,6 @@
 static struct usb_device_id mts_usb_ids [];
 
 static struct usb_driver mts_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"microtekX6",
 	.probe =	mts_usb_probe,
 	.disconnect =	mts_usb_disconnect,
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 1e53934..509dd0a 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -273,6 +273,20 @@
 	  To compile this driver as a module, choose M here: the module will be
 	  called ati_remote.
 
+config USB_ATI_REMOTE2
+	tristate "ATI / Philips USB RF remote control"
+	depends on USB && INPUT
+	---help---
+	  Say Y here if you want to use an ATI or Philips USB RF remote control.
+	  These are RF remotes with USB receivers.
+	  ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
+	  and is also available as a separate product.
+	  This driver provides mouse pointer, left and right mouse buttons,
+	  and maps all the other remote buttons to keypress events.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ati_remote2.
+
 config USB_KEYSPAN_REMOTE
 	tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
 	depends on USB && INPUT && EXPERIMENTAL
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 07cb17d..d512d9f 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -28,6 +28,7 @@
 
 obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
 obj-$(CONFIG_USB_ATI_REMOTE)	+= ati_remote.o
+obj-$(CONFIG_USB_ATI_REMOTE2)	+= ati_remote2.o
 obj-$(CONFIG_USB_HID)		+= usbhid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_KBTAB)		+= kbtab.o
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index a32558b..df29b80 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -261,7 +261,6 @@
 MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
 
 static struct usb_driver usb_acecad_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usb_acecad",
 	.probe =	usb_acecad_probe,
 	.disconnect =	usb_acecad_disconnect,
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index 0e2505c..a6693b0 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -338,7 +338,7 @@
  * the bitmap which comes from the tablet. This hides the
  * issue that the F_keys are not sequentially numbered.
  */
-static int macroKeyEvents[] = {
+static const int macroKeyEvents[] = {
 	KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
 	KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
 	KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
@@ -2093,7 +2093,7 @@
 	/* Programming the tablet macro keys needs to be done with a for loop
 	 * as the keycodes are discontiguous.
 	 */
-	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
+	for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
 		set_bit(macroKeyEvents[i], inputdev->keybit);
 
 	/*
@@ -2135,7 +2135,7 @@
 	 * not an error :-)
 	 */
 
-	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
+	for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
 		aiptek->curSetting.programmableDelay = speeds[i];
 		(void)aiptek_program_tablet(aiptek);
 		if (aiptek->inputdev->absmax[ABS_X] > 0) {
@@ -2190,7 +2190,6 @@
 static void aiptek_disconnect(struct usb_interface *intf);
 
 static struct usb_driver aiptek_driver = {
-	.owner = THIS_MODULE,
 	.name = "aiptek",
 	.probe = aiptek_probe,
 	.disconnect = aiptek_disconnect,
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index 15840db..1949b54 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -452,7 +452,6 @@
 }
 
 static struct usb_driver atp_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "appletouch",
 	.probe		= atp_probe,
 	.disconnect	= atp_disconnect,
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 9a2a47d..f7bdc50 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -96,6 +96,7 @@
 #include <linux/usb.h>
 #include <linux/usb_input.h>
 #include <linux/wait.h>
+#include <linux/jiffies.h>
 
 /*
  * Module and Version Information, Module Parameters
@@ -146,7 +147,7 @@
 static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
 
 /* Acceleration curve for directional control pad */
-static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
+static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 
 /* Duplicate event filtering time.
  * Sequential, identical KIND_FILTERED inputs with less than
@@ -197,7 +198,7 @@
 #define KIND_ACCEL      7   /* Directional keypad - left, right, up, down.*/
 
 /* Translation table from hardware messages to input events. */
-static struct {
+static const struct {
 	short kind;
 	unsigned char data1, data2;
 	int type;
@@ -295,7 +296,6 @@
 
 /* usb specific object to register with the usb subsystem */
 static struct usb_driver ati_remote_driver = {
-	.owner        = THIS_MODULE,
 	.name         = "ati_remote",
 	.probe        = ati_remote_probe,
 	.disconnect   = ati_remote_disconnect,
@@ -472,7 +472,7 @@
 		/* Filter duplicate events which happen "too close" together. */
 		if ((ati_remote->old_data[0] == data[1]) &&
 			(ati_remote->old_data[1] == data[2]) &&
-			((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
+			time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) {
 			ati_remote->repeat_count++;
 		} else {
 			ati_remote->repeat_count = 0;
@@ -507,16 +507,16 @@
 	 * pad down, so we increase acceleration, ramping up over two seconds to
 	 * a maximum speed.  The acceleration curve is #defined above.
 	 */
-	if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) {
+	if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
 		acc = 1;
 		ati_remote->acc_jiffies = jiffies;
 	}
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3))  acc = accel[0];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2))  acc = accel[1];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1))  acc = accel[2];
-	else if ((jiffies - ati_remote->acc_jiffies) < HZ )        acc = accel[3];
-	else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1))  acc = accel[5];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3)))  acc = accel[0];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2)))  acc = accel[1];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1)))  acc = accel[2];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + HZ))         acc = accel[3];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1)))  acc = accel[5];
 	else acc = accel[6];
 
 	input_regs(dev, regs);
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
new file mode 100644
index 0000000..ab1a1ae
--- /dev/null
+++ b/drivers/usb/input/ati_remote2.c
@@ -0,0 +1,477 @@
+/*
+ * ati_remote2 - ATI/Philips USB RF remote driver
+ *
+ * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/usb_input.h>
+
+#define DRIVER_DESC    "ATI/Philips USB RF remote driver"
+#define DRIVER_VERSION "0.1"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
+MODULE_LICENSE("GPL");
+
+static unsigned int mode_mask = 0x1F;
+module_param(mode_mask, uint, 0644);
+MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
+
+static struct usb_device_id ati_remote2_id_table[] = {
+	{ USB_DEVICE(0x0471, 0x0602) },	/* ATI Remote Wonder II */
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
+
+static struct {
+	int hw_code;
+	int key_code;
+} ati_remote2_key_table[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0c, KEY_POWER },
+	{ 0x0d, KEY_MUTE },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x20, KEY_CHANNELUP },
+	{ 0x21, KEY_CHANNELDOWN },
+	{ 0x28, KEY_FORWARD },
+	{ 0x29, KEY_REWIND },
+	{ 0x2c, KEY_PLAY },
+	{ 0x30, KEY_PAUSE },
+	{ 0x31, KEY_STOP },
+	{ 0x37, KEY_RECORD },
+	{ 0x38, KEY_DVD },
+	{ 0x39, KEY_TV },
+	{ 0x54, KEY_MENU },
+	{ 0x58, KEY_UP },
+	{ 0x59, KEY_DOWN },
+	{ 0x5a, KEY_LEFT },
+	{ 0x5b, KEY_RIGHT },
+	{ 0x5c, KEY_OK },
+	{ 0x78, KEY_A },
+	{ 0x79, KEY_B },
+	{ 0x7a, KEY_C },
+	{ 0x7b, KEY_D },
+	{ 0x7c, KEY_E },
+	{ 0x7d, KEY_F },
+	{ 0x82, KEY_ENTER },
+	{ 0x8e, KEY_VENDOR },
+	{ 0x96, KEY_COFFEE },
+	{ 0xa9, BTN_LEFT },
+	{ 0xaa, BTN_RIGHT },
+	{ 0xbe, KEY_QUESTION },
+	{ 0xd5, KEY_FRONT },
+	{ 0xd0, KEY_EDIT },
+	{ 0xf9, KEY_INFO },
+	{ (0x00 << 8) | 0x3f, KEY_PROG1 },
+	{ (0x01 << 8) | 0x3f, KEY_PROG2 },
+	{ (0x02 << 8) | 0x3f, KEY_PROG3 },
+	{ (0x03 << 8) | 0x3f, KEY_PROG4 },
+	{ (0x04 << 8) | 0x3f, KEY_PC },
+	{ 0, KEY_RESERVED }
+};
+
+struct ati_remote2 {
+	struct input_dev *idev;
+	struct usb_device *udev;
+
+	struct usb_interface *intf[2];
+	struct usb_endpoint_descriptor *ep[2];
+	struct urb *urb[2];
+	void *buf[2];
+	dma_addr_t buf_dma[2];
+
+	unsigned long jiffies;
+	int mode;
+
+	char name[64];
+	char phys[64];
+};
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static void ati_remote2_disconnect(struct usb_interface *interface);
+
+static struct usb_driver ati_remote2_driver = {
+	.name       = "ati_remote2",
+	.probe      = ati_remote2_probe,
+	.disconnect = ati_remote2_disconnect,
+	.id_table   = ati_remote2_id_table,
+};
+
+static int ati_remote2_open(struct input_dev *idev)
+{
+	struct ati_remote2 *ar2 = idev->private;
+	int r;
+
+	r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
+	if (r) {
+		dev_err(&ar2->intf[0]->dev,
+			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+		return r;
+	}
+	r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
+	if (r) {
+		usb_kill_urb(ar2->urb[0]);
+		dev_err(&ar2->intf[1]->dev,
+			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+		return r;
+	}
+
+	return 0;
+}
+
+static void ati_remote2_close(struct input_dev *idev)
+{
+	struct ati_remote2 *ar2 = idev->private;
+
+	usb_kill_urb(ar2->urb[0]);
+	usb_kill_urb(ar2->urb[1]);
+}
+
+static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+	struct input_dev *idev = ar2->idev;
+	u8 *data = ar2->buf[0];
+
+	if (data[0] > 4) {
+		dev_err(&ar2->intf[0]->dev,
+			"Unknown mode byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	if (!((1 << data[0]) & mode_mask))
+		return;
+
+	input_regs(idev, regs);
+	input_event(idev, EV_REL, REL_X, (s8) data[1]);
+	input_event(idev, EV_REL, REL_Y, (s8) data[2]);
+	input_sync(idev);
+}
+
+static int ati_remote2_lookup(unsigned int hw_code)
+{
+	int i;
+
+	for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+		if (ati_remote2_key_table[i].hw_code == hw_code)
+			return i;
+
+	return -1;
+}
+
+static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+	struct input_dev *idev = ar2->idev;
+	u8 *data = ar2->buf[1];
+	int hw_code, index;
+
+	if (data[0] > 4) {
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown mode byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	hw_code = data[2];
+	/*
+	 * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
+	 * Use the mode byte to figure out which one was pressed.
+	 */
+	if (hw_code == 0x3f) {
+		/*
+		 * For some incomprehensible reason the mouse pad generates
+		 * events which look identical to the events from the last
+		 * pressed mode key. Naturally we don't want to generate key
+		 * events for the mouse pad so we filter out any subsequent
+		 * events from the same mode key.
+		 */
+		if (ar2->mode == data[0])
+			return;
+
+		if (data[1] == 0)
+			ar2->mode = data[0];
+
+		hw_code |= data[0] << 8;
+	}
+
+	if (!((1 << data[0]) & mode_mask))
+		return;
+
+	index = ati_remote2_lookup(hw_code);
+	if (index < 0) {
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown code byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	switch (data[1]) {
+	case 0:	/* release */
+		break;
+	case 1:	/* press */
+		ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]);
+		break;
+	case 2:	/* repeat */
+
+		/* No repeat for mouse buttons. */
+		if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
+		    ati_remote2_key_table[index].key_code == BTN_RIGHT)
+			return;
+
+		if (!time_after_eq(jiffies, ar2->jiffies))
+			return;
+
+		ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]);
+		break;
+	default:
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown state byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	input_regs(idev, regs);
+	input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+	input_sync(idev);
+}
+
+static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs)
+{
+	struct ati_remote2 *ar2 = urb->context;
+	int r;
+
+	switch (urb->status) {
+	case 0:
+		ati_remote2_input_mouse(ar2, regs);
+		break;
+	case -ENOENT:
+	case -EILSEQ:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dev_dbg(&ar2->intf[0]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+		return;
+	default:
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+	}
+
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r)
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs)
+{
+	struct ati_remote2 *ar2 = urb->context;
+	int r;
+
+	switch (urb->status) {
+	case 0:
+		ati_remote2_input_key(ar2, regs);
+		break;
+	case -ENOENT:
+	case -EILSEQ:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dev_dbg(&ar2->intf[1]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+		return;
+	default:
+		dev_err(&ar2->intf[1]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+	}
+
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r)
+		dev_err(&ar2->intf[1]->dev,
+			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static int ati_remote2_input_init(struct ati_remote2 *ar2)
+{
+	struct input_dev *idev;
+	int i;
+
+	idev = input_allocate_device();
+	if (!idev)
+		return -ENOMEM;
+
+	ar2->idev = idev;
+	idev->private = ar2;
+
+	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
+	idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+		set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
+
+	idev->rep[REP_DELAY]  = 250;
+	idev->rep[REP_PERIOD] = 33;
+
+	idev->open = ati_remote2_open;
+	idev->close = ati_remote2_close;
+
+	idev->name = ar2->name;
+	idev->phys = ar2->phys;
+
+	usb_to_input_id(ar2->udev, &idev->id);
+	idev->cdev.dev = &ar2->udev->dev;
+
+	i = input_register_device(idev);
+	if (i)
+		input_free_device(idev);
+
+	return i;
+}
+
+static int ati_remote2_urb_init(struct ati_remote2 *ar2)
+{
+	struct usb_device *udev = ar2->udev;
+	int i, pipe, maxp;
+
+	for (i = 0; i < 2; i++) {
+		ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
+		if (!ar2->buf[i])
+			return -ENOMEM;
+
+		ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+		if (!ar2->urb[i])
+			return -ENOMEM;
+
+		pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress);
+		maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+		maxp = maxp > 4 ? 4 : maxp;
+
+		usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp,
+				 i ? ati_remote2_complete_key : ati_remote2_complete_mouse,
+				 ar2, ar2->ep[i]->bInterval);
+		ar2->urb[i]->transfer_dma = ar2->buf_dma[i];
+		ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	}
+
+	return 0;
+}
+
+static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (ar2->urb[i])
+			usb_free_urb(ar2->urb[i]);
+
+		if (ar2->buf[i])
+			usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+	}
+}
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	struct ati_remote2 *ar2;
+	int r;
+
+	if (alt->desc.bInterfaceNumber)
+		return -ENODEV;
+
+	ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL);
+	if (!ar2)
+		return -ENOMEM;
+
+	ar2->udev = udev;
+
+	ar2->intf[0] = interface;
+	ar2->ep[0] = &alt->endpoint[0].desc;
+
+	ar2->intf[1] = usb_ifnum_to_if(udev, 1);
+	r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
+	if (r)
+		goto fail1;
+	alt = ar2->intf[1]->cur_altsetting;
+	ar2->ep[1] = &alt->endpoint[0].desc;
+
+	r = ati_remote2_urb_init(ar2);
+	if (r)
+		goto fail2;
+
+	usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
+	strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
+
+	strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
+
+	r = ati_remote2_input_init(ar2);
+	if (r)
+		goto fail2;
+
+	usb_set_intfdata(interface, ar2);
+
+	return 0;
+
+ fail2:
+	ati_remote2_urb_cleanup(ar2);
+
+	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+ fail1:
+	kfree(ar2);
+
+	return r;
+}
+
+static void ati_remote2_disconnect(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+
+	if (alt->desc.bInterfaceNumber)
+		return;
+
+	ar2 = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	input_unregister_device(ar2->idev);
+
+	ati_remote2_urb_cleanup(ar2);
+
+	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+
+	kfree(ar2);
+}
+
+static int __init ati_remote2_init(void)
+{
+	int r;
+
+	r = usb_register(&ati_remote2_driver);
+	if (r)
+		printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r);
+	else
+		printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n");
+
+	return r;
+}
+
+static void __exit ati_remote2_exit(void)
+{
+	usb_deregister(&ati_remote2_driver);
+}
+
+module_init(ati_remote2_init);
+module_exit(ati_remote2_exit);
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h
index 26ca5b8..b44d398 100644
--- a/drivers/usb/input/fixp-arith.h
+++ b/drivers/usb/input/fixp-arith.h
@@ -38,7 +38,7 @@
 #define FRAC_MASK ((1<<FRAC_N)-1)
 
 // Not to be used directly. Use fixp_{cos,sin}
-static fixp_t cos_table[45] = {
+static const fixp_t cos_table[45] = {
 	0x0100,	0x00FF,	0x00FF,	0x00FE,	0x00FD,	0x00FC,	0x00FA,	0x00F8,
 	0x00F6,	0x00F3,	0x00F0,	0x00ED,	0x00E9,	0x00E6,	0x00E2,	0x00DD,
 	0x00D9,	0x00D4,	0x00CF,	0x00C9,	0x00C4,	0x00BE,	0x00B8,	0x00B1,
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index a3e44ef..5f52979 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1454,7 +1454,7 @@
  * Alphabetically sorted blacklist by quirk type.
  */
 
-static struct hid_blacklist {
+static const struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
 	unsigned quirks;
@@ -1930,7 +1930,6 @@
 MODULE_DEVICE_TABLE (usb, hid_usb_ids);
 
 static struct usb_driver hid_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbhid",
 	.probe =	hid_probe,
 	.disconnect =	hid_disconnect,
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 1220a50..192a03b 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -39,7 +39,7 @@
 
 #define unk	KEY_UNKNOWN
 
-static unsigned char hid_keyboard[256] = {
+static const unsigned char hid_keyboard[256] = {
 	  0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
 	 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
 	  4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
@@ -58,7 +58,7 @@
 	150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
 };
 
-static struct {
+static const struct {
 	__s32 x;
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 440377c..4dff847 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -826,7 +826,6 @@
 
 
 static /* const */ struct usb_driver hiddev_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hiddev",
 	.probe =	hiddev_usbd_probe,
 };
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index 4a50acb..7618ae5 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -250,7 +250,6 @@
 MODULE_DEVICE_TABLE(usb, itmtouch_ids);
 
 static struct usb_driver itmtouch_driver = {
-	.owner =        THIS_MODULE,
 	.name =         "itmtouch",
 	.probe =        itmtouch_probe,
 	.disconnect =   itmtouch_disconnect,
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index fd48e74e..f6d5cea 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -197,7 +197,6 @@
 }
 
 static struct usb_driver kbtab_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kbtab",
 	.probe =	kbtab_probe,
 	.disconnect =	kbtab_disconnect,
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index a32cfe5..b4a051b 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -95,7 +95,7 @@
  * Currently there are 15 and 17 button models so RESERVED codes
  * are blank areas in the mapping.
  */
-static int keyspan_key_table[] = {
+static const int keyspan_key_table[] = {
 	KEY_RESERVED,		/* 0 is just a place holder. */
 	KEY_RESERVED,
 	KEY_STOP,
@@ -559,7 +559,6 @@
  */
 static struct usb_driver keyspan_driver =
 {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan_remote",
 	.probe =	keyspan_probe,
 	.disconnect =	keyspan_disconnect,
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 52cc18c..f018953 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -310,7 +310,6 @@
 MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
 
 static struct usb_driver mtouchusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "mtouchusb",
 	.probe		= mtouchusb_probe,
 	.disconnect	= mtouchusb_disconnect,
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index b747623..fdf0f78 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -441,7 +441,6 @@
 MODULE_DEVICE_TABLE (usb, powermate_devices);
 
 static struct usb_driver powermate_driver = {
-	.owner =	THIS_MODULE,
         .name =         "powermate",
         .probe =        powermate_probe,
         .disconnect =   powermate_disconnect,
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 7420c6b..3b3c7b4 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -1,7 +1,7 @@
 /******************************************************************************
  * touchkitusb.c  --  Driver for eGalax TouchKit USB Touchscreens
  *
- * Copyright (C) 2004 by Daniel Ritz
+ * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
@@ -41,15 +41,13 @@
 #define TOUCHKIT_MAX_YC			0x07ff
 #define TOUCHKIT_YC_FUZZ		0x0
 #define TOUCHKIT_YC_FLAT		0x0
-#define TOUCHKIT_REPORT_DATA_SIZE	8
+#define TOUCHKIT_REPORT_DATA_SIZE	16
 
 #define TOUCHKIT_DOWN			0x01
-#define TOUCHKIT_POINT_TOUCH		0x81
-#define TOUCHKIT_POINT_NOTOUCH		0x80
 
-#define TOUCHKIT_GET_TOUCHED(dat)	((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0)
-#define TOUCHKIT_GET_X(dat)		(((dat)[3] << 7) | (dat)[4])
-#define TOUCHKIT_GET_Y(dat)		(((dat)[1] << 7) | (dat)[2])
+#define TOUCHKIT_PKT_TYPE_MASK		0xFE
+#define TOUCHKIT_PKT_TYPE_REPT		0x80
+#define TOUCHKIT_PKT_TYPE_DIAG		0x0A
 
 #define DRIVER_VERSION			"v0.1"
 #define DRIVER_AUTHOR			"Daniel Ritz <daniel.ritz@gmx.ch>"
@@ -62,6 +60,8 @@
 struct touchkit_usb {
 	unsigned char *data;
 	dma_addr_t data_dma;
+	char buffer[TOUCHKIT_REPORT_DATA_SIZE];
+	int buf_len;
 	struct urb *irq;
 	struct usb_device *udev;
 	struct input_dev *input;
@@ -77,11 +77,128 @@
 	{}
 };
 
+/* helpers to read the data */
+static inline int touchkit_get_touched(char *data)
+{
+	return (data[0] & TOUCHKIT_DOWN) ? 1 : 0;
+}
+
+static inline int touchkit_get_x(char *data)
+{
+	return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F);
+}
+
+static inline int touchkit_get_y(char *data)
+{
+	return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F);
+}
+
+
+/* processes one input packet. */
+static void touchkit_process_pkt(struct touchkit_usb *touchkit,
+                                 struct pt_regs *regs, char *pkt)
+{
+	int x, y;
+
+	/* only process report packets */
+	if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT)
+		return;
+
+	if (swap_xy) {
+		y = touchkit_get_x(pkt);
+		x = touchkit_get_y(pkt);
+	} else {
+		x = touchkit_get_x(pkt);
+		y = touchkit_get_y(pkt);
+	}
+
+	input_regs(touchkit->input, regs);
+	input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt));
+	input_report_abs(touchkit->input, ABS_X, x);
+	input_report_abs(touchkit->input, ABS_Y, y);
+	input_sync(touchkit->input);
+}
+
+
+static int touchkit_get_pkt_len(char *buf)
+{
+	switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) {
+	case TOUCHKIT_PKT_TYPE_REPT:
+		return 5;
+
+	case TOUCHKIT_PKT_TYPE_DIAG:
+		return buf[1] + 2;
+	}
+
+	return 0;
+}
+
+static void touchkit_process(struct touchkit_usb *touchkit, int len,
+                             struct pt_regs *regs)
+{
+	char *buffer;
+	int pkt_len, buf_len, pos;
+
+	/* if the buffer contains data, append */
+	if (unlikely(touchkit->buf_len)) {
+		int tmp;
+
+		/* if only 1 byte in buffer, add another one to get length */
+		if (touchkit->buf_len == 1)
+			touchkit->buffer[1] = touchkit->data[0];
+
+		pkt_len = touchkit_get_pkt_len(touchkit->buffer);
+
+		/* unknown packet: drop everything */
+		if (!pkt_len)
+			return;
+
+		/* append, process */
+		tmp = pkt_len - touchkit->buf_len;
+		memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp);
+		touchkit_process_pkt(touchkit, regs, touchkit->buffer);
+
+		buffer = touchkit->data + tmp;
+		buf_len = len - tmp;
+	} else {
+		buffer = touchkit->data;
+		buf_len = len;
+	}
+
+	/* only one byte left in buffer */
+	if (unlikely(buf_len == 1)) {
+		touchkit->buffer[0] = buffer[0];
+		touchkit->buf_len = 1;
+		return;
+	}
+
+	/* loop over the buffer */
+	pos = 0;
+	while (pos < buf_len) {
+		/* get packet len */
+		pkt_len = touchkit_get_pkt_len(buffer + pos);
+
+		/* unknown packet: drop everything */
+		if (unlikely(!pkt_len))
+			return;
+
+		/* full packet: process */
+		if (likely(pkt_len <= buf_len)) {
+			touchkit_process_pkt(touchkit, regs, buffer + pos);
+		} else {
+			/* incomplete packet: save in buffer */
+			memcpy(touchkit->buffer, buffer + pos, buf_len - pos);
+			touchkit->buf_len = buf_len - pos;
+		}
+		pos += pkt_len;
+	}
+}
+
+
 static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct touchkit_usb *touchkit = urb->context;
 	int retval;
-	int x, y;
 
 	switch (urb->status) {
 	case 0:
@@ -105,20 +222,7 @@
 		goto exit;
 	}
 
-	if (swap_xy) {
-		y = TOUCHKIT_GET_X(touchkit->data);
-		x = TOUCHKIT_GET_Y(touchkit->data);
-	} else {
-		x = TOUCHKIT_GET_X(touchkit->data);
-		y = TOUCHKIT_GET_Y(touchkit->data);
-	}
-
-	input_regs(touchkit->input, regs);
-	input_report_key(touchkit->input, BTN_TOUCH,
-	                 TOUCHKIT_GET_TOUCHED(touchkit->data));
-	input_report_abs(touchkit->input, ABS_X, x);
-	input_report_abs(touchkit->input, ABS_Y, y);
-	input_sync(touchkit->input);
+	touchkit_process(touchkit, urb->actual_length, regs);
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -267,7 +371,6 @@
 MODULE_DEVICE_TABLE(usb, touchkit_devices);
 
 static struct usb_driver touchkit_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "touchkitusb",
 	.probe		= touchkit_probe,
 	.disconnect	= touchkit_disconnect,
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 226b6f9..2f3edc2 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -345,7 +345,6 @@
 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
 
 static struct usb_driver usb_kbd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbkbd",
 	.probe =	usb_kbd_probe,
 	.disconnect =	usb_kbd_disconnect,
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 230f6b1..af52613 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -226,7 +226,6 @@
 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
 
 static struct usb_driver usb_mouse_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "usbmouse",
 	.probe		= usb_mouse_probe,
 	.disconnect	= usb_mouse_disconnect,
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index dc099bb..48df4cf 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -945,7 +945,6 @@
 }
 
 static struct usb_driver wacom_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"wacom",
 	.probe =	wacom_probe,
 	.disconnect =	wacom_disconnect,
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 43112f0..e278489 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -70,7 +70,7 @@
 
 #define XPAD_PKT_LEN 32
 
-static struct xpad_device {
+static const struct xpad_device {
 	u16 idVendor;
 	u16 idProduct;
 	char *name;
@@ -81,13 +81,13 @@
 	{ 0x0000, 0x0000, "X-Box pad" }
 };
 
-static signed short xpad_btn[] = {
+static const signed short xpad_btn[] = {
 	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,	/* "analog" buttons */
 	BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR,	/* start/back/sticks */
 	-1						/* terminating entry */
 };
 
-static signed short xpad_abs[] = {
+static const signed short xpad_abs[] = {
 	ABS_X, ABS_Y,		/* left stick */
 	ABS_RX, ABS_RY,		/* right stick */
 	ABS_Z, ABS_RZ,		/* triggers left/right */
@@ -316,7 +316,6 @@
 }
 
 static struct usb_driver xpad_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "xpad",
 	.probe		= xpad_probe,
 	.disconnect	= xpad_disconnect,
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index f526aeb..1bfc105 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -987,7 +987,6 @@
 }
 
 static struct usb_driver yealink_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "yealink",
 	.probe		= usb_probe,
 	.disconnect	= usb_disconnect,
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
index 27b23c5..18d8eaf 100644
--- a/drivers/usb/media/dabusb.c
+++ b/drivers/usb/media/dabusb.c
@@ -812,7 +812,6 @@
 MODULE_DEVICE_TABLE (usb, dabusb_ids);
 
 static struct usb_driver dabusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"dabusb",
 	.probe =	dabusb_probe,
 	.disconnect =	dabusb_disconnect,
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
index 7503f5b..6a5700e 100644
--- a/drivers/usb/media/dsbr100.c
+++ b/drivers/usb/media/dsbr100.c
@@ -150,7 +150,6 @@
 
 /* USB subsystem interface */
 static struct usb_driver usb_dsbr100_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"dsbr100",
 	.probe =	usb_dsbr100_probe,
 	.disconnect =	usb_dsbr100_disconnect,
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
index ba41fc7..a42c222 100644
--- a/drivers/usb/media/ibmcam.c
+++ b/drivers/usb/media/ibmcam.c
@@ -3457,7 +3457,7 @@
 	if(init_model3_input) {
 		if (debug > 0)
 			info("Setting input to RCA.");
-		for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) {
+		for (i=0; i < ARRAY_SIZE(initData); i++) {
 			ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
 		}
 	}
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
index 9fe2c27..e2ede58 100644
--- a/drivers/usb/media/konicawc.c
+++ b/drivers/usb/media/konicawc.c
@@ -77,14 +77,14 @@
 static int sharpness =	MAX_SHARPNESS/2;
 static int whitebal =	3*(MAX_WHITEBAL/4);
 
-static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
+static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
 
 /* These FPS speeds are from the windows config box. They are
  * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
  * real fps.
  */
 
-static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
+static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
 			       { 24, 40, 48, 60, 72, 80, 100 },
 			       { 18, 30, 36, 45, 54, 60, 75  },
 			       { 6,  10, 12, 15, 18, 21, 25  } };
@@ -95,7 +95,7 @@
 	u8	cmd;
 };
 
-static struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
+static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
 					  { 160, 136, 0xa },
 					  { 176, 144, 0x4 },
 					  { 320, 240, 0x5 } };
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 036c485..3a0e8ce 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -211,7 +211,7 @@
 
 /* Number of times to retry a failed I2C transaction. Increase this if you
  * are getting "Failed to read sensor ID..." */
-static int i2c_detect_tries = 5;
+static const int i2c_detect_tries = 5;
 
 /* MMX support is present in kernel and CPU. Checked upon decomp module load. */
 #if defined(__i386__) || defined(__x86_64__)
@@ -6008,7 +6008,6 @@
 }
 
 static struct usb_driver ov511_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ov511",
 	.id_table =	device_table,
 	.probe =	ov51x_probe,
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 5309919..359c4b2 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -109,7 +109,7 @@
 #define PT_RESET_CONTROL_FORMATTER		0x02
 #define PT_STATUS_FORMATTER			0x03
 
-static char *size2name[PSZ_MAX] =
+static const char *size2name[PSZ_MAX] =
 {
 	"subQCIF",
 	"QSIF",
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 5524fd7..09ca612 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -111,7 +111,6 @@
 static void usb_pwc_disconnect(struct usb_interface *intf);
 
 static struct usb_driver pwc_driver = {
-	.owner =		THIS_MODULE,
 	.name =			"Philips webcam",	/* name */
 	.id_table =		pwc_device_table,
 	.probe =		usb_pwc_probe,		/* probe() */
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
index f69e443..b2ae29a 100644
--- a/drivers/usb/media/se401.c
+++ b/drivers/usb/media/se401.c
@@ -1401,7 +1401,6 @@
 }
 
 static struct usb_driver se401_driver = {
-	.owner		= THIS_MODULE,
         .name		= "se401",
         .id_table	= device_table,
 	.probe		= se401_probe,
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index b2e66e3..8d1a1c3 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -1316,7 +1316,7 @@
 	struct v4l2_control ctrl;
 	struct v4l2_queryctrl *qctrl;
 	struct v4l2_rect* rect;
-	u8 i = 0, n = 0;
+	u8 i = 0;
 	int err = 0;
 
 	if (!(cam->state & DEV_INITIALIZED)) {
@@ -1352,7 +1352,7 @@
 		return err;
 
 	if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
-		DBG(3, "Compressed video format is active, quality %d", 
+		DBG(3, "Compressed video format is active, quality %d",
 		    cam->compression.quality)
 	else
 		DBG(3, "Uncompressed video format is active")
@@ -1364,9 +1364,8 @@
 		}
 
 	if (s->set_ctrl) {
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
-			if (s->qctrl[i].id != 0 && 
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+			if (s->qctrl[i].id != 0 &&
 			    !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
 				ctrl.id = s->qctrl[i].id;
 				ctrl.value = qctrl[i].default_value;
@@ -1388,7 +1387,7 @@
 		init_waitqueue_head(&cam->wait_stream);
 		cam->nreadbuffers = 2;
 		memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
-		memcpy(&(s->_rect), &(s->cropcap.defrect), 
+		memcpy(&(s->_rect), &(s->cropcap.defrect),
 		       sizeof(struct v4l2_rect));
 		cam->state |= DEV_INITIALIZED;
 	}
@@ -1810,13 +1809,12 @@
 	{
 		struct sn9c102_sensor* s = cam->sensor;
 		struct v4l2_queryctrl qc;
-		u8 i, n;
+		u8 i;
 
 		if (copy_from_user(&qc, arg, sizeof(qc)))
 			return -EFAULT;
 
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
 			if (qc.id && qc.id == s->qctrl[i].id) {
 				memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
 				if (copy_to_user(arg, &qc, sizeof(qc)))
@@ -1852,7 +1850,7 @@
 	{
 		struct sn9c102_sensor* s = cam->sensor;
 		struct v4l2_control ctrl;
-		u8 i, n;
+		u8 i;
 		int err = 0;
 
 		if (!s->set_ctrl)
@@ -1861,8 +1859,7 @@
 		if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
 			return -EFAULT;
 
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
 			if (ctrl.id == s->qctrl[i].id) {
 				if (ctrl.value < s->qctrl[i].minimum ||
 				    ctrl.value > s->qctrl[i].maximum)
@@ -2544,7 +2541,7 @@
 	unsigned int i, n;
 	int err = 0, r;
 
-	n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
+	n = ARRAY_SIZE(sn9c102_id_table);
 	for (i = 0; i < n-1; i++)
 		if (le16_to_cpu(udev->descriptor.idVendor) == 
 		    sn9c102_id_table[i].idVendor &&
@@ -2711,7 +2708,6 @@
 
 
 static struct usb_driver sn9c102_usb_driver = {
-	.owner =      THIS_MODULE,
 	.name =       "sn9c102",
 	.id_table =   sn9c102_id_table,
 	.probe =      sn9c102_usb_probe,
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
index 0fd0fa9..774038b 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -1477,7 +1477,6 @@
 }
 
 static struct usb_driver stv680_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"stv680",
 	.probe =	stv680_probe,
 	.disconnect =	stv680_disconnect,
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h
index 4459406..b0551cd 100644
--- a/drivers/usb/media/stv680.h
+++ b/drivers/usb/media/stv680.h
@@ -151,7 +151,7 @@
 };
 
 
-static unsigned char red[256] = { 
+static const unsigned char red[256] = {
 	0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
 	18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, 
 	44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, 
@@ -176,7 +176,7 @@
 	220, 220, 221, 221 
 }; 
 
-static unsigned char green[256] = {
+static const unsigned char green[256] = {
 	0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
 	21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, 
 	50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, 
@@ -201,7 +201,7 @@
 	245, 245, 246, 246 
 }; 
 
-static unsigned char blue[256] = {
+static const unsigned char blue[256] = {
 	0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
 	23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, 
 	55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, 
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
index 24efb21..4bd1133 100644
--- a/drivers/usb/media/usbvideo.c
+++ b/drivers/usb/media/usbvideo.c
@@ -725,7 +725,7 @@
 		/* Allocate user_data separately because of kmalloc's limits */
 		if (num_extra > 0) {
 			up->user_size = num_cams * num_extra;
-			up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
+			up->user_data = kmalloc(up->user_size, GFP_KERNEL);
 			if (up->user_data == NULL) {
 				err("%s: Failed to allocate user_data (%d. bytes)",
 				    __FUNCTION__, up->user_size);
@@ -955,7 +955,7 @@
 	.ioctl =  usbvideo_v4l_ioctl,
 	.llseek = no_llseek,
 };
-static struct video_device usbvideo_template = {
+static const struct video_device usbvideo_template = {
 	.owner =      THIS_MODULE,
 	.type =       VID_TYPE_CAPTURE,
 	.hardware =   VID_HARDWARE_CPIA,
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 0bc0b12..1c73155 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1257,7 +1257,6 @@
 MODULE_DEVICE_TABLE(usb, vicam_table);
 
 static struct usb_driver vicam_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "vicam",
 	.probe		= vicam_probe,
 	.disconnect	= vicam_disconnect,
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index 67612c8..04d6933 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -2958,7 +2958,7 @@
 	};
 
 	#define V4L1_IOCTL(cmd) \
-	        ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
+	        ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
 	        v4l1_ioctls[_IOC_NR((cmd))] : "?")
 
 	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
@@ -3554,7 +3554,7 @@
 
 
 	/* Allocate 2 bytes of memory for camera control USB transfers */
-	if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
+	if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
 		DBG(1,"Couldn't allocate memory for camera control transfers")
 		err = -ENOMEM;
 		goto fail;
@@ -3562,7 +3562,7 @@
 	memset(cam->control_buffer, 0, 2);
 
 	/* Allocate 8 bytes of memory for USB data transfers to the FSB */
-	if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
+	if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
 		DBG(1, "Couldn't allocate memory for data "
 		       "transfers to the FSB")
 		err = -ENOMEM;
@@ -3668,7 +3668,6 @@
 
 
 static struct usb_driver w9968cf_usb_driver = {
-	.owner =      THIS_MODULE,
 	.name =       "w9968cf",
 	.id_table =   winbond_id_table,
 	.probe =      w9968cf_usb_probe,
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index b293db3..449b250 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -767,7 +767,7 @@
 	        memset (bep, 0, sizeof (auerbuf_t));
                 bep->list = bcp;
                 INIT_LIST_HEAD (&bep->buff_list);
-                bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL);
+                bep->bufp = kmalloc (bufsize, GFP_KERNEL);
                 if (!bep->bufp)
 			goto bl_fail;
                 bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
@@ -1123,7 +1123,7 @@
                 }
         }
         if (!cp->intbufp) {
-                cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL);
+                cp->intbufp = kmalloc (irqsize, GFP_KERNEL);
                 if (!cp->intbufp) {
                         ret = -ENOMEM;
                         goto intoend;
@@ -2103,7 +2103,6 @@
 
 /* Standard usb driver struct */
 static struct usb_driver auerswald_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"auerswald",
 	.probe =	auerswald_probe,
 	.disconnect =	auerswald_disconnect,
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index b33044d..6671317 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -50,7 +50,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver cytherm_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cytherm",
 	.probe =	cytherm_probe,
 	.disconnect =	cytherm_disconnect,
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index c815520..3824df3 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -227,7 +227,6 @@
 }
 
 static struct usb_driver emi26_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "emi26 - firmware loader",
 	.probe		= emi26_probe,
 	.disconnect	= emi26_disconnect,
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 189986a..52fea2e 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -266,7 +266,6 @@
 }
 
 static struct usb_driver emi62_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "emi62 - firmware loader",
 	.probe		= emi62_probe,
 	.disconnect	= emi62_disconnect,
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 1dc3e0f..d8cde10 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -114,7 +114,6 @@
 
 /* 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,
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 7e93ac9..981d8a5 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -763,7 +763,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver ld_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ldusb",
 	.probe =	ld_usb_probe,
 	.disconnect =	ld_usb_disconnect,
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 2703e20..1336745 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -282,7 +282,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver tower_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"legousbtower",
 	.probe =	tower_probe,
 	.disconnect =	tower_disconnect,
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 067a814..605a3c8 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -555,7 +555,6 @@
 }
 
 static struct usb_driver interfacekit_driver = {
-	.owner = THIS_MODULE,
 	.name = "phidgetkit",
 	.probe = interfacekit_probe,
 	.disconnect = interfacekit_disconnect,
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index a30d4a6..b3418d2 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -306,7 +306,6 @@
 }
 
 static struct usb_driver servo_driver = {
-	.owner = THIS_MODULE,
 	.name = "phidgetservo",
 	.probe = servo_probe,
 	.disconnect = servo_disconnect,
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 9590dba..384fa37 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -465,14 +465,14 @@
 
 	rio->rio_dev = dev;
 
-	if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
+	if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
 		err("probe_rio: Not enough memory for the output buffer");
 		usb_deregister_dev(intf, &usb_rio_class);
 		return -ENOMEM;
 	}
 	dbg("probe_rio: obuf address:%p", rio->obuf);
 
-	if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
+	if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
 		err("probe_rio: Not enough memory for the input buffer");
 		usb_deregister_dev(intf, &usb_rio_class);
 		kfree(rio->obuf);
@@ -522,7 +522,6 @@
 MODULE_DEVICE_TABLE (usb, rio_table);
 
 static struct usb_driver rio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"rio500",
 	.probe =	probe_rio,
 	.disconnect =	disconnect_rio,
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 41ef2b6..3260d59 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -863,9 +863,6 @@
 
 	    switch (length) {
 
-		case 0:
-			return ret;
-
 		case 1:
 			if (userbuffer) {
 				if (get_user(swap8, (u8 __user *)userbuffer))
@@ -1221,9 +1218,6 @@
 
 	    switch (length) {
 
-		case 0:
-			return ret;
-
 		case 1:
 
 			ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM,
@@ -2443,8 +2437,8 @@
 	u8 *tempbuf;
 	u16 *tempbufb;
 	size_t written;
-	static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
-	static char bootlogo[] = "(o_ //\\ V_/_";
+	static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
+	static const char bootlogo[] = "(o_ //\\ V_/_";
 
 	/* sisusb->lock is down */
 
@@ -3489,7 +3483,6 @@
 MODULE_DEVICE_TABLE (usb, sisusb_table);
 
 static struct usb_driver sisusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"sisusb",
 	.probe =	sisusb_probe,
 	.disconnect =	sisusb_disconnect,
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 85f3725..cc3dae3 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -371,7 +371,6 @@
 }
 
 static struct usb_driver lcd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usblcd",
 	.probe =	lcd_probe,
 	.disconnect =	lcd_disconnect,
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index 3c93921..877b081 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -148,7 +148,6 @@
 }
 
 static struct usb_driver led_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbled",
 	.probe =	led_probe,
 	.disconnect =	led_disconnect,
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 605a2af..84fa172 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -2134,7 +2134,6 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver usbtest_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbtest",
 	.id_table =	id_table,
 	.probe =	usbtest_probe,
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 1cabe7e..4081990 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -780,7 +780,6 @@
 
 
 static struct usb_driver uss720_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"uss720",
 	.probe =	uss720_probe,
 	.disconnect =	uss720_disconnect,
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 17d0190..6116121 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -97,19 +97,12 @@
 	if (len >= DATA_MAX)
 		len = DATA_MAX;
 
-	/*
-	 * Bulk is easy to shortcut reliably. 
-	 * XXX Other pipe types need consideration. Currently, we overdo it
-	 * and collect garbage for them: better more than less.
-	 */
-	if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) {
-		if (usb_pipein(pipe)) {
-			if (ev_type == 'S')
-				return '<';
-		} else {
-			if (ev_type == 'C')
-				return '>';
-		}
+	if (usb_pipein(pipe)) {
+		if (ev_type == 'S')
+			return '<';
+	} else {
+		if (ev_type == 'C')
+			return '>';
 	}
 
 	/*
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 542120e..5411816 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -912,13 +912,16 @@
 	// ASIX AX88772 10/100
         USB_DEVICE (0x0b95, 0x7720),
         .driver_info = (unsigned long) &ax88772_info,
+}, {
+	// Linksys USB200M Rev 2
+	USB_DEVICE (0x13b1, 0x0018),
+	.driver_info = (unsigned long) &ax88772_info,
 },
 	{ },		// END
 };
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver asix_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"asix",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index 37ef365..be5f5e1 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -934,7 +934,6 @@
 MODULE_DEVICE_TABLE(usb, catc_id_table);
 
 static struct usb_driver catc_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	catc_probe,
 	.disconnect =	catc_disconnect,
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
index c008c98..63f1f3b 100644
--- a/drivers/usb/net/cdc_ether.c
+++ b/drivers/usb/net/cdc_ether.c
@@ -476,7 +476,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver cdc_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_ether",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
index f05cfb8..ec801e8 100644
--- a/drivers/usb/net/cdc_subset.c
+++ b/drivers/usb/net/cdc_subset.c
@@ -306,7 +306,6 @@
 /*-------------------------------------------------------------------------*/
 
 static struct usb_driver cdc_subset_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_subset",
 	.probe =	usbnet_probe,
 	.suspend =	usbnet_suspend,
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index 2455e9a..faf1e86 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -377,7 +377,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver gl620a_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"gl620a",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index b577651..def3bb8 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -175,7 +175,6 @@
  *     kaweth_driver
  ****************************************************************/
 static struct usb_driver kaweth_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	kaweth_probe,
 	.disconnect =	kaweth_disconnect,
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
index b3799b1..78e6a43 100644
--- a/drivers/usb/net/net1080.c
+++ b/drivers/usb/net/net1080.c
@@ -593,7 +593,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver net1080_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"net1080",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 683e3df..156a2f1 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -45,7 +45,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.6.12 (2005/01/13)"
+#define DRIVER_VERSION "v0.6.13 (2005/11/13)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -57,12 +57,14 @@
 
 static int loopback = 0;
 static int mii_mode = 0;
+static char *devid=NULL;
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define	PEGASUS_DEV(pn, vid, pid, flags)	\
 	{.name = pn, .vendor = vid, .device = pid, .private = flags},
 #include "pegasus.h"
 #undef	PEGASUS_DEV
+	{NULL, 0, 0, 0},
 	{NULL, 0, 0, 0}
 };
 
@@ -71,6 +73,7 @@
 	{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
 #include "pegasus.h"
 #undef	PEGASUS_DEV
+	{},
 	{}
 };
 
@@ -79,8 +82,10 @@
 MODULE_LICENSE("GPL");
 module_param(loopback, bool, 0);
 module_param(mii_mode, bool, 0);
+module_param(devid, charp, 0);
 MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
 MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
+MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
 
 /* use ethtool to change the level for any given device */
 static int msg_level = -1;
@@ -113,7 +118,7 @@
 		break;
 	default:
 		if (netif_msg_drv(pegasus))
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
+			dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
 				__FUNCTION__, urb->status);
 	}
 	pegasus->flags &= ~ETH_REGS_CHANGED;
@@ -308,9 +313,9 @@
 	__le16 regdi;
 	int ret;
 
-	ret = set_register(pegasus, PhyCtrl, 0);
-	ret = set_registers(pegasus, PhyAddr, sizeof (data), data);
-	ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ));
+	set_register(pegasus, PhyCtrl, 0);
+	set_registers(pegasus, PhyAddr, sizeof (data), data);
+	set_register(pegasus, PhyCtrl, (indx | PHY_READ));
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, PhyCtrl, 1, data);
 		if (data[0] & PHY_DONE)
@@ -319,12 +324,12 @@
 	if (i < REG_TIMEOUT) {
 		ret = get_registers(pegasus, PhyData, 2, &regdi);
 		*regd = le16_to_cpu(regdi);
-		return 1;
+		return ret;
 	}
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
 
-	return 0;
+	return ret;
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int loc)
@@ -344,20 +349,20 @@
 
 	data[1] = (u8) regd;
 	data[2] = (u8) (regd >> 8);
-	ret = set_register(pegasus, PhyCtrl, 0);
-	ret = set_registers(pegasus, PhyAddr, sizeof(data), data);
-	ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
+	set_register(pegasus, PhyCtrl, 0);
+	set_registers(pegasus, PhyAddr, sizeof(data), data);
+	set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, PhyCtrl, 1, data);
 		if (data[0] & PHY_DONE)
 			break;
 	}
 	if (i < REG_TIMEOUT)
-		return 0;
+		return ret;
 
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return 1;
+	return -ETIMEDOUT;
 }
 
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
@@ -374,9 +379,9 @@
 	__le16 retdatai;
 	int ret;
 
-	ret = set_register(pegasus, EpromCtrl, 0);
-	ret = set_register(pegasus, EpromOffset, index);
-	ret = set_register(pegasus, EpromCtrl, EPROM_READ);
+	set_register(pegasus, EpromCtrl, 0);
+	set_register(pegasus, EpromOffset, index);
+	set_register(pegasus, EpromCtrl, EPROM_READ);
 
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -386,12 +391,12 @@
 	if (i < REG_TIMEOUT) {
 		ret = get_registers(pegasus, EpromData, 2, &retdatai);
 		*retdata = le16_to_cpu(retdatai);
-		return 0;
+		return ret;
 	}
 
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return -1;
+	return -ETIMEDOUT;
 }
 
 #ifdef	PEGASUS_WRITE_EEPROM
@@ -400,8 +405,8 @@
 	__u8 tmp;
 	int ret;
 
-	ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-	ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
+	get_registers(pegasus, EthCtrl2, 1, &tmp);
+	set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
 }
 
 static inline void disable_eprom_write(pegasus_t * pegasus)
@@ -409,9 +414,9 @@
 	__u8 tmp;
 	int ret;
 
-	ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-	ret = set_register(pegasus, EpromCtrl, 0);
-	ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
+	get_registers(pegasus, EthCtrl2, 1, &tmp);
+	set_register(pegasus, EpromCtrl, 0);
+	set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
 }
 
 static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
@@ -420,11 +425,11 @@
 	__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
 	int ret;
 
-	ret = set_registers(pegasus, EpromOffset, 4, d);
+	set_registers(pegasus, EpromOffset, 4, d);
 	enable_eprom_write(pegasus);
-	ret = set_register(pegasus, EpromOffset, index);
-	ret = set_registers(pegasus, EpromData, 2, &data);
-	ret = set_register(pegasus, EpromCtrl, EPROM_WRITE);
+	set_register(pegasus, EpromOffset, index);
+	set_registers(pegasus, EpromData, 2, &data);
+	set_register(pegasus, EpromCtrl, EPROM_WRITE);
 
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -433,10 +438,10 @@
 	}
 	disable_eprom_write(pegasus);
 	if (i < REG_TIMEOUT)
-		return 0;
+		return ret;
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return -1;
+	return -ETIMEDOUT;
 }
 #endif				/* PEGASUS_WRITE_EEPROM */
 
@@ -454,10 +459,9 @@
 static void set_ethernet_addr(pegasus_t * pegasus)
 {
 	__u8 node_id[6];
-	int ret;
 
 	get_node_id(pegasus, node_id);
-	ret = set_registers(pegasus, EthID, sizeof (node_id), node_id);
+	set_registers(pegasus, EthID, sizeof (node_id), node_id);
 	memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
 }
 
@@ -465,30 +469,29 @@
 {
 	__u8 data = 0x8;
 	int i;
-	int ret;
 
-	ret = set_register(pegasus, EthCtrl1, data);
+	set_register(pegasus, EthCtrl1, data);
 	for (i = 0; i < REG_TIMEOUT; i++) {
-		ret = get_registers(pegasus, EthCtrl1, 1, &data);
+		get_registers(pegasus, EthCtrl1, 1, &data);
 		if (~data & 0x08) {
 			if (loopback & 1)
 				break;
 			if (mii_mode && (pegasus->features & HAS_HOME_PNA))
-				ret = set_register(pegasus, Gpio1, 0x34);
+				set_register(pegasus, Gpio1, 0x34);
 			else
-				ret = set_register(pegasus, Gpio1, 0x26);
-			ret = set_register(pegasus, Gpio0, pegasus->features);
-			ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
+				set_register(pegasus, Gpio1, 0x26);
+			set_register(pegasus, Gpio0, pegasus->features);
+			set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
 			break;
 		}
 	}
 	if (i == REG_TIMEOUT)
-		return 1;
+		return -ETIMEDOUT;
 
 	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
 	    usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
-		ret = set_register(pegasus, Gpio0, 0x24);
-		ret = set_register(pegasus, Gpio0, 0x26);
+		set_register(pegasus, Gpio0, 0x24);
+		set_register(pegasus, Gpio0, 0x26);
 	}
 	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
 		__u16 auxmode;
@@ -527,7 +530,7 @@
 		write_mii_word(pegasus, 0, 0x1b, auxmode | 4);
 	}
 
-	return 0;
+	return ret;
 }
 
 static void fill_skb_pool(pegasus_t * pegasus)
@@ -881,9 +884,8 @@
 static inline void disable_net_traffic(pegasus_t * pegasus)
 {
 	int tmp = 0;
-	int ret;
 
-	ret = set_registers(pegasus, EthCtrl0, 2, &tmp);
+	set_registers(pegasus, EthCtrl0, 2, &tmp);
 }
 
 static inline void get_interrupt_interval(pegasus_t * pegasus)
@@ -1206,18 +1208,17 @@
 static inline void setup_pegasus_II(pegasus_t * pegasus)
 {
 	__u8 data = 0xa5;
-	int ret;
 	
-	ret = set_register(pegasus, Reg1d, 0);
-	ret = set_register(pegasus, Reg7b, 1);
+	set_register(pegasus, Reg1d, 0);
+	set_register(pegasus, Reg7b, 1);
 	mdelay(100);
 	if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
-		ret = set_register(pegasus, Reg7b, 0);
+		set_register(pegasus, Reg7b, 0);
 	else
-		ret = set_register(pegasus, Reg7b, 2);
+		set_register(pegasus, Reg7b, 2);
 
-	ret = set_register(pegasus, 0x83, data);
-	ret = get_registers(pegasus, 0x83, 1, &data);
+	set_register(pegasus, 0x83, data);
+	get_registers(pegasus, 0x83, 1, &data);
 
 	if (data == 0xa5) {
 		pegasus->chip = 0x8513;
@@ -1225,14 +1226,14 @@
 		pegasus->chip = 0;
 	}
 
-	ret = set_register(pegasus, 0x80, 0xc0);
-	ret = set_register(pegasus, 0x83, 0xff);
-	ret = set_register(pegasus, 0x84, 0x01);
+	set_register(pegasus, 0x80, 0xc0);
+	set_register(pegasus, 0x83, 0xff);
+	set_register(pegasus, 0x84, 0x01);
 	
 	if (pegasus->features & HAS_HOME_PNA && mii_mode)
-		ret = set_register(pegasus, Reg81, 6);
+		set_register(pegasus, Reg81, 6);
 	else
-		ret = set_register(pegasus, Reg81, 2);
+		set_register(pegasus, Reg81, 2);
 }
 
 
@@ -1414,9 +1415,42 @@
 	.resume = pegasus_resume,
 };
 
+static void parse_id(char *id)
+{
+	unsigned int vendor_id=0, device_id=0, flags=0, i=0;
+	char *token, *name=NULL;
+
+	if ((token = strsep(&id, ":")) != NULL)
+		name = token;
+	/* name now points to a null terminated string*/
+	if ((token = strsep(&id, ":")) != NULL)
+		vendor_id = simple_strtoul(token, NULL, 16);
+	if ((token = strsep(&id, ":")) != NULL)
+		device_id = simple_strtoul(token, NULL, 16);
+	flags = simple_strtoul(id, NULL, 16);
+	pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
+	        driver_name, name, vendor_id, device_id, flags);
+
+	if (vendor_id > 0x10000 || vendor_id == 0)
+		return;
+	if (device_id > 0x10000 || device_id == 0)
+		return;
+
+	for (i=0; usb_dev_id[i].name; i++);
+	usb_dev_id[i].name = name;
+	usb_dev_id[i].vendor = vendor_id;
+	usb_dev_id[i].device = device_id;
+	usb_dev_id[i].private = flags;
+	pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+	pegasus_ids[i].idVendor = vendor_id;
+	pegasus_ids[i].idProduct = device_id;
+}
+
 static int __init pegasus_init(void)
 {
 	pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
+	if (devid)
+		parse_id(devid);
 	pegasus_workqueue = create_singlethread_workqueue("pegasus");
 	if (!pegasus_workqueue)
 		return -ENOMEM;
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
index 89856aa..4fe8633 100644
--- a/drivers/usb/net/plusb.c
+++ b/drivers/usb/net/plusb.c
@@ -127,7 +127,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver plusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"plusb",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index c0ecbab..49991ac 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -586,7 +586,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver rndis_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"rndis_host",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 787dd35..8ca52be 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -177,7 +177,6 @@
 static const char driver_name [] = "rtl8150";
 
 static struct usb_driver rtl8150_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	rtl8150_probe,
 	.disconnect =	rtl8150_disconnect,
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
index 680d139..9c5ab25 100644
--- a/drivers/usb/net/zaurus.c
+++ b/drivers/usb/net/zaurus.c
@@ -357,7 +357,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver zaurus_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"zaurus",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index 2f52261..f3a8e28 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -1722,7 +1722,7 @@
 	    IW_PRIV_TYPE_NONE, "sethostauth" },
 	{ ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE,
 	    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" },
-	{ ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 
+	{ ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1,
 	    IW_PRIV_TYPE_NONE, "authstation" },
 	{ ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	    IW_PRIV_TYPE_NONE, "setmaxassoc" },
@@ -1731,9 +1731,9 @@
 };
 
 static const struct iw_handler_def zd1201_iw_handlers = {
-	.num_standard 		= sizeof(zd1201_iw_handler)/sizeof(iw_handler),
-	.num_private 		= sizeof(zd1201_private_handler)/sizeof(iw_handler),
-	.num_private_args 	= sizeof(zd1201_private_args)/sizeof(struct iw_priv_args),
+	.num_standard 		= ARRAY_SIZE(zd1201_iw_handler),
+	.num_private 		= ARRAY_SIZE(zd1201_private_handler),
+	.num_private_args 	= ARRAY_SIZE(zd1201_private_args),
 	.standard 		= (iw_handler *)zd1201_iw_handler,
 	.private 		= (iw_handler *)zd1201_private_handler,
 	.private_args 		= (struct iw_priv_args *) zd1201_private_args,
@@ -1829,6 +1829,8 @@
 	if (err)
 		goto err_net;
 
+	SET_NETDEV_DEV(zd->dev, &usb->dev);
+
 	err = register_netdev(zd->dev);
 	if (err)
 		goto err_net;
@@ -1923,7 +1925,6 @@
 #endif
 
 static struct usb_driver zd1201_usb = {
-	.owner = THIS_MODULE,
 	.name = "zd1201",
 	.probe = zd1201_probe,
 	.disconnect = zd1201_disconnect,
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 1f29d88..dbf1f06 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -23,11 +23,11 @@
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver airprime_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"airprime",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver airprime_device = {
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c
index 18022a7..343f6f2 100644
--- a/drivers/usb/serial/anydata.c
+++ b/drivers/usb/serial/anydata.c
@@ -27,11 +27,11 @@
 static int debug;
 
 static struct usb_driver anydata_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"anydata",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static int anydata_open(struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 84bc0ee..4144777 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -113,11 +113,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver belkin_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"belkin",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* All of the device info needed for the serial converters */
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index c978700..da46b35 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -67,11 +67,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cp2101_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "cp2101",
 	.probe		= usb_serial_probe,
 	.disconnect	= usb_serial_disconnect,
 	.id_table	= id_table,
+	.no_dynamic_id	= 	1,
 };
 
 static struct usb_serial_driver cp2101_device = {
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index e581e4a..6d18d4e 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -76,11 +76,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cyberjack_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cyberjack",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver cyberjack_device = {
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index af9290e..af18355 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -112,6 +112,7 @@
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 struct cypress_private {
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index dc74644..8fc414b 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -493,11 +493,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver digi_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"digi_acceleport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 0b0546d..79a766e 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -105,11 +105,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver empeg_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"empeg",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver empeg_device = {
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 06e04b4..eb863b3 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -471,12 +471,15 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
 	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+	{ USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
@@ -488,9 +491,10 @@
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
-static char *ftdi_chip_name[] = {
+static const char *ftdi_chip_name[] = {
 	[SIO] = "SIO",	/* the serial part of FT8U100AX */
 	[FT8U232AM] = "FT8U232AM",
 	[FT232BM] = "FT232BM",
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index da004dd..00d45f8 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -343,6 +343,13 @@
 #define XSENS_CONVERTER_7_PID	0xD38F
 
 /*
+ * Teratronik product ids.
+ * Submitted by O. Wölfelschneider.
+ */
+#define FTDI_TERATRONIK_VCP_PID	 0xEC88	/* Teratronik device (preferring VCP driver on windows) */
+#define FTDI_TERATRONIK_D2XX_PID 0xEC89	/* Teratronik device (preferring D2XX driver on windows) */
+
+/*
  * Evolution Robotics products (http://www.evolution.com/).
  * Submitted by Shawn M. Lavelle.
  */
@@ -352,6 +359,12 @@
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID	0xE6C8	/* Pyramid Appliance Display */
 
+/*
+ * Posiflex inc retail equipment (http://www.posiflex.com.tw)
+ */
+#define POSIFLEX_VID		0x0d3a  /* Vendor ID */
+#define POSIFLEX_PP7000_PID	0x0300  /* PP-7000II thermal printer */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 35820bd..452efce 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -222,11 +222,11 @@
 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,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 53a47c3..4ddac62 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -68,11 +68,11 @@
 }
 
 static struct usb_driver generic_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbserial_generic",
 	.probe =	generic_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	generic_serial_ids,
+	.no_dynamic_id = 	1,
 };
 #endif
 
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 8eadfb7..e9719da 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -37,11 +37,11 @@
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver hp49gp_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hp4X",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver hp49gp_device = {
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index dc4c498..faedbeb 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -184,7 +184,7 @@
 // These assume a 3.6864MHz crystal, the standard /16, and
 // MCR.7 = 0.
 //
-static struct divisor_table_entry divisor_table[] = {
+static const struct divisor_table_entry divisor_table[] = {
 	{   50,		4608},  
 	{   75,		3072},  
 	{   110,	2095},		/* 2094.545455 => 230450   => .0217 % over */
@@ -242,11 +242,11 @@
 #include "io_tables.h"	/* all of the devices that this driver supports */
 
 static struct usb_driver io_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"io_edgeport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* function prototypes for all of our local functions */
@@ -2353,7 +2353,7 @@
 
 	dbg("%s - %d", __FUNCTION__, baudrate);
 
-	for (i = 0; i < NUM_ENTRIES(divisor_table); i++) {
+	for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
 		if ( divisor_table[i].BaudRate == baudrate ) {
 			*divisor = divisor_table[i].Divisor;
 			return 0;
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h
index 5112d7a..123fa8a 100644
--- a/drivers/usb/serial/io_edgeport.h
+++ b/drivers/usb/serial/io_edgeport.h
@@ -31,9 +31,6 @@
 #ifndef HIGH8
 	#define HIGH8(a)	((unsigned char)((a & 0xff00) >> 8))
 #endif
-#ifndef NUM_ENTRIES
-	#define NUM_ENTRIES(x)	(sizeof(x)/sizeof((x)[0]))
-#endif
 
 #ifndef __KERNEL__
 #define __KERNEL__
diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h
index c7c3a3c..e3463de 100644
--- a/drivers/usb/serial/io_fw_boot2.h
+++ b/drivers/usb/serial/io_fw_boot2.h
@@ -537,7 +537,7 @@
 
 };
 
-static struct edge_firmware_version_info IMAGE_VERSION_NAME = {
+static const struct edge_firmware_version_info IMAGE_VERSION_NAME = {
 	2, 0, 3 };		// Major, Minor, Build
 
 #undef IMAGE_VERSION_NAME
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 832b6d6..2edf9cab 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -216,11 +216,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver io_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"io_ti",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 
@@ -2843,7 +2843,7 @@
  * Free the buffer and all associated memory.
  */
 
-void edge_buf_free(struct edge_buf *eb)
+static void edge_buf_free(struct edge_buf *eb)
 {
 	if (eb) {
 		kfree(eb->buf_buf);
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index d5d0664..06d07ce 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -542,11 +542,11 @@
 MODULE_DEVICE_TABLE (usb, ipaq_id_table);
 
 static struct usb_driver ipaq_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ipaq",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	ipaq_id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 7744b81..2dd191f 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -152,11 +152,11 @@
 MODULE_DEVICE_TABLE(usb, usb_ipw_ids);
 
 static struct usb_driver usb_ipw_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ipwtty",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	usb_ipw_ids,
+	.no_dynamic_id = 	1,
 };
 
 static int debug;
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 19f329e..a590104 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -125,11 +125,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver ir_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ir-usb",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 5cfc13b..7472ed6 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -520,11 +520,11 @@
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
 static struct usb_driver keyspan_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan",                
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	keyspan_ids_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* usb_device_id table for the pre-firmware download keyspan devices */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index cd4f48b..b0441c3 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -150,11 +150,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan_pda",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_device_id id_table_std [] = {
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index a8951c0..4e2f7df 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -116,11 +116,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kl5kusb105d_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kl5kusb105d",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver kl5kusb105d_device = {
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 9456dd9..d9c21e2 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -97,11 +97,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kobil_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kobil",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index ca5dbad..b6d6cab 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -125,11 +125,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"mct_u232",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver mct_u232_device = {
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 3caf970..762d8ff 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -80,11 +80,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver omninet_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"omninet",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 7716000..3fd2405 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -95,11 +95,11 @@
 MODULE_DEVICE_TABLE(usb, option_ids);
 
 static struct usb_driver option_driver = {
-	.owner      = THIS_MODULE,
 	.name       = "option",
 	.probe      = usb_serial_probe,
 	.disconnect = usb_serial_disconnect,
 	.id_table   = option_ids,
+	.no_dynamic_id = 	1,
 };
 
 /* The card has three separate interfaces, wich the serial driver
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 41a45a5..f037210 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -82,11 +82,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver pl2303_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"pl2303",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 #define SET_LINE_REQUEST_TYPE		0x21
@@ -810,7 +810,7 @@
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	u8 status_idx = UART_STATE;
-	u8 length = UART_STATE;
+	u8 length = UART_STATE + 1;
 
 	if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
 	    (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 ||
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index c22bdc0..f0215f8 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -160,14 +160,14 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver safe_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"safe_serial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
-static __u16 crc10_table[256] = {
+static const __u16 crc10_table[256] = {
 	0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
 	0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
 	0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
@@ -425,7 +425,7 @@
 	if (vendor || product) {
 		info ("vendor: %x product: %x\n", vendor, product);
 
-		for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) {
+		for (i = 0; i < ARRAY_SIZE(id_table); i++) {
 			if (!id_table[i].idVendor && !id_table[i].idProduct) {
 				id_table[i].idVendor = vendor;
 				id_table[i].idProduct = product;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 205dbf7..abb830c 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -248,11 +248,11 @@
 };
 
 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,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver ti_1port_device = {
@@ -351,17 +351,14 @@
 	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;
+	j = ARRAY_SIZE(ti_id_table_3410) - 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;
+	j = ARRAY_SIZE(ti_id_table_5052) - 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];
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0c4881d..8bc8337 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -30,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 #include <linux/usb.h>
 #include "usb-serial.h"
 #include "pl2303.h"
@@ -42,10 +43,10 @@
 
 /* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbserial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
+	.no_dynamic_id = 	1,
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -188,6 +189,11 @@
 
 	portNumber = tty->index - serial->minor;
 	port = serial->port[portNumber];
+	if (!port)
+		return -ENODEV;
+
+	if (down_interruptible(&port->sem))
+		return -ERESTARTSYS;
 	 
 	++port->open_count;
 
@@ -213,6 +219,7 @@
 			goto bailout_module_put;
 	}
 
+	up(&port->sem);
 	return 0;
 
 bailout_module_put:
@@ -220,6 +227,7 @@
 bailout_kref_put:
 	kref_put(&serial->kref, destroy_serial);
 	port->open_count = 0;
+	up(&port->sem);
 	return retval;
 }
 
@@ -232,8 +240,10 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	down(&port->sem);
+
 	if (port->open_count == 0)
-		return;
+		goto out;
 
 	--port->open_count;
 	if (port->open_count == 0) {
@@ -251,6 +261,9 @@
 	}
 
 	kref_put(&port->serial->kref, destroy_serial);
+
+out:
+	up(&port->sem);
 }
 
 static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
@@ -258,6 +271,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
 
 	if (!port->open_count) {
@@ -277,6 +293,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -296,6 +315,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s = port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -314,6 +336,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -330,6 +355,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -347,6 +375,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -ENODEV;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
 
 	if (!port->open_count) {
@@ -368,6 +399,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -384,6 +418,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -445,6 +482,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -464,6 +504,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -742,6 +785,7 @@
 		port->number = i + serial->minor;
 		port->serial = serial;
 		spin_lock_init(&port->lock);
+		sema_init(&port->sem, 1);
 		INIT_WORK(&port->work, usb_serial_port_softint, port);
 		serial->port[i] = port;
 	}
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index 238a5a8..d7d27c3 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/kref.h>
+#include <asm/semaphore.h>
 
 #define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
 #define SERIAL_TTY_MINORS	255	/* loads of devices :) */
@@ -30,6 +31,8 @@
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @tty: pointer to the corresponding tty for this port.
  * @lock: spinlock to grab when updating portions of this structure.
+ * @sem: semaphore used to synchronize serial_open() and serial_close()
+ *	access for this port.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -60,6 +63,7 @@
 	struct usb_serial *	serial;
 	struct tty_struct *	tty;
 	spinlock_t		lock;
+	struct semaphore        sem;
 	unsigned char		number;
 
 	unsigned char *		interrupt_in_buffer;
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index a473c1c..49b1fbe 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -173,11 +173,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver visor_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"visor",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 18c3183..a7c3c47 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -127,11 +127,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver whiteheat_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"whiteheat",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index c41d64d..92be101 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -112,6 +112,15 @@
 	  Say Y here to include additional code to support the Lexar Jumpshot
 	  USB CompactFlash reader.
 
+config USB_STORAGE_ALAUDA
+	bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)"
+	depends on USB_STORAGE && EXPERIMENTAL
+	help
+	  Say Y here to include additional code to support the Olympus MAUSB-10
+	  and Fujifilm DPC-R1 USB Card reader/writer devices.
+
+	  These devices are based on the Alauda chip and support support both
+	  XD and SmartMedia cards.
 
 config USB_STORAGE_ONETOUCH
 	bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
@@ -124,3 +133,17 @@
 	  hard drive's as an input device. An action can be associated with
 	  this input in any keybinding software. (e.g. gnome's keyboard short-
 	  cuts)
+
+config USB_LIBUSUAL
+	bool "The shared table of common (or usual) storage devices"
+	depends on USB
+	help
+	  This module contains a table of common (or usual) devices
+	  for usb-storage and ub drivers, and allows to switch binding
+	  of these devices without rebuilding modules.
+
+	  Typical syntax of /etc/modprobe.conf is:
+
+		options libusual bias="ub"
+
+	  If unsure, say N.
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 44ab8f9..8cbba22 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,7 +18,12 @@
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)	+= isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)	+= datafab.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT)	+= jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)	+= alauda.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH)	+= onetouch.o
 
 usb-storage-objs :=	scsiglue.o protocol.o transport.o usb.o \
 			initializers.o $(usb-storage-obj-y)
+
+ifneq ($(CONFIG_USB_LIBUSUAL),)
+	obj-$(CONFIG_USB)	+= libusual.o
+endif
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
new file mode 100644
index 0000000..4d3cbb1
--- /dev/null
+++ b/drivers/usb/storage/alauda.c
@@ -0,0 +1,1119 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *   (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * The 'Alauda' is a chip manufacturered by RATOC for OEM use.
+ *
+ * Alauda implements a vendor-specific command set to access two media reader
+ * ports (XD, SmartMedia). This driver converts SCSI commands to the commands
+ * which are accepted by these devices.
+ *
+ * The driver was developed through reverse-engineering, with the help of the
+ * sddr09 driver which has many similarities, and with some help from the
+ * (very old) vendor-supplied GPL sma03 driver.
+ *
+ * For protocol info, see http://alauda.sourceforge.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You 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 <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "transport.h"
+#include "protocol.h"
+#include "debug.h"
+#include "alauda.h"
+
+#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
+#define LSB_of(s) ((s)&0xFF)
+#define MSB_of(s) ((s)>>8)
+
+#define MEDIA_PORT(us) us->srb->device->lun
+#define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)]
+
+#define PBA_LO(pba) ((pba & 0xF) << 5)
+#define PBA_HI(pba) (pba >> 3)
+#define PBA_ZONE(pba) (pba >> 11)
+
+/*
+ * Media handling
+ */
+
+struct alauda_card_info {
+	unsigned char id;		/* id byte */
+	unsigned char chipshift;	/* 1<<cs bytes total capacity */
+	unsigned char pageshift;	/* 1<<ps bytes in a page */
+	unsigned char blockshift;	/* 1<<bs pages per block */
+	unsigned char zoneshift;	/* 1<<zs blocks per zone */
+};
+
+static struct alauda_card_info alauda_card_ids[] = {
+	/* NAND flash */
+	{ 0x6e, 20, 8, 4, 8},	/* 1 MB */
+	{ 0xe8, 20, 8, 4, 8},	/* 1 MB */
+	{ 0xec, 20, 8, 4, 8},	/* 1 MB */
+	{ 0x64, 21, 8, 4, 9}, 	/* 2 MB */
+	{ 0xea, 21, 8, 4, 9},	/* 2 MB */
+	{ 0x6b, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe3, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe5, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe6, 23, 9, 4, 10},	/* 8 MB */
+	{ 0x73, 24, 9, 5, 10},	/* 16 MB */
+	{ 0x75, 25, 9, 5, 10},	/* 32 MB */
+	{ 0x76, 26, 9, 5, 10},	/* 64 MB */
+	{ 0x79, 27, 9, 5, 10},	/* 128 MB */
+	{ 0x71, 28, 9, 5, 10},	/* 256 MB */
+
+	/* MASK ROM */
+	{ 0x5d, 21, 9, 4, 8},	/* 2 MB */
+	{ 0xd5, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xd6, 23, 9, 4, 10},	/* 8 MB */
+	{ 0x57, 24, 9, 4, 11},	/* 16 MB */
+	{ 0x58, 25, 9, 4, 12},	/* 32 MB */
+	{ 0,}
+};
+
+static struct alauda_card_info *alauda_card_find_id(unsigned char id) {
+	int i;
+
+	for (i = 0; alauda_card_ids[i].id != 0; i++)
+		if (alauda_card_ids[i].id == id)
+			return &(alauda_card_ids[i]);
+	return NULL;
+}
+
+/*
+ * ECC computation.
+ */
+
+static unsigned char parity[256];
+static unsigned char ecc2[256];
+
+static void nand_init_ecc(void) {
+	int i, j, a;
+
+	parity[0] = 0;
+	for (i = 1; i < 256; i++)
+		parity[i] = (parity[i&(i-1)] ^ 1);
+
+	for (i = 0; i < 256; i++) {
+		a = 0;
+		for (j = 0; j < 8; j++) {
+			if (i & (1<<j)) {
+				if ((j & 1) == 0)
+					a ^= 0x04;
+				if ((j & 2) == 0)
+					a ^= 0x10;
+				if ((j & 4) == 0)
+					a ^= 0x40;
+			}
+		}
+		ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0));
+	}
+}
+
+/* compute 3-byte ecc on 256 bytes */
+static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) {
+	int i, j, a;
+	unsigned char par, bit, bits[8];
+
+	par = 0;
+	for (j = 0; j < 8; j++)
+		bits[j] = 0;
+
+	/* collect 16 checksum bits */
+	for (i = 0; i < 256; i++) {
+		par ^= data[i];
+		bit = parity[data[i]];
+		for (j = 0; j < 8; j++)
+			if ((i & (1<<j)) == 0)
+				bits[j] ^= bit;
+	}
+
+	/* put 4+4+4 = 12 bits in the ecc */
+	a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0];
+	ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+	a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4];
+	ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+	ecc[2] = ecc2[par];
+}
+
+static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) {
+	return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]);
+}
+
+static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
+	memcpy(data, ecc, 3);
+}
+
+/*
+ * Alauda driver
+ */
+
+/*
+ * Forget our PBA <---> LBA mappings for a particular port
+ */
+static void alauda_free_maps (struct alauda_media_info *media_info)
+{
+	unsigned int shift = media_info->zoneshift
+		+ media_info->blockshift + media_info->pageshift;
+	unsigned int num_zones = media_info->capacity >> shift;
+	unsigned int i;
+
+	if (media_info->lba_to_pba != NULL)
+		for (i = 0; i < num_zones; i++) {
+			kfree(media_info->lba_to_pba[i]);
+			media_info->lba_to_pba[i] = NULL;
+		}
+
+	if (media_info->pba_to_lba != NULL)
+		for (i = 0; i < num_zones; i++) {
+			kfree(media_info->pba_to_lba[i]);
+			media_info->pba_to_lba[i] = NULL;
+		}
+}
+
+/*
+ * Returns 2 bytes of status data
+ * The first byte describes media status, and second byte describes door status
+ */
+static int alauda_get_media_status(struct us_data *us, unsigned char *data)
+{
+	int rc;
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_GET_XD_MEDIA_STATUS;
+	else
+		command = ALAUDA_GET_SM_MEDIA_STATUS;
+
+	rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+		command, 0xc0, 0, 1, data, 2);
+
+	US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n",
+		data[0], data[1]);
+
+	return rc;
+}
+
+/*
+ * Clears the "media was changed" bit so that we know when it changes again
+ * in the future.
+ */
+static int alauda_ack_media(struct us_data *us)
+{
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_ACK_XD_MEDIA_CHANGE;
+	else
+		command = ALAUDA_ACK_SM_MEDIA_CHANGE;
+
+	return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
+		command, 0x40, 0, 1, NULL, 0);
+}
+
+/*
+ * Retrieves a 4-byte media signature, which indicates manufacturer, capacity,
+ * and some other details.
+ */
+static int alauda_get_media_signature(struct us_data *us, unsigned char *data)
+{
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_GET_XD_MEDIA_SIG;
+	else
+		command = ALAUDA_GET_SM_MEDIA_SIG;
+
+	return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+		command, 0xc0, 0, 0, data, 4);
+}
+
+/*
+ * Resets the media status (but not the whole device?)
+ */
+static int alauda_reset_media(struct us_data *us)
+{
+	unsigned char *command = us->iobuf;
+
+	memset(command, 0, 9);
+	command[0] = ALAUDA_BULK_CMD;
+	command[1] = ALAUDA_BULK_RESET_MEDIA;
+	command[8] = MEDIA_PORT(us);
+
+	return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+}
+
+/*
+ * Examines the media and deduces capacity, etc.
+ */
+static int alauda_init_media(struct us_data *us)
+{
+	unsigned char *data = us->iobuf;
+	int ready = 0;
+	struct alauda_card_info *media_info;
+	unsigned int num_zones;
+
+	while (ready == 0) {
+		msleep(20);
+
+		if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+			return USB_STOR_TRANSPORT_ERROR;
+
+		if (data[0] & 0x10)
+			ready = 1;
+	}
+
+	US_DEBUGP("alauda_init_media: We are ready for action!\n");
+
+	if (alauda_ack_media(us) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	msleep(10);
+
+	if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	if (data[0] != 0x14) {
+		US_DEBUGP("alauda_init_media: Media not ready after ack\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n",
+		data[0], data[1], data[2], data[3]);
+	media_info = alauda_card_find_id(data[1]);
+	if (media_info == NULL) {
+		printk("alauda_init_media: Unrecognised media signature: "
+			"%02X %02X %02X %02X\n",
+			data[0], data[1], data[2], data[3]);
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	MEDIA_INFO(us).capacity = 1 << media_info->chipshift;
+	US_DEBUGP("Found media with capacity: %ldMB\n",
+		MEDIA_INFO(us).capacity >> 20);
+
+	MEDIA_INFO(us).pageshift = media_info->pageshift;
+	MEDIA_INFO(us).blockshift = media_info->blockshift;
+	MEDIA_INFO(us).zoneshift = media_info->zoneshift;
+
+	MEDIA_INFO(us).pagesize = 1 << media_info->pageshift;
+	MEDIA_INFO(us).blocksize = 1 << media_info->blockshift;
+	MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift;
+
+	MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125;
+	MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1;
+
+	num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+		+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+	MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+	MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+
+	if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Examines the media status and does the right thing when the media has gone,
+ * appeared, or changed.
+ */
+static int alauda_check_media(struct us_data *us)
+{
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char status[2];
+	int rc;
+
+	rc = alauda_get_media_status(us, status);
+
+	/* Check for no media or door open */
+	if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
+		|| ((status[1] & 0x01) == 0)) {
+		US_DEBUGP("alauda_check_media: No media, or door open\n");
+		alauda_free_maps(&MEDIA_INFO(us));
+		info->sense_key = 0x02;
+		info->sense_asc = 0x3A;
+		info->sense_ascq = 0x00;
+		return USB_STOR_TRANSPORT_FAILED;
+	}
+
+	/* Check for media change */
+	if (status[0] & 0x08) {
+		US_DEBUGP("alauda_check_media: Media change detected\n");
+		alauda_free_maps(&MEDIA_INFO(us));
+		alauda_init_media(us);
+
+		info->sense_key = UNIT_ATTENTION;
+		info->sense_asc = 0x28;
+		info->sense_ascq = 0x00;
+		return USB_STOR_TRANSPORT_FAILED;
+	}
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Checks the status from the 2nd status register
+ * Returns 3 bytes of status data, only the first is known
+ */
+static int alauda_check_status2(struct us_data *us)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2,
+		0, 0, 0, 0, 3, 0, MEDIA_PORT(us)
+	};
+	unsigned char data[3];
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, 3, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]);
+	if (data[0] & ALAUDA_STATUS_ERROR)
+		return USB_STOR_XFER_ERROR;
+
+	return USB_STOR_XFER_GOOD;
+}
+
+/*
+ * Gets the redundancy data for the first page of a PBA
+ * Returns 16 bytes.
+ */
+static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA,
+		PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us)
+	};
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, 16, NULL);
+}
+
+/*
+ * Finds the first unused PBA in a zone
+ * Returns the absolute PBA of an unused PBA, or 0 if none found.
+ */
+static u16 alauda_find_unused_pba(struct alauda_media_info *info,
+	unsigned int zone)
+{
+	u16 *pba_to_lba = info->pba_to_lba[zone];
+	unsigned int i;
+
+	for (i = 0; i < info->zonesize; i++)
+		if (pba_to_lba[i] == UNDEF)
+			return (zone << info->zoneshift) + i;
+
+	return 0;
+}
+
+/*
+ * Reads the redundancy data for all PBA's in a zone
+ * Produces lba <--> pba mappings
+ */
+static int alauda_read_map(struct us_data *us, unsigned int zone)
+{
+	unsigned char *data = us->iobuf;
+	int result;
+	int i, j;
+	unsigned int zonesize = MEDIA_INFO(us).zonesize;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	unsigned int lba_offset, lba_real, blocknum;
+	unsigned int zone_base_lba = zone * uzonesize;
+	unsigned int zone_base_pba = zone * zonesize;
+	u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+	u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+	if (lba_to_pba == NULL || pba_to_lba == NULL) {
+		result = USB_STOR_TRANSPORT_ERROR;
+		goto error;
+	}
+
+	US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone);
+
+	/* 1024 PBA's per zone */
+	for (i = 0; i < zonesize; i++)
+		lba_to_pba[i] = pba_to_lba[i] = UNDEF;
+
+	for (i = 0; i < zonesize; i++) {
+		blocknum = zone_base_pba + i;
+
+		result = alauda_get_redu_data(us, blocknum, data);
+		if (result != USB_STOR_XFER_GOOD) {
+			result = USB_STOR_TRANSPORT_ERROR;
+			goto error;
+		}
+
+		/* special PBAs have control field 0^16 */
+		for (j = 0; j < 16; j++)
+			if (data[j] != 0)
+				goto nonz;
+		pba_to_lba[i] = UNUSABLE;
+		US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum);
+		continue;
+
+	nonz:
+		/* unwritten PBAs have control field FF^16 */
+		for (j = 0; j < 16; j++)
+			if (data[j] != 0xff)
+				goto nonff;
+		continue;
+
+	nonff:
+		/* normal PBAs start with six FFs */
+		if (j < 6) {
+			US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: "
+			       "reserved area = %02X%02X%02X%02X "
+			       "data status %02X block status %02X\n",
+			       blocknum, data[0], data[1], data[2], data[3],
+			       data[4], data[5]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		if ((data[6] >> 4) != 0x01) {
+			US_DEBUGP("alauda_read_map: PBA %d has invalid address "
+			       "field %02X%02X/%02X%02X\n",
+			       blocknum, data[6], data[7], data[11], data[12]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		/* check even parity */
+		if (parity[data[6] ^ data[7]]) {
+			printk("alauda_read_map: Bad parity in LBA for block %d"
+			       " (%02X %02X)\n", i, data[6], data[7]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		lba_offset = short_pack(data[7], data[6]);
+		lba_offset = (lba_offset & 0x07FF) >> 1;
+		lba_real = lba_offset + zone_base_lba;
+
+		/*
+		 * Every 1024 physical blocks ("zone"), the LBA numbers
+		 * go back to zero, but are within a higher block of LBA's.
+		 * Also, there is a maximum of 1000 LBA's per zone.
+		 * In other words, in PBA 1024-2047 you will find LBA 0-999
+		 * which are really LBA 1000-1999. This allows for 24 bad
+		 * or special physical blocks per zone.
+		 */
+
+		if (lba_offset >= uzonesize) {
+			printk("alauda_read_map: Bad low LBA %d for block %d\n",
+			       lba_real, blocknum);
+			continue;
+		}
+
+		if (lba_to_pba[lba_offset] != UNDEF) {
+			printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+			       lba_real, lba_to_pba[lba_offset], blocknum);
+			continue;
+		}
+
+		pba_to_lba[i] = lba_real;
+		lba_to_pba[lba_offset] = blocknum;
+		continue;
+	}
+
+	MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba;
+	MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba;
+	result = 0;
+	goto out;
+
+error:
+	kfree(lba_to_pba);
+	kfree(pba_to_lba);
+out:
+	return result;
+}
+
+/*
+ * Checks to see whether we have already mapped a certain zone
+ * If we haven't, the map is generated
+ */
+static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
+{
+	if (MEDIA_INFO(us).lba_to_pba[zone] == NULL
+		|| MEDIA_INFO(us).pba_to_lba[zone] == NULL)
+		alauda_read_map(us, zone);
+}
+
+/*
+ * Erases an entire block
+ */
+static int alauda_erase_block(struct us_data *us, u16 pba)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us)
+	};
+	unsigned char buf[2];
+
+	US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		buf, 2, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n",
+		buf[0], buf[1]);
+	return rc;
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, including interleaved
+ * redundancy data. Returns (pagesize+64)*pages bytes in data.
+ */
+static int alauda_read_block_raw(struct us_data *us, u16 pba,
+		unsigned int page, unsigned int pages, unsigned char *data)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us)
+	};
+
+	US_DEBUGP("alauda_read_block: pba %d page %d count %d\n",
+		pba, page, pages);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL);
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, excluding redundancy
+ * data. Returns pagesize*pages bytes in data. Note that data must be big enough
+ * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra'
+ * trailing bytes outside this function.
+ */
+static int alauda_read_block(struct us_data *us, u16 pba,
+		unsigned int page, unsigned int pages, unsigned char *data)
+{
+	int i, rc;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+
+	rc = alauda_read_block_raw(us, pba, page, pages, data);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	/* Cut out the redundancy data */
+	for (i = 0; i < pages; i++) {
+		int dest_offset = i * pagesize;
+		int src_offset = i * (pagesize + 64);
+		memmove(data + dest_offset, data + src_offset, pagesize);
+	}
+
+	return rc;
+}
+
+/*
+ * Writes an entire block of data and checks status after write.
+ * Redundancy data must be already included in data. Data should be
+ * (pagesize+64)*blocksize bytes in length.
+ */
+static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data)
+{
+	int rc;
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us)
+	};
+
+	US_DEBUGP("alauda_write_block: pba %d\n", pba);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data,
+		(MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize,
+		NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return alauda_check_status2(us);
+}
+
+/*
+ * Write some data to a specific LBA.
+ */
+static int alauda_write_lba(struct us_data *us, u16 lba,
+		 unsigned int page, unsigned int pages,
+		 unsigned char *ptr, unsigned char *blockbuffer)
+{
+	u16 pba, lbap, new_pba;
+	unsigned char *bptr, *cptr, *xptr;
+	unsigned char ecc[3];
+	int i, result;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	unsigned int zonesize = MEDIA_INFO(us).zonesize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int lba_offset = lba % uzonesize;
+	unsigned int new_pba_offset;
+	unsigned int zone = lba / uzonesize;
+
+	alauda_ensure_map_for_zone(us, zone);
+
+	pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+	if (pba == 1) {
+		/* Maybe it is impossible to write to PBA 1.
+		   Fake success, but don't do anything. */
+		printk("alauda_write_lba: avoid writing to pba 1\n");
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
+	if (!new_pba) {
+		printk("alauda_write_lba: Out of unused blocks\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* read old contents */
+	if (pba != UNDEF) {
+		result = alauda_read_block_raw(us, pba, 0,
+			blocksize, blockbuffer);
+		if (result != USB_STOR_XFER_GOOD)
+			return result;
+	} else {
+		memset(blockbuffer, 0, blocksize * (pagesize + 64));
+	}
+
+	lbap = (lba_offset << 1) | 0x1000;
+	if (parity[MSB_of(lbap) ^ LSB_of(lbap)])
+		lbap ^= 1;
+
+	/* check old contents and fill lba */
+	for (i = 0; i < blocksize; i++) {
+		bptr = blockbuffer + (i * (pagesize + 64));
+		cptr = bptr + pagesize;
+		nand_compute_ecc(bptr, ecc);
+		if (!nand_compare_ecc(cptr+13, ecc)) {
+			US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n",
+				  i, pba);
+			nand_store_ecc(cptr+13, ecc);
+		}
+		nand_compute_ecc(bptr + (pagesize / 2), ecc);
+		if (!nand_compare_ecc(cptr+8, ecc)) {
+			US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n",
+				  i, pba);
+			nand_store_ecc(cptr+8, ecc);
+		}
+		cptr[6] = cptr[11] = MSB_of(lbap);
+		cptr[7] = cptr[12] = LSB_of(lbap);
+	}
+
+	/* copy in new stuff and compute ECC */
+	xptr = ptr;
+	for (i = page; i < page+pages; i++) {
+		bptr = blockbuffer + (i * (pagesize + 64));
+		cptr = bptr + pagesize;
+		memcpy(bptr, xptr, pagesize);
+		xptr += pagesize;
+		nand_compute_ecc(bptr, ecc);
+		nand_store_ecc(cptr+13, ecc);
+		nand_compute_ecc(bptr + (pagesize / 2), ecc);
+		nand_store_ecc(cptr+8, ecc);
+	}
+
+	result = alauda_write_block(us, new_pba, blockbuffer);
+	if (result != USB_STOR_XFER_GOOD)
+		return result;
+
+	new_pba_offset = new_pba - (zone * zonesize);
+	MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba;
+	MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba;
+	US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n",
+		lba, new_pba);
+
+	if (pba != UNDEF) {
+		unsigned int pba_offset = pba - (zone * zonesize);
+		result = alauda_erase_block(us, pba);
+		if (result != USB_STOR_XFER_GOOD)
+			return result;
+		MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF;
+	}
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Read data from a specific sector address
+ */
+static int alauda_read_data(struct us_data *us, unsigned long address,
+		unsigned int sectors)
+{
+	unsigned char *buffer;
+	u16 lba, max_lba;
+	unsigned int page, len, index, offset;
+	unsigned int blockshift = MEDIA_INFO(us).blockshift;
+	unsigned int pageshift = MEDIA_INFO(us).pageshift;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	int result;
+
+	/*
+	 * Since we only read in one block at a time, we have to create
+	 * a bounce buffer and move the data a piece at a time between the
+	 * bounce buffer and the actual transfer buffer.
+	 * We make this buffer big enough to hold temporary redundancy data,
+	 * which we use when reading the data blocks.
+	 */
+
+	len = min(sectors, blocksize) * (pagesize + 64);
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("alauda_read_data: Out of memory\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* Figure out the initial LBA and page */
+	lba = address >> blockshift;
+	page = (address & MEDIA_INFO(us).blockmask);
+	max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
+
+	result = USB_STOR_TRANSPORT_GOOD;
+	index = offset = 0;
+
+	while (sectors > 0) {
+		unsigned int zone = lba / uzonesize; /* integer division */
+		unsigned int lba_offset = lba - (zone * uzonesize);
+		unsigned int pages;
+		u16 pba;
+		alauda_ensure_map_for_zone(us, zone);
+
+		/* Not overflowing capacity? */
+		if (lba >= max_lba) {
+			US_DEBUGP("Error: Requested lba %u exceeds "
+				  "maximum %u\n", lba, max_lba);
+			result = USB_STOR_TRANSPORT_ERROR;
+			break;
+		}
+
+		/* Find number of pages we can read in this block */
+		pages = min(sectors, blocksize - page);
+		len = pages << pageshift;
+
+		/* Find where this lba lives on disk */
+		pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+
+		if (pba == UNDEF) {	/* this lba was never written */
+			US_DEBUGP("Read %d zero pages (LBA %d) page %d\n",
+				  pages, lba, page);
+
+			/* This is not really an error. It just means
+			   that the block has never been written.
+			   Instead of returning USB_STOR_TRANSPORT_ERROR
+			   it is better to return all zero data. */
+
+			memset(buffer, 0, len);
+		} else {
+			US_DEBUGP("Read %d pages, from PBA %d"
+				  " (LBA %d) page %d\n",
+				  pages, pba, lba, page);
+
+			result = alauda_read_block(us, pba, page, pages, buffer);
+			if (result != USB_STOR_TRANSPORT_GOOD)
+				break;
+		}
+
+		/* Store the data in the transfer buffer */
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, TO_XFER_BUF);
+
+		page = 0;
+		lba++;
+		sectors -= pages;
+	}
+
+	kfree(buffer);
+	return result;
+}
+
+/*
+ * Write data to a specific sector address
+ */
+static int alauda_write_data(struct us_data *us, unsigned long address,
+		unsigned int sectors)
+{
+	unsigned char *buffer, *blockbuffer;
+	unsigned int page, len, index, offset;
+	unsigned int blockshift = MEDIA_INFO(us).blockshift;
+	unsigned int pageshift = MEDIA_INFO(us).pageshift;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	u16 lba, max_lba;
+	int result;
+
+	/*
+	 * Since we don't write the user data directly to the device,
+	 * we have to create a bounce buffer and move the data a piece
+	 * at a time between the bounce buffer and the actual transfer buffer.
+	 */
+
+	len = min(sectors, blocksize) * pagesize;
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("alauda_write_data: Out of memory\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/*
+	 * We also need a temporary block buffer, where we read in the old data,
+	 * overwrite parts with the new data, and manipulate the redundancy data
+	 */
+	blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
+	if (blockbuffer == NULL) {
+		printk("alauda_write_data: Out of memory\n");
+		kfree(buffer);
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* Figure out the initial LBA and page */
+	lba = address >> blockshift;
+	page = (address & MEDIA_INFO(us).blockmask);
+	max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
+
+	result = USB_STOR_TRANSPORT_GOOD;
+	index = offset = 0;
+
+	while (sectors > 0) {
+		/* Write as many sectors as possible in this block */
+		unsigned int pages = min(sectors, blocksize - page);
+		len = pages << pageshift;
+
+		/* Not overflowing capacity? */
+		if (lba >= max_lba) {
+			US_DEBUGP("alauda_write_data: Requested lba %u exceeds "
+				  "maximum %u\n", lba, max_lba);
+			result = USB_STOR_TRANSPORT_ERROR;
+			break;
+		}
+
+		/* Get the data from the transfer buffer */
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, FROM_XFER_BUF);
+
+		result = alauda_write_lba(us, lba, page, pages, buffer,
+			blockbuffer);
+		if (result != USB_STOR_TRANSPORT_GOOD)
+			break;
+
+		page = 0;
+		lba++;
+		sectors -= pages;
+	}
+
+	kfree(buffer);
+	kfree(blockbuffer);
+	return result;
+}
+
+/*
+ * Our interface with the rest of the world
+ */
+
+static void alauda_info_destructor(void *extra)
+{
+	struct alauda_info *info = (struct alauda_info *) extra;
+	int port;
+
+	if (!info)
+		return;
+
+	for (port = 0; port < 2; port++) {
+		struct alauda_media_info *media_info = &info->port[port];
+
+		alauda_free_maps(media_info);
+		kfree(media_info->lba_to_pba);
+		kfree(media_info->pba_to_lba);
+	}
+}
+
+/*
+ * Initialize alauda_info struct and find the data-write endpoint
+ */
+int init_alauda(struct us_data *us)
+{
+	struct alauda_info *info;
+	struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
+	nand_init_ecc();
+
+	us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO);
+	if (!us->extra) {
+		US_DEBUGP("init_alauda: Gah! Can't allocate storage for"
+			"alauda info struct!\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+	info = (struct alauda_info *) us->extra;
+	us->extra_destructor = alauda_info_destructor;
+
+	info->wr_ep = usb_sndbulkpipe(us->pusb_dev,
+		altsetting->endpoint[0].desc.bEndpointAddress
+		& USB_ENDPOINT_NUMBER_MASK);
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+	int rc;
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char *ptr = us->iobuf;
+	static unsigned char inquiry_response[36] = {
+		0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
+	};
+
+	if (srb->cmnd[0] == INQUIRY) {
+		US_DEBUGP("alauda_transport: INQUIRY. "
+			"Returning bogus response.\n");
+		memcpy(ptr, inquiry_response, sizeof(inquiry_response));
+		fill_inquiry_response(us, ptr, 36);
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == TEST_UNIT_READY) {
+		US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n");
+		return alauda_check_media(us);
+	}
+
+	if (srb->cmnd[0] == READ_CAPACITY) {
+		unsigned int num_zones;
+		unsigned long capacity;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+			+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+
+		capacity = num_zones * MEDIA_INFO(us).uzonesize
+			* MEDIA_INFO(us).blocksize;
+
+		/* Report capacity and page size */
+		((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1);
+		((__be32 *) ptr)[1] = cpu_to_be32(512);
+
+		usb_stor_set_xfer_buf(ptr, 8, srb);
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == READ_10) {
+		unsigned int page, pages;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+		page <<= 16;
+		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+		US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n",
+			  page, pages);
+
+		return alauda_read_data(us, page, pages);
+	}
+
+	if (srb->cmnd[0] == WRITE_10) {
+		unsigned int page, pages;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+		page <<= 16;
+		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+		US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n",
+			  page, pages);
+
+		return alauda_write_data(us, page, pages);
+	}
+
+	if (srb->cmnd[0] == REQUEST_SENSE) {
+		US_DEBUGP("alauda_transport: REQUEST_SENSE.\n");
+
+		memset(ptr, 0, 18);
+		ptr[0] = 0xF0;
+		ptr[2] = info->sense_key;
+		ptr[7] = 11;
+		ptr[12] = info->sense_asc;
+		ptr[13] = info->sense_ascq;
+		usb_stor_set_xfer_buf(ptr, 18, srb);
+
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
+		/* sure.  whatever.  not like we can stop the user from popping
+		   the media out of the device (no locking doors, etc) */
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n",
+		srb->cmnd[0], srb->cmnd[0]);
+	info->sense_key = 0x05;
+	info->sense_asc = 0x20;
+	info->sense_ascq = 0x00;
+	return USB_STOR_TRANSPORT_FAILED;
+}
+
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
new file mode 100644
index 0000000..a700f87
--- /dev/null
+++ b/drivers/usb/storage/alauda.h
@@ -0,0 +1,100 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *    (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * See alauda.c for more explanation.
+ *
+ * This program is free software; you can redistribute 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 _USB_ALAUDA_H
+#define _USB_ALAUDA_H
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR		0x01
+#define ALAUDA_STATUS_READY		0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS	0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS	0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE	0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE	0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG		0x86
+#define ALAUDA_GET_SM_MEDIA_SIG		0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD			0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA	0x85
+#define ALAUDA_BULK_READ_BLOCK		0x94
+#define ALAUDA_BULK_ERASE_BLOCK		0xa3
+#define ALAUDA_BULK_WRITE_BLOCK		0xb4
+#define ALAUDA_BULK_GET_STATUS2		0xb7
+#define ALAUDA_BULK_RESET_MEDIA		0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD			0x00
+#define ALAUDA_PORT_SM			0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF    0xffff
+#define SPARE    0xfffe
+#define UNUSABLE 0xfffd
+
+int init_alauda(struct us_data *us);
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
+
+struct alauda_media_info {
+	unsigned long capacity;		/* total media size in bytes */
+	unsigned int pagesize;		/* page size in bytes */
+	unsigned int blocksize;		/* number of pages per block */
+	unsigned int uzonesize;		/* number of usable blocks per zone */
+	unsigned int zonesize;		/* number of blocks per zone */
+	unsigned int blockmask;		/* mask to get page from address */
+
+	unsigned char pageshift;
+	unsigned char blockshift;
+	unsigned char zoneshift;
+
+	u16 **lba_to_pba;		/* logical to physical block map */
+	u16 **pba_to_lba;		/* physical to logical block map */
+};
+
+struct alauda_info {
+	struct alauda_media_info port[2];
+	int wr_ep;			/* endpoint to write data out of */
+
+	unsigned char sense_key;
+	unsigned long sense_asc;	/* additional sense code */
+	unsigned long sense_ascq;	/* additional sense code qualifier */
+};
+
+#endif
+
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
index 5a93217..01e4306 100644
--- a/drivers/usb/storage/debug.c
+++ b/drivers/usb/storage/debug.c
@@ -132,6 +132,7 @@
 	case 0x5C: what = "READ BUFFER CAPACITY"; break;
 	case 0x5D: what = "SEND CUE SHEET"; break;
 	case GPCMD_BLANK: what = "BLANK"; break;
+	case REPORT_LUNS: what = "REPORT LUNS"; break;
 	case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break;
 	case READ_12: what = "READ_12"; break;
 	case WRITE_12: what = "WRITE_12"; break;
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 7372386..4c1b2bd 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -45,10 +45,6 @@
  * mode */
 int usb_stor_euscsi_init(struct us_data *us);
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-int sddr09_init(struct us_data *us);
-#endif
-
 /* This function is required to activate all four slots on the UCR-61S2B
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
new file mode 100644
index 0000000..b28151d
--- /dev/null
+++ b/drivers/usb/storage/libusual.c
@@ -0,0 +1,266 @@
+/*
+ * libusual
+ *
+ * The libusual contains the table of devices common for ub and usb-storage.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/vmalloc.h>
+
+/*
+ */
+#define USU_MOD_FL_THREAD   1	/* Thread is running */
+#define USU_MOD_FL_PRESENT  2	/* The module is loaded */
+
+struct mod_status {
+	unsigned long fls;
+};
+
+static struct mod_status stat[3];
+static DEFINE_SPINLOCK(usu_lock);
+
+/*
+ */
+#define USB_US_DEFAULT_BIAS	USB_US_TYPE_STOR
+static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS);
+
+#define BIAS_NAME_SIZE  (sizeof("usb-storage"))
+static const char *bias_names[3] = { "none", "usb-storage", "ub" };
+
+static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static DECLARE_COMPLETION(usu_end_notify);
+static atomic_t total_threads = ATOMIC_INIT(0);
+
+static int usu_probe_thread(void *arg);
+
+/*
+ * The table.
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+		    vendorName, productName,useProtocol, useTransport, \
+		    initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = ((useType)<<24) }
+
+struct usb_device_id storage_usb_ids [] = {
+#	include "unusual_devs.h"
+	{ } /* Terminating entry */
+};
+
+#undef USUAL_DEV
+#undef UNUSUAL_DEV
+
+MODULE_DEVICE_TABLE(usb, storage_usb_ids);
+EXPORT_SYMBOL_GPL(storage_usb_ids);
+
+/*
+ * @type: the module type as an integer
+ */
+void usb_usual_set_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls |= USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_set_present);
+
+void usb_usual_clear_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls &= ~USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_clear_present);
+
+/*
+ * Match the calling driver type against the table.
+ * Returns: 0 if the device matches.
+ */
+int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
+{
+	int id_type = USB_US_TYPE(id->driver_info);
+
+	if (caller_type <= 0 || caller_type >= 3)
+		return -EINVAL;
+
+	/* Drivers grab fixed assignment devices */
+	if (id_type == caller_type)
+		return 0;
+	/* Drivers grab devices biased to them */
+	if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias))
+		return 0;
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(usb_usual_check_type);
+
+/*
+ */
+static int usu_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	int type;
+	int rc;
+	unsigned long flags;
+
+	type = USB_US_TYPE(id->driver_info);
+	if (type == 0)
+		type = atomic_read(&usu_bias);
+
+	spin_lock_irqsave(&usu_lock, flags);
+	if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return -ENXIO;
+	}
+	stat[type].fls |= USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM);
+	if (rc < 0) {
+		printk(KERN_WARNING "libusual: "
+		    "Unable to start the thread for %s: %d\n",
+		    bias_names[type], rc);
+		spin_lock_irqsave(&usu_lock, flags);
+		stat[type].fls &= ~USU_MOD_FL_THREAD;
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return rc;	/* Not being -ENXIO causes a message printed */
+	}
+	atomic_inc(&total_threads);
+
+	return -ENXIO;
+}
+
+static void usu_disconnect(struct usb_interface *intf)
+{
+	;	/* We should not be here. */
+}
+
+static struct usb_driver usu_driver = {
+	.name =		"libusual",
+	.probe =	usu_probe,
+	.disconnect =	usu_disconnect,
+	.id_table =	storage_usb_ids,
+};
+
+/*
+ * A whole new thread for a purpose of request_module seems quite stupid.
+ * The request_module forks once inside again. However, if we attempt
+ * to load a storage module from our own modprobe thread, that module
+ * references our symbols, which cannot be resolved until our module is
+ * initialized. I wish there was a way to wait for the end of initialization.
+ * The module notifier reports MODULE_STATE_COMING only.
+ * So, we wait until module->init ends as the next best thing.
+ */
+static int usu_probe_thread(void *arg)
+{
+	int type = (unsigned long) arg;
+	struct mod_status *st = &stat[type];
+	int rc;
+	unsigned long flags;
+
+	daemonize("libusual_%d", type);	/* "usb-storage" is kinda too long */
+
+	/* A completion does not work here because it's counted. */
+	down(&usu_init_notify);
+	up(&usu_init_notify);
+
+	rc = request_module(bias_names[type]);
+	spin_lock_irqsave(&usu_lock, flags);
+	if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
+		/*
+		 * This should not happen, but let us keep tabs on it.
+		 */
+		printk(KERN_NOTICE "libusual: "
+		    "modprobe for %s succeeded, but module is not present\n",
+		    bias_names[type]);
+	}
+	st->fls &= ~USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	complete_and_exit(&usu_end_notify, 0);
+}
+
+/*
+ */
+static int __init usb_usual_init(void)
+{
+	int rc;
+
+	rc = usb_register(&usu_driver);
+	up(&usu_init_notify);
+	return rc;
+}
+
+static void __exit usb_usual_exit(void)
+{
+	/*
+	 * We do not check for any drivers present, because
+	 * they keep us pinned with symbol references.
+	 */
+
+	usb_deregister(&usu_driver);
+
+	while (atomic_read(&total_threads) > 0) {
+		wait_for_completion(&usu_end_notify);
+		atomic_dec(&total_threads);
+	}
+}
+
+/*
+ * Validate and accept the bias parameter.
+ */
+static int usu_set_bias(const char *bias_s, struct kernel_param *kp)
+{
+	int i;
+	int len;
+	int bias_n = 0;
+
+	len = strlen(bias_s);
+	if (len == 0)
+		return -EDOM;
+	if (bias_s[len-1] == '\n')
+		--len;
+
+	for (i = 1; i < 3; i++) {
+		if (strncmp(bias_s, bias_names[i], len) == 0) {
+			bias_n = i;
+			break;
+		}
+	}
+	if (bias_n == 0)
+		return -EINVAL;
+
+	atomic_set(&usu_bias, bias_n);
+	return 0;
+}
+
+static int usu_get_bias(char *buffer, struct kernel_param *kp)
+{
+	return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)]));
+}
+
+module_init(usb_usual_init);
+module_exit(usb_usual_exit);
+
+module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR);
+__MODULE_PARM_TYPE(bias, "string");
+MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 89401a5..55ee2d3 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -52,6 +52,7 @@
 	struct urb *irq;	/* urb for interrupt in report */
 	unsigned char *data;	/* input data */
 	dma_addr_t data_dma;
+	unsigned int is_open:1;
 };
 
 static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
@@ -89,6 +90,7 @@
 {
 	struct usb_onetouch *onetouch = dev->private;
 
+	onetouch->is_open = 1;
 	onetouch->irq->dev = onetouch->udev;
 	if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
 		err("usb_submit_urb failed");
@@ -103,8 +105,30 @@
 	struct usb_onetouch *onetouch = dev->private;
 
 	usb_kill_urb(onetouch->irq);
+	onetouch->is_open = 0;
 }
 
+#ifdef CONFIG_PM
+static void usb_onetouch_pm_hook(struct us_data *us, int action)
+{
+	struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra;
+
+	if (onetouch->is_open) {
+		switch (action) {
+		case US_SUSPEND:
+			usb_kill_urb(onetouch->irq);
+			break;
+		case US_RESUME:
+			if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
+				err("usb_submit_urb failed");
+			break;
+		default:
+			break;
+		}
+	}
+}
+#endif /* CONFIG_PM */
+
 int onetouch_connect_input(struct us_data *ss)
 {
 	struct usb_device *udev = ss->pusb_dev;
@@ -185,6 +209,9 @@
 
 	ss->extra_destructor = onetouch_release_input;
 	ss->extra = onetouch;
+#ifdef CONFIG_PM
+	ss->suspend_resume_hook = usb_onetouch_pm_hook;
+#endif
 
 	input_register_device(onetouch->dev);
 
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
index 02bff01..845bed4 100644
--- a/drivers/usb/storage/protocol.h
+++ b/drivers/usb/storage/protocol.h
@@ -41,20 +41,6 @@
 #ifndef _PROTOCOL_H_
 #define _PROTOCOL_H_
 
-/* Sub Classes */
-
-#define US_SC_RBC	0x01		/* Typically, flash devices */
-#define US_SC_8020	0x02		/* CD-ROM */
-#define US_SC_QIC	0x03		/* QIC-157 Tapes */
-#define US_SC_UFI	0x04		/* Floppy */
-#define US_SC_8070	0x05		/* Removable media */
-#define US_SC_SCSI	0x06		/* Transparent */
-#define US_SC_ISD200    0x07		/* ISD200 ATA */
-#define US_SC_MIN	US_SC_RBC
-#define US_SC_MAX	US_SC_ISD200
-
-#define US_SC_DEVICE	0xff		/* Use device's value */
-
 /* Protocol handling routines */
 extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*);
 extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*);
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 0ea2f5a..fb8baca 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -133,13 +133,11 @@
 	{ 0,}
 };
 
-#define SIZE(a)	(sizeof(a)/sizeof((a)[0]))
-
 static struct nand_flash_dev *
 nand_find_id(unsigned char id) {
 	int i;
 
-	for (i = 0; i < SIZE(nand_flash_ids); i++)
+	for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++)
 		if (nand_flash_ids[i].model_id == id)
 			return &(nand_flash_ids[i]);
 	return NULL;
@@ -214,6 +212,20 @@
  * The actual driver starts here.
  */
 
+struct sddr09_card_info {
+	unsigned long	capacity;	/* Size of card in bytes */
+	int		pagesize;	/* Size of page in bytes */
+	int		pageshift;	/* log2 of pagesize */
+	int		blocksize;	/* Size of block in pages */
+	int		blockshift;	/* log2 of blocksize */
+	int		blockmask;	/* 2^blockshift - 1 */
+	int		*lba_to_pba;	/* logical to physical map */
+	int		*pba_to_lba;	/* physical to logical map */
+	int		lbact;		/* number of available pages */
+	int		flags;
+#define	SDDR09_WP	1		/* write protected */
+};
+
 /*
  * On my 16MB card, control blocks have size 64 (16 real control bytes,
  * and 48 junk bytes). In reality of course the card uses 16 control bytes,
@@ -237,7 +249,7 @@
 #define SPARE    0xfffffffe
 #define UNUSABLE 0xfffffffd
 
-static int erase_bad_lba_entries = 0;
+static const int erase_bad_lba_entries = 0;
 
 /* send vendor interface command (0x41) */
 /* called for requests 0, 1, 8 */
@@ -260,8 +272,11 @@
 
 	rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype,
 				   0, 0, xfer_data, xfer_len);
-	return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD :
-			USB_STOR_TRANSPORT_ERROR);
+	switch (rc) {
+		case USB_STOR_XFER_GOOD:	return 0;
+		case USB_STOR_XFER_STALLED:	return -EPIPE;
+		default:			return -EIO;
+	}
 }
 
 static int
@@ -308,20 +323,12 @@
 	command[4] = buflen;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
-		US_DEBUGP("request sense failed\n");
+	if (result)
 		return result;
-	}
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 			sensebuf, buflen, NULL);
-	if (result != USB_STOR_XFER_GOOD) {
-		US_DEBUGP("request sense bulk in failed\n");
-		return USB_STOR_TRANSPORT_ERROR;
-	} else {
-		US_DEBUGP("request sense worked\n");
-		return USB_STOR_TRANSPORT_GOOD;
-	}
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 /*
@@ -369,7 +376,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_read2%d %d\n",
 			  x, result);
 		return result;
@@ -381,9 +388,9 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n",
 			  x, result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 /*
@@ -497,7 +504,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		US_DEBUGP("Result for send_control in sddr09_erase %d\n",
 			  result);
 
@@ -555,7 +562,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_writeX %d\n",
 			  result);
 		return result;
@@ -567,9 +574,9 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n",
 			  result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 /* erase address, write same address */
@@ -633,7 +640,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 4*nsg+3);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_read_sg %d\n",
 			  result);
 		return result;
@@ -641,7 +648,7 @@
 
 	buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO);
 	if (!buf)
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 				       buf, bulklen, NULL);
@@ -649,10 +656,10 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n",
 			  result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
 
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 #endif
 
@@ -681,14 +688,13 @@
 	command[1] = LUNBITS;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 				       data, 64, NULL);
 	*status = data[0];
-	return (result == USB_STOR_XFER_GOOD ?
-			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -703,6 +709,13 @@
 	unsigned int len, index, offset;
 	int result;
 
+	// Figure out the initial LBA and page
+	lba = address >> info->blockshift;
+	page = (address & info->blockmask);
+	maxlba = info->capacity >> (info->pageshift + info->blockshift);
+	if (lba >= maxlba)
+		return -EIO;
+
 	// Since we only read in one block at a time, we have to create
 	// a bounce buffer and move the data a piece at a time between the
 	// bounce buffer and the actual transfer buffer.
@@ -711,18 +724,13 @@
 	buffer = kmalloc(len, GFP_NOIO);
 	if (buffer == NULL) {
 		printk("sddr09_read_data: Out of memory\n");
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
-	// Figure out the initial LBA and page
-	lba = address >> info->blockshift;
-	page = (address & info->blockmask);
-	maxlba = info->capacity >> (info->pageshift + info->blockshift);
-
 	// This could be made much more efficient by checking for
 	// contiguous LBA's. Another exercise left to the student.
 
-	result = USB_STOR_TRANSPORT_GOOD;
+	result = 0;
 	index = offset = 0;
 
 	while (sectors > 0) {
@@ -735,7 +743,7 @@
 		if (lba >= maxlba) {
 			US_DEBUGP("Error: Requested lba %u exceeds "
 				  "maximum %u\n", lba, maxlba);
-			result = USB_STOR_TRANSPORT_ERROR;
+			result = -EIO;
 			break;
 		}
 
@@ -749,7 +757,7 @@
 
 			/* This is not really an error. It just means
 			   that the block has never been written.
-			   Instead of returning USB_STOR_TRANSPORT_ERROR
+			   Instead of returning an error
 			   it is better to return all zero data. */
 
 			memset(buffer, 0, len);
@@ -764,7 +772,7 @@
 
 			result = sddr09_read20(us, address>>1,
 					pages, info->pageshift, buffer, 0);
-			if (result != USB_STOR_TRANSPORT_GOOD)
+			if (result)
 				break;
 		}
 
@@ -830,7 +838,7 @@
 		pba = sddr09_find_unused_pba(info, lba);
 		if (!pba) {
 			printk("sddr09_write_lba: Out of unused blocks\n");
-			return USB_STOR_TRANSPORT_ERROR;
+			return -ENOSPC;
 		}
 		info->pba_to_lba[pba] = lba;
 		info->lba_to_pba[lba] = pba;
@@ -841,7 +849,7 @@
 		/* Maybe it is impossible to write to PBA 1.
 		   Fake success, but don't do anything. */
 		printk("sddr09: avoid writing to pba 1\n");
-		return USB_STOR_TRANSPORT_GOOD;
+		return 0;
 	}
 
 	pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT);
@@ -850,7 +858,7 @@
 	address = (pba << (info->pageshift + info->blockshift));
 	result = sddr09_read22(us, address>>1, info->blocksize,
 			       info->pageshift, blockbuffer, 0);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	/* check old contents and fill lba */
@@ -897,7 +905,7 @@
 	{
 		unsigned char status = 0;
 		int result2 = sddr09_read_status(us, &status);
-		if (result2 != USB_STOR_TRANSPORT_GOOD)
+		if (result2)
 			US_DEBUGP("sddr09_write_inplace: cannot read status\n");
 		else if (status != 0xc0)
 			US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n",
@@ -920,13 +928,20 @@
 		  unsigned int sectors) {
 
 	struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
-	unsigned int lba, page, pages;
+	unsigned int lba, maxlba, page, pages;
 	unsigned int pagelen, blocklen;
 	unsigned char *blockbuffer;
 	unsigned char *buffer;
 	unsigned int len, index, offset;
 	int result;
 
+	// Figure out the initial LBA and page
+	lba = address >> info->blockshift;
+	page = (address & info->blockmask);
+	maxlba = info->capacity >> (info->pageshift + info->blockshift);
+	if (lba >= maxlba)
+		return -EIO;
+
 	// blockbuffer is used for reading in the old data, overwriting
 	// with the new data, and performing ECC calculations
 
@@ -938,7 +953,7 @@
 	blockbuffer = kmalloc(blocklen, GFP_NOIO);
 	if (!blockbuffer) {
 		printk("sddr09_write_data: Out of memory\n");
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
 	// Since we don't write the user data directly to the device,
@@ -950,14 +965,10 @@
 	if (buffer == NULL) {
 		printk("sddr09_write_data: Out of memory\n");
 		kfree(blockbuffer);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
-	// Figure out the initial LBA and page
-	lba = address >> info->blockshift;
-	page = (address & info->blockmask);
-
-	result = USB_STOR_TRANSPORT_GOOD;
+	result = 0;
 	index = offset = 0;
 
 	while (sectors > 0) {
@@ -967,13 +978,21 @@
 		pages = min(sectors, info->blocksize - page);
 		len = (pages << info->pageshift);
 
+		/* Not overflowing capacity? */
+		if (lba >= maxlba) {
+			US_DEBUGP("Error: Requested lba %u exceeds "
+				  "maximum %u\n", lba, maxlba);
+			result = -EIO;
+			break;
+		}
+
 		// Get the data from the transfer buffer
 		usb_stor_access_xfer_buf(buffer, len, us->srb,
 				&index, &offset, FROM_XFER_BUF);
 
 		result = sddr09_write_lba(us, lba, page, pages,
 				buffer, blockbuffer);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result)
 			break;
 
 		page = 0;
@@ -1022,7 +1041,7 @@
 	command[1] = LUNBITS;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
@@ -1031,8 +1050,7 @@
 	for (i = 0; i < 4; i++)
 		deviceID[i] = content[i];
 
-	return (result == USB_STOR_XFER_GOOD ?
-			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -1041,7 +1059,7 @@
 	unsigned char status;
 
 	result = sddr09_read_status(us, &status);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_get_wp: read_status fails\n");
 		return result;
 	}
@@ -1057,7 +1075,7 @@
 	if (status & 0x1)
 		US_DEBUGP(" Error");
 	US_DEBUGP("\n");
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 #if 0
@@ -1089,7 +1107,7 @@
 
 	result = sddr09_read_deviceID(us, deviceID);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result of read_deviceID is %d\n", result);
 		printk("sddr09: could not read card info\n");
 		return NULL;
@@ -1200,7 +1218,7 @@
 				us, address>>1,
 				min(alloc_blocks, numblocks - i),
 				buffer, 0);
-			if (result != USB_STOR_TRANSPORT_GOOD) {
+			if (result) {
 				result = -1;
 				goto done;
 			}
@@ -1342,29 +1360,53 @@
 	kfree(info->pba_to_lba);
 }
 
-static void
-sddr09_init_card_info(struct us_data *us) {
-	if (!us->extra) {
-		us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
-		if (us->extra) {
-			memset(us->extra, 0, sizeof(struct sddr09_card_info));
-			us->extra_destructor = sddr09_card_info_destructor;
-		}
+static int
+sddr09_common_init(struct us_data *us) {
+	int result;
+
+	/* set the configuration -- STALL is an acceptable response here */
+	if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
+		US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
+				->actconfig->desc.bConfigurationValue);
+		return -EINVAL;
 	}
+
+	result = usb_reset_configuration(us->pusb_dev);
+	US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
+	if (result == -EPIPE) {
+		US_DEBUGP("-- stall on control interface\n");
+	} else if (result != 0) {
+		/* it's not a stall, but another error -- time to bail */
+		US_DEBUGP("-- Unknown error.  Rejecting device\n");
+		return -EINVAL;
+	}
+
+	us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
+	if (!us->extra)
+		return -ENOMEM;
+	us->extra_destructor = sddr09_card_info_destructor;
+
+	nand_init_ecc();
+	return 0;
 }
 
+
 /*
  * This is needed at a very early stage. If this is not listed in the
  * unusual devices list but called from here then LUN 0 of the combo reader
  * is not recognized. But I do not know what precisely these calls do.
  */
 int
-sddr09_init(struct us_data *us) {
+usb_stor_sddr09_dpcm_init(struct us_data *us) {
 	int result;
 	unsigned char *data = us->iobuf;
 
+	result = sddr09_common_init(us);
+	if (result)
+		return result;
+
 	result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_init: send_command fails\n");
 		return result;
 	}
@@ -1373,7 +1415,7 @@
 	// get 07 02
 
 	result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_init: 2nd send_command fails\n");
 		return result;
 	}
@@ -1382,7 +1424,7 @@
 	// get 07 00
 
 	result = sddr09_request_sense(us, data, 18);
-	if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) {
+	if (result == 0 && data[2] != 0) {
 		int j;
 		for (j=0; j<18; j++)
 			printk(" %02X", data[j]);
@@ -1398,7 +1440,7 @@
 
 	// test unit ready
 
-	return USB_STOR_TRANSPORT_GOOD;		/* not result */
+	return 0;		/* not result */
 }
 
 /*
@@ -1427,13 +1469,6 @@
 	};
 
 	info = (struct sddr09_card_info *)us->extra;
-	if (!info) {
-		nand_init_ecc();
-		sddr09_init_card_info(us);
-		info = (struct sddr09_card_info *)us->extra;
-		if (!info)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
 
 	if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) {
 		/* for a faked command, we have to follow with a faked sense */
@@ -1536,7 +1571,9 @@
 		US_DEBUGP("READ_10: read page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_read_data(us, page, pages);
+		result = sddr09_read_data(us, page, pages);
+		return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+				USB_STOR_TRANSPORT_ERROR);
 	}
 
 	if (srb->cmnd[0] == WRITE_10) {
@@ -1549,7 +1586,9 @@
 		US_DEBUGP("WRITE_10: write page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_write_data(us, page, pages);
+		result = sddr09_write_data(us, page, pages);
+		return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+				USB_STOR_TRANSPORT_ERROR);
 	}
 
 	/* catch-all for all other commands, except
@@ -1575,10 +1614,10 @@
 	US_DEBUGP("SDDR09: Send control for command %s\n", ptr);
 
 	result = sddr09_send_scsi_command(us, srb->cmnd, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_transport: sddr09_send_scsi_command "
 			  "returns %d\n", result);
-		return result;
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	if (srb->request_bufflen == 0)
@@ -1606,3 +1645,10 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
+/*
+ * Initialization routine for the sddr09 subdriver
+ */
+int
+usb_stor_sddr09_init(struct us_data *us) {
+	return sddr09_common_init(us);
+}
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
index c9d78d6..c03089a 100644
--- a/drivers/usb/storage/sddr09.h
+++ b/drivers/usb/storage/sddr09.h
@@ -31,18 +31,7 @@
 
 extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
 
-struct sddr09_card_info {
-	unsigned long	capacity;	/* Size of card in bytes */
-	int		pagesize;	/* Size of page in bytes */
-	int		pageshift;	/* log2 of pagesize */
-	int		blocksize;	/* Size of block in pages */
-	int		blockshift;	/* log2 of blocksize */
-	int		blockmask;	/* 2^blockshift - 1 */
-	int		*lba_to_pba;	/* logical to physical map */
-	int		*pba_to_lba;	/* physical to logical map */
-	int		lbact;		/* number of available pages */
-	int		flags;
-#define	SDDR09_WP	1		/* write protected */
-};
+extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
+extern int usb_stor_sddr09_init(struct us_data *us);
 
 #endif
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index 0a362cc..633a715 100644
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -41,39 +41,8 @@
 #ifndef _TRANSPORT_H_
 #define _TRANSPORT_H_
 
-#include <linux/config.h>
 #include <linux/blkdev.h>
 
-/* Protocols */
-
-#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
-#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
-#define US_PR_BULK	0x50		/* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
-#endif
-#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1		/* Freecom */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
-#endif
-
-#define US_PR_DEVICE	0xff		/* Use device's value */
-
 /*
  * Bulk only data structures
  */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index f5f47a3..dc301e5 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -79,13 +79,6 @@
 		US_SC_8070, US_PR_USBAT, init_usbat, 0),
 #endif
 
-/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
-UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
-		"VIA Technologies Inc.",
-		"USB 2.0 Card Reader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
 /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
  * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
  * for USB floppies that need the SINGLE_LUN enforcement.
@@ -96,6 +89,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN ),
 
+/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
+UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
+		"VIA Technologies Inc.",
+		"USB 2.0 Card Reader",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
  * always fails and confuses drive.
@@ -187,6 +187,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
+/* Patch for Nikon coolpix 2000
+ * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
+UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
+		"NIKON",
+		"NIKON DSC E2000",
+		US_SC_DEVICE, US_PR_DEVICE,NULL,
+		US_FL_NOT_LOCKABLE ),
+
 /* BENQ DC5330
  * Reported by Manuel Fombuena <mfombuena@ya.com> and
  * Frank Copeland <fjc@thingy.apana.org.au> */
@@ -276,14 +284,14 @@
 UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999, 
 		"Sandisk",
 		"ImageMate SDDR09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 
 /* This entry is from Andries.Brouwer@cwi.nl */
 UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
 		"SCM Microsystems",
 		"eUSB SmartMedia / CompactFlash Adapter",
-		US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, 
+		US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
 		0), 
 #endif
 
@@ -527,6 +535,13 @@
 		"Silicon Media R/W",
 		US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
+		"Fujifilm",
+		"DPC-R1 (Alauda)",
+ 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 /* Fabrizio Fellini <fello@libero.it> */
 UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
 		"Fujifilm",
@@ -673,8 +688,8 @@
 UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100, 
 		"Olympus",
 		"Camedia MAUSB-2",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 #endif
 
 /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
@@ -739,8 +754,8 @@
 UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999, 
 		"Sandisk",
 		"ImageMate SDDR-09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 #endif
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
@@ -776,6 +791,13 @@
  		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
+		"Olympus",
+		"MAUSB-10 (Alauda)",
+ 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 #ifdef CONFIG_USB_STORAGE_DATAFAB
 UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
 		"Datafab",
@@ -1134,3 +1156,27 @@
 		US_SC_SCSI, US_PR_SDDR55, NULL,
 		US_FL_SINGLE_LUN),
 #endif
+
+/* Control/Bulk transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
+
+/* Control/Bulk/Interrupt transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
+
+/* Bulk-only transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3847ebe..dbcf239 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -94,6 +94,9 @@
 #ifdef CONFIG_USB_STORAGE_ONETOUCH
 #include "onetouch.h"
 #endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#include "alauda.h"
+#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -112,49 +115,33 @@
 static DECLARE_COMPLETION(threads_gone);
 
 
-/* The entries in this table, except for final ones here
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
- * line for line with the entries of us_unsuaul_dev_list[].
+/*
+ * The entries in this table correspond, line for line,
+ * with the entries of us_unusual_dev_list[].
  */
+#ifndef CONFIG_USB_LIBUSUAL
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
 		    vendorName, productName,useProtocol, useTransport, \
 		    initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = (USB_US_TYPE_STOR<<24) }
 
 static struct usb_device_id storage_usb_ids [] = {
 
 #	include "unusual_devs.h"
 #undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
-
-	/* Bulk-only transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
-
+#undef USUAL_DEV
 	/* Terminating entry */
 	{ }
 };
 
 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /* This is the list of devices we recognize, along with their flag data */
 
@@ -167,7 +154,6 @@
  * are free to use as many characters as you like.
  */
 
-#undef UNUSUAL_DEV
 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
 		    vendor_name, product_name, use_protocol, use_transport, \
 		    init_function, Flags) \
@@ -177,53 +163,18 @@
 	.useProtocol = use_protocol,	\
 	.useTransport = use_transport,	\
 	.initFunction = init_function,	\
-	.flags = Flags, \
+}
+
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
+{ \
+	.useProtocol = use_protocol,	\
+	.useTransport = use_transport,	\
 }
 
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #	include "unusual_devs.h" 
 #	undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CB},
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CBI},
-
-	/* Bulk-only transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_BULK},
+#	undef USUAL_DEV
 
 	/* Terminating entry */
 	{ NULL }
@@ -240,6 +191,8 @@
 	down(&us->dev_semaphore);
 
 	US_DEBUGP("%s\n", __FUNCTION__);
+	if (us->suspend_resume_hook)
+		(us->suspend_resume_hook)(us, US_SUSPEND);
 	iface->dev.power.power_state.event = message.event;
 
 	/* When runtime PM is working, we'll set a flag to indicate
@@ -256,6 +209,8 @@
 	down(&us->dev_semaphore);
 
 	US_DEBUGP("%s\n", __FUNCTION__);
+	if (us->suspend_resume_hook)
+		(us->suspend_resume_hook)(us, US_RESUME);
 	iface->dev.power.power_state.event = PM_EVENT_ON;
 
 	up(&us->dev_semaphore);
@@ -484,14 +439,20 @@
 	return 0;
 }
 
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
+{
+	const int id_index = id - storage_usb_ids;
+	return &us_unusual_dev_list[id_index];
+}
+
 /* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, int id_index)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
 {
 	struct usb_device *dev = us->pusb_dev;
 	struct usb_interface_descriptor *idesc =
 		&us->pusb_intf->cur_altsetting->desc;
-	struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
-	struct usb_device_id *id = &storage_usb_ids[id_index];
+	struct us_unusual_dev *unusual_dev = find_unusual(id);
 
 	/* Store the entries */
 	us->unusual_dev = unusual_dev;
@@ -501,7 +462,7 @@
 	us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
 			idesc->bInterfaceProtocol :
 			unusual_dev->useTransport;
-	us->flags = unusual_dev->flags;
+	us->flags = USB_US_ORIG_FLAGS(id->driver_info);
 
 	/*
 	 * This flag is only needed when we're in high-speed, so let's
@@ -516,7 +477,7 @@
 	 * from the unusual_devs.h table.
 	 */
 	if (id->idVendor || id->idProduct) {
-		static char *msgs[3] = {
+		static const char *msgs[3] = {
 			"an unneeded SubClass entry",
 			"an unneeded Protocol entry",
 			"unneeded SubClass and Protocol entries"};
@@ -529,7 +490,7 @@
 		if (unusual_dev->useTransport != US_PR_DEVICE &&
 			us->protocol == idesc->bInterfaceProtocol)
 			msg += 2;
-		if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
+		if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
 			printk(KERN_NOTICE USB_STORAGE "This device "
 				"(%04x,%04x,%04x S %02x P %02x)"
 				" has %s in unusual_devs.h\n"
@@ -686,6 +647,15 @@
 		break;
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+	case US_PR_ALAUDA:
+		us->transport_name  = "Alauda Control/Bulk";
+		us->transport = alauda_transport;
+		us->transport_reset = usb_stor_Bulk_reset;
+		us->max_lun = 1;
+		break;
+#endif
+
 	default:
 		return -EIO;
 	}
@@ -921,10 +891,12 @@
 {
 	struct Scsi_Host *host;
 	struct us_data *us;
-	const int id_index = id - storage_usb_ids; 
 	int result;
 	struct task_struct *th;
 
+	if (usb_usual_check_type(id, USB_US_TYPE_STOR))
+		return -ENXIO;
+
 	US_DEBUGP("USB Mass Storage device detected\n");
 
 	/*
@@ -957,29 +929,7 @@
 	 * of the match from the usb_device_id table, so we can find the
 	 * corresponding entry in the private table.
 	 */
-	get_device_info(us, id_index);
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-	if (us->protocol == US_PR_EUSB_SDDR09 ||
-			us->protocol == US_PR_DPCM_USB) {
-		/* set the configuration -- STALL is an acceptable response here */
-		if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
-			US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
-				->actconfig->desc.bConfigurationValue);
-			goto BadDevice;
-		}
-		result = usb_reset_configuration(us->pusb_dev);
-
-		US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
-		if (result == -EPIPE) {
-			US_DEBUGP("-- stall on control interface\n");
-		} else if (result != 0) {
-			/* it's not a stall, but another error -- time to bail */
-			US_DEBUGP("-- Unknown error.  Rejecting device\n");
-			goto BadDevice;
-		}
-	}
-#endif
+	get_device_info(us, id);
 
 	/* Get the transport, protocol, and pipe settings */
 	result = get_transport(us);
@@ -1044,7 +994,6 @@
  ***********************************************************************/
 
 static struct usb_driver usb_storage_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usb-storage",
 	.probe =	storage_probe,
 	.disconnect =	storage_disconnect,
@@ -1062,9 +1011,10 @@
 
 	/* register the driver, return usb_register return code if error */
 	retval = usb_register(&usb_storage_driver);
-	if (retval == 0)
+	if (retval == 0) {
 		printk(KERN_INFO "USB Mass Storage support registered.\n");
-
+		usb_usual_set_present(USB_US_TYPE_STOR);
+	}
 	return retval;
 }
 
@@ -1088,6 +1038,8 @@
 		wait_for_completion(&threads_gone);
 		atomic_dec(&total_threads);
 	}
+
+	usb_usual_clear_present(USB_US_TYPE_STOR);
 }
 
 module_init(usb_stor_init);
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 98b0971..7259fd1 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -45,6 +45,7 @@
 #define _USB_H_
 
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
@@ -63,38 +64,8 @@
 	__u8  useProtocol;
 	__u8  useTransport;
 	int (*initFunction)(struct us_data *);
-	unsigned int flags;
 };
 
-/*
- * Static flag definitions.  We use this roundabout technique so that the
- * proc_info() routine can automatically display a message for each flag.
- */
-#define US_DO_ALL_FLAGS						\
-	US_FLAG(SINGLE_LUN,	0x00000001)			\
-		/* allow access to only LUN 0 */		\
-	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
-		/* unusual_devs entry is necessary */		\
-	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
-		/* supports multiple targets */			\
-	US_FLAG(FIX_INQUIRY,	0x00000008)			\
-		/* INQUIRY response needs faking */		\
-	US_FLAG(FIX_CAPACITY,	0x00000010)			\
-		/* READ CAPACITY response too big */		\
-	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
-		/* reported residue is wrong */			\
-	US_FLAG(BULK32,		0x00000040)			\
-		/* Uses 32-byte CBW length */			\
-	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
-		/* PREVENT/ALLOW not supported */		\
-	US_FLAG(GO_SLOW,	0x00000100)			\
-		/* Need delay after Command phase */		\
-	US_FLAG(NO_WP_DETECT,	0x00000200)			\
-		/* Don't check for write-protect */		\
-
-#define US_FLAG(name, value)	US_FL_##name = value ,
-enum { US_DO_ALL_FLAGS };
-#undef US_FLAG
 
 /* Dynamic flag definitions: used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	18  /* 0x00040000  current_urb is in use  */
@@ -122,7 +93,11 @@
 typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
 typedef int (*trans_reset)(struct us_data*);
 typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
-typedef void (*extra_data_destructor)(void *);	 /* extra data destructor   */
+typedef void (*extra_data_destructor)(void *);	/* extra data destructor */
+typedef void (*pm_hook)(struct us_data *, int);	/* power management hook */
+
+#define US_SUSPEND	0
+#define US_RESUME	1
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
@@ -178,6 +153,9 @@
 	/* subdriver information */
 	void			*extra;		 /* Any extra data          */
 	extra_data_destructor	extra_destructor;/* extra data destructor   */
+#ifdef CONFIG_PM
+	pm_hook			suspend_resume_hook;
+#endif
 };
 
 /* Convert between us_data and the corresponding Scsi_Host */
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 6c3a53f..5d02f16 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -39,10 +39,15 @@
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE	192
 
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER		( PAGE_SIZE - 512 )
+#define WRITES_IN_FLIGHT	8
+
 /* Structure to hold all of our device specific stuff */
 struct usb_skel {
 	struct usb_device *	udev;			/* the usb device for this device */
 	struct usb_interface *	interface;		/* the interface for this device */
+	struct semaphore	limit_sem;		/* limiting the number of writes in progress */
 	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 */
@@ -152,6 +157,7 @@
 	/* free up our allocated buffer */
 	usb_buffer_free(urb->dev, urb->transfer_buffer_length, 
 			urb->transfer_buffer, urb->transfer_dma);
+	up(&dev->limit_sem);
 }
 
 static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
@@ -160,6 +166,7 @@
 	int retval = 0;
 	struct urb *urb = NULL;
 	char *buf = NULL;
+	size_t writesize = min(count, (size_t)MAX_TRANSFER);
 
 	dev = (struct usb_skel *)file->private_data;
 
@@ -167,6 +174,12 @@
 	if (count == 0)
 		goto exit;
 
+	/* limit the number of URBs in flight to stop a user from using up all RAM */
+	if (down_interruptible(&dev->limit_sem)) {
+		retval = -ERESTARTSYS;
+		goto exit;
+	}
+
 	/* create a urb, and a buffer for it, and copy the data to the urb */
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb) {
@@ -174,13 +187,13 @@
 		goto error;
 	}
 
-	buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+	buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
 	if (!buf) {
 		retval = -ENOMEM;
 		goto error;
 	}
 
-	if (copy_from_user(buf, user_buffer, count)) {
+	if (copy_from_user(buf, user_buffer, writesize)) {
 		retval = -EFAULT;
 		goto error;
 	}
@@ -188,7 +201,7 @@
 	/* initialize the urb properly */
 	usb_fill_bulk_urb(urb, dev->udev,
 			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
-			  buf, count, skel_write_bulk_callback, dev);
+			  buf, writesize, skel_write_bulk_callback, dev);
 	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* send the data out the bulk port */
@@ -202,11 +215,12 @@
 	usb_free_urb(urb);
 
 exit:
-	return count;
+	return writesize;
 
 error:
-	usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
+	usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
 	usb_free_urb(urb);
+	up(&dev->limit_sem);
 	return retval;
 }
 
@@ -238,13 +252,13 @@
 	int retval = -ENOMEM;
 
 	/* allocate memory for our device state and initialize it */
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
 		err("Out of memory");
 		goto error;
 	}
-	memset(dev, 0x00, sizeof(*dev));
 	kref_init(&dev->kref);
+	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
 
 	dev->udev = usb_get_dev(interface_to_usbdev(interface));
 	dev->interface = interface;
@@ -330,7 +344,6 @@
 }
 
 static struct usb_driver skel_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"skeleton",
 	.probe =	skel_probe,
 	.disconnect =	skel_disconnect,
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c
index 15fb250..b914630 100644
--- a/drivers/w1/dscore.c
+++ b/drivers/w1/dscore.c
@@ -52,7 +52,6 @@
 
 
 static struct usb_driver ds_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"DS9490R",
 	.probe =	ds_probe,
 	.disconnect =	ds_disconnect,
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index a93c2bf..6a9a75d 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -26,6 +26,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/net.h>
 #include <linux/ipv6.h>
diff --git a/fs/bio.c b/fs/bio.c
index 460554b..38d3e80 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -313,7 +313,8 @@
 }
 
 static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
-			  *page, unsigned int len, unsigned int offset)
+			  *page, unsigned int len, unsigned int offset,
+			  unsigned short max_sectors)
 {
 	int retried_segments = 0;
 	struct bio_vec *bvec;
@@ -327,7 +328,7 @@
 	if (bio->bi_vcnt >= bio->bi_max_vecs)
 		return 0;
 
-	if (((bio->bi_size + len) >> 9) > q->max_sectors)
+	if (((bio->bi_size + len) >> 9) > max_sectors)
 		return 0;
 
 	/*
@@ -386,6 +387,25 @@
 }
 
 /**
+ *	bio_add_pc_page	-	attempt to add page to bio
+ *	@bio: destination bio
+ *	@page: page to add
+ *	@len: vec entry length
+ *	@offset: vec entry offset
+ *
+ *	Attempt to add a page to the bio_vec maplist. This can fail for a
+ *	number of reasons, such as the bio being full or target block
+ *	device limitations. The target block device must allow bio's
+ *      smaller than PAGE_SIZE, so it is always possible to add a single
+ *      page to an empty bio. This should only be used by REQ_PC bios.
+ */
+int bio_add_pc_page(request_queue_t *q, struct bio *bio, struct page *page,
+		    unsigned int len, unsigned int offset)
+{
+	return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors);
+}
+
+/**
  *	bio_add_page	-	attempt to add page to bio
  *	@bio: destination bio
  *	@page: page to add
@@ -401,8 +421,8 @@
 int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
 		 unsigned int offset)
 {
-	return __bio_add_page(bdev_get_queue(bio->bi_bdev), bio, page,
-			      len, offset);
+	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+	return __bio_add_page(q, bio, page, len, offset, q->max_sectors);
 }
 
 struct bio_map_data {
@@ -514,7 +534,7 @@
 			break;
 		}
 
-		if (__bio_add_page(q, bio, page, bytes, 0) < bytes) {
+		if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
 			ret = -EINVAL;
 			break;
 		}
@@ -628,7 +648,8 @@
 			/*
 			 * sorry...
 			 */
-			if (__bio_add_page(q, bio, pages[j], bytes, offset) < bytes)
+			if (bio_add_pc_page(q, bio, pages[j], bytes, offset) <
+					    bytes)
 				break;
 
 			len -= bytes;
@@ -801,8 +822,8 @@
 		if (bytes > len)
 			bytes = len;
 
-		if (__bio_add_page(q, bio, virt_to_page(data), bytes,
-				   offset) < bytes)
+		if (bio_add_pc_page(q, bio, virt_to_page(data), bytes,
+				    offset) < bytes)
 			break;
 
 		data += bytes;
@@ -1228,6 +1249,7 @@
 EXPORT_SYMBOL(bio_phys_segments);
 EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
+EXPORT_SYMBOL(bio_add_pc_page);
 EXPORT_SYMBOL(bio_get_nr_vecs);
 EXPORT_SYMBOL(bio_map_user);
 EXPORT_SYMBOL(bio_unmap_user);
diff --git a/fs/compat.c b/fs/compat.c
index 8186341..55ac032 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1170,7 +1170,7 @@
 	}
 
 	ret = rw_verify_area(type, file, pos, tot_len);
-	if (ret)
+	if (ret < 0)
 		goto out;
 
 	fnv = NULL;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index f2ca782..30cae36 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -14,6 +14,9 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
+
+#include <net/inet_sock.h>
+
 #include "nfs4_fs.h"
 #include "callback.h"
 
diff --git a/fs/read_write.c b/fs/read_write.c
index a091ee4..df3468a 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -14,6 +14,7 @@
 #include <linux/security.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
+#include <linux/pagemap.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -182,22 +183,33 @@
 }
 #endif
 
+/*
+ * rw_verify_area doesn't like huge counts. We limit
+ * them to something that fits in "int" so that others
+ * won't have to do range checks all the time.
+ */
+#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
 
 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 > INT_MAX))
+	if (unlikely((ssize_t) count < 0))
 		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;
+	if (inode->i_flock && MANDATORY_LOCK(inode)) {
+		int retval = locks_mandatory_area(
+			read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
+			inode, file, pos, count);
+		if (retval < 0)
+			return retval;
+	}
+	return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
 
 Einval:
 	return -EINVAL;
@@ -244,7 +256,8 @@
 		return -EFAULT;
 
 	ret = rw_verify_area(READ, file, pos, count);
-	if (!ret) {
+	if (ret >= 0) {
+		count = ret;
 		ret = security_file_permission (file, MAY_READ);
 		if (!ret) {
 			if (file->f_op->read)
@@ -295,7 +308,8 @@
 		return -EFAULT;
 
 	ret = rw_verify_area(WRITE, file, pos, count);
-	if (!ret) {
+	if (ret >= 0) {
+		count = ret;
 		ret = security_file_permission (file, MAY_WRITE);
 		if (!ret) {
 			if (file->f_op->write)
@@ -497,7 +511,7 @@
 	}
 
 	ret = rw_verify_area(type, file, pos, tot_len);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
 	if (ret)
@@ -653,8 +667,9 @@
 		if (!(in_file->f_mode & FMODE_PREAD))
 			goto fput_in;
 	retval = rw_verify_area(READ, in_file, ppos, count);
-	if (retval)
+	if (retval < 0)
 		goto fput_in;
+	count = retval;
 
 	retval = security_file_permission (in_file, MAY_READ);
 	if (retval)
@@ -674,8 +689,9 @@
 		goto fput_out;
 	out_inode = out_file->f_dentry->d_inode;
 	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
-	if (retval)
+	if (retval < 0)
 		goto fput_out;
+	count = retval;
 
 	retval = security_file_permission (out_file, MAY_WRITE);
 	if (retval)
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 578ed3f..302201f 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -321,6 +321,7 @@
 #else
 #define fls	generic_fls
 #endif
+#define fls64   generic_fls64
 
 /* Compute powers of two for the given integer.  */
 static inline long floor_log2(unsigned long word)
diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h
new file mode 100644
index 0000000..7da8956
--- /dev/null
+++ b/include/asm-arm/arch-pxa/ohci.h
@@ -0,0 +1,18 @@
+#ifndef ASMARM_ARCH_OHCI_H
+#define ASMARM_ARCH_OHCI_H
+
+struct device;
+
+struct pxaohci_platform_data {
+	int (*init)(struct device *);
+	void (*exit)(struct device *);
+
+	int port_mode;
+#define PMM_NPS_MODE           1
+#define PMM_GLOBAL_MODE        2
+#define PMM_PERPORT_MODE       3
+};
+
+extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
+
+#endif
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 7399d43..d02de72 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -332,6 +332,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -351,6 +352,7 @@
 #define fls(x) \
 	( __builtin_constant_p(x) ? generic_fls(x) : \
 	  ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
+#define fls64(x)   generic_fls64(x)
 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
 #define __ffs(x) (ffs(x) - 1)
 #define ffz(x) __ffs( ~(x) )
diff --git a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h
index 7d062fb..15cc6f2 100644
--- a/include/asm-arm26/bitops.h
+++ b/include/asm-arm26/bitops.h
@@ -259,6 +259,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index 1bddb3f..d3eb0f1 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -240,6 +240,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN - returns the hamming weight of a N-bit word
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index b664bd5..02be7b3 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -228,6 +228,7 @@
 							\
 	bit ? 33 - bit : bit;				\
 })
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index ce31b73..0e6d985 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -56,6 +56,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index 5036f59..c0411ec 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -406,5 +406,6 @@
 #endif /* __KERNEL__ */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _H8300_BITOPS_H */
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index ddf1739..4807aa1 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -372,6 +372,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
index 7232528..36d0fb9 100644
--- a/include/asm-ia64/bitops.h
+++ b/include/asm-ia64/bitops.h
@@ -345,6 +345,7 @@
 	x |= x >> 16;
 	return ia64_popcnt(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as the libc and compiler builtin
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index e784439..abea2fd 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -465,6 +465,7 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index b1bcf7c66..13f4c00 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -310,6 +310,7 @@
 
 	return 32 - cnt;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index c42f88a..4058dd0 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -499,5 +499,6 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _M68KNOMMU_BITOPS_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 5496f90..3b0c8aa 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -695,7 +695,7 @@
 
 	return flz(~word) + 1;
 }
-
+#define fls64(x)   generic_fls64(x)
 
 /*
  * find_next_zero_bit - find the first zero bit in a memory region
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 55b98c6..15d8c2b 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -263,6 +263,7 @@
 
 	return ret;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 5727229..1996eaa 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -310,6 +310,7 @@
 	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
 	return 32 - lz;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index b07c578..6123276 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -839,6 +839,7 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index 5163d1f..1c52608 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -470,6 +470,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h
index e1ff63e..ce9c3ad 100644
--- a/include/asm-sh64/bitops.h
+++ b/include/asm-sh64/bitops.h
@@ -510,6 +510,7 @@
 
 #define ffs(x)	generic_ffs(x)
 #define fls(x)	generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index bfbd795..41722b5 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -298,6 +298,7 @@
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index 6388b83..6efc016 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -119,6 +119,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index b91e799..8955d23 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -276,6 +276,7 @@
 
 #define ffs(x) generic_ffs (x)
 #define fls(x) generic_fls (x)
+#define fls64(x) generic_fls64(x)
 #define __ffs(x) ffs(x)
 
 
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 05a0d37..a4d5d09 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -340,6 +340,20 @@
 	return word;
 }
 
+/*
+ * __fls: find last bit set.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static __inline__ unsigned long __fls(unsigned long word)
+{
+	__asm__("bsrq %1,%0"
+		:"=r" (word)
+		:"rm" (word));
+	return word;
+}
+
 #ifdef __KERNEL__
 
 static inline int sched_find_first_bit(const unsigned long *b)
@@ -370,6 +384,19 @@
 }
 
 /**
+ * fls64 - find last bit set in 64 bit word
+ * @x: the word to search
+ *
+ * This is defined the same way as fls.
+ */
+static __inline__ int fls64(__u64 x)
+{
+	if (x == 0)
+		return 0;
+	return __fls(x) + 1;
+}
+
+/**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
  *
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index e76ee88..0a2065f 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -245,6 +245,7 @@
 {
 	return __cntlz(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 static __inline__ int
 find_next_bit(const unsigned long *addr, int size, int offset)
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 685fd37..b60ffe3 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -292,6 +292,8 @@
 extern void bio_init(struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
+extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
+			   unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
 				unsigned long, unsigned int, int);
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 38c2fb7..6a2a19f 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -76,6 +76,15 @@
  */
 #include <asm/bitops.h>
 
+
+static inline int generic_fls64(__u64 x)
+{
+	__u32 h = x >> 32;
+	if (h)
+		return fls(x) + 32;
+	return fls(x);
+}
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
 	int order;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index a33a31e..a18500d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -184,6 +184,7 @@
 	void *sense;
 
 	unsigned int timeout;
+	int retries;
 
 	/*
 	 * For Power Management requests
@@ -558,6 +559,7 @@
 extern void register_disk(struct gendisk *dev);
 extern void generic_make_request(struct bio *bio);
 extern void blk_put_request(struct request *);
+extern void __blk_put_request(request_queue_t *, struct request *);
 extern void blk_end_sync_rq(struct request *rq);
 extern void blk_attempt_remerge(request_queue_t *, struct request *);
 extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
@@ -579,6 +581,10 @@
 extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
 extern int blk_execute_rq(request_queue_t *, struct gendisk *,
 			  struct request *, int);
+extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
+				  struct request *, int,
+				  void (*done)(struct request *));
+
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
 {
 	return bdev->bd_disk->queue;
@@ -696,7 +702,8 @@
 
 #define MAX_PHYS_SEGMENTS 128
 #define MAX_HW_SEGMENTS 128
-#define MAX_SECTORS 255
+#define SAFE_MAX_SECTORS 255
+#define BLK_DEF_MAX_SECTORS 1024
 
 #define MAX_SEGMENT_SIZE	65536
 
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index d068176..c31650d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -256,6 +256,16 @@
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
+/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
+#ifdef CONFIG_CPU_FREQ
+unsigned int cpufreq_quick_get(unsigned int cpu);
+#else
+static inline unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+	return 0;
+}
+#endif
+
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 71fab43..088529f 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -192,10 +192,9 @@
 #include <linux/workqueue.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/inet_timewait_sock.h>
-#include <net/sock.h>
 #include <net/tcp_states.h>
-#include <net/tcp.h>
 
 enum dccp_state {
 	DCCP_OPEN	= TCP_ESTABLISHED,
@@ -408,8 +407,6 @@
  * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
  * @dccps_timestamp_time - time of latest TIMESTAMP option
  * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
- * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
- * @dccps_pmtu_cookie - Last pmtu seen by socket
  * @dccps_packet_size - Set thru setsockopt
  * @dccps_role - Role of this sock, one of %dccp_role
  * @dccps_ndp_count - number of Non Data Packets since last data packet
@@ -434,8 +431,6 @@
 	__u32				dccps_timestamp_echo;
 	__u32				dccps_packet_size;
 	unsigned long			dccps_ndp_count;
-	__u16				dccps_ext_header_len;
-	__u32				dccps_pmtu_cookie;
 	__u32				dccps_mss_cache;
 	struct dccp_options		dccps_options;
 	struct dccp_ackvec		*dccps_hc_rx_ackvec;
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 5f49a30..745c988 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -63,10 +63,11 @@
  * @addr: Pointer to a six-byte array containing the Ethernet address
  *
  * Return true if the address is a multicast address.
+ * By definition the broadcast address is also a multicast address.
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-	return ((addr[0] != 0xff) && (0x01 & addr[0]));
+	return (0x01 & addr[0]);
 }
 
 /**
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index e677f73..4fab3d0 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -157,8 +157,7 @@
 extern int register_pppox_proto(int proto_num, struct pppox_proto *pp);
 extern void unregister_pppox_proto(int proto_num);
 extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
-extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
-			       unsigned long arg);
+extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 
 /* PPPoX socket states */
 enum {
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 33e8a19..9e2eb9a 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -16,6 +16,7 @@
  */
 #ifndef _LINUX_IP_H
 #define _LINUX_IP_H
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define IPTOS_TOS_MASK		0x1E
@@ -78,126 +79,6 @@
 #define	IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
 #define	IPOPT_TS_PRESPEC	3		/* specified modules only */
 
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <net/request_sock.h>
-#include <net/sock.h>
-#include <linux/igmp.h>
-#include <net/flow.h>
-
-struct ip_options {
-  __u32		faddr;				/* Saved first hop address */
-  unsigned char	optlen;
-  unsigned char srr;
-  unsigned char rr;
-  unsigned char ts;
-  unsigned char is_setbyuser:1,			/* Set by setsockopt?			*/
-                is_data:1,			/* Options in __data, rather than skb	*/
-                is_strictroute:1,		/* Strict source route			*/
-                srr_is_hit:1,			/* Packet destination addr was our one	*/
-                is_changed:1,			/* IP checksum more not valid		*/	
-                rr_needaddr:1,			/* Need to record addr of outgoing dev	*/
-                ts_needtime:1,			/* Need to record timestamp		*/
-                ts_needaddr:1;			/* Need to record addr of outgoing dev  */
-  unsigned char router_alert;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __data[0];
-};
-
-#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
-
-struct inet_request_sock {
-	struct request_sock	req;
-	u32			loc_addr;
-	u32			rmt_addr;
-	u16			rmt_port;
-	u16			snd_wscale : 4, 
-				rcv_wscale : 4, 
-				tstamp_ok  : 1,
-				sack_ok	   : 1,
-				wscale_ok  : 1,
-				ecn_ok	   : 1,
-				acked	   : 1;
-	struct ip_options	*opt;
-};
-
-static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
-{
-	return (struct inet_request_sock *)sk;
-}
-
-struct ipv6_pinfo;
-
-struct inet_sock {
-	/* 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 */
-	__u16			dport;		/* Destination port */
-	__u16			num;		/* Local port */
-	__u32			saddr;		/* Sending source */
-	__s16			uc_ttl;		/* Unicast TTL */
-	__u16			cmsg_flags;
-	struct ip_options	*opt;
-	__u16			sport;		/* Source port */
-	__u16			id;		/* ID counter for DF pkts */
-	__u8			tos;		/* TOS */
-	__u8			mc_ttl;		/* Multicasting TTL */
-	__u8			pmtudisc;
-	unsigned		recverr : 1,
-				freebind : 1,
-				hdrincl : 1,
-				mc_loop : 1;
-	int			mc_index;	/* Multicast device index */
-	__u32			mc_addr;
-	struct ip_mc_socklist	*mc_list;	/* Group array */
-	/*
-	 * Following members are used to retain the infomation to build
-	 * an ip header on each ip fragmentation while the socket is corked.
-	 */
-	struct {
-		unsigned int		flags;
-		unsigned int		fragsize;
-		struct ip_options	*opt;
-		struct rtable		*rt;
-		int			length; /* Total length of all frames */
-		u32			addr;
-		struct flowi		fl;
-	} cork;
-};
-
-#define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
-#define IPCORK_ALLFRAG	2	/* always fragment (for ipv6 for now) */
-
-static inline struct inet_sock *inet_sk(const struct sock *sk)
-{
-	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->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
-
-extern int inet_sk_rebuild_header(struct sock *sk);
-
 struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
 	__u8	ihl:4,
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e0b9227..93bbed5 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -171,12 +171,13 @@
 };
 
 #ifdef __KERNEL__
-#include <linux/in6.h>          /* struct sockaddr_in6 */
 #include <linux/icmpv6.h>
-#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
 #include <linux/tcp.h>
 #include <linux/udp.h>
 
+#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
+#include <net/inet_sock.h>
+
 /* 
    This structure contains results of exthdrs parsing
    as offsets from skb->nh.
@@ -199,18 +200,17 @@
 	return IP6CB(skb)->iif;
 }
 
-struct tcp6_request_sock {
-	struct tcp_request_sock	req;
+struct inet6_request_sock {
 	struct in6_addr		loc_addr;
 	struct in6_addr		rmt_addr;
 	struct sk_buff		*pktopts;
 	int			iif;
 };
 
-static inline struct tcp6_request_sock *tcp6_rsk(const struct request_sock *sk)
-{
-	return (struct tcp6_request_sock *)sk;
-}
+struct tcp6_request_sock {
+	struct tcp_request_sock	  tcp6rsk_tcp;
+	struct inet6_request_sock tcp6rsk_inet6;
+};
 
 /**
  * struct ipv6_pinfo - ipv6 private area
@@ -298,12 +298,36 @@
 	struct ipv6_pinfo inet6;
 };
 
+extern int inet6_sk_rebuild_header(struct sock *sk);
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
 {
 	return inet_sk(__sk)->pinet6;
 }
 
+static inline struct inet6_request_sock *
+			inet6_rsk(const struct request_sock *rsk)
+{
+	return (struct inet6_request_sock *)(((u8 *)rsk) +
+					     inet_rsk(rsk)->inet6_rsk_offset);
+}
+
+static inline u32 inet6_rsk_offset(struct request_sock *rsk)
+{
+	return rsk->rsk_ops->obj_size - sizeof(struct inet6_request_sock);
+}
+
+static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *ops)
+{
+	struct request_sock *req = reqsk_alloc(ops);
+
+	if (req != NULL)
+		inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req);
+
+	return req;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
 	return (struct raw6_sock *)sk;
@@ -323,28 +347,37 @@
 #define __ipv6_only_sock(sk)	(inet6_sk(sk)->ipv6only)
 #define ipv6_only_sock(sk)	((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
 
-#include <linux/tcp.h>
-
-struct tcp6_timewait_sock {
-	struct tcp_timewait_sock tw_v6_sk;
-	struct in6_addr		 tw_v6_daddr;
-	struct in6_addr		 tw_v6_rcv_saddr;
+struct inet6_timewait_sock {
+	struct in6_addr tw_v6_daddr;
+	struct in6_addr	tw_v6_rcv_saddr;
 };
 
-static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk)
+struct tcp6_timewait_sock {
+	struct tcp_timewait_sock   tcp6tw_tcp;
+	struct inet6_timewait_sock tcp6tw_inet6;
+};
+
+static inline u16 inet6_tw_offset(const struct proto *prot)
 {
-	return (struct tcp6_timewait_sock *)sk;
+	return prot->twsk_prot->twsk_obj_size -
+			sizeof(struct inet6_timewait_sock);
 }
 
-static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk)
+{
+	return (struct inet6_timewait_sock *)(((u8 *)sk) +
+					      inet_twsk(sk)->tw_ipv6_offset);
+}
+
+static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk)
 {
 	return likely(sk->sk_state != TCP_TIME_WAIT) ?
-		&inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr;
+		&inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr;
 }
 
-static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk)
 {
-	return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
+	return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL;
 }
 
 static inline int inet_v6_ipv6only(const struct sock *sk)
@@ -361,13 +394,19 @@
 	return NULL;
 }
 
+static inline struct inet6_request_sock *
+			inet6_rsk(const struct request_sock *rsk)
+{
+	return NULL;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
 	return NULL;
 }
 
-#define __tcp_v6_rcv_saddr(__sk)	NULL
-#define tcp_v6_rcv_saddr(__sk)		NULL
+#define __inet6_rcv_saddr(__sk)	NULL
+#define inet6_rcv_saddr(__sk)	NULL
 #define tcp_twsk_ipv6only(__sk)		0
 #define inet_v6_ipv6only(__sk)		0
 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 41ea7db..e828e17 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -136,6 +136,8 @@
 	ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* hueristic */
 	ATA_TMOUT_CDB		= 30 * HZ,
 	ATA_TMOUT_CDB_QUICK	= 5 * HZ,
+	ATA_TMOUT_INTERNAL	= 30 * HZ,
+	ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
 
 	/* ATA bus states */
 	BUS_UNKNOWN		= 0,
@@ -195,7 +197,7 @@
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
 
 struct ata_ioports {
 	unsigned long		cmd_addr;
@@ -280,9 +282,9 @@
 	/* DO NOT iterate over __sg manually, use ata_for_each_sg() */
 	struct scatterlist	*__sg;
 
-	ata_qc_cb_t		complete_fn;
+	unsigned int		err_mask;
 
-	struct completion	*waiting;
+	ata_qc_cb_t		complete_fn;
 
 	void			*private_data;
 };
@@ -331,8 +333,6 @@
 
 	u8			ctl;	/* cache of ATA control register */
 	u8			last_ctl;	/* Cache last written value */
-	unsigned int		bus_state;
-	unsigned int		port_state;
 	unsigned int		pio_mask;
 	unsigned int		mwdma_mask;
 	unsigned int		udma_mask;
@@ -478,7 +478,7 @@
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 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, unsigned int err_mask);
+extern void ata_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
 			      void (*done)(struct scsi_cmnd *));
@@ -670,6 +670,7 @@
 	qc->cursect = qc->cursg = qc->cursg_ofs = 0;
 	qc->nsect = 0;
 	qc->nbytes = qc->curbytes = 0;
+	qc->err_mask = 0;
 
 	ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
 }
diff --git a/include/linux/net.h b/include/linux/net.h
index d6a41e6..28195a2 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -107,7 +107,7 @@
 struct socket {
 	socket_state		state;
 	unsigned long		flags;
-	struct proto_ops	*ops;
+	const struct proto_ops	*ops;
 	struct fasync_struct	*fasync_list;
 	struct file		*file;
 	struct sock		*sk;
@@ -260,7 +260,7 @@
 SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \
 	      (file, sock, vma)) \
 	      \
-static struct proto_ops name##_ops = {			\
+static const struct proto_ops name##_ops = {			\
 	.family		= fam,				\
 	.owner		= THIS_MODULE,			\
 	.release	= __lock_##name##_release,	\
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 936f8b7..7fda03d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -684,6 +684,7 @@
 extern int		netif_rx_ni(struct sk_buff *skb);
 #define HAVE_NETIF_RECEIVE_SKB 1
 extern int		netif_receive_skb(struct sk_buff *skb);
+extern int		dev_valid_name(const char *name);
 extern int		dev_ioctl(unsigned int cmd, void __user *);
 extern int		dev_ethtool(struct ifreq *);
 extern unsigned		dev_get_flags(const struct net_device *);
@@ -801,12 +802,16 @@
 	return (1 << debug_value) - 1;
 }
 
-/* Schedule rx intr now? */
+/* Test if receive needs to be scheduled */
+static inline int __netif_rx_schedule_prep(struct net_device *dev)
+{
+	return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
 
+/* Test if receive needs to be scheduled but only if up */
 static inline int netif_rx_schedule_prep(struct net_device *dev)
 {
-	return netif_running(dev) &&
-		!test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+	return netif_running(dev) && __netif_rx_schedule_prep(dev);
 }
 
 /* Add interface to tail of rx poll list. This assumes that _prep has
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 4db67b3..a17e171 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -15,6 +15,7 @@
 #define PCI_CLASS_STORAGE_FLOPPY	0x0102
 #define PCI_CLASS_STORAGE_IPI		0x0103
 #define PCI_CLASS_STORAGE_RAID		0x0104
+#define PCI_CLASS_STORAGE_SAS		0x0107
 #define PCI_CLASS_STORAGE_OTHER		0x0180
 
 #define PCI_BASE_CLASS_NETWORK		0x02
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index 7240667..6351c40 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -216,6 +216,16 @@
 } __attribute__((packed));
 /* sizeof(struct sadb_x_nat_t_port) == 8 */
 
+/* Generic LSM security context */
+struct sadb_x_sec_ctx {
+	uint16_t	sadb_x_sec_len;
+	uint16_t	sadb_x_sec_exttype;
+	uint8_t		sadb_x_ctx_alg;  /* LSMs: e.g., selinux == 1 */
+	uint8_t		sadb_x_ctx_doi;
+	uint16_t	sadb_x_ctx_len;
+} __attribute__((packed));
+/* sizeof(struct sadb_sec_ctx) = 8 */
+
 /* Message types */
 #define SADB_RESERVED		0
 #define SADB_GETSPI		1
@@ -325,7 +335,8 @@
 #define SADB_X_EXT_NAT_T_SPORT		21
 #define SADB_X_EXT_NAT_T_DPORT		22
 #define SADB_X_EXT_NAT_T_OA		23
-#define SADB_EXT_MAX			23
+#define SADB_X_EXT_SEC_CTX		24
+#define SADB_EXT_MAX			24
 
 /* Identity Extension values */
 #define SADB_IDENTTYPE_RESERVED	0
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index e87b233..d10f353 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -429,6 +429,7 @@
 	TCA_NETEM_CORR,
 	TCA_NETEM_DELAY_DIST,
 	TCA_NETEM_REORDER,
+	TCA_NETEM_CORRUPT,
 	__TCA_NETEM_MAX,
 };
 
@@ -457,6 +458,12 @@
 	__u32	correlation;
 };
 
+struct tc_netem_corrupt
+{
+	__u32	probability;
+	__u32	correlation;
+};
+
 #define NETEM_DIST_SCALE	8192
 
 #endif
diff --git a/include/linux/random.h b/include/linux/random.h
index 7b2adb3..5d6456b 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -52,9 +52,9 @@
 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_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
-				       __u16 dport);
+extern u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
+extern u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
+				      __u16 dport);
 extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
 					__u16 sport, __u16 dport);
 extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
diff --git a/include/linux/security.h b/include/linux/security.h
index f7e0ae0..ef75365 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -59,6 +59,12 @@
 struct sock;
 struct sockaddr;
 struct socket;
+struct flowi;
+struct dst_entry;
+struct xfrm_selector;
+struct xfrm_policy;
+struct xfrm_state;
+struct xfrm_user_sec_ctx;
 
 extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
 extern int cap_netlink_recv(struct sk_buff *skb);
@@ -788,6 +794,52 @@
  *      which is used to copy security attributes between local stream sockets.
  * @sk_free_security:
  *	Deallocate security structure.
+ * @sk_getsid:
+ *	Retrieve the LSM-specific sid for the sock to enable caching of network
+ *	authorizations.
+ *
+ * Security hooks for XFRM operations.
+ *
+ * @xfrm_policy_alloc_security:
+ *	@xp contains the xfrm_policy being added to Security Policy Database
+ *	used by the XFRM system.
+ *	@sec_ctx contains the security context information being provided by
+ *	the user-level policy update program (e.g., setkey).
+ *	Allocate a security structure to the xp->selector.security field.
+ *	The security field is initialized to NULL when the xfrm_policy is
+ *	allocated.
+ *	Return 0 if operation was successful (memory to allocate, legal context)
+ * @xfrm_policy_clone_security:
+ *	@old contains an existing xfrm_policy in the SPD.
+ *	@new contains a new xfrm_policy being cloned from old.
+ *	Allocate a security structure to the new->selector.security field
+ *	that contains the information from the old->selector.security field.
+ *	Return 0 if operation was successful (memory to allocate).
+ * @xfrm_policy_free_security:
+ *	@xp contains the xfrm_policy
+ *	Deallocate xp->selector.security.
+ * @xfrm_state_alloc_security:
+ *	@x contains the xfrm_state being added to the Security Association
+ *	Database by the XFRM system.
+ *	@sec_ctx contains the security context information being provided by
+ *	the user-level SA generation program (e.g., setkey or racoon).
+ *	Allocate a security structure to the x->sel.security field.  The
+ *	security field is initialized to NULL when the xfrm_state is
+ *	allocated.
+ *	Return 0 if operation was successful (memory to allocate, legal context).
+ * @xfrm_state_free_security:
+ *	@x contains the xfrm_state.
+ *	Deallocate x>sel.security.
+ * @xfrm_policy_lookup:
+ *	@xp contains the xfrm_policy for which the access control is being
+ *	checked.
+ *	@sk_sid contains the sock security label that is used to authorize
+ *	access to the policy xp.
+ *	@dir contains the direction of the flow (input or output).
+ *	Check permission when a sock selects a xfrm_policy for processing
+ *	XFRMs on a packet.  The hook is called when selecting either a
+ *	per-socket policy or a generic xfrm policy.
+ *	Return 0 if permission is granted.
  *
  * Security hooks affecting all Key Management operations
  *
@@ -1237,8 +1289,18 @@
 	int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
 	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
 	void (*sk_free_security) (struct sock *sk);
+	unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+	int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+	int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
+	void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
+	int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+	void (*xfrm_state_free_security) (struct xfrm_state *x);
+	int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
+
 	/* key management security hooks */
 #ifdef CONFIG_KEYS
 	int (*key_alloc)(struct key *key);
@@ -2679,6 +2741,11 @@
 {
 	return security_ops->sk_free_security(sk);
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return security_ops->sk_getsid(sk, fl, dir);
+}
 #else	/* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct socket * sock,
 					       struct socket * other, 
@@ -2795,8 +2862,73 @@
 static inline void security_sk_free(struct sock *sk)
 {
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return security_ops->xfrm_policy_clone_security(old, new);
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+	security_ops->xfrm_policy_free_security(xp);
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return security_ops->xfrm_state_alloc_security(x, sec_ctx);
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+	security_ops->xfrm_state_free_security(x);
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return security_ops->xfrm_policy_lookup(xp, sk_sid, dir);
+}
+#else	/* CONFIG_SECURITY_NETWORK_XFRM */
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return 0;
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return 0;
+}
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
+
 #ifdef CONFIG_KEYS
 #ifdef CONFIG_SECURITY
 static inline int security_key_alloc(struct key *key)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8c5d600..483cfc4 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -32,7 +32,6 @@
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
-#define SLAB_SKB 		/* Slabified skbuffs 	   */
 
 #define CHECKSUM_NONE 0
 #define CHECKSUM_HW 1
@@ -134,7 +133,7 @@
  */
 struct skb_shared_info {
 	atomic_t	dataref;
-	unsigned int	nr_frags;
+	unsigned short	nr_frags;
 	unsigned short	tso_size;
 	unsigned short	tso_segs;
 	unsigned short  ufo_size;
@@ -1239,6 +1238,8 @@
 							int hlen,
 							struct iovec *iov);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
+extern void	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
+					 unsigned int flags);
 extern unsigned int    skb_checksum(const struct sk_buff *skb, int offset,
 				    int len, unsigned int csum);
 extern int	       skb_copy_bits(const struct sk_buff *skb, int offset,
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 1739c2d..9f40191 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -27,7 +27,6 @@
 #include <linux/compiler.h>		/* __user			*/
 
 extern int sysctl_somaxconn;
-extern void sock_init(void);
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void socket_seq_show(struct seq_file *seq);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 4be34ef..93fa765 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -390,6 +390,7 @@
 	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
 	NET_TCP_CONG_CONTROL=110,
 	NET_TCP_ABC=111,
+	NET_IPV4_IPFRAG_MAX_DIST=112,
 };
 
 enum {
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 0e1da66..f2bb239 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -55,22 +55,6 @@
 	__u16	urg_ptr;
 };
 
-#define TCP_ACTION_FIN	(1 << 7)
-
-enum {
-  TCPF_ESTABLISHED = (1 << 1),
-  TCPF_SYN_SENT  = (1 << 2),
-  TCPF_SYN_RECV  = (1 << 3),
-  TCPF_FIN_WAIT1 = (1 << 4),
-  TCPF_FIN_WAIT2 = (1 << 5),
-  TCPF_TIME_WAIT = (1 << 6),
-  TCPF_CLOSE     = (1 << 7),
-  TCPF_CLOSE_WAIT = (1 << 8),
-  TCPF_LAST_ACK  = (1 << 9),
-  TCPF_LISTEN    = (1 << 10),
-  TCPF_CLOSING   = (1 << 11) 
-};
-
 /*
  *	The union cast uses a gcc extension to avoid aliasing problems
  *  (union is compatible to any of its members)
@@ -254,10 +238,9 @@
 	__u32	snd_wl1;	/* Sequence for window update		*/
 	__u32	snd_wnd;	/* The window we expect to receive	*/
 	__u32	max_window;	/* Maximal window ever seen from peer	*/
-	__u32	pmtu_cookie;	/* Last pmtu seen by socket		*/
 	__u32	mss_cache;	/* Cached effective mss, not including SACKS */
 	__u16	xmit_size_goal;	/* Goal for segmenting output packets	*/
-	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
+	/* XXX Two bytes hole, try to pack */
 
 	__u32	window_clamp;	/* Maximal window to advertise		*/
 	__u32	rcv_ssthresh;	/* Current window clamp			*/
@@ -295,8 +278,6 @@
 
 	struct sk_buff_head	out_of_order_queue; /* Out of order segments go here */
 
-	struct tcp_func		*af_specific;	/* Operations which are AF_INET{4,6} specific	*/
-
  	__u32	rcv_wnd;	/* Current receiver window		*/
 	__u32	rcv_wup;	/* rcv_nxt on last window update sent	*/
 	__u32	write_seq;	/* Tail(+1) of data held in tcp send buffer */
diff --git a/include/linux/udp.h b/include/linux/udp.h
index b60e0b4..85a5565 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -35,10 +35,10 @@
 #define UDP_ENCAP_ESPINUDP	2 /* draft-ietf-ipsec-udp-encaps-06 */
 
 #ifdef __KERNEL__
-
 #include <linux/config.h>
-#include <net/sock.h>
-#include <linux/ip.h>
+#include <linux/types.h>
+
+#include <net/inet_sock.h>
 
 struct udp_sock {
 	/* inet_sock has to be the first member */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index d81b050..e59d1bd 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -329,8 +329,6 @@
 	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
 	int		ttport;		/* device port on that tt hub */
 
-	struct semaphore serialize;
-
 	unsigned int toggle[2];		/* one bit for each endpoint
 					 * ([0] = IN, [1] = OUT) */
 
@@ -349,6 +347,9 @@
 
 	char **rawdescriptors;		/* Raw descriptors for each config */
 
+	unsigned short bus_mA;		/* Current available from the bus */
+	u8 portnum;			/* Parent port number (origin 1) */
+
 	int have_langid;		/* whether string_langid is valid */
 	int string_langid;		/* language ID for strings */
 
@@ -377,11 +378,12 @@
 extern struct usb_device *usb_get_dev(struct usb_device *dev);
 extern void usb_put_dev(struct usb_device *dev);
 
-extern void usb_lock_device(struct usb_device *udev);
-extern int usb_trylock_device(struct usb_device *udev);
+/* USB device locking */
+#define usb_lock_device(udev)		down(&(udev)->dev.sem)
+#define usb_unlock_device(udev)		up(&(udev)->dev.sem)
+#define usb_trylock_device(udev)	down_trylock(&(udev)->dev.sem)
 extern int usb_lock_device_for_reset(struct usb_device *udev,
 		struct usb_interface *iface);
-extern void usb_unlock_device(struct usb_device *udev);
 
 /* USB port reset for device reinitialization */
 extern int usb_reset_device(struct usb_device *dev);
@@ -529,10 +531,13 @@
 
 /* ----------------------------------------------------------------------- */
 
+struct usb_dynids {
+	spinlock_t lock;
+	struct list_head list;
+};
+
 /**
  * struct usb_driver - identifies USB driver to usbcore
- * @owner: Pointer to the module owner of this driver; initialize
- *	it using THIS_MODULE.
  * @name: The driver name should be unique among USB drivers,
  *	and should normally be the same as the module name.
  * @probe: Called to see if the driver is willing to manage a particular
@@ -553,7 +558,11 @@
  * @id_table: USB drivers use ID table to support hotplugging.
  *	Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
  *	or your driver's probe function will never get called.
+ * @dynids: used internally to hold the list of dynamically added device
+ *	ids for this driver.
  * @driver: the driver model core driver structure.
+ * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
+ *	added to this driver by preventing the sysfs file from being created.
  *
  * USB drivers must provide a name, probe() and disconnect() methods,
  * and an id_table.  Other driver fields are optional.
@@ -571,8 +580,6 @@
  * them as necessary, and blocking until the unlinks complete).
  */
 struct usb_driver {
-	struct module *owner;
-
 	const char *name;
 
 	int (*probe) (struct usb_interface *intf,
@@ -588,7 +595,9 @@
 
 	const struct usb_device_id *id_table;
 
+	struct usb_dynids dynids;
 	struct device_driver driver;
+	unsigned int no_dynamic_id:1;
 };
 #define	to_usb_driver(d) container_of(d, struct usb_driver, driver)
 
@@ -614,7 +623,11 @@
  * use these in module_init()/module_exit()
  * and don't forget MODULE_DEVICE_TABLE(usb, ...)
  */
-extern int usb_register(struct usb_driver *);
+int usb_register_driver(struct usb_driver *, struct module *);
+static inline int usb_register(struct usb_driver *driver)
+{
+	return usb_register_driver(driver, THIS_MODULE);
+}
 extern void usb_deregister(struct usb_driver *);
 
 extern int usb_register_dev(struct usb_interface *intf,
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
new file mode 100644
index 0000000..b2d0898
--- /dev/null
+++ b/include/linux/usb_usual.h
@@ -0,0 +1,126 @@
+/*
+ * Interface to the libusual.
+ *
+ * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com>
+ * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com)
+ */
+
+#ifndef __LINUX_USB_USUAL_H
+#define __LINUX_USB_USUAL_H
+
+#include <linux/config.h>
+
+/* We should do this for cleanliness... But other usb_foo.h do not do this. */
+/* #include <linux/usb.h> */
+
+/*
+ * The flags field, which we store in usb_device_id.driver_info.
+ * It is compatible with the old usb-storage flags in lower 24 bits.
+ */
+
+/*
+ * Static flag definitions.  We use this roundabout technique so that the
+ * proc_info() routine can automatically display a message for each flag.
+ */
+#define US_DO_ALL_FLAGS						\
+	US_FLAG(SINGLE_LUN,	0x00000001)			\
+		/* allow access to only LUN 0 */		\
+	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
+		/* unusual_devs entry is necessary */		\
+	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
+		/* supports multiple targets */			\
+	US_FLAG(FIX_INQUIRY,	0x00000008)			\
+		/* INQUIRY response needs faking */		\
+	US_FLAG(FIX_CAPACITY,	0x00000010)			\
+		/* READ CAPACITY response too big */		\
+	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
+		/* reported residue is wrong */			\
+	US_FLAG(BULK32,		0x00000040)			\
+		/* Uses 32-byte CBW length */			\
+	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
+		/* PREVENT/ALLOW not supported */		\
+	US_FLAG(GO_SLOW,	0x00000100)			\
+		/* Need delay after Command phase */		\
+	US_FLAG(NO_WP_DETECT,	0x00000200)			\
+		/* Don't check for write-protect */		\
+
+#define US_FLAG(name, value)	US_FL_##name = value ,
+enum { US_DO_ALL_FLAGS };
+#undef US_FLAG
+
+/*
+ * The bias field for libusual and friends.
+ */
+#define USB_US_TYPE_NONE   0
+#define USB_US_TYPE_STOR   1		/* usb-storage */
+#define USB_US_TYPE_UB     2		/* ub */
+
+#define USB_US_TYPE(flags) 		(((flags) >> 24) & 0xFF)
+#define USB_US_ORIG_FLAGS(flags)	((flags) & 0x00FFFFFF)
+
+/*
+ * This is probably not the best place to keep these constants, conceptually.
+ * But it's the only header included into all places which need them.
+ */
+
+/* Sub Classes */
+
+#define US_SC_RBC	0x01		/* Typically, flash devices */
+#define US_SC_8020	0x02		/* CD-ROM */
+#define US_SC_QIC	0x03		/* QIC-157 Tapes */
+#define US_SC_UFI	0x04		/* Floppy */
+#define US_SC_8070	0x05		/* Removable media */
+#define US_SC_SCSI	0x06		/* Transparent */
+#define US_SC_ISD200    0x07		/* ISD200 ATA */
+#define US_SC_MIN	US_SC_RBC
+#define US_SC_MAX	US_SC_ISD200
+
+#define US_SC_DEVICE	0xff		/* Use device's value */
+
+/* Protocols */
+
+#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
+#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
+#define US_PR_BULK	0x50		/* bulk only */
+#ifdef CONFIG_USB_STORAGE_USBAT
+#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
+#endif
+#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
+#ifdef CONFIG_USB_STORAGE_FREECOM
+#define US_PR_FREECOM   0xf1		/* Freecom */
+#endif
+#ifdef CONFIG_USB_STORAGE_DATAFAB
+#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
+#endif
+#ifdef CONFIG_USB_STORAGE_JUMPSHOT
+#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
+#endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#define US_PR_ALAUDA    0xf4		/* Alauda chipsets */
+#endif
+
+#define US_PR_DEVICE	0xff		/* Use device's value */
+
+/*
+ */
+#ifdef CONFIG_USB_LIBUSUAL
+
+extern struct usb_device_id storage_usb_ids[];
+extern void usb_usual_set_present(int type);
+extern void usb_usual_clear_present(int type);
+extern int usb_usual_check_type(const struct usb_device_id *, int type);
+#else
+
+#define usb_usual_set_present(t)	do { } while(0)
+#define usb_usual_clear_present(t)	do { } while(0)
+#define usb_usual_check_type(id, t)	(0)
+#endif /* CONFIG_USB_LIBUSUAL */
+
+#endif /* __LINUX_USB_USUAL_H */
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 0fb077d..82fbb75 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -27,6 +27,22 @@
 	__u8		proto;
 };
 
+struct xfrm_sec_ctx {
+	__u8	ctx_doi;
+	__u8	ctx_alg;
+	__u16	ctx_len;
+	__u32	ctx_sid;
+	char	ctx_str[0];
+};
+
+/* Security Context Domains of Interpretation */
+#define XFRM_SC_DOI_RESERVED 0
+#define XFRM_SC_DOI_LSM 1
+
+/* Security Context Algorithms */
+#define XFRM_SC_ALG_RESERVED 0
+#define XFRM_SC_ALG_SELINUX 1
+
 /* Selector, used as selector both on policy rules (SPD) and SAs. */
 
 struct xfrm_selector
@@ -146,6 +162,18 @@
 
 #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
 
+/*
+ * Generic LSM security context for comunicating to user space
+ * NOTE: Same format as sadb_x_sec_ctx
+ */
+struct xfrm_user_sec_ctx {
+	__u16			len;
+	__u16			exttype;
+	__u8			ctx_alg;  /* LSMs: e.g., selinux == 1 */
+	__u8			ctx_doi;
+	__u16			ctx_len;
+};
+
 struct xfrm_user_tmpl {
 	struct xfrm_id		id;
 	__u16			family;
@@ -176,6 +204,7 @@
 	XFRMA_TMPL,		/* 1 or more struct xfrm_user_tmpl */
 	XFRMA_SA,
 	XFRMA_POLICY,
+	XFRMA_SEC_CTX,		/* struct xfrm_sec_ctx */
 	__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index b5d785a..bfc1779 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -13,7 +13,7 @@
 #define UNIX_HASH_SIZE	256
 
 extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-extern rwlock_t unix_table_lock;
+extern spinlock_t unix_table_lock;
 
 extern atomic_t unix_tot_inflight;
 
@@ -58,10 +58,10 @@
 #define UNIXCB(skb) 	(*(struct unix_skb_parms*)&((skb)->cb))
 #define UNIXCREDS(skb)	(&UNIXCB((skb)).creds)
 
-#define unix_state_rlock(s)	read_lock(&unix_sk(s)->lock)
-#define unix_state_runlock(s)	read_unlock(&unix_sk(s)->lock)
-#define unix_state_wlock(s)	write_lock(&unix_sk(s)->lock)
-#define unix_state_wunlock(s)	write_unlock(&unix_sk(s)->lock)
+#define unix_state_rlock(s)	spin_lock(&unix_sk(s)->lock)
+#define unix_state_runlock(s)	spin_unlock(&unix_sk(s)->lock)
+#define unix_state_wlock(s)	spin_lock(&unix_sk(s)->lock)
+#define unix_state_wunlock(s)	spin_unlock(&unix_sk(s)->lock)
 
 #ifdef __KERNEL__
 /* The AF_UNIX socket */
@@ -76,7 +76,7 @@
         struct sock		*other;
         struct sock		*gc_tree;
         atomic_t                inflight;
-        rwlock_t                lock;
+        spinlock_t		lock;
         wait_queue_head_t       peer_wait;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/include/net/atmclip.h b/include/net/atmclip.h
index 47048b1..90fcc98 100644
--- a/include/net/atmclip.h
+++ b/include/net/atmclip.h
@@ -7,7 +7,6 @@
 #define _ATMCLIP_H
 
 #include <linux/netdevice.h>
-#include <linux/skbuff.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/atmarp.h>
@@ -18,6 +17,7 @@
 #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back))
 #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key)
 
+struct sk_buff;
 
 struct clip_vcc {
 	struct atm_vcc	*vcc;		/* VCC descriptor */
diff --git a/include/net/dst.h b/include/net/dst.h
index 6c196a5..bee8b84 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -9,6 +9,7 @@
 #define _NET_DST_H
 
 #include <linux/config.h>
+#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/rcupdate.h>
 #include <linux/jiffies.h>
diff --git a/include/net/flow.h b/include/net/flow.h
index 9a5c94b..ec7eb86 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -84,11 +84,12 @@
 #define FLOW_DIR_OUT	1
 #define FLOW_DIR_FWD	2
 
-typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
+struct sock;
+typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
 			       void **objp, atomic_t **obj_refp);
 
-extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
-			       flow_resolve_t resolver);
+extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
+	 		       flow_resolve_t resolver);
 extern void flow_cache_flush(void);
 extern atomic_t flow_cache_genid;
 
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 52d8b1a..c5b96b2 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -60,7 +60,7 @@
  */
 struct genl_ops
 {
-	unsigned int		cmd;
+	u8			cmd;
 	unsigned int		flags;
 	struct nla_policy	*policy;
 	int		       (*doit)(struct sk_buff *skb,
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 6cdebee..e7c3f20 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -20,12 +20,9 @@
 
 #include <linux/config.h>
 #include <linux/icmp.h>
-#include <linux/skbuff.h>
 
-#include <net/sock.h>
-#include <net/protocol.h>
+#include <net/inet_sock.h>
 #include <net/snmp.h>
-#include <linux/ip.h>
 
 struct icmp_err {
   int		errno;
@@ -38,6 +35,10 @@
 #define ICMP_INC_STATS_BH(field)	SNMP_INC_STATS_BH(icmp_statistics, field)
 #define ICMP_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(icmp_statistics, field)
 
+struct dst_entry;
+struct net_proto_family;
+struct sk_buff;
+
 extern void	icmp_send(struct sk_buff *skb_in,  int type, int code, u32 info);
 extern int	icmp_rcv(struct sk_buff *skb);
 extern int	icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index 225fc751..03b766a 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -23,12 +23,17 @@
 #ifndef IEEE80211_CRYPT_H
 #define IEEE80211_CRYPT_H
 
-#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <asm/atomic.h>
 
 enum {
 	IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
 };
 
+struct sk_buff;
+struct module;
+
 struct ieee80211_crypto_ops {
 	const char *name;
 	struct list_head list;
@@ -87,6 +92,8 @@
 	atomic_t refcnt;
 };
 
+struct ieee80211_device;
+
 int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
 int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
 struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
new file mode 100644
index 0000000..b33b438
--- /dev/null
+++ b/include/net/inet6_connection_sock.h
@@ -0,0 +1,42 @@
+/*
+ * NET		Generic infrastructure for INET6 connection oriented protocols.
+ *
+ * Authors:	Many people, see the TCPv6 sources
+ *
+ * 		From code originally in TCPv6
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the 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 _INET6_CONNECTION_SOCK_H
+#define _INET6_CONNECTION_SOCK_H
+
+#include <linux/types.h>
+
+struct in6_addr;
+struct inet_bind_bucket;
+struct request_sock;
+struct sk_buff;
+struct sock;
+struct sockaddr;
+
+extern int inet6_csk_bind_conflict(const struct sock *sk,
+				   const struct inet_bind_bucket *tb);
+
+extern struct request_sock *inet6_csk_search_req(const struct sock *sk,
+						 struct request_sock ***prevp,
+						 const __u16 rport,
+						 const struct in6_addr *raddr,
+						 const struct in6_addr *laddr,
+						 const int iif);
+
+extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+					   struct request_sock *req,
+					   const unsigned long timeout);
+
+extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
+extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok);
+#endif /* _INET6_CONNECTION_SOCK_H */
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 5a2beed..25f708f 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -48,6 +48,32 @@
 	return inet6_ehashfn(laddr, lport, faddr, fport);
 }
 
+static inline void __inet6_hash(struct inet_hashinfo *hashinfo,
+				struct sock *sk)
+{
+	struct hlist_head *list;
+	rwlock_t *lock;
+
+	BUG_TRAP(sk_unhashed(sk));
+
+	if (sk->sk_state == TCP_LISTEN) {
+		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+		lock = &hashinfo->lhash_lock;
+		inet_listen_wlock(hashinfo);
+	} else {
+		unsigned int hash;
+		sk->sk_hash = hash = inet6_sk_ehashfn(sk);
+		hash &= (hashinfo->ehash_size - 1);
+		list = &hashinfo->ehash[hash].chain;
+		lock = &hashinfo->ehash[hash].lock;
+		write_lock(lock);
+	}
+
+	__sk_add_node(sk, list);
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(lock);
+}
+
 /*
  * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
  * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
@@ -84,10 +110,10 @@
 
 		if(*((__u32 *)&(tw->tw_dport))	== ports	&&
 		   sk->sk_family		== PF_INET6) {
-			const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+			const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
-			if (ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr)	&&
-			    ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)	&&
+			if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)	&&
+			    ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr)	&&
 			    (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
 				goto hit;
 		}
diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index f943306..227adcb 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -1,8 +1,8 @@
 #ifndef _INET_COMMON_H
 #define _INET_COMMON_H
 
-extern struct proto_ops		inet_stream_ops;
-extern struct proto_ops		inet_dgram_ops;
+extern const struct proto_ops		inet_stream_ops;
+extern const struct proto_ops		inet_dgram_ops;
 
 /*
  *	INET4 prototypes used by INET6
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index b0c9906..50234fa 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -15,9 +15,11 @@
 #ifndef _INET_CONNECTION_SOCK_H
 #define _INET_CONNECTION_SOCK_H
 
-#include <linux/ip.h>
+#include <linux/compiler.h>
 #include <linux/string.h>
 #include <linux/timer.h>
+
+#include <net/inet_sock.h>
 #include <net/request_sock.h>
 
 #define INET_CSK_DEBUG 1
@@ -29,6 +31,29 @@
 struct inet_hashinfo;
 struct tcp_congestion_ops;
 
+/*
+ * Pointers to address related TCP functions
+ * (i.e. things that depend on the address family)
+ */
+struct inet_connection_sock_af_ops {
+	int	    (*queue_xmit)(struct sk_buff *skb, int ipfragok);
+	void	    (*send_check)(struct sock *sk, int len,
+				  struct sk_buff *skb);
+	int	    (*rebuild_header)(struct sock *sk);
+	int	    (*conn_request)(struct sock *sk, struct sk_buff *skb);
+	struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
+				      struct request_sock *req,
+				      struct dst_entry *dst);
+	int	    (*remember_stamp)(struct sock *sk);
+	__u16	    net_header_len;
+	int	    (*setsockopt)(struct sock *sk, int level, int optname, 
+				  char __user *optval, int optlen);
+	int	    (*getsockopt)(struct sock *sk, int level, int optname, 
+				  char __user *optval, int __user *optlen);
+	void	    (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
+	int sockaddr_len;
+};
+
 /** inet_connection_sock - INET connection oriented sock
  *
  * @icsk_accept_queue:	   FIFO of established children 
@@ -36,13 +61,16 @@
  * @icsk_timeout:	   Timeout
  * @icsk_retransmit_timer: Resend (no ack)
  * @icsk_rto:		   Retransmit timeout
+ * @icsk_pmtu_cookie	   Last pmtu seen by socket
  * @icsk_ca_ops		   Pluggable congestion control hook
+ * @icsk_af_ops		   Operations which are AF_INET{4,6} specific
  * @icsk_ca_state:	   Congestion control state
  * @icsk_retransmits:	   Number of unrecovered [RTO] timeouts
  * @icsk_pending:	   Scheduled timer event
  * @icsk_backoff:	   Backoff
  * @icsk_syn_retries:      Number of allowed SYN (or equivalent) retries
  * @icsk_probes_out:	   unanswered 0 window probes
+ * @icsk_ext_hdr_len:	   Network protocol overhead (IP/IPv6 options)
  * @icsk_ack:		   Delayed ACK control data
  */
 struct inet_connection_sock {
@@ -54,14 +82,17 @@
  	struct timer_list	  icsk_retransmit_timer;
  	struct timer_list	  icsk_delack_timer;
 	__u32			  icsk_rto;
+	__u32			  icsk_pmtu_cookie;
 	struct tcp_congestion_ops *icsk_ca_ops;
+	struct inet_connection_sock_af_ops *icsk_af_ops;
+	unsigned int		  (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
 	__u8			  icsk_ca_state;
 	__u8			  icsk_retransmits;
 	__u8			  icsk_pending;
 	__u8			  icsk_backoff;
 	__u8			  icsk_syn_retries;
 	__u8			  icsk_probes_out;
-	/* 2 BYTES HOLE, TRY TO PACK! */
+	__u16			  icsk_ext_hdr_len;
 	struct {
 		__u8		  pending;	 /* ACK is pending			   */
 		__u8		  quick;	 /* Scheduled number of quick acks	   */
@@ -192,8 +223,12 @@
 						const __u16 rport,
 						const __u32 raddr,
 						const __u32 laddr);
+extern int inet_csk_bind_conflict(const struct sock *sk,
+				  const struct inet_bind_bucket *tb);
 extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-			     struct sock *sk, unsigned short snum);
+			     struct sock *sk, unsigned short snum,
+			     int (*bind_conflict)(const struct sock *sk,
+						  const struct inet_bind_bucket *tb));
 
 extern struct dst_entry* inet_csk_route_req(struct sock *sk,
 					    const struct request_sock *req);
@@ -207,7 +242,7 @@
 
 extern void inet_csk_reqsk_queue_hash_add(struct sock *sk,
 					  struct request_sock *req,
-					  const unsigned timeout);
+					  unsigned long timeout);
 
 static inline void inet_csk_reqsk_queue_removed(struct sock *sk,
 						struct request_sock *req)
@@ -273,4 +308,6 @@
 extern int  inet_csk_listen_start(struct sock *sk, const int nr_table_entries);
 extern void inet_csk_listen_stop(struct sock *sk);
 
+extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
 #endif /* _INET_CONNECTION_SOCK_H */
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index b0c47e2..d599c6b 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -3,6 +3,8 @@
 
 #include <linux/ip.h>
 #include <linux/skbuff.h>
+
+#include <net/inet_sock.h>
 #include <net/dsfield.h>
 
 enum {
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 07840ba..135d80f 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -26,6 +26,7 @@
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
@@ -128,26 +129,6 @@
 	kmem_cache_t			*bind_bucket_cachep;
 };
 
-static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
-			       const __u32 faddr, const __u16 fport)
-{
-	unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
-	h ^= h >> 16;
-	h ^= h >> 8;
-	return h;
-}
-
-static inline int inet_sk_ehashfn(const struct sock *sk)
-{
-	const struct inet_sock *inet = inet_sk(sk);
-	const __u32 laddr = inet->rcv_saddr;
-	const __u16 lport = inet->num;
-	const __u32 faddr = inet->daddr;
-	const __u16 fport = inet->dport;
-
-	return inet_ehashfn(laddr, lport, faddr, fport);
-}
-
 static inline struct inet_ehash_bucket *inet_ehash_bucket(
 	struct inet_hashinfo *hashinfo,
 	unsigned int hash)
@@ -434,4 +415,7 @@
 
 	return sk;
 }
+
+extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
+			     struct sock *sk);
 #endif /* _INET_HASHTABLES_H */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
new file mode 100644
index 0000000..883eb52
--- /dev/null
+++ b/include/net/inet_sock.h
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ *
+ *		Definitions for inet_sock
+ *
+ * Authors:	Many, reorganised here by
+ * 		Arnaldo Carvalho de Melo <acme@mandriva.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 _INET_SOCK_H
+#define _INET_SOCK_H
+
+#include <linux/config.h>
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <net/flow.h>
+#include <net/sock.h>
+#include <net/request_sock.h>
+
+/** struct ip_options - IP Options
+ *
+ * @faddr - Saved first hop address
+ * @is_setbyuser - Set by setsockopt?
+ * @is_data - Options in __data, rather than skb
+ * @is_strictroute - Strict source route
+ * @srr_is_hit - Packet destination addr was our one
+ * @is_changed - IP checksum more not valid
+ * @rr_needaddr - Need to record addr of outgoing dev
+ * @ts_needtime - Need to record timestamp
+ * @ts_needaddr - Need to record addr of outgoing dev
+ */
+struct ip_options {
+	__u32		faddr;
+	unsigned char	optlen;
+	unsigned char	srr;
+	unsigned char	rr;
+	unsigned char	ts;
+	unsigned char	is_setbyuser:1,
+			is_data:1,
+			is_strictroute:1,
+			srr_is_hit:1,
+			is_changed:1,
+			rr_needaddr:1,
+			ts_needtime:1,
+			ts_needaddr:1;
+	unsigned char	router_alert;
+	unsigned char	__pad1;
+	unsigned char	__pad2;
+	unsigned char	__data[0];
+};
+
+#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
+
+struct inet_request_sock {
+	struct request_sock	req;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	u16			inet6_rsk_offset;
+	/* 2 bytes hole, try to pack */
+#endif
+	u32			loc_addr;
+	u32			rmt_addr;
+	u16			rmt_port;
+	u16			snd_wscale : 4, 
+				rcv_wscale : 4, 
+				tstamp_ok  : 1,
+				sack_ok	   : 1,
+				wscale_ok  : 1,
+				ecn_ok	   : 1,
+				acked	   : 1;
+	struct ip_options	*opt;
+};
+
+static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+{
+	return (struct inet_request_sock *)sk;
+}
+
+struct ip_mc_socklist;
+struct ipv6_pinfo;
+struct rtable;
+
+/** struct inet_sock - representation of INET sockets
+ *
+ * @sk - ancestor class
+ * @pinet6 - pointer to IPv6 control block
+ * @daddr - Foreign IPv4 addr
+ * @rcv_saddr - Bound local IPv4 addr
+ * @dport - Destination port
+ * @num - Local port
+ * @saddr - Sending source
+ * @uc_ttl - Unicast TTL
+ * @sport - Source port
+ * @id - ID counter for DF pkts
+ * @tos - TOS
+ * @mc_ttl - Multicasting TTL
+ * @is_icsk - is this an inet_connection_sock?
+ * @mc_index - Multicast device index
+ * @mc_list - Group array
+ * @cork - info to build ip hdr on each ip frag while socket is corked
+ */
+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;
+	__u32			rcv_saddr;
+	__u16			dport;
+	__u16			num;
+	__u32			saddr;
+	__s16			uc_ttl;
+	__u16			cmsg_flags;
+	struct ip_options	*opt;
+	__u16			sport;
+	__u16			id;
+	__u8			tos;
+	__u8			mc_ttl;
+	__u8			pmtudisc;
+	__u8			recverr:1,
+				is_icsk:1,
+				freebind:1,
+				hdrincl:1,
+				mc_loop:1;
+	int			mc_index;
+	__u32			mc_addr;
+	struct ip_mc_socklist	*mc_list;
+	struct {
+		unsigned int		flags;
+		unsigned int		fragsize;
+		struct ip_options	*opt;
+		struct rtable		*rt;
+		int			length; /* Total length of all frames */
+		u32			addr;
+		struct flowi		fl;
+	} cork;
+};
+
+#define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
+#define IPCORK_ALLFRAG	2	/* always fragment (for ipv6 for now) */
+
+static inline struct inet_sock *inet_sk(const struct sock *sk)
+{
+	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->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
+
+extern int inet_sk_rebuild_header(struct sock *sk);
+
+static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
+					const __u32 faddr, const __u16 fport)
+{
+	unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+	h ^= h >> 16;
+	h ^= h >> 8;
+	return h;
+}
+
+static inline int inet_sk_ehashfn(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	const __u32 laddr = inet->rcv_saddr;
+	const __u16 lport = inet->num;
+	const __u32 faddr = inet->daddr;
+	const __u16 fport = inet->dport;
+
+	return inet_ehashfn(laddr, lport, faddr, fport);
+}
+
+#endif	/* _INET_SOCK_H */
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 28f7b21..1da294c 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -17,15 +17,16 @@
 
 #include <linux/config.h>
 
-#include <linux/ip.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
+#include <net/timewait_sock.h>
 
 #include <asm/atomic.h>
 
@@ -127,7 +128,8 @@
 	__u16			tw_num;
 	/* And these are ours. */
 	__u8			tw_ipv6only:1;
-	/* 31 bits hole, try to pack */
+	/* 15 bits hole, try to pack */
+	__u16			tw_ipv6_offset;
 	int			tw_timeout;
 	unsigned long		tw_ttd;
 	struct inet_bind_bucket	*tw_tb;
@@ -199,7 +201,7 @@
 		printk(KERN_DEBUG "%s timewait_sock %p released\n",
 		       tw->tw_prot->name, tw);
 #endif
-		kmem_cache_free(tw->tw_prot->twsk_slab, tw);
+		kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
 		module_put(owner);
 	}
 }
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 7fda471..0965515 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -25,6 +25,7 @@
 	__u32			v4daddr;	/* peer's address */
 	__u16			avl_height;
 	__u16			ip_id_count;	/* IP ID for the next packet */
+	atomic_t		rid;		/* Frag reception counter */
 	__u32			tcp_ts;
 	unsigned long		tcp_ts_stamp;
 };
diff --git a/include/net/ip.h b/include/net/ip.h
index e4563bb..f7e7fd7 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -24,14 +24,10 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/in.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/in_route.h>
-#include <net/route.h>
-#include <net/arp.h>
+
+#include <net/inet_sock.h>
 #include <net/snmp.h>
 
 struct sock;
@@ -45,6 +41,7 @@
 #define IPSKB_TRANSLATED	2
 #define IPSKB_FORWARDED		4
 #define IPSKB_XFRM_TUNNEL_SIZE	8
+#define IPSKB_FRAG_COMPLETE	16
 };
 
 struct ipcm_cookie
@@ -74,6 +71,13 @@
 
 #define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/
 
+struct msghdr;
+struct net_device;
+struct packet_type;
+struct rtable;
+struct sk_buff;
+struct sockaddr;
+
 extern void		ip_mc_dropsocket(struct sock *);
 extern void		ip_mc_dropdevice(struct net_device *dev);
 extern int		igmp_mc_proc_init(void);
@@ -168,6 +172,7 @@
 extern int sysctl_ipfrag_low_thresh;
 extern int sysctl_ipfrag_time;
 extern int sysctl_ipfrag_secret_interval;
+extern int sysctl_ipfrag_max_dist;
 
 /* From inetpeer.c */
 extern int inet_peer_threshold;
@@ -182,6 +187,8 @@
 extern void ipfrag_init(void);
 
 #ifdef CONFIG_INET
+#include <net/dst.h>
+
 /* The function in 2.2 was invalid, producing wrong result for
  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
 static inline
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 14de4eb..e000fa2 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -238,6 +238,8 @@
 			       struct net_device *dev, u32 *spec_dst, u32 *itag);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
+struct rtentry;
+
 /* Exported by fib_semantics.c */
 extern int ip_fib_check_default(u32 gw, struct net_device *dev);
 extern int fib_sync_down(u32 local, struct net_device *dev, int force);
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 3b5559a..7d2674f 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -251,16 +251,15 @@
 #include <linux/config.h>
 #include <linux/list.h>                 /* for struct list_head */
 #include <linux/spinlock.h>             /* for struct rwlock_t */
-#include <linux/skbuff.h>               /* for struct sk_buff */
-#include <linux/ip.h>                   /* for struct iphdr */
 #include <asm/atomic.h>                 /* for struct atomic_t */
-#include <linux/netdevice.h>		/* for struct neighbour */
-#include <net/dst.h>			/* for struct dst_entry */
-#include <net/udp.h>
 #include <linux/compiler.h>
+#include <linux/timer.h>
 
+#include <net/checksum.h>
 
 #ifdef CONFIG_IP_VS_DEBUG
+#include <linux/net.h>
+
 extern int ip_vs_get_debug_level(void);
 #define IP_VS_DBG(level, msg...)			\
     do {						\
@@ -429,8 +428,11 @@
 	spinlock_t              lock;           /* spin lock */
 };
 
+struct dst_entry;
+struct iphdr;
 struct ip_vs_conn;
 struct ip_vs_app;
+struct sk_buff;
 
 struct ip_vs_protocol {
 	struct ip_vs_protocol	*next;
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 0a2ad51..860bbac 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -240,6 +240,8 @@
 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
 					  struct ipv6_txoptions *opt);
 
+extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
+
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
 
@@ -525,6 +527,9 @@
 extern int inet6_ioctl(struct socket *sock, unsigned int cmd, 
 		       unsigned long arg);
 
+extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+			      struct sock *sk);
+
 /*
  * reassembly.c
  */
@@ -533,8 +538,11 @@
 extern int sysctl_ip6frag_time;
 extern int sysctl_ip6frag_secret_interval;
 
-extern struct proto_ops inet6_stream_ops;
-extern struct proto_ops inet6_dgram_ops;
+extern const struct proto_ops inet6_stream_ops;
+extern const struct proto_ops inet6_dgram_ops;
+
+struct group_source_req;
+struct group_filter;
 
 extern int ip6_mc_source(int add, int omode, struct sock *sk,
 			 struct group_source_req *pgsr);
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index f85d6e4..bbac87e 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -35,11 +35,20 @@
 
 #ifdef __KERNEL__
 
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/icmpv6.h>
+#include <linux/in6.h>
+#include <linux/types.h>
+
 #include <net/neighbour.h>
-#include <asm/atomic.h>
+
+struct ctl_table;
+struct file;
+struct inet6_dev;
+struct net_device;
+struct net_proto_family;
+struct sk_buff;
 
 extern struct neigh_table nd_tbl;
 
@@ -108,7 +117,7 @@
 extern void			igmp6_cleanup(void);
 
 #ifdef CONFIG_SYSCTL
-extern int 			ndisc_ifinfo_sysctl_change(ctl_table *ctl,
+extern int 			ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
 							   int write,
 							   struct file * filp,
 							   void __user *buffer,
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 34c0773..6fa9ae1 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -49,8 +49,8 @@
 #ifdef __KERNEL__
 
 #include <asm/atomic.h>
-#include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/skbuff.h>
 #include <linux/rcupdate.h>
 #include <linux/seq_file.h>
 
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h
index bd08964..b225d84 100644
--- a/include/net/pkt_act.h
+++ b/include/net/pkt_act.h
@@ -15,7 +15,6 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 357691f..63f7db9 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -65,7 +65,7 @@
 	int		 protocol; /* This is the L4 protocol number.  */
 
 	struct proto	 *prot;
-	struct proto_ops *ops;
+	const struct proto_ops *ops;
   
 	int              capability; /* Which (if any) capability do
 				      * we need to use this socket
@@ -76,6 +76,7 @@
 };
 #define INET_PROTOSW_REUSE 0x01	     /* Are ports automatically reusable? */
 #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
+#define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
 
 extern struct net_protocol *inet_protocol_base;
 extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
diff --git a/include/net/raw.h b/include/net/raw.h
index f479174..e67b28a 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -19,6 +19,8 @@
 
 #include <linux/config.h>
 
+#include <net/protocol.h>
+
 extern struct proto raw_prot;
 
 extern void 	raw_err(struct sock *, struct sk_buff *, u32 info);
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index b52cc52..11641c9 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -244,7 +244,7 @@
 
 static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
 					u32 hash, struct request_sock *req,
-					unsigned timeout)
+					unsigned long timeout)
 {
 	struct listen_sock *lopt = queue->listen_opt;
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 8e7794e..f5c22d7 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -277,6 +277,24 @@
 	__u32 default_context;
 	__u32 default_timetolive;
 
+	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+	 * the destination address every heartbeat interval. This value
+	 * will be inherited by all new associations.
+	 */
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for new associations. */
+	__u16 pathmaxrxt;
+
+	/* The initial Path MTU to use for new associations. */
+	__u32 pathmtu;
+
+	/* The default SACK delay timeout for new associations. */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
+
 	struct sctp_initmsg initmsg;
 	struct sctp_rtoinfo rtoinfo;
 	struct sctp_paddrparams paddrparam;
@@ -845,9 +863,6 @@
 	/* Data that has been sent, but not acknowledged. */
 	__u32 flight_size;
 
-	/* PMTU	      : The current known path MTU.  */
-	__u32 pmtu;
-
 	/* Destination */
 	struct dst_entry *dst;
 	/* Source address. */
@@ -862,7 +877,22 @@
 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
 	 * the destination address every heartbeat interval.
 	 */
-	int hb_interval;
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for the transport and will
+	 * be initialized from the assocs value.  This can be changed
+	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
+	 */
+	__u16 pathmaxrxt;
+
+	/* PMTU	      : The current known path MTU.  */
+	__u32 pathmtu;
+
+	/* SACK delay timeout */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
 
 	/* When was the last time (in jiffies) that we heard from this
 	 * transport?  We use this to pick new active and retran paths.
@@ -882,22 +912,11 @@
 	 */
 	int state;
 
-	/* hb_allowed  : The current heartbeat state of this destination,
-	 *	       :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
-	 */
-	int hb_allowed;
-
 	/* These are the error stats for this destination.  */
 
 	/* Error count : The current error count for this destination.	*/
 	unsigned short error_count;
 
-	/* 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.
-	 */
-	int max_retrans;
-
 	/* Per	       : A timer used by each destination.
 	 * Destination :
 	 * Timer       :
@@ -1502,6 +1521,28 @@
 	/* The largest timeout or RTO value to use in attempting an INIT */
 	__u16 max_init_timeo;
 
+	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+	 * the destination address every heartbeat interval. This value
+	 * will be inherited by all new transports.
+	 */
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for new transports in the
+	 * association.
+	 */
+	__u16 pathmaxrxt;
+
+	/* Association : The smallest PMTU discovered for all of the
+	 * PMTU	       : peer's transport addresses.
+	 */
+	__u32 pathmtu;
+
+	/* SACK delay timeout */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
+
 	int timeouts[SCTP_NUM_TIMEOUT_TYPES];
 	struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
 
@@ -1571,11 +1612,6 @@
 	 */
 	wait_queue_head_t	wait;
 
-	/* Association : The smallest PMTU discovered for all of the
-	 * PMTU	       : peer's transport addresses.
-	 */
-	__u32 pmtu;
-
 	/* The message size at which SCTP fragmentation will occur. */
 	__u32 frag_point;
 
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index f1c3bc5..8a6bef6 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -93,6 +93,8 @@
 #define SCTP_STATUS SCTP_STATUS
 	SCTP_GET_PEER_ADDR_INFO,
 #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
+	SCTP_DELAYED_ACK_TIME,
+#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
 
 	/* Internal Socket Options. Some of the sctp library functions are 
 	 * implemented using these socket options.
@@ -503,13 +505,41 @@
  *   unreachable. The following structure is used to access and modify an
  *   address's parameters:
  */
+enum  sctp_spp_flags {
+	SPP_HB_ENABLE = 1,		/*Enable heartbeats*/
+	SPP_HB_DISABLE = 2,		/*Disable heartbeats*/
+	SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE,
+	SPP_HB_DEMAND = 4,		/*Send heartbeat immediately*/
+	SPP_PMTUD_ENABLE = 8,		/*Enable PMTU discovery*/
+	SPP_PMTUD_DISABLE = 16,		/*Disable PMTU discovery*/
+	SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE,
+	SPP_SACKDELAY_ENABLE = 32,	/*Enable SACK*/
+	SPP_SACKDELAY_DISABLE = 64,	/*Disable SACK*/
+	SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
+};
+
 struct sctp_paddrparams {
 	sctp_assoc_t		spp_assoc_id;
 	struct sockaddr_storage	spp_address;
 	__u32			spp_hbinterval;
 	__u16			spp_pathmaxrxt;
+	__u32			spp_pathmtu;
+	__u32			spp_sackdelay;
+	__u32			spp_flags;
 } __attribute__((packed, aligned(4)));
 
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ */
+struct sctp_assoc_value {
+    sctp_assoc_t            assoc_id;
+    uint32_t                assoc_value;
+};
+
 /*
  * 7.2.2 Peer Address Information
  *
diff --git a/include/net/sock.h b/include/net/sock.h
index 982b4ec..6961700 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -493,6 +493,7 @@
 extern int sk_wait_data(struct sock *sk, long *timeo);
 
 struct request_sock_ops;
+struct timewait_sock_ops;
 
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
@@ -557,11 +558,10 @@
 	kmem_cache_t		*slab;
 	unsigned int		obj_size;
 
-	kmem_cache_t		*twsk_slab;
-	unsigned int		twsk_obj_size;
 	atomic_t		*orphan_count;
 
 	struct request_sock_ops	*rsk_prot;
+	struct timewait_sock_ops *twsk_prot;
 
 	struct module		*owner;
 
@@ -926,6 +926,29 @@
 		sk_free(sk);
 }
 
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
+{
+	int rc = NET_RX_SUCCESS;
+
+	if (sk_filter(sk, skb, 0))
+		goto discard_and_relse;
+
+	skb->dev = NULL;
+
+	bh_lock_sock(sk);
+	if (!sock_owned_by_user(sk))
+		rc = sk->sk_backlog_rcv(sk, skb);
+	else
+		sk_add_backlog(sk, skb);
+	bh_unlock_sock(sk);
+out:
+	sock_put(sk);
+	return rc;
+discard_and_relse:
+	kfree_skb(skb);
+	goto out;
+}
+
 /* Detach socket from process context.
  * Announce socket dead, detach it from wait queue and inode.
  * Note that parent inode held reference count on this struct sock,
@@ -1166,7 +1189,10 @@
  
 static inline int sock_error(struct sock *sk)
 {
-	int err = xchg(&sk->sk_err, 0);
+	int err;
+	if (likely(!sk->sk_err))
+		return 0;
+	err = xchg(&sk->sk_err, 0);
 	return -err;
 }
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d78025f..77f21c6 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -225,53 +225,6 @@
 extern int tcp_memory_pressure;
 
 /*
- *	Pointers to address related TCP functions
- *	(i.e. things that depend on the address family)
- */
-
-struct tcp_func {
-	int			(*queue_xmit)		(struct sk_buff *skb,
-							 int ipfragok);
-
-	void			(*send_check)		(struct sock *sk,
-							 struct tcphdr *th,
-							 int len,
-							 struct sk_buff *skb);
-
-	int			(*rebuild_header)	(struct sock *sk);
-
-	int			(*conn_request)		(struct sock *sk,
-							 struct sk_buff *skb);
-
-	struct sock *		(*syn_recv_sock)	(struct sock *sk,
-							 struct sk_buff *skb,
-							 struct request_sock *req,
-							 struct dst_entry *dst);
-    
-	int			(*remember_stamp)	(struct sock *sk);
-
-	__u16			net_header_len;
-
-	int			(*setsockopt)		(struct sock *sk, 
-							 int level, 
-							 int optname, 
-							 char __user *optval, 
-							 int optlen);
-
-	int			(*getsockopt)		(struct sock *sk, 
-							 int level, 
-							 int optname, 
-							 char __user *optval, 
-							 int __user *optlen);
-
-
-	void			(*addr2sockaddr)	(struct sock *sk,
-							 struct sockaddr *);
-
-	int sockaddr_len;
-};
-
-/*
  * The next routines deal with comparing 32 bit unsigned ints
  * and worry about wraparound (automatic with unsigned arithmetic).
  */
@@ -334,6 +287,9 @@
 
 extern void			tcp_rcv_space_adjust(struct sock *sk);
 
+extern int			tcp_twsk_unique(struct sock *sk,
+						struct sock *sktw, void *twp);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
 					 const unsigned int pkts)
 {
@@ -405,8 +361,7 @@
  *	TCP v4 functions exported for the inet6 API
  */
 
-extern void		       	tcp_v4_send_check(struct sock *sk, 
-						  struct tcphdr *th, int len, 
+extern void		       	tcp_v4_send_check(struct sock *sk, int len,
 						  struct sk_buff *skb);
 
 extern int			tcp_v4_conn_request(struct sock *sk,
@@ -490,34 +445,16 @@
 extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 			 sk_read_actor_t recv_actor);
 
-/* Initialize RCV_MSS value.
- * RCV_MSS is an our guess about MSS used by the peer.
- * We haven't any direct information about the MSS.
- * It's better to underestimate the RCV_MSS rather than overestimate.
- * Overestimations make us ACKing less frequently than needed.
- * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
- */
+extern void tcp_initialize_rcv_mss(struct sock *sk);
 
-static inline void tcp_initialize_rcv_mss(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
-
-	hint = min(hint, tp->rcv_wnd/2);
-	hint = min(hint, TCP_MIN_RCVMSS);
-	hint = max(hint, TCP_MIN_MSS);
-
-	inet_csk(sk)->icsk_ack.rcv_mss = hint;
-}
-
-static __inline__ void __tcp_fast_path_on(struct tcp_sock *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_sock *tp)
+static inline void tcp_fast_path_on(struct tcp_sock *tp)
 {
 	__tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 }
@@ -535,7 +472,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_sock *tp)
+static inline u32 tcp_receive_window(const struct tcp_sock *tp)
 {
 	s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt;
 
@@ -707,6 +644,7 @@
 extern int tcp_set_default_congestion_control(const char *name);
 extern void tcp_get_default_congestion_control(char *name);
 extern int tcp_set_congestion_control(struct sock *sk, const char *name);
+extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
@@ -746,7 +684,7 @@
  *	"Packets left network, but not honestly ACKed yet" PLUS
  *	"Packets fast retransmitted"
  */
-static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
+static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 {
 	return (tp->packets_out - tp->left_out + tp->retrans_out);
 }
@@ -766,33 +704,6 @@
 			    (tp->snd_cwnd >> 2)));
 }
 
-/*
- * Linear increase during slow start
- */
-static inline void tcp_slow_start(struct tcp_sock *tp)
-{
-	if (sysctl_tcp_abc) {
-		/* RFC3465: Slow Start
-		 * TCP sender SHOULD increase cwnd by the number of
-		 * previously unacknowledged bytes ACKed by each incoming
-		 * acknowledgment, provided the increase is not more than L
-		 */
-		if (tp->bytes_acked < tp->mss_cache)
-			return;
-
-		/* We MAY increase by 2 if discovered delayed ack */
-		if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
-			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-				tp->snd_cwnd++;
-		}
-	}
-	tp->bytes_acked = 0;
-
-	if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-		tp->snd_cwnd++;
-}
-
-
 static inline void tcp_sync_left_out(struct tcp_sock *tp)
 {
 	if (tp->rx_opt.sack_ok &&
@@ -801,34 +712,7 @@
 	tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-/* Set slow start threshold and cwnd not falling to slow start */
-static inline void __tcp_enter_cwr(struct sock *sk)
-{
-	const struct inet_connection_sock *icsk = inet_csk(sk);
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->undo_marker = 0;
-	tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
-	tp->snd_cwnd = min(tp->snd_cwnd,
-			   tcp_packets_in_flight(tp) + 1U);
-	tp->snd_cwnd_cnt = 0;
-	tp->high_seq = tp->snd_nxt;
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-	TCP_ECN_queue_cwr(tp);
-}
-
-static inline void tcp_enter_cwr(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->prior_ssthresh = 0;
-	tp->bytes_acked = 0;
-	if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
-		__tcp_enter_cwr(sk);
-		tcp_set_ca_state(sk, TCP_CA_CWR);
-	}
-}
-
+extern void tcp_enter_cwr(struct sock *sk);
 extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
@@ -860,14 +744,14 @@
 		return left <= tcp_max_burst(tp);
 }
 
-static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
-					   const struct sk_buff *skb)
+static inline void tcp_minshall_update(struct tcp_sock *tp, int mss,
+				       const struct sk_buff *skb)
 {
 	if (skb->len < mss)
 		tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	if (!tp->packets_out && !icsk->icsk_pending)
@@ -875,18 +759,18 @@
 					  icsk->icsk_rto, TCP_RTO_MAX);
 }
 
-static __inline__ void tcp_push_pending_frames(struct sock *sk,
-					       struct tcp_sock *tp)
+static inline void tcp_push_pending_frames(struct sock *sk,
+					   struct tcp_sock *tp)
 {
 	__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
-static __inline__ void tcp_init_wl(struct tcp_sock *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_sock *tp, u32 ack, u32 seq)
+static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
 }
@@ -894,19 +778,19 @@
 /*
  * Calculate(/check) TCP checksum
  */
-static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
-				   unsigned long saddr, unsigned long daddr, 
-				   unsigned long base)
+static inline u16 tcp_v4_check(struct tcphdr *th, int len,
+			       unsigned long saddr, unsigned long daddr, 
+			       unsigned long base)
 {
 	return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
 }
 
-static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
+static inline int __tcp_checksum_complete(struct sk_buff *skb)
 {
 	return __skb_checksum_complete(skb);
 }
 
-static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
+static inline int tcp_checksum_complete(struct sk_buff *skb)
 {
 	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
 		__tcp_checksum_complete(skb);
@@ -914,7 +798,7 @@
 
 /* Prequeue for VJ style copy to user, combined with checksumming. */
 
-static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
+static inline void tcp_prequeue_init(struct tcp_sock *tp)
 {
 	tp->ucopy.task = NULL;
 	tp->ucopy.len = 0;
@@ -930,7 +814,7 @@
  *
  * NOTE: is this not too big to inline?
  */
-static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
@@ -971,7 +855,7 @@
 };
 #endif
 
-static __inline__ void tcp_set_state(struct sock *sk, int state)
+static inline void tcp_set_state(struct sock *sk, int state)
 {
 	int oldstate = sk->sk_state;
 
@@ -1005,7 +889,7 @@
 #endif	
 }
 
-static __inline__ void tcp_done(struct sock *sk)
+static inline void tcp_done(struct sock *sk)
 {
 	tcp_set_state(sk, TCP_CLOSE);
 	tcp_clear_xmit_timers(sk);
@@ -1018,81 +902,13 @@
 		inet_csk_destroy_sock(sk);
 }
 
-static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt)
+static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
 {
 	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_sock *tp, __u32 tstamp)
-{
-	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->rx_opt.ts_recent);
-	}
-	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->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->rx_opt.dsack) {
-			tp->rx_opt.dsack = 0;
-			tp->rx_opt.eff_sacks--;
-		}
-	}
-}
-
-/* Construct a tcp options header for a SYN or SYN_ACK packet.
- * If this is every changed make sure to change the definition of
- * MAX_SYN_SIZE to match the new maximum number of options that you
- * can generate.
- */
-static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
-					     int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
-{
-	/* We always get an MSS option.
-	 * The option bytes which will be seen in normal data
-	 * packets should timestamps be used, must be in the MSS
-	 * advertised.  But we subtract them from tp->mss_cache so
-	 * that calculations in tcp_sendmsg are simpler etc.
-	 * So account for this fact here if necessary.  If we
-	 * don't do this correctly, as a receiver we won't
-	 * recognize data packets as being full sized when we
-	 * should, and thus we won't abide by the delayed ACK
-	 * rules correctly.
-	 * SACKs don't matter, we never delay an ACK when we
-	 * have any of those going out.
-	 */
-	*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
-	if (ts) {
-		if(sack)
-			*ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
-						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-		else
-			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-		*ptr++ = htonl(tstamp);		/* TSVAL */
-		*ptr++ = htonl(ts_recent);	/* TSECR */
-	} else if(sack)
-		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
-	if (offer_wscale)
-		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
-}
-
 /* Determine a window scaling and initial window to offer. */
 extern void tcp_select_initial_window(int __space, __u32 mss,
 				      __u32 *rcv_wnd, __u32 *window_clamp,
@@ -1117,9 +933,9 @@
 	return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static __inline__ void tcp_openreq_init(struct request_sock *req,
-					struct tcp_options_received *rx_opt,
-					struct sk_buff *skb)
+static inline void tcp_openreq_init(struct request_sock *req,
+				    struct tcp_options_received *rx_opt,
+				    struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq = inet_rsk(req);
 
diff --git a/include/net/tcp_states.h b/include/net/tcp_states.h
index b9d4176..b0b6459 100644
--- a/include/net/tcp_states.h
+++ b/include/net/tcp_states.h
@@ -31,4 +31,20 @@
 
 #define TCP_STATE_MASK	0xF
 
+#define TCP_ACTION_FIN	(1 << 7)
+
+enum {
+	TCPF_ESTABLISHED = (1 << 1),
+	TCPF_SYN_SENT	 = (1 << 2),
+	TCPF_SYN_RECV	 = (1 << 3),
+	TCPF_FIN_WAIT1	 = (1 << 4),
+	TCPF_FIN_WAIT2	 = (1 << 5),
+	TCPF_TIME_WAIT	 = (1 << 6),
+	TCPF_CLOSE	 = (1 << 7),
+	TCPF_CLOSE_WAIT	 = (1 << 8),
+	TCPF_LAST_ACK	 = (1 << 9),
+	TCPF_LISTEN	 = (1 << 10),
+	TCPF_CLOSING	 = (1 << 11) 
+};
+
 #endif	/* _LINUX_TCP_STATES_H */
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
new file mode 100644
index 0000000..2544281
--- /dev/null
+++ b/include/net/timewait_sock.h
@@ -0,0 +1,31 @@
+/*
+ * NET		Generic infrastructure for Network protocols.
+ *
+ * Authors:	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the 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 _TIMEWAIT_SOCK_H
+#define _TIMEWAIT_SOCK_H
+
+#include <linux/slab.h>
+#include <net/sock.h>
+
+struct timewait_sock_ops {
+	kmem_cache_t	*twsk_slab;
+	unsigned int	twsk_obj_size;
+	int		(*twsk_unique)(struct sock *sk,
+				       struct sock *sktw, void *twp);
+};
+
+static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+{
+	if (sk->sk_prot->twsk_prot->twsk_unique != NULL)
+		return sk->sk_prot->twsk_prot->twsk_unique(sk, sktw, twp);
+	return 0;
+}
+
+#endif /* _TIMEWAIT_SOCK_H */
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 4e86f2d..61f724c 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -44,7 +44,7 @@
 /*
  *	address family specific functions
  */
-extern struct tcp_func	ipv4_specific;
+extern struct inet_connection_sock_af_ops ipv4_specific;
 
 extern int inet6_destroy_sock(struct sock *sk);
 
diff --git a/include/net/udp.h b/include/net/udp.h
index 107b9d7..766fba1 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -22,9 +22,8 @@
 #ifndef _UDP_H
 #define _UDP_H
 
-#include <linux/udp.h>
-#include <linux/ip.h>
 #include <linux/list.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 #include <linux/seq_file.h>
@@ -62,6 +61,7 @@
 
 extern struct proto udp_prot;
 
+struct sk_buff;
 
 extern void	udp_err(struct sk_buff *, u32);
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1cdb879..07d7b50 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -2,11 +2,12 @@
 #define _NET_XFRM_H
 
 #include <linux/compiler.h>
+#include <linux/in.h>
 #include <linux/xfrm.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/socket.h>
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
@@ -144,6 +145,9 @@
 	 * transformer. */
 	struct xfrm_type	*type;
 
+	/* Security context */
+	struct xfrm_sec_ctx	*security;
+
 	/* Private data of this transformer, format is opaque,
 	 * interpreted by xfrm_type methods. */
 	void			*data;
@@ -298,6 +302,7 @@
 	__u8			flags;
 	__u8			dead;
 	__u8			xfrm_nr;
+	struct xfrm_sec_ctx	*security;
 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
 };
 
@@ -510,6 +515,25 @@
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+/*	If neither has a context --> match
+ * 	Otherwise, both must have a context and the sids, doi, alg must match
+ */
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+	return ((!s1 && !s2) ||
+		(s1 && s2 &&
+		 (s1->ctx_sid == s2->ctx_sid) &&
+		 (s1->ctx_doi == s2->ctx_doi) &&
+		 (s1->ctx_alg == s2->ctx_alg)));
+}
+#else
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+	return 1;
+}
+#endif
+
 /* A struct encoding bundle of transformations to apply to some set of flow.
  *
  * dst->child points to the next element of bundle.
@@ -878,8 +902,8 @@
 struct xfrm_policy *xfrm_policy_alloc(gfp_t 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);
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-				      int delete);
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+					  struct xfrm_sec_ctx *ctx, int delete);
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
 void xfrm_policy_flush(void);
 u32 xfrm_get_acqseq(void);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 20da282..41cfc29 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -151,6 +151,6 @@
 extern void scsi_put_command(struct scsi_cmnd *);
 extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
-extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries);
+extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd);
 
 #endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index b090a11..4d69dee 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -16,7 +16,6 @@
 extern void scsi_print_driverbyte(int);
 extern void scsi_print_hostbyte(int);
 extern void scsi_print_status(unsigned char);
-extern int scsi_print_msg(const unsigned char *);
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 85cfd88..e94ca4d 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -79,9 +79,9 @@
 	char inq_periph_qual;	/* PQ from INQUIRY data */	
 	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
 	unsigned char * inquiry;	/* INQUIRY response data */
-	char * vendor;		/* [back_compat] point into 'inquiry' ... */
-	char * model;		/* ... after scan; point to static string */
-	char * rev;		/* ... "nullnullnullnull" before scan */
+	const char * vendor;		/* [back_compat] point into 'inquiry' ... */
+	const char * model;		/* ... after scan; point to static string */
+	const char * rev;		/* ... "nullnullnullnull" before scan */
 	unsigned char current_tag;	/* current tag */
 	struct scsi_target      *sdev_target;   /* used only for single_lun */
 
@@ -274,6 +274,12 @@
 extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
 			    int data_direction, void *buffer, unsigned bufflen,
 			    struct scsi_sense_hdr *, int timeout, int retries);
+extern int scsi_execute_async(struct scsi_device *sdev,
+			      const unsigned char *cmd, int data_direction,
+			      void *buffer, unsigned bufflen, int use_sg,
+			      int timeout, int retries, void *privdata,
+			      void (*done)(void *, char *, int, int),
+			      gfp_t gfp);
 
 static inline unsigned int sdev_channel(struct scsi_device *sdev)
 {
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 6bdc4af..54a8961 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -24,6 +24,9 @@
 #include <linux/transport_class.h>
 
 struct scsi_transport_template;
+struct scsi_target;
+struct scsi_device;
+struct Scsi_Host;
 
 struct spi_transport_attrs {
 	int period;		/* value in the PPR/SDTR command */
@@ -143,5 +146,6 @@
 void spi_schedule_dv_device(struct scsi_device *);
 void spi_dv_device(struct scsi_device *);
 void spi_display_xfer_agreement(struct scsi_target *);
+int spi_print_msg(const unsigned char *);
 
 #endif /* SCSI_TRANSPORT_SPI_H */
diff --git a/init/main.c b/init/main.c
index 27f97f9..54aaf56 100644
--- a/init/main.c
+++ b/init/main.c
@@ -47,7 +47,6 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
-#include <net/sock.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -614,9 +613,6 @@
 	sysctl_init();
 #endif
 
-	/* Networking initialization needs a process context */ 
-	sock_init();
-
 	do_initcalls();
 }
 
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 7982656..a5144e4 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -63,7 +63,7 @@
 #include <linux/atalk.h>
 
 struct datalink_proto *ddp_dl, *aarp_dl;
-static struct proto_ops atalk_dgram_ops;
+static const struct proto_ops atalk_dgram_ops;
 
 /**************************************************************************\
 *                                                                          *
@@ -1763,7 +1763,7 @@
  */
 static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	int rc = -EINVAL;
+	int rc = -ENOIOCTLCMD;
 	struct sock *sk = sock->sk;
 	void __user *argp = (void __user *)arg;
 
@@ -1813,23 +1813,6 @@
 			rc = atif_ioctl(cmd, argp);
 			rtnl_unlock();
 			break;
-		/* Physical layer ioctl calls */
-		case SIOCSIFLINK:
-		case SIOCGIFHWADDR:
-		case SIOCSIFHWADDR:
-		case SIOCGIFFLAGS:
-		case SIOCSIFFLAGS:
-		case SIOCGIFTXQLEN:
-		case SIOCSIFTXQLEN:
-		case SIOCGIFMTU:
-		case SIOCGIFCONF:
-		case SIOCADDMULTI:
-		case SIOCDELMULTI:
-		case SIOCGIFCOUNT:
-		case SIOCGIFINDEX:
-		case SIOCGIFNAME:
-			rc = dev_ioctl(cmd, argp);
-			break;
 	}
 
 	return rc;
@@ -1841,7 +1824,7 @@
 	.owner		= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
 	.family		= PF_APPLETALK,
 	.owner		= THIS_MODULE,
 	.release	= atalk_release,
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 2684a92..f2c5417 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -102,7 +102,7 @@
 }
 
 
-static struct proto_ops pvc_proto_ops = {
+static const struct proto_ops pvc_proto_ops = {
 	.family =	PF_ATMPVC,
 	.owner =	THIS_MODULE,
 
diff --git a/net/atm/svc.c b/net/atm/svc.c
index d7b2661..3a180cf 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -613,7 +613,7 @@
 	return error;
 }
 
-static struct proto_ops svc_proto_ops = {
+static const struct proto_ops svc_proto_ops = {
 	.family =	PF_ATMSVC,
 	.owner =	THIS_MODULE,
 
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 1b683f3..e8753c7 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -54,7 +54,7 @@
 HLIST_HEAD(ax25_list);
 DEFINE_SPINLOCK(ax25_list_lock);
 
-static struct proto_ops ax25_proto_ops;
+static const struct proto_ops ax25_proto_ops;
 
 static void ax25_free_sock(struct sock *sk)
 {
@@ -1827,7 +1827,7 @@
 		break;
 
 	default:
-		res = dev_ioctl(cmd, argp);
+		res = -ENOIOCTLCMD;
 		break;
 	}
 	release_sock(sk);
@@ -1944,7 +1944,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops ax25_proto_ops = {
+static const struct proto_ops ax25_proto_ops = {
 	.family		= PF_AX25,
 	.owner		= THIS_MODULE,
 	.release	= ax25_release,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ea616e3..fb031fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -287,10 +287,9 @@
 		timeo = schedule_timeout(timeo);
 		lock_sock(sk);
 
-		if (sk->sk_err) {
-			err = sock_error(sk);
+		err = sock_error(sk);
+		if (err)
 			break;
-		}
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 9778c6a..ccbaf69 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -146,7 +146,7 @@
 	return 0;
 }
 
-static struct proto_ops bnep_sock_ops = {
+static const struct proto_ops bnep_sock_ops = {
 	.family     = PF_BLUETOOTH,
 	.owner      = THIS_MODULE,
 	.release    = bnep_sock_release,
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index beb045b..5e22343 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -137,7 +137,7 @@
 	return -EINVAL;
 }
 
-static struct proto_ops cmtp_sock_ops = {
+static const struct proto_ops cmtp_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= cmtp_sock_release,
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 1d6d0a1..84e6c93 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -575,7 +575,7 @@
 	return 0;
 }
 
-static struct proto_ops hci_sock_ops = {
+static const struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hci_sock_release,
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index f8986f8..8f8dd93 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -143,7 +143,7 @@
 	return -EINVAL;
 }
 
-static struct proto_ops hidp_sock_ops = {
+static const struct proto_ops hidp_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hidp_sock_release,
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e3bb11c..7f0781e 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -57,7 +57,7 @@
 
 #define VERSION "2.8"
 
-static struct proto_ops l2cap_sock_ops;
+static const struct proto_ops l2cap_sock_ops;
 
 static struct bt_sock_list l2cap_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -767,8 +767,9 @@
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
-	if (sk->sk_err)
-		return sock_error(sk);
+	err = sock_error(sk);
+	if (err)
+		return err;
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
@@ -2160,7 +2161,7 @@
 
 static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
 
-static struct proto_ops l2cap_sock_ops = {
+static const struct proto_ops l2cap_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= l2cap_sock_release,
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 6c34261..757d2dd 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -58,7 +58,7 @@
 #define BT_DBG(D...)
 #endif
 
-static struct proto_ops rfcomm_sock_ops;
+static const struct proto_ops rfcomm_sock_ops;
 
 static struct bt_sock_list rfcomm_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -907,7 +907,7 @@
 
 static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
 
-static struct proto_ops rfcomm_sock_ops = {
+static const struct proto_ops rfcomm_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= rfcomm_sock_release,
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9cb00dc..6b61323 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -56,7 +56,7 @@
 
 #define VERSION "0.5"
 
-static struct proto_ops sco_sock_ops;
+static const struct proto_ops sco_sock_ops;
 
 static struct bt_sock_list sco_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -637,8 +637,9 @@
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
-	if (sk->sk_err)
-		return sock_error(sk);
+	err = sock_error(sk);
+	if (err)
+		return err;
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
@@ -913,7 +914,7 @@
 
 static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
 
-static struct proto_ops sco_sock_ops = {
+static const struct proto_ops sco_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= sco_sock_release,
diff --git a/net/bridge/br.c b/net/bridge/br.c
index f8f1849..188cc1a 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -67,3 +67,4 @@
 module_init(br_init)
 module_exit(br_deinit)
 MODULE_LICENSE("GPL");
+MODULE_VERSION(BR_VERSION);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f564ee9..0b33a7b 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -15,7 +15,9 @@
 
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
 #include <asm/uaccess.h>
 #include "br_private.h"
 
@@ -82,6 +84,87 @@
 	return 0;
 }
 
+/* Allow setting mac address of pseudo-bridge to be same as
+ * any of the bound interfaces
+ */
+static int br_set_mac_address(struct net_device *dev, void *p)
+{
+	struct net_bridge *br = netdev_priv(dev);
+	struct sockaddr *addr = p;
+	struct net_bridge_port *port;
+	int err = -EADDRNOTAVAIL;
+
+	spin_lock_bh(&br->lock);
+	list_for_each_entry(port, &br->port_list, list) {
+		if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
+			br_stp_change_bridge_id(br, addr->sa_data);
+			err = 0;
+			break;
+		}
+	}
+	spin_unlock_bh(&br->lock);
+
+	return err;
+}
+
+static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "bridge");
+	strcpy(info->version, BR_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, "N/A");
+}
+
+static int br_set_sg(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_SG;
+	else
+		br->feature_mask &= ~NETIF_F_SG;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static int br_set_tso(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_TSO;
+	else
+		br->feature_mask &= ~NETIF_F_TSO;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static int br_set_tx_csum(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_IP_CSUM;
+	else
+		br->feature_mask &= ~NETIF_F_IP_CSUM;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static struct ethtool_ops br_ethtool_ops = {
+	.get_drvinfo = br_getinfo,
+	.get_link = ethtool_op_get_link,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = br_set_sg,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = br_set_tx_csum,
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = br_set_tso,
+};
+
 void br_dev_setup(struct net_device *dev)
 {
 	memset(dev->dev_addr, 0, ETH_ALEN);
@@ -96,8 +179,12 @@
 	dev->change_mtu = br_change_mtu;
 	dev->destructor = free_netdev;
 	SET_MODULE_OWNER(dev);
+ 	SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
 	dev->stop = br_dev_stop;
 	dev->tx_queue_len = 0;
-	dev->set_mac_address = NULL;
+	dev->set_mac_address = br_set_mac_address;
 	dev->priv_flags = IFF_EBRIDGE;
+
+ 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+ 		| NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 }
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 975abe2..1132119 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -32,9 +32,8 @@
  * ethtool, use ethtool_ops.  Also, since driver might sleep need to
  * not be holding any locks.
  */
-static int br_initial_port_cost(struct net_device *dev)
+static int port_cost(struct net_device *dev)
 {
-
 	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
 	struct ifreq ifr;
 	mm_segment_t old_fs;
@@ -58,10 +57,6 @@
 			return 2;
 		case SPEED_10:
 			return 100;
-		default:
-			pr_info("bridge: can't decode speed from %s: %d\n",
-				dev->name, ecmd.speed);
-			return 100;
 		}
 	}
 
@@ -75,6 +70,35 @@
 	return 100;	/* assume old 10Mbps */
 }
 
+
+/*
+ * Check for port carrier transistions.
+ * Called from work queue to allow for calling functions that
+ * might sleep (such as speed check), and to debounce.
+ */
+static void port_carrier_check(void *arg)
+{
+	struct net_bridge_port *p = arg;
+
+	rtnl_lock();
+	if (netif_carrier_ok(p->dev)) {
+		u32 cost = port_cost(p->dev);
+
+		spin_lock_bh(&p->br->lock);
+		if (p->state == BR_STATE_DISABLED) {
+			p->path_cost = cost;
+			br_stp_enable_port(p);
+		}
+		spin_unlock_bh(&p->br->lock);
+	} else {
+		spin_lock_bh(&p->br->lock);
+		if (p->state != BR_STATE_DISABLED)
+			br_stp_disable_port(p);
+		spin_unlock_bh(&p->br->lock);
+	}
+	rtnl_unlock();
+}
+
 static void destroy_nbp(struct net_bridge_port *p)
 {
 	struct net_device *dev = p->dev;
@@ -102,6 +126,9 @@
 	dev->br_port = NULL;
 	dev_set_promiscuity(dev, -1);
 
+	cancel_delayed_work(&p->carrier_check);
+	flush_scheduled_work();
+
 	spin_lock_bh(&br->lock);
 	br_stp_disable_port(p);
 	spin_unlock_bh(&br->lock);
@@ -155,6 +182,7 @@
 	br->bridge_id.prio[1] = 0x00;
 	memset(br->bridge_id.addr, 0, ETH_ALEN);
 
+	br->feature_mask = dev->features;
 	br->stp_enabled = 0;
 	br->designated_root = br->bridge_id;
 	br->root_path_cost = 0;
@@ -195,10 +223,9 @@
 	return (index >= BR_MAX_PORTS) ? -EXFULL : index;
 }
 
-/* called with RTNL */
+/* called with RTNL but without bridge lock */
 static struct net_bridge_port *new_nbp(struct net_bridge *br, 
-				       struct net_device *dev,
-				       unsigned long cost)
+				       struct net_device *dev)
 {
 	int index;
 	struct net_bridge_port *p;
@@ -215,12 +242,13 @@
 	p->br = br;
 	dev_hold(dev);
 	p->dev = dev;
-	p->path_cost = cost;
+	p->path_cost = port_cost(dev);
  	p->priority = 0x8000 >> BR_PORT_BITS;
 	dev->br_port = p;
 	p->port_no = index;
 	br_init_port(p);
 	p->state = BR_STATE_DISABLED;
+	INIT_WORK(&p->carrier_check, port_carrier_check, p);
 	kobject_init(&p->kobj);
 
 	return p;
@@ -322,9 +350,8 @@
 	struct net_bridge_port *p;
 	unsigned long features, checksum;
 
-	features = NETIF_F_SG | NETIF_F_FRAGLIST 
-		| NETIF_F_HIGHDMA | NETIF_F_TSO;
-	checksum = NETIF_F_IP_CSUM;	/* least commmon subset */
+	features = br->feature_mask &~ NETIF_F_IP_CSUM;
+	checksum = br->feature_mask & NETIF_F_IP_CSUM;
 
 	list_for_each_entry(p, &br->port_list, list) {
 		if (!(p->dev->features 
@@ -351,7 +378,7 @@
 	if (dev->br_port != NULL)
 		return -EBUSY;
 
-	if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev))))
+	if (IS_ERR(p = new_nbp(br, dev)))
 		return PTR_ERR(p);
 
  	if ((err = br_fdb_insert(br, p, dev->dev_addr)))
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index b88220a..c387852 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -53,6 +53,11 @@
 	/* insert into forwarding database after filtering to avoid spoofing */
 	br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
 
+	if (p->state == BR_STATE_LEARNING) {
+		kfree_skb(skb);
+		goto out;
+	}
+
 	if (br->dev->flags & IFF_PROMISC) {
 		struct sk_buff *skb2;
 
@@ -107,9 +112,6 @@
 	if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
 		goto err;
 
-	if (p->state == BR_STATE_LEARNING)
-		br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
-
 	if (p->br->stp_enabled &&
 	    !memcmp(dest, bridge_ula, 5) &&
 	    !(dest[5] & 0xF0)) {
@@ -118,9 +120,10 @@
 				NULL, br_stp_handle_bpdu);
 			return 1;
 		}
+		goto err;
 	}
 
-	else if (p->state == BR_STATE_FORWARDING) {
+	if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
 		if (br_should_route_hook) {
 			if (br_should_route_hook(pskb)) 
 				return 0;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 23422bd..223f827 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -26,6 +26,7 @@
 #include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/netfilter_bridge.h>
@@ -33,8 +34,11 @@
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter_arp.h>
 #include <linux/in_route.h>
+
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
+
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
 #include "br_private.h"
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 917311c..a43a9c1 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -52,17 +52,9 @@
 		br_stp_recalculate_bridge_id(br);
 		break;
 
-	case NETDEV_CHANGE:	/* device is up but carrier changed */
-		if (!(br->dev->flags & IFF_UP))
-			break;
-
-		if (netif_carrier_ok(dev)) {
-			if (p->state == BR_STATE_DISABLED)
-				br_stp_enable_port(p);
-		} else {
-			if (p->state != BR_STATE_DISABLED)
-				br_stp_disable_port(p);
-		}
+	case NETDEV_CHANGE:
+		if (br->dev->flags & IFF_UP)
+			schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
 		break;
 
 	case NETDEV_FEAT_CHANGE:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index bdf95a7..c5bd631 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -27,6 +27,10 @@
 #define BR_PORT_BITS	10
 #define BR_MAX_PORTS	(1<<BR_PORT_BITS)
 
+#define BR_PORT_DEBOUNCE (HZ/10)
+
+#define BR_VERSION	"2.1"
+
 typedef struct bridge_id bridge_id;
 typedef struct mac_addr mac_addr;
 typedef __u16 port_id;
@@ -78,6 +82,7 @@
 	struct timer_list		hold_timer;
 	struct timer_list		message_age_timer;
 	struct kobject			kobj;
+	struct work_struct		carrier_check;
 	struct rcu_head			rcu;
 };
 
@@ -90,6 +95,7 @@
 	spinlock_t			hash_lock;
 	struct hlist_head		hash[BR_HASH_SIZE];
 	struct list_head		age_list;
+	unsigned long			feature_mask;
 
 	/* STP */
 	bridge_id			designated_root;
@@ -201,6 +207,7 @@
 extern void br_stp_enable_port(struct net_bridge_port *p);
 extern void br_stp_disable_port(struct net_bridge_port *p);
 extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
+extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
 extern void br_stp_set_bridge_priority(struct net_bridge *br,
 				       u16 newprio);
 extern void br_stp_set_port_priority(struct net_bridge_port *p,
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index ac09b6a..cc047f7 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -120,8 +120,7 @@
 }
 
 /* called under bridge lock */
-static void br_stp_change_bridge_id(struct net_bridge *br, 
-				    const unsigned char *addr)
+void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
 {
 	unsigned char oldaddr[6];
 	struct net_bridge_port *p;
@@ -158,7 +157,7 @@
 
 	list_for_each_entry(p, &br->port_list, list) {
 		if (addr == br_mac_zero ||
-		    compare_ether_addr(p->dev->dev_addr, addr) < 0)
+		    memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
 			addr = p->dev->dev_addr;
 
 	}
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index c70b3be..b84fc60 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -196,9 +196,13 @@
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 config BRIDGE_EBT_ULOG
-	tristate "ebt: ulog support"
+	tristate "ebt: ulog support (OBSOLETE)"
 	depends on BRIDGE_NF_EBTABLES
 	help
+	  This option enables the old bridge-specific "ebt_ulog" implementation
+	  which has been obsoleted by the new "nfnetlink_log" code (see
+	  CONFIG_NETFILTER_NETLINK_LOG).
+
 	  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
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 662975b..9f6e019 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -3,13 +3,16 @@
  *
  *	Authors:
  *	Bart De Schuymer <bdschuym@pandora.be>
+ *	Harald Welte <laforge@netfilter.org>
  *
  *  April, 2002
  *
  */
 
+#include <linux/in.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_log.h>
+#include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/if_arp.h>
@@ -55,27 +58,30 @@
 }
 
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
-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)
+static void
+ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *loginfo,
+   const char *prefix)
 {
-	struct ebt_log_info *info = (struct ebt_log_info *)data;
-	char level_string[4] = "< >";
+	unsigned int bitmask;
 
-	level_string[1] = '0' + info->loglevel;
 	spin_lock_bh(&ebt_log_lock);
-	printk(level_string);
-	printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "",
-	   out ? out->name : "");
+	printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
+	       prefix, in ? in->name : "", out ? out->name : "");
 
-	printk("MAC source = ");
 	print_MAC(eth_hdr(skb)->h_source);
 	printk("MAC dest = ");
 	print_MAC(eth_hdr(skb)->h_dest);
 
 	printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
 
-	if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
+	if (loginfo->type == NF_LOG_TYPE_LOG)
+		bitmask = loginfo->u.log.logflags;
+	else
+		bitmask = NF_LOG_MASK;
+
+	if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
 	   htons(ETH_P_IP)){
 		struct iphdr _iph, *ih;
 
@@ -84,10 +90,9 @@
 			printk(" INCOMPLETE IP header");
 			goto out;
 		}
-		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
-		   NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
-		printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
-		       ih->protocol);
+		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
+		       "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
+		       NIPQUAD(ih->daddr), ih->tos, ih->protocol);
 		if (ih->protocol == IPPROTO_TCP ||
 		    ih->protocol == IPPROTO_UDP) {
 			struct tcpudphdr _ports, *pptr;
@@ -104,7 +109,7 @@
 		goto out;
 	}
 
-	if ((info->bitmask & EBT_LOG_ARP) &&
+	if ((bitmask & EBT_LOG_ARP) &&
 	    ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
 	     (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
 		struct arphdr _arph, *ah;
@@ -144,6 +149,21 @@
 out:
 	printk("\n");
 	spin_unlock_bh(&ebt_log_lock);
+
+}
+
+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;
+	struct nf_loginfo li;
+
+	li.type = NF_LOG_TYPE_LOG;
+	li.u.log.level = info->loglevel;
+	li.u.log.logflags = info->bitmask;
+
+	nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
 }
 
 static struct ebt_watcher log =
@@ -154,13 +174,32 @@
 	.me		= THIS_MODULE,
 };
 
+static struct nf_logger ebt_log_logger = {
+	.name 		= "ebt_log",
+	.logfn		= &ebt_log_packet,
+	.me		= THIS_MODULE,
+};
+
 static int __init init(void)
 {
-	return ebt_register_watcher(&log);
+	int ret;
+
+	ret = ebt_register_watcher(&log);
+	if (ret < 0)
+		return ret;
+	if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
+		printk(KERN_WARNING "ebt_log: not logging via system console "
+		       "since somebody else already registered for PF_INET\n");
+		/* we cannot make module load fail here, since otherwise 
+		 * ebtables userspace would abort */
+	}
+
+	return 0;
 }
 
 static void __exit fini(void)
 {
+	nf_log_unregister_logger(&ebt_log_logger);
 	ebt_unregister_watcher(&log);
 }
 
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index aae26ae..ce617b3 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -3,6 +3,7 @@
  *
  *	Authors:
  *	Bart De Schuymer <bdschuym@pandora.be>
+ *	Harald Welte <laforge@netfilter.org>
  *
  *  November, 2004
  *
@@ -115,14 +116,13 @@
 	return skb;
 }
 
-static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+   const struct ebt_ulog_info *uloginfo, const char *prefix)
 {
 	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;
@@ -216,6 +216,39 @@
 	goto unlock;
 }
 
+/* this function is registered with the netfilter core */
+static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *li,
+   const char *prefix)
+{
+	struct ebt_ulog_info loginfo;
+
+	if (!li || li->type != NF_LOG_TYPE_ULOG) {
+		loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
+		loginfo.cprange = 0;
+		loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
+		loginfo.prefix[0] = '\0';
+	} else {
+		loginfo.nlgroup = li->u.ulog.group;
+		loginfo.cprange = li->u.ulog.copy_len;
+		loginfo.qthreshold = li->u.ulog.qthreshold;
+		strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
+	}
+
+	ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
+}
+
+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)
+{
+	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+
+	ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
+}
+
+
 static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
@@ -240,6 +273,12 @@
 	.me		= THIS_MODULE,
 };
 
+static struct nf_logger ebt_ulog_logger = {
+	.name		= EBT_ULOG_WATCHER,
+	.logfn		= &ebt_log_packet,
+	.me		= THIS_MODULE,
+};
+
 static int __init init(void)
 {
 	int i, ret = 0;
@@ -265,6 +304,13 @@
 	else if ((ret = ebt_register_watcher(&ulog)))
 		sock_release(ebtulognl->sk_socket);
 
+	if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
+		printk(KERN_WARNING "ebt_ulog: not logging via ulog "
+		       "since somebody else already registered for PF_BRIDGE\n");
+		/* we cannot make module load fail here, since otherwise
+		 * ebtables userspace would abort */
+	}
+
 	return ret;
 }
 
@@ -273,6 +319,7 @@
 	ebt_ulog_buff_t *ub;
 	int i;
 
+	nf_log_unregister_logger(&ebt_ulog_logger);
 	ebt_unregister_watcher(&ulog);
 	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
 		ub = &ulog_buffers[i];
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 1bcfef5..f8d322e 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/poll.h>
 #include <linux/highmem.h>
+#include <linux/spinlock.h>
 
 #include <net/protocol.h>
 #include <linux/skbuff.h>
@@ -200,6 +201,41 @@
 }
 
 /**
+ *	skb_kill_datagram - Free a datagram skbuff forcibly
+ *	@sk: socket
+ *	@skb: datagram skbuff
+ *	@flags: MSG_ flags
+ *
+ *	This function frees a datagram skbuff that was received by
+ *	skb_recv_datagram.  The flags argument must match the one
+ *	used for skb_recv_datagram.
+ *
+ *	If the MSG_PEEK flag is set, and the packet is still on the
+ *	receive queue of the socket, it will be taken off the queue
+ *	before it is freed.
+ *
+ *	This function currently only disables BH when acquiring the
+ *	sk_receive_queue lock.  Therefore it must not be used in a
+ *	context where that lock is acquired in an IRQ context.
+ */
+
+void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
+{
+	if (flags & MSG_PEEK) {
+		spin_lock_bh(&sk->sk_receive_queue.lock);
+		if (skb == skb_peek(&sk->sk_receive_queue)) {
+			__skb_unlink(skb, &sk->sk_receive_queue);
+			atomic_dec(&skb->users);
+		}
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
+	}
+
+	kfree_skb(skb);
+}
+
+EXPORT_SYMBOL(skb_kill_datagram);
+
+/**
  *	skb_copy_datagram_iovec - Copy a datagram to an iovec.
  *	@skb: buffer to copy
  *	@offset: offset in the buffer to start copying from
diff --git a/net/core/dev.c b/net/core/dev.c
index a5efc9a..5081287 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -626,7 +626,7 @@
  *	Network device names need to be valid file names to
  *	to allow sysfs to work
  */
-static int dev_valid_name(const char *name)
+int dev_valid_name(const char *name)
 {
 	return !(*name == '\0' 
 		 || !strcmp(name, ".")
@@ -3270,13 +3270,13 @@
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
 EXPORT_SYMBOL(__skb_linearize);
+EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
 EXPORT_SYMBOL(dev_close);
 EXPORT_SYMBOL(dev_get_by_flags);
 EXPORT_SYMBOL(dev_get_by_index);
 EXPORT_SYMBOL(dev_get_by_name);
-EXPORT_SYMBOL(dev_ioctl);
 EXPORT_SYMBOL(dev_open);
 EXPORT_SYMBOL(dev_queue_xmit);
 EXPORT_SYMBOL(dev_remove_pack);
diff --git a/net/core/filter.c b/net/core/filter.c
index 3a10e0b..8964d34 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -13,6 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  *
  * Andi Kleen - Fix a few bad bugs and races.
+ * Kris Katterjohn - Added many additional checks in sk_chk_filter()
  */
 
 #include <linux/module.h>
@@ -250,7 +251,7 @@
 			mem[fentry->k] = X;
 			continue;
 		default:
-			/* Invalid instruction counts as RET */
+			WARN_ON(1);
 			return 0;
 		}
 
@@ -283,8 +284,8 @@
  *
  * Check the user's filter code. If we let some ugly
  * filter code slip through kaboom! The filter must contain
- * no references or jumps that are out of range, no illegal instructions
- * and no backward jumps. It must end with a RET instruction
+ * no references or jumps that are out of range, no illegal
+ * instructions, and must end with a RET instruction.
  *
  * Returns 0 if the rule set is legal or a negative errno code if not.
  */
@@ -300,38 +301,85 @@
 	for (pc = 0; pc < flen; pc++) {
 		/* all jumps are forward as they are not signed */
 		ftest = &filter[pc];
-		if (BPF_CLASS(ftest->code) == BPF_JMP) {
-			/* but they mustn't jump off the end */
-			if (BPF_OP(ftest->code) == BPF_JA) {
-				/*
-				 * Note, the large ftest->k might cause loops.
-				 * Compare this with conditional jumps below,
-				 * where offsets are limited. --ANK (981016)
-				 */
-				if (ftest->k >= (unsigned)(flen-pc-1))
-					return -EINVAL;
-			} else {
-				/* for conditionals both must be safe */
- 				if (pc + ftest->jt +1 >= flen ||
-				    pc + ftest->jf +1 >= flen)
-					return -EINVAL;
-			}
-		}
 
-		/* check for division by zero   -Kris Katterjohn 2005-10-30 */
-		if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0)
-			return -EINVAL;
+		/* Only allow valid instructions */
+		switch (ftest->code) {
+		case BPF_ALU|BPF_ADD|BPF_K:
+		case BPF_ALU|BPF_ADD|BPF_X:
+		case BPF_ALU|BPF_SUB|BPF_K:
+		case BPF_ALU|BPF_SUB|BPF_X:
+		case BPF_ALU|BPF_MUL|BPF_K:
+		case BPF_ALU|BPF_MUL|BPF_X:
+		case BPF_ALU|BPF_DIV|BPF_X:
+		case BPF_ALU|BPF_AND|BPF_K:
+		case BPF_ALU|BPF_AND|BPF_X:
+		case BPF_ALU|BPF_OR|BPF_K:
+		case BPF_ALU|BPF_OR|BPF_X:
+		case BPF_ALU|BPF_LSH|BPF_K:
+		case BPF_ALU|BPF_LSH|BPF_X:
+		case BPF_ALU|BPF_RSH|BPF_K:
+		case BPF_ALU|BPF_RSH|BPF_X:
+		case BPF_ALU|BPF_NEG:
+		case BPF_LD|BPF_W|BPF_ABS:
+		case BPF_LD|BPF_H|BPF_ABS:
+		case BPF_LD|BPF_B|BPF_ABS:
+		case BPF_LD|BPF_W|BPF_LEN:
+		case BPF_LD|BPF_W|BPF_IND:
+		case BPF_LD|BPF_H|BPF_IND:
+		case BPF_LD|BPF_B|BPF_IND:
+		case BPF_LD|BPF_IMM:
+		case BPF_LDX|BPF_W|BPF_LEN:
+		case BPF_LDX|BPF_B|BPF_MSH:
+		case BPF_LDX|BPF_IMM:
+		case BPF_MISC|BPF_TAX:
+		case BPF_MISC|BPF_TXA:
+		case BPF_RET|BPF_K:
+		case BPF_RET|BPF_A:
+			break;
 
-		/* check that memory operations use valid addresses. */
-		if (ftest->k >= BPF_MEMWORDS) {
-			/* but it might not be a memory operation... */
-			switch (ftest->code) {
-			case BPF_ST:	
-			case BPF_STX:	
-			case BPF_LD|BPF_MEM:	
-			case BPF_LDX|BPF_MEM:	
+		/* Some instructions need special checks */
+
+		case BPF_ALU|BPF_DIV|BPF_K:
+			/* check for division by zero */
+			if (ftest->k == 0)
 				return -EINVAL;
-			}
+			break;
+
+		case BPF_LD|BPF_MEM:
+		case BPF_LDX|BPF_MEM:
+		case BPF_ST:
+		case BPF_STX:
+			/* check for invalid memory addresses */
+			if (ftest->k >= BPF_MEMWORDS)
+				return -EINVAL;
+			break;
+
+		case BPF_JMP|BPF_JA:
+			/*
+			 * Note, the large ftest->k might cause loops.
+			 * Compare this with conditional jumps below,
+			 * where offsets are limited. --ANK (981016)
+			 */
+			if (ftest->k >= (unsigned)(flen-pc-1))
+				return -EINVAL;
+			break;
+
+		case BPF_JMP|BPF_JEQ|BPF_K:
+		case BPF_JMP|BPF_JEQ|BPF_X:
+		case BPF_JMP|BPF_JGE|BPF_K:
+		case BPF_JMP|BPF_JGE|BPF_X:
+		case BPF_JMP|BPF_JGT|BPF_K:
+		case BPF_JMP|BPF_JGT|BPF_X:
+		case BPF_JMP|BPF_JSET|BPF_K:
+		case BPF_JMP|BPF_JSET|BPF_X:
+			/* for conditionals both must be safe */
+ 			if (pc + ftest->jt + 1 >= flen ||
+			    pc + ftest->jf + 1 >= flen)
+				return -EINVAL;
+			break;
+
+		default:
+			return -EINVAL;
 		}
 	}
 
diff --git a/net/core/flow.c b/net/core/flow.c
index 7e95b39..c4f2538 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -23,6 +23,7 @@
 #include <net/flow.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
+#include <linux/security.h>
 
 struct flow_cache_entry {
 	struct flow_cache_entry	*next;
@@ -30,6 +31,7 @@
 	u8			dir;
 	struct flowi		key;
 	u32			genid;
+	u32			sk_sid;
 	void			*object;
 	atomic_t		*object_ref;
 };
@@ -162,7 +164,7 @@
 	return 0;
 }
 
-void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
+void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
 			flow_resolve_t resolver)
 {
 	struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@
 	for (fle = *head; fle; fle = fle->next) {
 		if (fle->family == family &&
 		    fle->dir == dir &&
+		    fle->sk_sid == sk_sid &&
 		    flow_key_compare(key, &fle->key) == 0) {
 			if (fle->genid == atomic_read(&flow_cache_genid)) {
 				void *ret = fle->object;
@@ -210,6 +213,7 @@
 			*head = fle;
 			fle->family = family;
 			fle->dir = dir;
+			fle->sk_sid = sk_sid;
 			memcpy(&fle->key, key, sizeof(*key));
 			fle->object = NULL;
 			flow_count(cpu)++;
@@ -221,7 +225,7 @@
 		void *obj;
 		atomic_t *obj_ref;
 
-		resolver(key, family, dir, &obj, &obj_ref);
+		resolver(key, sk_sid, family, dir, &obj, &obj_ref);
 
 		if (fle) {
 			fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 49424a4..281a632 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -13,6 +13,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/string.h>
+#include <linux/if_arp.h>
 #include <linux/inetdevice.h>
 #include <linux/inet.h>
 #include <linux/interrupt.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 7fc3e9e..06cad2d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -487,9 +487,9 @@
 
 /* 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;
+static int pg_delay_d;
+static int pg_clone_skb_d;
+static int debug;
 
 static DECLARE_MUTEX(pktgen_sem);
 static struct pktgen_thread *pktgen_threads = NULL;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 83fee37..070f91c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -135,17 +135,13 @@
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 			    int fclone)
 {
+	struct skb_shared_info *shinfo;
 	struct sk_buff *skb;
 	u8 *data;
 
 	/* Get the HEAD */
-	if (fclone)
-		skb = kmem_cache_alloc(skbuff_fclone_cache,
-				       gfp_mask & ~__GFP_DMA);
-	else
-		skb = kmem_cache_alloc(skbuff_head_cache,
-				       gfp_mask & ~__GFP_DMA);
-
+	skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
+				gfp_mask & ~__GFP_DMA);
 	if (!skb)
 		goto out;
 
@@ -162,6 +158,16 @@
 	skb->data = data;
 	skb->tail = data;
 	skb->end  = data + size;
+	/* make sure we initialize shinfo sequentially */
+	shinfo = skb_shinfo(skb);
+	atomic_set(&shinfo->dataref, 1);
+	shinfo->nr_frags  = 0;
+	shinfo->tso_size = 0;
+	shinfo->tso_segs = 0;
+	shinfo->ufo_size = 0;
+	shinfo->ip6_frag_id = 0;
+	shinfo->frag_list = NULL;
+
 	if (fclone) {
 		struct sk_buff *child = skb + 1;
 		atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -171,13 +177,6 @@
 
 		child->fclone = SKB_FCLONE_UNAVAILABLE;
 	}
-	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;
-	skb_shinfo(skb)->ufo_size = 0;
-	skb_shinfo(skb)->ip6_frag_id = 0;
 out:
 	return skb;
 nodata:
diff --git a/net/core/sock.c b/net/core/sock.c
index 13cc3be..6465b0e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1488,7 +1488,7 @@
 			}
 		}
 
-		if (prot->twsk_obj_size) {
+		if (prot->twsk_prot != NULL) {
 			static const char mask[] = "tw_sock_%s";
 
 			timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
@@ -1497,11 +1497,12 @@
 				goto out_free_request_sock_slab;
 
 			sprintf(timewait_sock_slab_name, mask, prot->name);
-			prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name,
-							    prot->twsk_obj_size,
-							    0, SLAB_HWCACHE_ALIGN,
-							    NULL, NULL);
-			if (prot->twsk_slab == NULL)
+			prot->twsk_prot->twsk_slab =
+				kmem_cache_create(timewait_sock_slab_name,
+						  prot->twsk_prot->twsk_obj_size,
+						  0, SLAB_HWCACHE_ALIGN,
+						  NULL, NULL);
+			if (prot->twsk_prot->twsk_slab == NULL)
 				goto out_free_timewait_sock_slab_name;
 		}
 	}
@@ -1548,12 +1549,12 @@
 		prot->rsk_prot->slab = NULL;
 	}
 
-	if (prot->twsk_slab != NULL) {
-		const char *name = kmem_cache_name(prot->twsk_slab);
+	if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {
+		const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab);
 
-		kmem_cache_destroy(prot->twsk_slab);
+		kmem_cache_destroy(prot->twsk_prot->twsk_slab);
 		kfree(name);
-		prot->twsk_slab = NULL;
+		prot->twsk_prot->twsk_slab = NULL;
 	}
 }
 
diff --git a/net/core/stream.c b/net/core/stream.c
index 15bfd03..35e2525 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -55,8 +55,9 @@
 	int done;
 
 	do {
-		if (sk->sk_err)
-			return sock_error(sk);
+		int err = sock_error(sk);
+		if (err)
+			return err;
 		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
 			return -EPIPE;
 		if (!*timeo_p)
@@ -67,6 +68,7 @@
 		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 		sk->sk_write_pending++;
 		done = sk_wait_event(sk, timeo_p,
+				     !sk->sk_err &&
 				     !((1 << sk->sk_state) & 
 				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
 		finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@
 
 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 		sk->sk_write_pending++;
-		sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+		sk_wait_event(sk, &current_timeo, !sk->sk_err && 
+						  !(sk->sk_shutdown & SEND_SHUTDOWN) &&
+						  sk_stream_memory_free(sk) &&
 						  vm_wait);
 		sk->sk_write_pending--;
 
diff --git a/net/core/utils.c b/net/core/utils.c
index 7b5970f..587eb77 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -175,7 +175,7 @@
 		if (*str != '\0')
 		{
 			val = 0;
-			while (*str != '\0' && *str != '.')
+			while (*str != '\0' && *str != '.' && *str != '\n')
 			{
 				val *= 10;
 				val += *str - '0';
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 344a8da..87b27ff 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,3 +1,7 @@
+obj-$(CONFIG_IPV6) += dccp_ipv6.o
+
+dccp_ipv6-y := ipv6.o
+
 obj-$(CONFIG_IP_DCCP) += dccp.o
 
 dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index c9a62cc..ce9cb77 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -55,8 +55,8 @@
 	from = av->dccpav_buf + av->dccpav_buf_head;
 
 	/* Check if buf_head wraps */
-	if (av->dccpav_buf_head + len > av->dccpav_vec_len) {
-		const u32 tailsize = (av->dccpav_vec_len - av->dccpav_buf_head);
+	if ((int)av->dccpav_buf_head + len > av->dccpav_vec_len) {
+		const u32 tailsize = av->dccpav_vec_len - av->dccpav_buf_head;
 
 		memcpy(to, from, tailsize);
 		to   += tailsize;
@@ -93,8 +93,14 @@
 struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len,
 				      const gfp_t priority)
 {
-	struct dccp_ackvec *av = kmalloc(sizeof(*av) + len, priority);
+	struct dccp_ackvec *av;
 
+	BUG_ON(len == 0);
+
+	if (len > DCCP_MAX_ACKVEC_LEN)
+		return NULL;
+
+	av = kmalloc(sizeof(*av) + len, priority);
 	if (av != NULL) {
 		av->dccpav_buf_len	= len;
 		av->dccpav_buf_head	=
@@ -117,13 +123,13 @@
 }
 
 static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
-				   const unsigned int index)
+				   const u8 index)
 {
 	return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
 }
 
 static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
-				 const unsigned int index)
+				 const u8 index)
 {
 	return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
 }
@@ -135,7 +141,7 @@
  */
 static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
 						 const unsigned int packets,
-						  const unsigned char state)
+						 const unsigned char state)
 {
 	unsigned int gap;
 	signed long new_head;
@@ -223,7 +229,7 @@
 		 *	could reduce the complexity of this scan.)
 		 */
 		u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
-		unsigned int index = av->dccpav_buf_head;
+		u8 index = av->dccpav_buf_head;
 
 		while (1) {
 			const u8 len = dccp_ackvec_len(av, index);
@@ -291,7 +297,7 @@
 }
 #endif
 
-static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av)
+static void dccp_ackvec_throw_away_ack_record(struct dccp_ackvec *av)
 {
 	/*
 	 * As we're keeping track of the ack vector size (dccpav_vec_len) and
@@ -301,9 +307,10 @@
 	 * draft-ietf-dccp-spec-11.txt Appendix A. -acme
 	 */
 #if 0
-	av->dccpav_buf_tail = av->dccpav_ack_ptr + 1;
-	if (av->dccpav_buf_tail >= av->dccpav_vec_len)
-		av->dccpav_buf_tail -= av->dccpav_vec_len;
+	u32 new_buf_tail = av->dccpav_ack_ptr + 1;
+	if (new_buf_tail >= av->dccpav_vec_len)
+		new_buf_tail -= av->dccpav_vec_len;
+	av->dccpav_buf_tail = new_buf_tail;
 #endif
 	av->dccpav_vec_len -= av->dccpav_sent_len;
 }
@@ -326,7 +333,7 @@
 			      debug_prefix, 1,
 			      (unsigned long long)av->dccpav_ack_seqno,
 			      (unsigned long long)av->dccpav_ack_ackno);
-		dccp_ackvec_trow_away_ack_record(av);
+		dccp_ackvec_throw_away_ack_record(av);
 		av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1;
 	}
 }
@@ -389,7 +396,7 @@
 					      av->dccpav_ack_seqno,
 					      (unsigned long long)
 					      av->dccpav_ack_ackno);
-				dccp_ackvec_trow_away_ack_record(av);
+				dccp_ackvec_throw_away_ack_record(av);
 			}
 			/*
 			 * If dccpav_ack_seqno was not received, no problem
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index d0fd6c6..f7dfb5f 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -54,16 +54,16 @@
  * @dccpav_buf - circular buffer of acknowledgeable packets
  */
 struct dccp_ackvec {
-	unsigned int	dccpav_buf_head;
-	unsigned int	dccpav_buf_tail;
 	u64		dccpav_buf_ackno;
 	u64		dccpav_ack_seqno;
 	u64		dccpav_ack_ackno;
-	unsigned int	dccpav_ack_ptr;
-	unsigned int	dccpav_sent_len;
-	unsigned int	dccpav_vec_len;
-	unsigned int	dccpav_buf_len;
 	struct timeval	dccpav_time;
+	u8		dccpav_buf_head;
+	u8		dccpav_buf_tail;
+	u8		dccpav_ack_ptr;
+	u8		dccpav_sent_len;
+	u8		dccpav_vec_len;
+	u8		dccpav_buf_len;
 	u8		dccpav_buf_nonce;
 	u8		dccpav_ack_nonce;
 	u8		dccpav_buf[0];
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index c37eeea..de681c6 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -21,6 +21,8 @@
 
 #define CCID_MAX 255
 
+struct tcp_info;
+
 struct ccid {
 	unsigned char	ccid_id;
 	const char	*ccid_name;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index f97b85d..93f26dd 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -59,7 +59,7 @@
 
 #define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
 
-extern struct proto dccp_v4_prot;
+extern struct proto dccp_prot;
 
 /* is seq1 < seq2 ? */
 static inline int before48(const u64 seq1, const u64 seq2)
@@ -228,6 +228,9 @@
 extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 				const struct dccp_hdr *dh, const unsigned len);
 
+extern int dccp_v4_init_sock(struct sock *sk);
+extern int dccp_v4_destroy_sock(struct sock *sk);
+
 extern void		dccp_close(struct sock *sk, long timeout);
 extern struct sk_buff	*dccp_make_response(struct sock *sk,
 					    struct dst_entry *dst,
@@ -238,6 +241,7 @@
 
 extern int	   dccp_connect(struct sock *sk);
 extern int	   dccp_disconnect(struct sock *sk, int flags);
+extern void	   dccp_unhash(struct sock *sk);
 extern int	   dccp_getsockopt(struct sock *sk, int level, int optname,
 				   char __user *optval, int __user *optlen);
 extern int	   dccp_setsockopt(struct sock *sk, int level, int optname,
@@ -249,6 +253,13 @@
 				struct msghdr *msg, size_t len, int nonblock,
 				int flags, int *addr_len);
 extern void	   dccp_shutdown(struct sock *sk, int how);
+extern int	   inet_dccp_listen(struct socket *sock, int backlog);
+extern unsigned int dccp_poll(struct file *file, struct socket *sock,
+			     poll_table *wait);
+extern void	   dccp_v4_send_check(struct sock *sk, int len,
+				      struct sk_buff *skb);
+extern int	   dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
+				   int addr_len);
 
 extern int	   dccp_v4_checksum(const struct sk_buff *skb,
 				    const u32 saddr, const u32 daddr);
@@ -256,6 +267,17 @@
 extern int	   dccp_v4_send_reset(struct sock *sk,
 				      enum dccp_reset_codes code);
 extern void	   dccp_send_close(struct sock *sk, const int active);
+extern int	   dccp_invalid_packet(struct sk_buff *skb);
+
+static inline int dccp_bad_service_code(const struct sock *sk,
+					const __u32 service)
+{
+	const struct dccp_sock *dp = dccp_sk(sk);
+
+	if (dp->dccps_service == service)
+		return 0;
+	return !dccp_list_has_service(dp->dccps_service_list, service);
+}
 
 struct dccp_skb_cb {
 	__u8  dccpd_type:4;
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index f675d8e6..3f78c00 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -28,7 +28,7 @@
 	info->tcpi_retransmits	= icsk->icsk_retransmits;
 	info->tcpi_probes	= icsk->icsk_probes_out;
 	info->tcpi_backoff	= icsk->icsk_backoff;
-	info->tcpi_pmtu		= dp->dccps_pmtu_cookie;
+	info->tcpi_pmtu		= icsk->icsk_pmtu_cookie;
 
 	if (dp->dccps_options.dccpo_send_ack_vector)
 		info->tcpi_options |= TCPI_OPT_SACK;
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 3454d59..b6cba72 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -151,29 +151,12 @@
 	return 0;
 }
 
-int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
-			 const struct dccp_hdr *dh, const unsigned len)
+static inline int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+					 const struct dccp_hdr *dh,
+					 const unsigned len)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
-	if (dccp_check_seqno(sk, skb))
-		goto discard;
-
-	if (dccp_parse_options(sk, skb))
-		goto discard;
-
-	if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
-		dccp_event_ack_recv(sk, skb);
-
-	if (dp->dccps_options.dccpo_send_ack_vector &&
-	    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-			    DCCP_SKB_CB(skb)->dccpd_seq,
-			    DCCP_ACKVEC_STATE_RECEIVED))
-		goto discard;
-
-	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
 	switch (dccp_hdr(skb)->dccph_type) {
 	case DCCP_PKT_DATAACK:
 	case DCCP_PKT_DATA:
@@ -250,6 +233,37 @@
 	return 0;
 }
 
+int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+			 const struct dccp_hdr *dh, const unsigned len)
+{
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	if (dccp_check_seqno(sk, skb))
+		goto discard;
+
+	if (dccp_parse_options(sk, skb))
+		goto discard;
+
+	if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+		dccp_event_ack_recv(sk, skb);
+
+	if (dp->dccps_options.dccpo_send_ack_vector &&
+	    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+			    DCCP_SKB_CB(skb)->dccpd_seq,
+			    DCCP_ACKVEC_STATE_RECEIVED))
+		goto discard;
+
+	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+
+	return __dccp_rcv_established(sk, skb, dh, len);
+discard:
+	__kfree_skb(skb);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(dccp_rcv_established);
+
 static int dccp_rcv_request_sent_state_process(struct sock *sk,
 					       struct sk_buff *skb,
 					       const struct dccp_hdr *dh,
@@ -286,6 +300,12 @@
 			goto out_invalid_packet;
 		}
 
+                if (dp->dccps_options.dccpo_send_ack_vector &&
+                    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+                                    DCCP_SKB_CB(skb)->dccpd_seq,
+                                    DCCP_ACKVEC_STATE_RECEIVED))
+                        goto out_invalid_packet; /* FIXME: change error code */
+
 		dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
 		dccp_update_gsr(sk, dp->dccps_isr);
 		/*
@@ -309,7 +329,7 @@
 			goto out_invalid_packet;
 		}
 
-		dccp_sync_mss(sk, dp->dccps_pmtu_cookie);
+		dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 
 		/*
 		 *    Step 10: Process REQUEST state (second part)
@@ -329,7 +349,7 @@
 		dccp_set_state(sk, DCCP_PARTOPEN);
 
 		/* Make sure socket is routed, for correct metrics. */
-		inet_sk_rebuild_header(sk);
+		icsk->icsk_af_ops->rebuild_header(sk);
 
 		if (!sock_flag(sk, SOCK_DEAD)) {
 			sk->sk_state_change(sk);
@@ -398,9 +418,9 @@
 
 		if (dh->dccph_type == DCCP_PKT_DATAACK ||
 		    dh->dccph_type == DCCP_PKT_DATA) {
-			dccp_rcv_established(sk, skb, dh, len);
+			__dccp_rcv_established(sk, skb, dh, len);
 			queued = 1; /* packet was queued
-				       (by dccp_rcv_established) */
+				       (by __dccp_rcv_established) */
 		}
 		break;
 	}
@@ -444,7 +464,8 @@
 	 */
 	if (sk->sk_state == DCCP_LISTEN) {
 		if (dh->dccph_type == DCCP_PKT_REQUEST) {
-			if (dccp_v4_conn_request(sk, skb) < 0)
+			if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
+								    skb) < 0)
 				return 1;
 
 			/* FIXME: do congestion control initialization */
@@ -471,14 +492,14 @@
 		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
 			dccp_event_ack_recv(sk, skb);
 
-		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
  		if (dp->dccps_options.dccpo_send_ack_vector &&
 		    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
  				    DCCP_SKB_CB(skb)->dccpd_seq,
  				    DCCP_ACKVEC_STATE_RECEIVED))
  			goto discard;
+
+		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
 	}
 
 	/*
@@ -566,3 +587,5 @@
 	}
 	return 0;
 }
+
+EXPORT_SYMBOL_GPL(dccp_rcv_state_process);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 656e13e..3f24467 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -19,7 +19,9 @@
 
 #include <net/icmp.h>
 #include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
+#include <net/timewait_sock.h>
 #include <net/tcp_states.h>
 #include <net/xfrm.h>
 
@@ -37,7 +39,8 @@
 
 static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
 {
-	return inet_csk_get_port(&dccp_hashinfo, sk, snum);
+	return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+				 inet_csk_bind_conflict);
 }
 
 static void dccp_v4_hash(struct sock *sk)
@@ -45,171 +48,14 @@
 	inet_hash(&dccp_hashinfo, sk);
 }
 
-static void dccp_v4_unhash(struct sock *sk)
+void dccp_unhash(struct sock *sk)
 {
 	inet_unhash(&dccp_hashinfo, sk);
 }
 
-/* called with local bh disabled */
-static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
-				      struct inet_timewait_sock **twp)
-{
-	struct inet_sock *inet = inet_sk(sk);
-	const u32 daddr = inet->rcv_saddr;
-	const u32 saddr = inet->daddr;
-	const int dif = sk->sk_bound_dev_if;
-	INET_ADDR_COOKIE(acookie, saddr, daddr)
-	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&dccp_hashinfo, hash);
-	const struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
+EXPORT_SYMBOL_GPL(dccp_unhash);
 
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
-
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + dccp_hashinfo.ehash_size)->chain) {
-		tw = inet_twsk(sk2);
-
-		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-	/* Must record num and sport now. Otherwise we will see
-	 * in hash table socket with a funny identity. */
-	inet->num = lport;
-	inet->sport = htons(lport);
-	sk->sk_hash = hash;
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp != NULL) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw != NULL) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &dccp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
-	}
-
-	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static int dccp_v4_hash_connect(struct sock *sk)
-{
-	const unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (snum == 0) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
- 		int remaining = (high - low) + 1;
- 		int rover = net_random() % (high - low) + low;
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
- 		do {
- 			head = &dccp_hashinfo.bhash[inet_bhashfn(rover,
-						    dccp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == rover) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__dccp_v4_check_established(sk,
-									 rover,
-									 &tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(dccp_hashinfo.bind_bucket_cachep,
-						     head, rover);
- 			if (tb == NULL) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 			if (++rover > high)
- 				rover = low;
- 		} while (--remaining > 0);
-
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
- 		/* All locks still held and bhs disabled */
- 		inet_bind_hash(sk, tb, rover);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(rover);
- 			__inet_hash(&dccp_hashinfo, sk, 0);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw != NULL) {
- 			inet_twsk_deschedule(tw, &dccp_death_row);
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &dccp_hashinfo.bhash[inet_bhashfn(snum,
-						 dccp_hashinfo.bhash_size)];
- 	tb   = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-	if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
-		__inet_hash(&dccp_hashinfo, sk, 0);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __dccp_v4_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
-
-static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
-			   int addr_len)
+int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
@@ -259,9 +105,9 @@
 	inet->dport = usin->sin_port;
 	inet->daddr = daddr;
 
-	dp->dccps_ext_header_len = 0;
+	inet_csk(sk)->icsk_ext_hdr_len = 0;
 	if (inet->opt != NULL)
-		dp->dccps_ext_header_len = inet->opt->optlen;
+		inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
 	/*
 	 * Socket identity is still unknown (sport may be zero).
 	 * However we set state to DCCP_REQUESTING and not releasing socket
@@ -269,7 +115,7 @@
 	 * complete initialization after this.
 	 */
 	dccp_set_state(sk, DCCP_REQUESTING);
-	err = dccp_v4_hash_connect(sk);
+	err = inet_hash_connect(&dccp_death_row, sk);
 	if (err != 0)
 		goto failure;
 
@@ -287,16 +133,6 @@
 							    usin->sin_port);
 	dccp_update_gss(sk, dp->dccps_iss);
 
-	/*
-	 * SWL and AWL are initially adjusted so that they are not less than
-	 * the initial Sequence Numbers received and sent, respectively:
-	 *	SWL := max(GSR + 1 - floor(W/4), ISR),
-	 *	AWL := max(GSS - W' + 1, ISS).
-	 * These adjustments MUST be applied only at the beginning of the
-	 * connection.
-	 */
-	dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
-
 	inet->id = dp->dccps_iss ^ jiffies;
 
 	err = dccp_connect(sk);
@@ -316,6 +152,8 @@
 	goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_connect);
+
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
@@ -354,7 +192,7 @@
 	mtu = dst_mtu(dst);
 
 	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-	    dp->dccps_pmtu_cookie > mtu) {
+	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
 		dccp_sync_mss(sk, mtu);
 
 		/*
@@ -606,6 +444,17 @@
 	sock_put(sk);
 }
 
+/* This routine computes an IPv4 DCCP checksum. */
+void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	struct dccp_hdr *dh = dccp_hdr(skb);
+
+	dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
+}
+
+EXPORT_SYMBOL_GPL(dccp_v4_send_check);
+
 int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
 	struct sk_buff *skb;
@@ -641,16 +490,6 @@
 					   dccp_hdr(skb)->dccph_sport);
 }
 
-static inline int dccp_bad_service_code(const struct sock *sk,
-					const __u32 service)
-{
-	const struct dccp_sock *dp = dccp_sk(sk);
-
-	if (dp->dccps_service == service)
-		return 0;
-	return !dccp_list_has_service(dp->dccps_service_list, service);
-}
-
 int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq;
@@ -662,7 +501,6 @@
  	const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
 	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 	__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
-	struct dst_entry *dst = NULL;
 
 	/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
 	if (((struct rtable *)skb->dst)->rt_flags &
@@ -703,7 +541,6 @@
 	ireq = inet_rsk(req);
 	ireq->loc_addr = daddr;
 	ireq->rmt_addr = saddr;
-	/* FIXME: Merge Aristeu's option parsing code when ready */
 	req->rcv_wnd	= 100; /* Fake, option parsing will get the
 				  right value */
 	ireq->opt	= NULL;
@@ -721,23 +558,22 @@
 	dreq->dreq_iss	   = dccp_v4_init_sequence(sk, skb);
 	dreq->dreq_service = service;
 
-	if (dccp_v4_send_response(sk, req, dst))
+	if (dccp_v4_send_response(sk, req, NULL))
 		goto drop_and_free;
 
 	inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
 	return 0;
 
 drop_and_free:
-	/*
-	 * FIXME: should be reqsk_free after implementing req->rsk_ops
-	 */
-	__reqsk_free(req);
+	reqsk_free(req);
 drop:
 	DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
 	dcb->dccpd_reset_code = reset_code;
 	return -1;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
+
 /*
  * The three way handshake has completed - we got a valid ACK or DATAACK -
  * now create the new socket.
@@ -792,6 +628,8 @@
 	return NULL;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
+
 static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -1011,7 +849,9 @@
 	return 0;
 }
 
-static inline int dccp_invalid_packet(struct sk_buff *skb)
+EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
+
+int dccp_invalid_packet(struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh;
 
@@ -1065,29 +905,30 @@
 		return 1;
 	}
 
-	/* If the header checksum is incorrect, drop packet and return */
-	if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
-				    skb->nh.iph->daddr) < 0) {
-		LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
-					    "incorrect\n");
-		return 1;
-	}
-
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_invalid_packet);
+
 /* this is called when real data arrives */
 int dccp_v4_rcv(struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh;
 	struct sock *sk;
-	int rc;
 
 	/* Step 1: Check header basics: */
 
 	if (dccp_invalid_packet(skb))
 		goto discard_it;
 
+	/* If the header checksum is incorrect, drop packet and return */
+	if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
+				    skb->nh.iph->daddr) < 0) {
+		LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
+			       __FUNCTION__);
+		goto discard_it;
+	}
+
 	dh = dccp_hdr(skb);
 
 	DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
@@ -1143,28 +984,10 @@
                 goto do_time_wait;
 	}
 
-	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
-		dccp_pr_debug("xfrm4_policy_check failed\n");
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
-	}
 
-        if (sk_filter(sk, skb, 0)) {
-		dccp_pr_debug("sk_filter failed\n");
-                goto discard_and_relse;
-	}
-
-	skb->dev = NULL;
-
-	bh_lock_sock(sk);
-	rc = 0;
-	if (!sock_owned_by_user(sk))
-		rc = dccp_v4_do_rcv(sk, skb);
-	else
-		sk_add_backlog(sk, skb);
-	bh_unlock_sock(sk);
-
-	sock_put(sk);
-	return rc;
+	return sk_receive_skb(sk, skb);
 
 no_dccp_socket:
 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -1194,9 +1017,23 @@
 	goto no_dccp_socket;
 }
 
-static int dccp_v4_init_sock(struct sock *sk)
+struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+	.queue_xmit	= ip_queue_xmit,
+	.send_check	= dccp_v4_send_check,
+	.rebuild_header	= inet_sk_rebuild_header,
+	.conn_request	= dccp_v4_conn_request,
+	.syn_recv_sock	= dccp_v4_request_recv_sock,
+	.net_header_len	= sizeof(struct iphdr),
+	.setsockopt	= ip_setsockopt,
+	.getsockopt	= ip_getsockopt,
+	.addr2sockaddr	= inet_csk_addr2sockaddr,
+	.sockaddr_len	= sizeof(struct sockaddr_in),
+};
+
+int dccp_v4_init_sock(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	static int dccp_ctl_socket_init = 1;
 
 	dccp_options_init(&dp->dccps_options);
@@ -1236,9 +1073,11 @@
 		dccp_ctl_socket_init = 0;
 
 	dccp_init_xmit_timers(sk);
-	inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
+	icsk->icsk_rto = DCCP_TIMEOUT_INIT;
 	sk->sk_state = DCCP_CLOSED;
 	sk->sk_write_space = dccp_write_space;
+	icsk->icsk_af_ops = &dccp_ipv4_af_ops;
+	icsk->icsk_sync_mss = dccp_sync_mss;
 	dp->dccps_mss_cache = 536;
 	dp->dccps_role = DCCP_ROLE_UNDEFINED;
 	dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
@@ -1246,7 +1085,9 @@
 	return 0;
 }
 
-static int dccp_v4_destroy_sock(struct sock *sk)
+EXPORT_SYMBOL_GPL(dccp_v4_init_sock);
+
+int dccp_v4_destroy_sock(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
@@ -1279,6 +1120,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock);
+
 static void dccp_v4_reqsk_destructor(struct request_sock *req)
 {
 	kfree(inet_rsk(req)->opt);
@@ -1293,7 +1136,11 @@
 	.send_reset	= dccp_v4_ctl_send_reset,
 };
 
-struct proto dccp_v4_prot = {
+static struct timewait_sock_ops dccp_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct inet_timewait_sock),
+};
+
+struct proto dccp_prot = {
 	.name			= "DCCP",
 	.owner			= THIS_MODULE,
 	.close			= dccp_close,
@@ -1307,7 +1154,7 @@
 	.recvmsg		= dccp_recvmsg,
 	.backlog_rcv		= dccp_v4_do_rcv,
 	.hash			= dccp_v4_hash,
-	.unhash			= dccp_v4_unhash,
+	.unhash			= dccp_unhash,
 	.accept			= inet_csk_accept,
 	.get_port		= dccp_v4_get_port,
 	.shutdown		= dccp_shutdown,
@@ -1316,5 +1163,7 @@
 	.max_header		= MAX_DCCP_HEADER,
 	.obj_size		= sizeof(struct dccp_sock),
 	.rsk_prot		= &dccp_request_sock_ops,
-	.twsk_obj_size		= sizeof(struct inet_timewait_sock),
+	.twsk_prot		= &dccp_timewait_sock_ops,
 };
+
+EXPORT_SYMBOL_GPL(dccp_prot);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
new file mode 100644
index 0000000..c609dc7
--- /dev/null
+++ b/net/dccp/ipv6.c
@@ -0,0 +1,1261 @@
+/*
+ *	DCCP over IPv6
+ *	Linux INET6 implementation 
+ *
+ *	Based on net/dccp6/ipv6.c
+ *
+ *	Arnaldo Carvalho de Melo <acme@ghostprotocols.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.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/xfrm.h>
+
+#include <net/addrconf.h>
+#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
+#include <net/inet6_connection_sock.h>
+#include <net/inet6_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/transp_v6.h>
+#include <net/xfrm.h>
+
+#include "dccp.h"
+#include "ipv6.h"
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+				   struct request_sock *req);
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
+
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
+
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
+
+static int dccp_v6_get_port(struct sock *sk, unsigned short snum)
+{
+	return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+				 inet6_csk_bind_conflict);
+}
+
+static void dccp_v6_hash(struct sock *sk)
+{
+	if (sk->sk_state != DCCP_CLOSED) {
+		if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
+			dccp_prot.hash(sk);
+			return;
+		}
+		local_bh_disable();
+		__inet6_hash(&dccp_hashinfo, sk);
+		local_bh_enable();
+	}
+}
+
+static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len,
+				struct in6_addr *saddr, 
+				struct in6_addr *daddr, 
+				unsigned long base)
+{
+	return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base);
+}
+
+static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
+{
+	const struct dccp_hdr *dh = dccp_hdr(skb);
+
+	if (skb->protocol == htons(ETH_P_IPV6))
+		return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
+						    skb->nh.ipv6h->saddr.s6_addr32,
+						    dh->dccph_dport,
+						    dh->dccph_sport);
+	else
+		return secure_dccp_sequence_number(skb->nh.iph->daddr,
+						   skb->nh.iph->saddr,
+						   dh->dccph_dport,
+						   dh->dccph_sport);
+}
+
+static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
+			   int addr_len)
+{
+	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
+	struct inet_connection_sock *icsk = inet_csk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct dccp_sock *dp = dccp_sk(sk);
+	struct in6_addr *saddr = NULL, *final_p = NULL, final;
+	struct flowi fl;
+	struct dst_entry *dst;
+	int addr_type;
+	int err;
+
+	dp->dccps_role = DCCP_ROLE_CLIENT;
+
+	if (addr_len < SIN6_LEN_RFC2133) 
+		return -EINVAL;
+
+	if (usin->sin6_family != AF_INET6) 
+		return -EAFNOSUPPORT;
+
+	memset(&fl, 0, sizeof(fl));
+
+	if (np->sndflow) {
+		fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
+		IP6_ECN_flow_init(fl.fl6_flowlabel);
+		if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
+			struct ip6_flowlabel *flowlabel;
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+			if (flowlabel == NULL)
+				return -EINVAL;
+			ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
+			fl6_sock_release(flowlabel);
+		}
+	}
+
+	/*
+  	 *	connect() to INADDR_ANY means loopback (BSD'ism).
+  	 */
+  	
+  	if (ipv6_addr_any(&usin->sin6_addr))
+		usin->sin6_addr.s6_addr[15] = 0x1; 
+
+	addr_type = ipv6_addr_type(&usin->sin6_addr);
+
+	if(addr_type & IPV6_ADDR_MULTICAST)
+		return -ENETUNREACH;
+
+	if (addr_type & IPV6_ADDR_LINKLOCAL) {
+		if (addr_len >= sizeof(struct sockaddr_in6) &&
+		    usin->sin6_scope_id) {
+			/* If interface is set while binding, indices
+			 * must coincide.
+			 */
+			if (sk->sk_bound_dev_if &&
+			    sk->sk_bound_dev_if != usin->sin6_scope_id)
+				return -EINVAL;
+
+			sk->sk_bound_dev_if = usin->sin6_scope_id;
+		}
+
+		/* Connect to link-local address requires an interface */
+		if (!sk->sk_bound_dev_if)
+			return -EINVAL;
+	}
+
+	ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
+	np->flow_label = fl.fl6_flowlabel;
+
+	/*
+	 *	DCCP over IPv4
+	 */
+
+	if (addr_type == IPV6_ADDR_MAPPED) {
+		u32 exthdrlen = icsk->icsk_ext_hdr_len;
+		struct sockaddr_in sin;
+
+		SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
+
+		if (__ipv6_only_sock(sk))
+			return -ENETUNREACH;
+
+		sin.sin_family = AF_INET;
+		sin.sin_port = usin->sin6_port;
+		sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
+
+		icsk->icsk_af_ops = &dccp_ipv6_mapped;
+		sk->sk_backlog_rcv = dccp_v4_do_rcv;
+
+		err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
+
+		if (err) {
+			icsk->icsk_ext_hdr_len = exthdrlen;
+			icsk->icsk_af_ops = &dccp_ipv6_af_ops;
+			sk->sk_backlog_rcv = dccp_v6_do_rcv;
+			goto failure;
+		} else {
+			ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
+				      inet->saddr);
+			ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
+				      inet->rcv_saddr);
+		}
+
+		return err;
+	}
+
+	if (!ipv6_addr_any(&np->rcv_saddr))
+		saddr = &np->rcv_saddr;
+
+	fl.proto = IPPROTO_DCCP;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
+	fl.oif = sk->sk_bound_dev_if;
+	fl.fl_ip_dport = usin->sin6_port;
+	fl.fl_ip_sport = inet->sport;
+
+	if (np->opt && np->opt->srcrt) {
+		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		final_p = &final;
+	}
+
+	err = ip6_dst_lookup(sk, &dst, &fl);
+	if (err)
+		goto failure;
+	if (final_p)
+		ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+		goto failure;
+
+	if (saddr == NULL) {
+		saddr = &fl.fl6_src;
+		ipv6_addr_copy(&np->rcv_saddr, saddr);
+	}
+
+	/* set the source address */
+	ipv6_addr_copy(&np->saddr, saddr);
+	inet->rcv_saddr = LOOPBACK4_IPV6;
+
+	ip6_dst_store(sk, dst, NULL);
+
+	icsk->icsk_ext_hdr_len = 0;
+	if (np->opt)
+		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+					  np->opt->opt_nflen);
+
+	inet->dport = usin->sin6_port;
+
+	dccp_set_state(sk, DCCP_REQUESTING);
+	err = inet6_hash_connect(&dccp_death_row, sk);
+	if (err)
+		goto late_failure;
+	/* FIXME */
+#if 0
+	dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
+						       np->daddr.s6_addr32,
+						       inet->sport,
+						       inet->dport);
+#endif
+	err = dccp_connect(sk);
+	if (err)
+		goto late_failure;
+
+	return 0;
+
+late_failure:
+	dccp_set_state(sk, DCCP_CLOSED);
+	__sk_dst_reset(sk);
+failure:
+	inet->dport = 0;
+	sk->sk_route_caps = 0;
+	return err;
+}
+
+static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			int type, int code, int offset, __u32 info)
+{
+	struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
+	const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
+	struct ipv6_pinfo *np;
+	struct sock *sk;
+	int err;
+	__u64 seq;
+
+	sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+			  &hdr->saddr, dh->dccph_sport, skb->dev->ifindex);
+
+	if (sk == NULL) {
+		ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+		return;
+	}
+
+	if (sk->sk_state == DCCP_TIME_WAIT) {
+		inet_twsk_put((struct inet_timewait_sock *)sk);
+		return;
+	}
+
+	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk))
+		NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
+
+	if (sk->sk_state == DCCP_CLOSED)
+		goto out;
+
+	np = inet6_sk(sk);
+
+	if (type == ICMPV6_PKT_TOOBIG) {
+		struct dst_entry *dst = NULL;
+
+		if (sock_owned_by_user(sk))
+			goto out;
+		if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
+			goto out;
+
+		/* icmp should have updated the destination cache entry */
+		dst = __sk_dst_check(sk, np->dst_cookie);
+
+		if (dst == NULL) {
+			struct inet_sock *inet = inet_sk(sk);
+			struct flowi fl;
+
+			/* BUGGG_FUTURE: Again, it is not clear how
+			   to handle rthdr case. Ignore this complexity
+			   for now.
+			 */
+			memset(&fl, 0, sizeof(fl));
+			fl.proto = IPPROTO_DCCP;
+			ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+			ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+			fl.oif = sk->sk_bound_dev_if;
+			fl.fl_ip_dport = inet->dport;
+			fl.fl_ip_sport = inet->sport;
+
+			if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
+				sk->sk_err_soft = -err;
+				goto out;
+			}
+
+			if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+				sk->sk_err_soft = -err;
+				goto out;
+			}
+
+		} else
+			dst_hold(dst);
+
+		if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
+			dccp_sync_mss(sk, dst_mtu(dst));
+		} /* else let the usual retransmit timer handle it */
+		dst_release(dst);
+		goto out;
+	}
+
+	icmpv6_err_convert(type, code, &err);
+
+	seq = DCCP_SKB_CB(skb)->dccpd_seq;
+	/* Might be for an request_sock */
+	switch (sk->sk_state) {
+		struct request_sock *req, **prev;
+	case DCCP_LISTEN:
+		if (sock_owned_by_user(sk))
+			goto out;
+
+		req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
+					   &hdr->daddr, &hdr->saddr,
+					   inet6_iif(skb));
+		if (!req)
+			goto out;
+
+		/* ICMPs are not backlogged, hence we cannot get
+		 * an established socket here.
+		 */
+		BUG_TRAP(req->sk == NULL);
+
+		if (seq != dccp_rsk(req)->dreq_iss) {
+			NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
+			goto out;
+		}
+
+		inet_csk_reqsk_queue_drop(sk, req, prev);
+		goto out;
+
+	case DCCP_REQUESTING:
+	case DCCP_RESPOND:  /* Cannot happen.
+			       It can, it SYNs are crossed. --ANK */ 
+		if (!sock_owned_by_user(sk)) {
+			DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+			sk->sk_err = err;
+			/*
+			 * Wake people up to see the error
+			 * (see connect in sock.c)
+			 */
+			sk->sk_error_report(sk);
+
+			dccp_done(sk);
+		} else
+			sk->sk_err_soft = err;
+		goto out;
+	}
+
+	if (!sock_owned_by_user(sk) && np->recverr) {
+		sk->sk_err = err;
+		sk->sk_error_report(sk);
+	} else
+		sk->sk_err_soft = err;
+
+out:
+	bh_unlock_sock(sk);
+	sock_put(sk);
+}
+
+
+static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
+				 struct dst_entry *dst)
+{
+	struct inet6_request_sock *ireq6 = inet6_rsk(req);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sk_buff *skb;
+	struct ipv6_txoptions *opt = NULL;
+	struct in6_addr *final_p = NULL, final;
+	struct flowi fl;
+	int err = -1;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = IPPROTO_DCCP;
+	ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+	ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+	fl.fl6_flowlabel = 0;
+	fl.oif = ireq6->iif;
+	fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+	fl.fl_ip_sport = inet_sk(sk)->sport;
+
+	if (dst == NULL) {
+		opt = np->opt;
+		if (opt == NULL &&
+		    np->rxopt.bits.osrcrt == 2 &&
+		    ireq6->pktopts) {
+			struct sk_buff *pktopts = ireq6->pktopts;
+			struct inet6_skb_parm *rxopt = IP6CB(pktopts);
+			if (rxopt->srcrt)
+				opt = ipv6_invert_rthdr(sk,
+					(struct ipv6_rt_hdr *)(pktopts->nh.raw +
+							       rxopt->srcrt));
+		}
+
+		if (opt && opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+
+		err = ip6_dst_lookup(sk, &dst, &fl);
+		if (err)
+			goto done;
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+			goto done;
+	}
+
+	skb = dccp_make_response(sk, dst, req);
+	if (skb != NULL) {
+		struct dccp_hdr *dh = dccp_hdr(skb);
+		dh->dccph_checksum = dccp_v6_check(dh, skb->len,
+						   &ireq6->loc_addr,
+						   &ireq6->rmt_addr,
+						   csum_partial((char *)dh,
+								skb->len,
+								skb->csum));
+		ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+		err = ip6_xmit(sk, skb, &fl, opt, 0);
+		if (err == NET_XMIT_CN)
+			err = 0;
+	}
+
+done:
+        if (opt && opt != np->opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+	return err;
+}
+
+static void dccp_v6_reqsk_destructor(struct request_sock *req)
+{
+	if (inet6_rsk(req)->pktopts != NULL)
+		kfree_skb(inet6_rsk(req)->pktopts);
+}
+
+static struct request_sock_ops dccp6_request_sock_ops = {
+	.family		= AF_INET6,
+	.obj_size	= sizeof(struct dccp6_request_sock),
+	.rtx_syn_ack	= dccp_v6_send_response,
+	.send_ack	= dccp_v6_reqsk_send_ack,
+	.destructor	= dccp_v6_reqsk_destructor,
+	.send_reset	= dccp_v6_ctl_send_reset,
+};
+
+static struct timewait_sock_ops dccp6_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct dccp6_timewait_sock),
+};
+
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct dccp_hdr *dh = dccp_hdr(skb);
+
+	dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
+					     len, IPPROTO_DCCP, 
+					     csum_partial((char *)dh,
+							  dh->dccph_doff << 2,
+							  skb->csum));
+}
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
+{
+	struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 
+	const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
+				       sizeof(struct dccp_hdr_ext) +
+				       sizeof(struct dccp_hdr_reset);
+	struct sk_buff *skb;
+	struct flowi fl;
+	u64 seqno;
+
+	if (rxdh->dccph_type == DCCP_PKT_RESET)
+		return;
+
+	if (!ipv6_unicast_destination(rxskb))
+		return; 
+
+	/*
+	 * We need to grab some memory, and put together an RST,
+	 * and then put it into the queue to be sent.
+	 */
+
+	skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+			dccp_hdr_reset_len, GFP_ATOMIC);
+	if (skb == NULL) 
+	  	return;
+
+	skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+		    dccp_hdr_reset_len);
+
+	skb->h.raw = skb_push(skb, dccp_hdr_reset_len);
+	dh = dccp_hdr(skb);
+	memset(dh, 0, dccp_hdr_reset_len);
+
+	/* Swap the send and the receive. */
+	dh->dccph_type	= DCCP_PKT_RESET;
+	dh->dccph_sport	= rxdh->dccph_dport;
+	dh->dccph_dport	= rxdh->dccph_sport;
+	dh->dccph_doff	= dccp_hdr_reset_len / 4;
+	dh->dccph_x	= 1;
+	dccp_hdr_reset(skb)->dccph_reset_code =
+				DCCP_SKB_CB(rxskb)->dccpd_reset_code;
+
+	/* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+	seqno = 0;
+	if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+		dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
+
+	dccp_hdr_set_seq(dh, seqno);
+	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+			 DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+	dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
+					     sizeof(*dh), IPPROTO_DCCP,
+					     skb->csum);
+	fl.proto = IPPROTO_DCCP;
+	fl.oif = inet6_iif(rxskb);
+	fl.fl_ip_dport = dh->dccph_dport;
+	fl.fl_ip_sport = dh->dccph_sport;
+
+	/* sk = NULL, but it is safe for now. RST socket required. */
+	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, skb, &fl, NULL, 0);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
+			return;
+		}
+	}
+
+	kfree_skb(skb);
+}
+
+static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
+{
+	struct flowi fl;
+	struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
+	const int dccp_hdr_ack_len = sizeof(struct dccp_hdr) +
+				     sizeof(struct dccp_hdr_ext) +
+				     sizeof(struct dccp_hdr_ack_bits);
+	struct sk_buff *skb;
+
+	skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+			dccp_hdr_ack_len, GFP_ATOMIC);
+	if (skb == NULL)
+		return;
+
+	skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+			 dccp_hdr_ack_len);
+
+	skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
+	dh = dccp_hdr(skb);
+	memset(dh, 0, dccp_hdr_ack_len);
+
+	/* Build DCCP header and checksum it. */
+	dh->dccph_type	= DCCP_PKT_ACK;
+	dh->dccph_sport = rxdh->dccph_dport;
+	dh->dccph_dport = rxdh->dccph_sport;
+	dh->dccph_doff	= dccp_hdr_ack_len / 4;
+	dh->dccph_x	= 1;
+	
+	dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
+	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+			 DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+
+	/* FIXME: calculate checksum, IPv4 also should... */
+
+	fl.proto = IPPROTO_DCCP;
+	fl.oif = inet6_iif(rxskb);
+	fl.fl_ip_dport = dh->dccph_dport;
+	fl.fl_ip_sport = dh->dccph_sport;
+
+	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, skb, &fl, NULL, 0);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+			return;
+		}
+	}
+
+	kfree_skb(skb);
+}
+
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+				   struct request_sock *req)
+{
+	dccp_v6_ctl_send_ack(skb);
+}
+
+static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
+{
+	const struct dccp_hdr *dh = dccp_hdr(skb);
+	const struct ipv6hdr *iph = skb->nh.ipv6h;
+	struct sock *nsk;
+	struct request_sock **prev;
+	/* Find possible connection requests. */
+	struct request_sock *req = inet6_csk_search_req(sk, &prev,
+							dh->dccph_sport,
+							&iph->saddr,
+							&iph->daddr,
+							inet6_iif(skb));
+	if (req != NULL)
+		return dccp_check_req(sk, skb, req, prev);
+
+	nsk = __inet6_lookup_established(&dccp_hashinfo,
+					 &iph->saddr, dh->dccph_sport,
+					 &iph->daddr, ntohs(dh->dccph_dport),
+					 inet6_iif(skb));
+
+	if (nsk != NULL) {
+		if (nsk->sk_state != DCCP_TIME_WAIT) {
+			bh_lock_sock(nsk);
+			return nsk;
+		}
+		inet_twsk_put((struct inet_timewait_sock *)nsk);
+		return NULL;
+	}
+
+	return sk;
+}
+
+static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+{
+	struct inet_request_sock *ireq;
+	struct dccp_sock dp;
+	struct request_sock *req;
+	struct dccp_request_sock *dreq;
+	struct inet6_request_sock *ireq6;
+	struct ipv6_pinfo *np = inet6_sk(sk);
+ 	const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+	__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
+
+	if (skb->protocol == htons(ETH_P_IP))
+		return dccp_v4_conn_request(sk, skb);
+
+	if (!ipv6_unicast_destination(skb))
+		goto drop; 
+
+	if (dccp_bad_service_code(sk, service)) {
+		reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
+		goto drop;
+ 	}
+	/*
+	 *	There are no SYN attacks on IPv6, yet...	
+	 */
+	if (inet_csk_reqsk_queue_is_full(sk))
+		goto drop;		
+
+	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+		goto drop;
+
+	req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+	if (req == NULL)
+		goto drop;
+
+	/* FIXME: process options */
+
+	dccp_openreq_init(req, &dp, skb);
+
+	ireq6 = inet6_rsk(req);
+	ireq = inet_rsk(req);
+	ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
+	req->rcv_wnd	= 100; /* Fake, option parsing will get the
+				  right value */
+	ireq6->pktopts	= NULL;
+
+	if (ipv6_opt_accepted(sk, skb) ||
+	    np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+	    np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
+		atomic_inc(&skb->users);
+		ireq6->pktopts = skb;
+	}
+	ireq6->iif = sk->sk_bound_dev_if;
+
+	/* So that link locals have meaning */
+	if (!sk->sk_bound_dev_if &&
+	    ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+		ireq6->iif = inet6_iif(skb);
+
+	/* 
+	 * Step 3: Process LISTEN state
+	 *
+	 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+	 *
+	 * In fact we defer setting S.GSR, S.SWL, S.SWH to
+	 * dccp_create_openreq_child.
+	 */
+	dreq = dccp_rsk(req);
+	dreq->dreq_isr	   = dcb->dccpd_seq;
+	dreq->dreq_iss	   = dccp_v6_init_sequence(sk, skb);
+	dreq->dreq_service = service;
+
+	if (dccp_v6_send_response(sk, req, NULL))
+		goto drop_and_free;
+
+	inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+	return 0;
+
+drop_and_free:
+	reqsk_free(req);
+drop:
+	DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+	dcb->dccpd_reset_code = reset_code;
+	return -1;
+}
+
+static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
+					      struct sk_buff *skb,
+					      struct request_sock *req,
+					      struct dst_entry *dst)
+{
+	struct inet6_request_sock *ireq6 = inet6_rsk(req);
+	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+	struct inet_sock *newinet;
+	struct dccp_sock *newdp;
+	struct dccp6_sock *newdp6;
+	struct sock *newsk;
+	struct ipv6_txoptions *opt;
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+		/*
+		 *	v6 mapped
+		 */
+
+		newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
+		if (newsk == NULL) 
+			return NULL;
+
+		newdp6 = (struct dccp6_sock *)newsk;
+		newdp = dccp_sk(newsk);
+		newinet = inet_sk(newsk);
+		newinet->pinet6 = &newdp6->inet6;
+		newnp = inet6_sk(newsk);
+
+		memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+		ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
+			      newinet->daddr);
+
+		ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
+			      newinet->saddr);
+
+		ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
+
+		inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
+		newsk->sk_backlog_rcv = dccp_v4_do_rcv;
+		newnp->pktoptions  = NULL;
+		newnp->opt	   = NULL;
+		newnp->mcast_oif   = inet6_iif(skb);
+		newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
+
+		/*
+		 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
+		 * here, dccp_create_openreq_child now does this for us, see the comment in
+		 * that function for the gory details. -acme
+		 */
+
+		/* It is tricky place. Until this moment IPv4 tcp
+		   worked with IPv6 icsk.icsk_af_ops.
+		   Sync it now.
+		 */
+		dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
+
+		return newsk;
+	}
+
+	opt = np->opt;
+
+	if (sk_acceptq_is_full(sk))
+		goto out_overflow;
+
+	if (np->rxopt.bits.osrcrt == 2 &&
+	    opt == NULL && ireq6->pktopts) {
+		struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
+		if (rxopt->srcrt)
+			opt = ipv6_invert_rthdr(sk,
+				(struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
+						       rxopt->srcrt));
+	}
+
+	if (dst == NULL) {
+		struct in6_addr *final_p = NULL, final;
+		struct flowi fl;
+
+		memset(&fl, 0, sizeof(fl));
+		fl.proto = IPPROTO_DCCP;
+		ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+		if (opt && opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+		ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+		fl.oif = sk->sk_bound_dev_if;
+		fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+		fl.fl_ip_sport = inet_sk(sk)->sport;
+
+		if (ip6_dst_lookup(sk, &dst, &fl))
+			goto out;
+
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+			goto out;
+	} 
+
+	newsk = dccp_create_openreq_child(sk, req, skb);
+	if (newsk == NULL)
+		goto out;
+
+	/*
+	 * No need to charge this sock to the relevant IPv6 refcnt debug socks
+	 * count here, dccp_create_openreq_child now does this for us, see the
+	 * comment in that function for the gory details. -acme
+	 */
+
+	ip6_dst_store(newsk, dst, NULL);
+	newsk->sk_route_caps = dst->dev->features &
+		~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+	newdp6 = (struct dccp6_sock *)newsk;
+	newinet = inet_sk(newsk);
+	newinet->pinet6 = &newdp6->inet6;
+	newdp = dccp_sk(newsk);
+	newnp = inet6_sk(newsk);
+
+	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+	ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr);
+	ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr);
+	ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr);
+	newsk->sk_bound_dev_if = ireq6->iif;
+
+	/* Now IPv6 options... 
+
+	   First: no IPv4 options.
+	 */
+	newinet->opt = NULL;
+
+	/* Clone RX bits */
+	newnp->rxopt.all = np->rxopt.all;
+
+	/* Clone pktoptions received with SYN */
+	newnp->pktoptions = NULL;
+	if (ireq6->pktopts != NULL) {
+		newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC);
+		kfree_skb(ireq6->pktopts);
+		ireq6->pktopts = NULL;
+		if (newnp->pktoptions)
+			skb_set_owner_r(newnp->pktoptions, newsk);
+	}
+	newnp->opt	  = NULL;
+	newnp->mcast_oif  = inet6_iif(skb);
+	newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
+
+	/* Clone native IPv6 options from listening socket (if any)
+
+	   Yes, keeping reference count would be much more clever,
+	   but we make one more one thing there: reattach optmem
+	   to newsk.
+	 */
+	if (opt) {
+		newnp->opt = ipv6_dup_options(newsk, opt);
+		if (opt != np->opt)
+			sock_kfree_s(sk, opt, opt->tot_len);
+	}
+
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
+	if (newnp->opt)
+		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+						     newnp->opt->opt_flen);
+
+	dccp_sync_mss(newsk, dst_mtu(dst));
+
+	newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
+
+	__inet6_hash(&dccp_hashinfo, newsk);
+	inet_inherit_port(&dccp_hashinfo, sk, newsk);
+
+	return newsk;
+
+out_overflow:
+	NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
+out:
+	NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
+	if (opt && opt != np->opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+	dst_release(dst);
+	return NULL;
+}
+
+/* The socket must have it's spinlock held when we get
+ * here.
+ *
+ * We have a potential double-lock case here, so even when
+ * doing backlog processing we use the BH locking scheme.
+ * This is because we cannot sleep with the original spinlock
+ * held.
+ */
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sk_buff *opt_skb = NULL;
+
+	/* Imagine: socket is IPv6. IPv4 packet arrives,
+	   goes to IPv4 receive handler and backlogged.
+	   From backlog it always goes here. Kerboom...
+	   Fortunately, dccp_rcv_established and rcv_established
+	   handle them correctly, but it is not case with
+	   dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
+	 */
+
+	if (skb->protocol == htons(ETH_P_IP))
+		return dccp_v4_do_rcv(sk, skb);
+
+	if (sk_filter(sk, skb, 0))
+		goto discard;
+
+	/*
+	 *	socket locking is here for SMP purposes as backlog rcv
+	 *	is currently called with bh processing disabled.
+	 */
+
+	/* Do Stevens' IPV6_PKTOPTIONS.
+
+	   Yes, guys, it is the only place in our code, where we
+	   may make it not affecting IPv4.
+	   The rest of code is protocol independent,
+	   and I do not like idea to uglify IPv4.
+
+	   Actually, all the idea behind IPV6_PKTOPTIONS
+	   looks not very well thought. For now we latch
+	   options, received in the last packet, enqueued
+	   by tcp. Feel free to propose better solution.
+	                                       --ANK (980728)
+	 */
+	if (np->rxopt.all)
+		opt_skb = skb_clone(skb, GFP_ATOMIC);
+
+	if (sk->sk_state == DCCP_OPEN) { /* Fast path */
+		if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
+			goto reset;
+		return 0;
+	}
+
+	if (sk->sk_state == DCCP_LISTEN) { 
+		struct sock *nsk = dccp_v6_hnd_req(sk, skb);
+		if (!nsk)
+			goto discard;
+
+		/*
+		 * Queue it on the new socket if the new socket is active,
+		 * otherwise we just shortcircuit this and continue with
+		 * the new socket..
+		 */
+ 		if(nsk != sk) {
+			if (dccp_child_process(sk, nsk, skb))
+				goto reset;
+			if (opt_skb)
+				__kfree_skb(opt_skb);
+			return 0;
+		}
+	}
+
+	if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
+		goto reset;
+	return 0;
+
+reset:
+	dccp_v6_ctl_send_reset(skb);
+discard:
+	if (opt_skb)
+		__kfree_skb(opt_skb);
+	kfree_skb(skb);
+	return 0;
+}
+
+static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+{
+	const struct dccp_hdr *dh;
+	struct sk_buff *skb = *pskb;
+	struct sock *sk;
+
+	/* Step 1: Check header basics: */
+
+	if (dccp_invalid_packet(skb))
+		goto discard_it;
+
+	dh = dccp_hdr(skb);
+
+	DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
+	DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
+
+	if (dccp_packet_without_ack(skb))
+		DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
+	else
+		DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
+
+	/* Step 2:
+	 * 	Look up flow ID in table and get corresponding socket */
+	sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
+			    dh->dccph_sport,
+			    &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
+			    inet6_iif(skb));
+	/* 
+	 * Step 2:
+	 * 	If no socket ...
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	if (sk == NULL)
+		goto no_dccp_socket;
+
+	/* 
+	 * Step 2:
+	 * 	... or S.state == TIMEWAIT,
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	       
+	if (sk->sk_state == DCCP_TIME_WAIT)
+                goto do_time_wait;
+
+	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+		goto discard_and_relse;
+
+	return sk_receive_skb(sk, skb) ? -1 : 0;
+
+no_dccp_socket:
+	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+		goto discard_it;
+	/*
+	 * Step 2:
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	if (dh->dccph_type != DCCP_PKT_RESET) {
+		DCCP_SKB_CB(skb)->dccpd_reset_code =
+					DCCP_RESET_CODE_NO_CONNECTION;
+		dccp_v6_ctl_send_reset(skb);
+	}
+discard_it:
+
+	/*
+	 *	Discard frame
+	 */
+
+	kfree_skb(skb);
+	return 0;
+
+discard_and_relse:
+	sock_put(sk);
+	goto discard_it;
+
+do_time_wait:
+	inet_twsk_put((struct inet_timewait_sock *)sk);
+	goto no_dccp_socket;
+}
+
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
+	.queue_xmit	=	inet6_csk_xmit,
+	.send_check	=	dccp_v6_send_check,
+	.rebuild_header	=	inet6_sk_rebuild_header,
+	.conn_request	=	dccp_v6_conn_request,
+	.syn_recv_sock	=	dccp_v6_request_recv_sock,
+	.net_header_len	=	sizeof(struct ipv6hdr),
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
+};
+
+/*
+ *	DCCP over IPv4 via INET6 API
+ */
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
+	.queue_xmit	=	ip_queue_xmit,
+	.send_check	=	dccp_v4_send_check,
+	.rebuild_header	=	inet_sk_rebuild_header,
+	.conn_request	=	dccp_v6_conn_request,
+	.syn_recv_sock	=	dccp_v6_request_recv_sock,
+	.net_header_len	=	sizeof(struct iphdr),
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
+};
+
+/* NOTE: A lot of things set to zero explicitly by call to
+ *       sk_alloc() so need not be done here.
+ */
+static int dccp_v6_init_sock(struct sock *sk)
+{
+	int err = dccp_v4_init_sock(sk);
+
+	if (err == 0)
+		inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
+
+	return err;
+}
+
+static int dccp_v6_destroy_sock(struct sock *sk)
+{
+	dccp_v4_destroy_sock(sk);
+	return inet6_destroy_sock(sk);
+}
+
+static struct proto dccp_v6_prot = {
+	.name			= "DCCPv6",
+	.owner			= THIS_MODULE,
+	.close			= dccp_close,
+	.connect		= dccp_v6_connect,
+	.disconnect		= dccp_disconnect,
+	.ioctl			= dccp_ioctl,
+	.init			= dccp_v6_init_sock,
+	.setsockopt		= dccp_setsockopt,
+	.getsockopt		= dccp_getsockopt,
+	.sendmsg		= dccp_sendmsg,
+	.recvmsg		= dccp_recvmsg,
+	.backlog_rcv		= dccp_v6_do_rcv,
+	.hash			= dccp_v6_hash,
+	.unhash			= dccp_unhash,
+	.accept			= inet_csk_accept,
+	.get_port		= dccp_v6_get_port,
+	.shutdown		= dccp_shutdown,
+	.destroy		= dccp_v6_destroy_sock,
+	.orphan_count		= &dccp_orphan_count,
+	.max_header		= MAX_DCCP_HEADER,
+	.obj_size		= sizeof(struct dccp6_sock),
+	.rsk_prot		= &dccp6_request_sock_ops,
+	.twsk_prot		= &dccp6_timewait_sock_ops,
+};
+
+static struct inet6_protocol dccp_v6_protocol = {
+	.handler	=	dccp_v6_rcv,
+	.err_handler	=	dccp_v6_err,
+	.flags		=	INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
+};
+
+static struct proto_ops inet6_dccp_ops = {
+	.family		= PF_INET6,
+	.owner		= THIS_MODULE,
+	.release	= inet6_release,
+	.bind		= inet6_bind,
+	.connect	= inet_stream_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= inet_accept,
+	.getname	= inet6_getname,
+	.poll		= dccp_poll,
+	.ioctl		= inet6_ioctl,
+	.listen		= inet_dccp_listen,
+	.shutdown	= inet_shutdown,
+	.setsockopt	= sock_common_setsockopt,
+	.getsockopt	= sock_common_getsockopt,
+	.sendmsg	= inet_sendmsg,
+	.recvmsg	= sock_common_recvmsg,
+	.mmap		= sock_no_mmap,
+	.sendpage	= sock_no_sendpage,
+};
+
+static struct inet_protosw dccp_v6_protosw = {
+	.type		= SOCK_DCCP,
+	.protocol	= IPPROTO_DCCP,
+	.prot		= &dccp_v6_prot,
+	.ops		= &inet6_dccp_ops,
+	.capability	= -1,
+	.flags		= INET_PROTOSW_ICSK,
+};
+
+static int __init dccp_v6_init(void)
+{
+	int err = proto_register(&dccp_v6_prot, 1);
+
+	if (err != 0)
+		goto out;
+
+	err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+	if (err != 0)
+		goto out_unregister_proto;
+
+	inet6_register_protosw(&dccp_v6_protosw);
+out:
+	return err;
+out_unregister_proto:
+	proto_unregister(&dccp_v6_prot);
+	goto out;
+}
+
+static void __exit dccp_v6_exit(void)
+{
+	inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+	inet6_unregister_protosw(&dccp_v6_protosw);
+	proto_unregister(&dccp_v6_prot);
+}
+
+module_init(dccp_v6_init);
+module_exit(dccp_v6_exit);
+
+/*
+ * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/ipv6.h b/net/dccp/ipv6.h
new file mode 100644
index 0000000..e4d4e93
--- /dev/null
+++ b/net/dccp/ipv6.h
@@ -0,0 +1,37 @@
+#ifndef _DCCP_IPV6_H
+#define _DCCP_IPV6_H
+/*
+ *  net/dccp/ipv6.h
+ *
+ *  An implementation of the DCCP protocol
+ *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.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/config.h>
+#include <linux/dccp.h>
+#include <linux/ipv6.h>
+
+struct dccp6_sock {
+	struct dccp_sock  dccp;
+	/*
+	 * ipv6_pinfo has to be the last member of dccp6_sock,
+	 * see inet6_sk_generic.
+	 */
+	struct ipv6_pinfo inet6;
+};
+
+struct dccp6_request_sock {
+	struct dccp_request_sock  dccp;
+	struct inet6_request_sock inet6;
+};
+
+struct dccp6_timewait_sock {
+	struct inet_timewait_sock   inet;
+	struct inet6_timewait_sock  tw6;
+};
+
+#endif /* _DCCP_IPV6_H */
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 1393461..29261fc 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -40,6 +40,8 @@
 					    (unsigned long)&dccp_death_row),
 };
 
+EXPORT_SYMBOL_GPL(dccp_death_row);
+
 void dccp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
@@ -50,7 +52,18 @@
 	if (tw != NULL) {
 		const struct inet_connection_sock *icsk = inet_csk(sk);
 		const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		if (tw->tw_family == PF_INET6) {
+			const struct ipv6_pinfo *np = inet6_sk(sk);
+			struct inet6_timewait_sock *tw6;
 
+			tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+			tw6 = inet6_twsk((struct sock *)tw);
+			ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+			ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
+			tw->tw_ipv6only = np->ipv6only;
+		}
+#endif
 		/* Linkage updates. */
 		__inet_twsk_hashdance(tw, sk, &dccp_hashinfo);
 
@@ -170,6 +183,8 @@
 	return newsk;
 }
 
+EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
+
 /* 
  * Process an incoming packet for RESPOND sockets represented
  * as an request_sock.
@@ -214,7 +229,7 @@
 		goto drop;
 	}
 
-	child = dccp_v4_request_recv_sock(sk, skb, req, NULL);
+	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
 	if (child == NULL)
 		goto listen_overflow;
 
@@ -236,6 +251,8 @@
 	goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_check_req);
+
 /*
  *  Queue segment on the new socket if the new socket is active,
  *  otherwise we just shortcircuit this and continue with
@@ -266,3 +283,5 @@
 	sock_put(child);
 	return ret;
 }
+
+EXPORT_SYMBOL_GPL(dccp_child_process);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 74ff870..efd7ffb 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 
 #include "ackvec.h"
@@ -43,6 +44,7 @@
 {
 	if (likely(skb != NULL)) {
 		const struct inet_sock *inet = inet_sk(sk);
+		const struct inet_connection_sock *icsk = inet_csk(sk);
 		struct dccp_sock *dp = dccp_sk(sk);
 		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 		struct dccp_hdr *dh;
@@ -108,8 +110,7 @@
 			break;
 		}
 
-		dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr,
-						      inet->daddr);
+		icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
 		if (set_ack)
 			dccp_event_ack_sent(sk);
@@ -117,7 +118,7 @@
 		DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 
 		memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-		err = ip_queue_xmit(skb, 0);
+		err = icsk->icsk_af_ops->queue_xmit(skb, 0);
 		if (err <= 0)
 			return err;
 
@@ -134,20 +135,13 @@
 
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-	int mss_now;
-
-	/*
-	 * FIXME: we really should be using the af_specific thing to support
-	 * 	  IPv6.
-	 * mss_now = pmtu - tp->af_specific->net_header_len -
-	 * 	     sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
-	 */
-	mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) -
-		  sizeof(struct dccp_hdr_ext);
+	int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+		       sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
 
 	/* Now subtract optional transport overhead */
-	mss_now -= dp->dccps_ext_header_len;
+	mss_now -= icsk->icsk_ext_hdr_len;
 
 	/*
 	 * FIXME: this should come from the CCID infrastructure, where, say,
@@ -160,12 +154,14 @@
 	mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
 
 	/* And store cached results */
-	dp->dccps_pmtu_cookie = pmtu;
+	icsk->icsk_pmtu_cookie = pmtu;
 	dp->dccps_mss_cache = mss_now;
 
 	return mss_now;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sync_mss);
+
 void dccp_write_space(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
@@ -266,7 +262,7 @@
 
 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
-	if (inet_sk_rebuild_header(sk) != 0)
+	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
 		return -EHOSTUNREACH; /* Routing failure or similar. */
 
 	return dccp_transmit_skb(sk, (skb_cloned(skb) ?
@@ -321,6 +317,8 @@
 	return skb;
 }
 
+EXPORT_SYMBOL_GPL(dccp_make_response);
+
 struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
 				const enum dccp_reset_codes code)
 				   
@@ -377,6 +375,7 @@
  */
 static inline void dccp_connect_init(struct sock *sk)
 {
+	struct dccp_sock *dp = dccp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -385,10 +384,16 @@
 	
 	dccp_sync_mss(sk, dst_mtu(dst));
 
-	/*
-	 * FIXME: set dp->{dccps_swh,dccps_swl}, with
-	 * something like dccp_inc_seq
-	 */
+	dccp_update_gss(sk, dp->dccps_iss);
+ 	/*
+	 * SWL and AWL are initially adjusted so that they are not less than
+	 * the initial Sequence Numbers received and sent, respectively:
+	 *	SWL := max(GSR + 1 - floor(W/4), ISR),
+	 *	AWL := max(GSS - W' + 1, ISS).
+	 * These adjustments MUST be applied only at the beginning of the
+	 * connection.
+ 	 */
+	dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
 
 	icsk->icsk_retransmits = 0;
 }
@@ -420,6 +425,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_connect);
+
 void dccp_send_ack(struct sock *sk)
 {
 	/* If we have been reset, we may not send again. */
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 8a6b2a9..65b11ea 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -24,7 +24,7 @@
 #include <net/checksum.h>
 
 #include <net/inet_common.h>
-#include <net/ip.h>
+#include <net/inet_sock.h>
 #include <net/protocol.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
@@ -34,15 +34,18 @@
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/poll.h>
-#include <linux/dccp.h>
 
 #include "ccid.h"
 #include "dccp.h"
 
 DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly;
 
+EXPORT_SYMBOL_GPL(dccp_statistics);
+
 atomic_t dccp_orphan_count = ATOMIC_INIT(0);
 
+EXPORT_SYMBOL_GPL(dccp_orphan_count);
+
 static struct net_protocol dccp_protocol = {
 	.handler	= dccp_v4_rcv,
 	.err_handler	= dccp_v4_err,
@@ -149,6 +152,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_disconnect);
+
 /*
  *	Wait for a DCCP event.
  *
@@ -156,8 +161,8 @@
  *	take care of normal races (between the test and the event) and we don't
  *	go look at any of the socket buffers directly.
  */
-static unsigned int dccp_poll(struct file *file, struct socket *sock,
-			      poll_table *wait)
+unsigned int dccp_poll(struct file *file, struct socket *sock,
+		       poll_table *wait)
 {
 	unsigned int mask;
 	struct sock *sk = sock->sk;
@@ -205,12 +210,16 @@
 	return mask;
 }
 
+EXPORT_SYMBOL_GPL(dccp_poll);
+
 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
 	dccp_pr_debug("entry\n");
 	return -ENOIOCTLCMD;
 }
 
+EXPORT_SYMBOL_GPL(dccp_ioctl);
+
 static int dccp_setsockopt_service(struct sock *sk, const u32 service,
 				   char __user *optval, int optlen)
 {
@@ -254,7 +263,9 @@
 	int val;
 
 	if (level != SOL_DCCP)
-		return ip_setsockopt(sk, level, optname, optval, optlen);
+		return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
+							     optname, optval,
+							     optlen);
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
@@ -282,6 +293,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_setsockopt);
+
 static int dccp_getsockopt_service(struct sock *sk, int len,
 				   u32 __user *optval,
 				   int __user *optlen)
@@ -320,8 +333,9 @@
 	int val, len;
 
 	if (level != SOL_DCCP)
-		return ip_getsockopt(sk, level, optname, optval, optlen);
-
+		return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
+							     optname, optval,
+							     optlen);
 	if (get_user(len, optlen))
 		return -EFAULT;
 
@@ -354,6 +368,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_getsockopt);
+
 int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		 size_t len)
 {
@@ -410,6 +426,8 @@
 	goto out_release;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sendmsg);
+
 int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		 size_t len, int nonblock, int flags, int *addr_len)
 {
@@ -507,7 +525,9 @@
 	return len;
 }
 
-static int inet_dccp_listen(struct socket *sock, int backlog)
+EXPORT_SYMBOL_GPL(dccp_recvmsg);
+
+int inet_dccp_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	unsigned char old_state;
@@ -543,6 +563,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(inet_dccp_listen);
+
 static const unsigned char dccp_new_state[] = {
 	/* current state:   new state:      action:	*/
 	[0]		  = DCCP_CLOSED,
@@ -648,12 +670,16 @@
 	sock_put(sk);
 }
 
+EXPORT_SYMBOL_GPL(dccp_close);
+
 void dccp_shutdown(struct sock *sk, int how)
 {
 	dccp_pr_debug("entry\n");
 }
 
-static struct proto_ops inet_dccp_ops = {
+EXPORT_SYMBOL_GPL(dccp_shutdown);
+
+static const struct proto_ops inet_dccp_ops = {
 	.family		= PF_INET,
 	.owner		= THIS_MODULE,
 	.release	= inet_release,
@@ -681,11 +707,11 @@
 static struct inet_protosw dccp_v4_protosw = {
 	.type		= SOCK_DCCP,
 	.protocol	= IPPROTO_DCCP,
-	.prot		= &dccp_v4_prot,
+	.prot		= &dccp_prot,
 	.ops		= &inet_dccp_ops,
 	.capability	= -1,
 	.no_check	= 0,
-	.flags		= 0,
+	.flags		= INET_PROTOSW_ICSK,
 };
 
 /*
@@ -760,13 +786,15 @@
 int dccp_debug;
 module_param(dccp_debug, int, 0444);
 MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
+
+EXPORT_SYMBOL_GPL(dccp_debug);
 #endif
 
 static int __init dccp_init(void)
 {
 	unsigned long goal;
 	int ehash_order, bhash_order, i;
-	int rc = proto_register(&dccp_v4_prot, 1);
+	int rc = proto_register(&dccp_prot, 1);
 
 	if (rc)
 		goto out;
@@ -869,7 +897,7 @@
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
 	dccp_hashinfo.bind_bucket_cachep = NULL;
 out_proto_unregister:
-	proto_unregister(&dccp_v4_prot);
+	proto_unregister(&dccp_prot);
 	goto out;
 }
 
@@ -892,7 +920,7 @@
 		   get_order(dccp_hashinfo.ehash_size *
 			     sizeof(struct inet_ehash_bucket)));
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
-	proto_unregister(&dccp_v4_prot);
+	proto_unregister(&dccp_prot);
 }
 
 module_init(dccp_init);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index d402e90..78ec534 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -149,7 +149,7 @@
 #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
 
 
-static struct proto_ops dn_proto_ops;
+static const struct proto_ops dn_proto_ops;
 static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
@@ -1252,7 +1252,7 @@
 		break;
 
 	default:
-		err = dev_ioctl(cmd, (void __user *)arg);
+		err = -ENOIOCTLCMD;
 		break;
 	}
 
@@ -2342,7 +2342,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops dn_proto_ops = {
+static const struct proto_ops dn_proto_ops = {
 	.family =	AF_DECnet,
 	.owner =	THIS_MODULE,
 	.release =	dn_release,
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 8d0cc3c..33ab256 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -408,11 +408,14 @@
 			}
 		}
 
-		if (!dn_db->router) {
-			dn_db->router = neigh_clone(neigh);
-		} else {
-			if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
-				neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+		/* Only use routers in our area */
+		if ((dn_ntohs(src)>>10) == dn_ntohs((decnet_address)>>10)) {
+			if (!dn_db->router) {
+				dn_db->router = neigh_clone(neigh);
+			} else {
+				if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
+					neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+			}
 		}
 		write_unlock(&neigh->lock);
 		neigh_release(neigh);
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 369f25b..44bda85 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -793,7 +793,6 @@
 got_it:
 	if (sk != NULL) {
 		struct dn_scp *scp = DN_SK(sk);
-		int ret;
 
 		/* Reset backoff */
 		scp->nsp_rxtshift = 0;
@@ -807,21 +806,7 @@
 				goto free_out;
 		}
 
-		bh_lock_sock(sk);
-		ret = NET_RX_SUCCESS;
-		if (decnet_debug_level & 8)
-			printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
-				(int)cb->rt_flags, (int)cb->nsp_flags, 
-				(int)cb->src_port, (int)cb->dst_port, 
-				!!sock_owned_by_user(sk));
-		if (!sock_owned_by_user(sk))
-			ret = dn_nsp_backlog_rcv(sk, skb);
-		else
-			sk_add_backlog(sk, skb);
-		bh_unlock_sock(sk);
-		sock_put(sk);
-
-		return ret;
+		return sk_receive_skb(sk, skb);
 	}
 
 	return dn_nsp_no_socket(skb, reason);
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 34fdac5..c792994 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -31,6 +31,7 @@
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
+#include <linux/udp.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -45,7 +46,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct proto_ops econet_ops;
+static const struct proto_ops econet_ops;
 static struct hlist_head econet_sklist;
 static DEFINE_RWLOCK(econet_lock);
 
@@ -56,7 +57,7 @@
 #define EC_PORT_IP	0xd2
 
 #ifdef CONFIG_ECONET_AUNUDP
-static spinlock_t aun_queue_lock;
+static DEFINE_SPINLOCK(aun_queue_lock);
 static struct socket *udpsock;
 #define AUN_PORT	0x8000
 
@@ -686,7 +687,7 @@
 			break;
 
 		default:
-			return dev_ioctl(cmd, argp);
+			return -ENOIOCTLCMD;
 	}
 	/*NOTREACHED*/
 	return 0;
@@ -698,7 +699,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
 	.family =	PF_ECONET,
 	.owner =	THIS_MODULE,
 	.release =	econet_release,
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 03efaac..4cc6f41 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -410,9 +410,8 @@
 		return 1;
 	}
 
-	if ((is_multicast_ether_addr(hdr->addr1) ||
-	     is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
-	    ieee->host_decrypt) {
+	if (is_multicast_ether_addr(hdr->addr1)
+	    ? ieee->host_mc_decrypt : ieee->host_decrypt) {
 		int idx = 0;
 		if (skb->len >= hdrlen + 3)
 			idx = skb->data[hdrlen + 3] >> 6;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index e55136a..011cca7 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -456,6 +456,14 @@
 	increase provides TCP friendliness.
 	See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/
 
+config TCP_CONG_CUBIC
+	tristate "CUBIC TCP"
+	default m
+	---help---
+	This is version 2.0 of BIC-TCP which uses a cubic growth function
+	among other techniques.
+	See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+
 config TCP_CONG_WESTWOOD
 	tristate "TCP Westwood+"
 	default m
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f0435d0..c54edd7 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -34,6 +34,7 @@
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
+obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
 obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
 obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o
 obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d368cf2..966a071 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -93,6 +93,7 @@
 #include <linux/smp_lock.h>
 #include <linux/inet.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -302,6 +303,7 @@
 		sk->sk_reuse = 1;
 
 	inet = inet_sk(sk);
+	inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
 	if (SOCK_RAW == sock->type) {
 		inet->num = protocol;
@@ -775,16 +777,16 @@
 			err = devinet_ioctl(cmd, (void __user *)arg);
 			break;
 		default:
-			if (!sk->sk_prot->ioctl ||
-			    (err = sk->sk_prot->ioctl(sk, cmd, arg)) ==
-			    					-ENOIOCTLCMD)
-				err = dev_ioctl(cmd, (void __user *)arg);
+			if (sk->sk_prot->ioctl)
+				err = sk->sk_prot->ioctl(sk, cmd, arg);
+			else
+				err = -ENOIOCTLCMD;
 			break;
 	}
 	return err;
 }
 
-struct proto_ops inet_stream_ops = {
+const struct proto_ops inet_stream_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -805,7 +807,7 @@
 	.sendpage =	tcp_sendpage
 };
 
-struct proto_ops inet_dgram_ops = {
+const struct proto_ops inet_dgram_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -830,7 +832,7 @@
  * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
  * udp_poll
  */
-static struct proto_ops inet_sockraw_ops = {
+static const struct proto_ops inet_sockraw_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -869,7 +871,8 @@
                 .ops =        &inet_stream_ops,
                 .capability = -1,
                 .no_check =   0,
-                .flags =      INET_PROTOSW_PERMANENT,
+                .flags =      INET_PROTOSW_PERMANENT |
+			      INET_PROTOSW_ICSK,
         },
 
         {
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 035ad2c..aed537f 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -6,6 +6,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <asm/scatterlist.h>
 
 
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index b425748..3743208 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -86,6 +86,7 @@
 #include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/fddidevice.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 04a6fe3..7b9bb28 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -58,6 +58,7 @@
 #endif
 #include <linux/kmod.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 1b18ce6..73bfcae 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -9,6 +9,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/random.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <net/udp.h>
 
 /* decapsulation data for use when post-processing */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 19b1b98..18f5e50 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 7ea0209..e2890ec 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 0b298bb..0dd4d06 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 6d2a6ac..ef4724d 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
@@ -36,6 +37,7 @@
 #include <linux/netlink.h>
 #include <linux/init.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 705e3ce..e320b32 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -41,6 +41,13 @@
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
+ *
+ * Substantial contributions to this work comes from:
+ *
+ *		David S. Miller, <davem@davemloft.net>
+ *		Stephen Hemminger <shemminger@osdl.org>
+ *		Paul E. McKenney <paulmck@us.ibm.com>
+ *		Patrick McHardy <kaber@trash.net>
  */
 
 #define VERSION "0.404"
@@ -59,6 +66,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 92e23b2..be5a519 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -73,6 +73,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/string.h>
 #include <linux/netfilter_ipv4.h>
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 4a195c7..3475811 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -91,6 +91,8 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/times.h>
+
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 3fe021f..ae20281 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -37,7 +37,8 @@
  */
 int sysctl_local_port_range[2] = { 1024, 4999 };
 
-static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb)
+int inet_csk_bind_conflict(const struct sock *sk,
+			   const struct inet_bind_bucket *tb)
 {
 	const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
 	struct sock *sk2;
@@ -62,11 +63,15 @@
 	return node != NULL;
 }
 
+EXPORT_SYMBOL_GPL(inet_csk_bind_conflict);
+
 /* Obtain a reference to a local port for the given sock,
  * if snum is zero it means select any available local port.
  */
 int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-		      struct sock *sk, unsigned short snum)
+		      struct sock *sk, unsigned short snum,
+		      int (*bind_conflict)(const struct sock *sk,
+					   const struct inet_bind_bucket *tb))
 {
 	struct inet_bind_hashbucket *head;
 	struct hlist_node *node;
@@ -125,7 +130,7 @@
 			goto success;
 		} else {
 			ret = 1;
-			if (inet_csk_bind_conflict(sk, tb))
+			if (bind_conflict(sk, tb))
 				goto fail_unlock;
 		}
 	}
@@ -380,7 +385,7 @@
 EXPORT_SYMBOL_GPL(inet_csk_search_req);
 
 void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
-				   const unsigned timeout)
+				   unsigned long timeout)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
@@ -631,3 +636,15 @@
 }
 
 EXPORT_SYMBOL_GPL(inet_csk_listen_stop);
+
+void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
+{
+	struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
+	const struct inet_sock *inet = inet_sk(sk);
+
+	sin->sin_family		= AF_INET;
+	sin->sin_addr.s_addr	= inet->daddr;
+	sin->sin_port		= inet->dport;
+}
+
+EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 39061ed..c499081 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -112,12 +112,12 @@
 		r->idiag_inode = 0;
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 		if (r->idiag_family == AF_INET6) {
-			const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+			const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
 			ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-				       &tcp6tw->tw_v6_rcv_saddr);
+				       &tw6->tw_v6_rcv_saddr);
 			ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-				       &tcp6tw->tw_v6_daddr);
+				       &tw6->tw_v6_daddr);
 		}
 #endif
 		nlh->nlmsg_len = skb->tail - b;
@@ -489,9 +489,9 @@
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 	if (r->idiag_family == AF_INET6) {
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-			       &tcp6_rsk(req)->loc_addr);
+			       &inet6_rsk(req)->loc_addr);
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-			       &tcp6_rsk(req)->rmt_addr);
+			       &inet6_rsk(req)->rmt_addr);
 	}
 #endif
 	nlh->nlmsg_len = skb->tail - b;
@@ -553,13 +553,13 @@
 				entry.saddr =
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 					(entry.family == AF_INET6) ?
-					tcp6_rsk(req)->loc_addr.s6_addr32 :
+					inet6_rsk(req)->loc_addr.s6_addr32 :
 #endif
 					&ireq->loc_addr;
 				entry.daddr = 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 					(entry.family == AF_INET6) ?
-					tcp6_rsk(req)->rmt_addr.s6_addr32 :
+					inet6_rsk(req)->rmt_addr.s6_addr32 :
 #endif
 					&ireq->rmt_addr;
 				entry.dport = ntohs(ireq->rmt_port);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index e8d29fe..3322811 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -15,12 +15,14 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
+#include <net/ip.h>
 
 /*
  * Allocate and initialize a new local port bind bucket.
@@ -163,3 +165,179 @@
 }
 
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
+
+/* called with local bh disabled */
+static int __inet_check_established(struct inet_timewait_death_row *death_row,
+				    struct sock *sk, __u16 lport,
+				    struct inet_timewait_sock **twp)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	struct inet_sock *inet = inet_sk(sk);
+	u32 daddr = inet->rcv_saddr;
+	u32 saddr = inet->daddr;
+	int dif = sk->sk_bound_dev_if;
+	INET_ADDR_COOKIE(acookie, saddr, daddr)
+	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
+	struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+	struct sock *sk2;
+	const struct hlist_node *node;
+	struct inet_timewait_sock *tw;
+
+	prefetch(head->chain.first);
+	write_lock(&head->lock);
+
+	/* Check TIME-WAIT sockets first. */
+	sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+		tw = inet_twsk(sk2);
+
+		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+			if (twsk_unique(sk, sk2, twp))
+				goto unique;
+			else
+				goto not_unique;
+		}
+	}
+	tw = NULL;
+
+	/* And established part... */
+	sk_for_each(sk2, node, &head->chain) {
+		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+			goto not_unique;
+	}
+
+unique:
+	/* Must record num and sport now. Otherwise we will see
+	 * in hash table socket with a funny identity. */
+	inet->num = lport;
+	inet->sport = htons(lport);
+	sk->sk_hash = hash;
+	BUG_TRAP(sk_unhashed(sk));
+	__sk_add_node(sk, &head->chain);
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(&head->lock);
+
+	if (twp) {
+		*twp = tw;
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+	} else if (tw) {
+		/* Silly. Should hash-dance instead... */
+		inet_twsk_deschedule(tw, death_row);
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+		inet_twsk_put(tw);
+	}
+
+	return 0;
+
+not_unique:
+	write_unlock(&head->lock);
+	return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet_sk_port_offset(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	return secure_ipv4_port_ephemeral(inet->rcv_saddr, inet->daddr, 
+					  inet->dport);
+}
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+		      struct sock *sk)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const unsigned short snum = inet_sk(sk)->num;
+ 	struct inet_bind_hashbucket *head;
+ 	struct inet_bind_bucket *tb;
+	int ret;
+
+ 	if (!snum) {
+ 		int low = sysctl_local_port_range[0];
+ 		int high = sysctl_local_port_range[1];
+		int range = high - low;
+ 		int i;
+		int port;
+		static u32 hint;
+		u32 offset = hint + inet_sk_port_offset(sk);
+		struct hlist_node *node;
+ 		struct inet_timewait_sock *tw = NULL;
+
+ 		local_bh_disable();
+		for (i = 1; i <= range; i++) {
+			port = low + (i + offset) % range;
+ 			head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+ 			spin_lock(&head->lock);
+
+ 			/* Does not bother with rcv_saddr checks,
+ 			 * because the established check is already
+ 			 * unique enough.
+ 			 */
+			inet_bind_bucket_for_each(tb, node, &head->chain) {
+ 				if (tb->port == port) {
+ 					BUG_TRAP(!hlist_empty(&tb->owners));
+ 					if (tb->fastreuse >= 0)
+ 						goto next_port;
+ 					if (!__inet_check_established(death_row,
+								      sk, port,
+								      &tw))
+ 						goto ok;
+ 					goto next_port;
+ 				}
+ 			}
+
+ 			tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+ 			if (!tb) {
+ 				spin_unlock(&head->lock);
+ 				break;
+ 			}
+ 			tb->fastreuse = -1;
+ 			goto ok;
+
+ 		next_port:
+ 			spin_unlock(&head->lock);
+ 		}
+ 		local_bh_enable();
+
+ 		return -EADDRNOTAVAIL;
+
+ok:
+		hint += i;
+
+ 		/* Head lock still held and bh's disabled */
+ 		inet_bind_hash(sk, tb, port);
+		if (sk_unhashed(sk)) {
+ 			inet_sk(sk)->sport = htons(port);
+ 			__inet_hash(hinfo, sk, 0);
+ 		}
+ 		spin_unlock(&head->lock);
+
+ 		if (tw) {
+ 			inet_twsk_deschedule(tw, death_row);;
+ 			inet_twsk_put(tw);
+ 		}
+
+		ret = 0;
+		goto out;
+ 	}
+
+ 	head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+ 	tb  = inet_csk(sk)->icsk_bind_hash;
+	spin_lock_bh(&head->lock);
+	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+		__inet_hash(hinfo, sk, 0);
+		spin_unlock_bh(&head->lock);
+		return 0;
+	} else {
+		spin_unlock(&head->lock);
+		/* No definite answer... Walk to established hash table */
+		ret = __inet_check_established(death_row, sk, snum, NULL);
+out:
+		local_bh_enable();
+		return ret;
+	}
+}
+
+EXPORT_SYMBOL_GPL(inet_hash_connect);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index a010e9a..417f126 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -90,8 +90,9 @@
 
 struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state)
 {
-	struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab,
-							 SLAB_ATOMIC);
+	struct inet_timewait_sock *tw =
+		kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab,
+				 SLAB_ATOMIC);
 	if (tw != NULL) {
 		const struct inet_sock *inet = inet_sk(sk);
 
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 2fc3fd3..ce5fe3f 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -401,6 +401,7 @@
 		return NULL;
 	n->v4daddr = daddr;
 	atomic_set(&n->refcnt, 1);
+	atomic_set(&n->rid, 0);
 	n->ip_id_count = secure_ip_id(daddr);
 	n->tcp_ts_stamp = 0;
 
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 8ce0ce2..ce2b70c 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -22,6 +22,7 @@
  *		Patrick McHardy :	LRU queue of frag heads for evictor.
  */
 
+#include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -38,6 +39,7 @@
 #include <net/ip.h>
 #include <net/icmp.h>
 #include <net/checksum.h>
+#include <net/inetpeer.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/inet.h>
@@ -56,6 +58,8 @@
 int sysctl_ipfrag_high_thresh = 256*1024;
 int sysctl_ipfrag_low_thresh = 192*1024;
 
+int sysctl_ipfrag_max_dist = 64;
+
 /* Important NOTE! Fragment queue must be destroyed before MSL expires.
  * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
  */
@@ -89,8 +93,10 @@
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	int		iif;
 	struct timeval	stamp;
+	int             iif;
+	unsigned int    rid;
+	struct inet_peer *peer;
 };
 
 /* Hash table. */
@@ -195,6 +201,9 @@
 	BUG_TRAP(qp->last_in&COMPLETE);
 	BUG_TRAP(del_timer(&qp->timer) == 0);
 
+	if (qp->peer)
+		inet_putpeer(qp->peer);
+
 	/* Release all fragment data. */
 	fp = qp->fragments;
 	while (fp) {
@@ -353,6 +362,7 @@
 	qp->meat = 0;
 	qp->fragments = NULL;
 	qp->iif = 0;
+	qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
 
 	/* Initialize a timer for this entry. */
 	init_timer(&qp->timer);
@@ -398,6 +408,56 @@
 	return ip_frag_create(hash, iph, user);
 }
 
+/* Is the fragment too far ahead to be part of ipq? */
+static inline int ip_frag_too_far(struct ipq *qp)
+{
+	struct inet_peer *peer = qp->peer;
+	unsigned int max = sysctl_ipfrag_max_dist;
+	unsigned int start, end;
+
+	int rc;
+
+	if (!peer || !max)
+		return 0;
+
+	start = qp->rid;
+	end = atomic_inc_return(&peer->rid);
+	qp->rid = end;
+
+	rc = qp->fragments && (end - start) > max;
+
+	if (rc) {
+		IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
+	}
+
+	return rc;
+}
+
+static int ip_frag_reinit(struct ipq *qp)
+{
+	struct sk_buff *fp;
+
+	if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
+		atomic_inc(&qp->refcnt);
+		return -ETIMEDOUT;
+	}
+
+	fp = qp->fragments;
+	do {
+		struct sk_buff *xp = fp->next;
+		frag_kfree_skb(fp, NULL);
+		fp = xp;
+	} while (fp);
+
+	qp->last_in = 0;
+	qp->len = 0;
+	qp->meat = 0;
+	qp->fragments = NULL;
+	qp->iif = 0;
+
+	return 0;
+}
+
 /* Add new segment to existing queue. */
 static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 {
@@ -408,6 +468,12 @@
 	if (qp->last_in & COMPLETE)
 		goto err;
 
+	if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
+	    unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) {
+		ipq_kill(qp);
+		goto err;
+	}
+
  	offset = ntohs(skb->nh.iph->frag_off);
 	flags = offset & ~IP_OFFSET;
 	offset &= IP_OFFSET;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 473d0f2..e45846a 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -128,6 +128,7 @@
 #include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index dbe12da..d3f6c46 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -22,6 +22,7 @@
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
+#include <net/route.h>
 
 /* 
  * Write options to IP header, record destination address to
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index eba64e2..2a830de 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -445,6 +445,7 @@
 
 	hlen = iph->ihl * 4;
 	mtu = dst_mtu(&rt->u.dst) - hlen;	/* Size of data space */
+	IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
 
 	/* When frag_list is given, use it. First, check its validity:
 	 * some transformers could create wrong frag_list or break existing
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4f2d872..6986e11 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -25,12 +25,12 @@
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
-#include <net/tcp.h>
-#include <linux/tcp.h>
+#include <net/tcp_states.h>
 #include <linux/udp.h>
 #include <linux/igmp.h>
 #include <linux/netfilter.h>
@@ -427,8 +427,8 @@
 			err = ip_options_get_from_user(&opt, optval, optlen);
 			if (err)
 				break;
-			if (sk->sk_type == SOCK_STREAM) {
-				struct tcp_sock *tp = tcp_sk(sk);
+			if (inet->is_icsk) {
+				struct inet_connection_sock *icsk = inet_csk(sk);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 				if (sk->sk_family == PF_INET ||
 				    (!((1 << sk->sk_state) &
@@ -436,10 +436,10 @@
 				     inet->daddr != LOOPBACK4_IPV6)) {
 #endif
 					if (inet->opt)
-						tp->ext_header_len -= inet->opt->optlen;
+						icsk->icsk_ext_hdr_len -= inet->opt->optlen;
 					if (opt)
-						tp->ext_header_len += opt->optlen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+						icsk->icsk_ext_hdr_len += opt->optlen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 				}
 #endif
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index fc718df..d64e2ec 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -28,6 +28,7 @@
 #include <net/xfrm.h>
 #include <net/icmp.h>
 #include <net/ipcomp.h>
+#include <net/protocol.h>
 
 struct ipcomp_tfms {
 	struct list_head list;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index e8674ba..bb3613e 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -42,6 +42,7 @@
 #include <linux/in.h>
 #include <linux/if.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
@@ -58,6 +59,7 @@
 #include <net/arp.h>
 #include <net/ip.h>
 #include <net/ipconfig.h>
+#include <net/route.h>
 
 #include <asm/uaccess.h>
 #include <net/checksum.h>
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 302b7eb..caa3b7d 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -52,6 +52,7 @@
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
+#include <net/route.h>
 #include <net/sock.h>
 #include <net/icmp.h>
 #include <net/udp.h>
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index d7eb680..9b176a9 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -224,34 +224,6 @@
 }
 
 
-#if 0000
-/*
- *	Get reference to app by name (called from user context)
- */
-struct ip_vs_app *ip_vs_app_get_by_name(char *appname)
-{
-	struct ip_vs_app *app, *a = NULL;
-
-	down(&__ip_vs_app_mutex);
-
-	list_for_each_entry(ent, &ip_vs_app_list, a_list) {
-		if (strcmp(app->name, appname))
-			continue;
-
-		/* softirq may call ip_vs_app_get too, so the caller
-		   must disable softirq on the current CPU */
-		if (ip_vs_app_get(app))
-			a = app;
-		break;
-	}
-
-	up(&__ip_vs_app_mutex);
-
-	return a;
-}
-#endif
-
-
 /*
  *	Bind ip_vs_conn to its ip_vs_app (called by cp constructor)
  */
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 2a3a8c5..81d9035 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -24,7 +24,10 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/net.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>		/* for proc_net_* */
 #include <linux/seq_file.h>
@@ -219,7 +222,7 @@
 	if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
 		cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port);
 
-	IP_VS_DBG(7, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -254,7 +257,7 @@
   out:
 	ct_read_unlock(hash);
 
-	IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -295,7 +298,7 @@
 
 	ct_read_unlock(hash);
 
-	IP_VS_DBG(7, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -391,8 +394,9 @@
 	cp->flags |= atomic_read(&dest->conn_flags);
 	cp->dest = dest;
 
-	IP_VS_DBG(9, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-		  "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+	IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+		  "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+		  "dest->refcnt:%d\n",
 		  ip_vs_proto_name(cp->protocol),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -430,8 +434,9 @@
 	if (!dest)
 		return;
 
-	IP_VS_DBG(9, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-		  "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+	IP_VS_DBG(7, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+		  "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+		  "dest->refcnt:%d\n",
 		  ip_vs_proto_name(cp->protocol),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -571,7 +576,7 @@
 	ip_vs_conn_hash(cp);
 
   expire_later:
-	IP_VS_DBG(7, "delayed: refcnt-1=%d conn.n_control=%d\n",
+	IP_VS_DBG(7, "delayed: conn->refcnt-1=%d conn->n_control=%d\n",
 		  atomic_read(&cp->refcnt)-1,
 		  atomic_read(&cp->n_control));
 
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 1a0843c..1aca94a 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -426,7 +426,7 @@
 		return NULL;
 
 	IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u "
-		  "d:%u.%u.%u.%u:%u flg:%X cnt:%d\n",
+		  "d:%u.%u.%u.%u:%u conn->flags:%X conn->refcnt:%d\n",
 		  ip_vs_fwd_tag(cp),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 9bdcf31..c935c50 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -35,6 +35,7 @@
 #include <linux/netfilter_ipv4.h>
 
 #include <net/ip.h>
+#include <net/route.h>
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
@@ -447,7 +448,7 @@
   out:
 	read_unlock(&__ip_vs_svc_lock);
 
-	IP_VS_DBG(6, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
+	IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
 		  fwmark, ip_vs_proto_name(protocol),
 		  NIPQUAD(vaddr), ntohs(vport),
 		  svc?"hit":"not hit");
@@ -597,7 +598,7 @@
 	 */
 	list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
 		IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
-			  "refcnt=%d\n",
+			  "dest->refcnt=%d\n",
 			  dest->vfwmark,
 			  NIPQUAD(dest->addr), ntohs(dest->port),
 			  atomic_read(&dest->refcnt));
@@ -804,7 +805,7 @@
 	dest = ip_vs_trash_get_dest(svc, daddr, dport);
 	if (dest != NULL) {
 		IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, "
-			  "refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
+			  "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
 			  NIPQUAD(daddr), ntohs(dport),
 			  atomic_read(&dest->refcnt),
 			  dest->vfwmark,
@@ -949,7 +950,8 @@
 		atomic_dec(&dest->svc->refcnt);
 		kfree(dest);
 	} else {
-		IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, refcnt=%d\n",
+		IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, "
+			  "dest->refcnt=%d\n",
 			  NIPQUAD(dest->addr), ntohs(dest->port),
 			  atomic_read(&dest->refcnt));
 		list_add(&dest->n_list, &ip_vs_dest_trash);
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c
index f3bc320..9fee19c 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/ipv4/ipvs/ip_vs_dh.c
@@ -37,8 +37,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index 67b3e2f..e700474 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -13,7 +13,10 @@
  * Changes:
  *
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <net/ip_vs.h>
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 561cda3..6e5cb92 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -41,8 +41,10 @@
  * me to write this module.
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -228,33 +230,6 @@
 }
 
 
-#if 0000
-/*
- *	Unhash ip_vs_lblc_entry from ip_vs_lblc_table.
- *	returns bool success.
- */
-static int ip_vs_lblc_unhash(struct ip_vs_lblc_table *tbl,
-			     struct ip_vs_lblc_entry *en)
-{
-	if (list_empty(&en->list)) {
-		IP_VS_ERR("ip_vs_lblc_unhash(): request for not hashed entry, "
-			  "called from %p\n", __builtin_return_address(0));
-		return 0;
-	}
-
-	/*
-	 * Remove it from the table
-	 */
-	write_lock(&tbl->lock);
-	list_del(&en->list);
-	INIT_LIST_HEAD(&en->list);
-	write_unlock(&tbl->lock);
-
-	return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblc_entry associated with supplied parameters.
  */
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index ce456db..32ba37b 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -39,8 +39,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -414,33 +416,6 @@
 }
 
 
-#if 0000
-/*
- *	Unhash ip_vs_lblcr_entry from ip_vs_lblcr_table.
- *	returns bool success.
- */
-static int ip_vs_lblcr_unhash(struct ip_vs_lblcr_table *tbl,
-			     struct ip_vs_lblcr_entry *en)
-{
-	if (list_empty(&en->list)) {
-		IP_VS_ERR("ip_vs_lblcr_unhash(): request for not hashed entry, "
-			  "called from %p\n", __builtin_return_address(0));
-		return 0;
-	}
-
-	/*
-	 * Remove it from the table
-	 */
-	write_lock(&tbl->lock);
-	list_del(&en->list);
-	INIT_LIST_HEAD(&en->list);
-	write_unlock(&tbl->lock);
-
-	return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblcr_entry associated with supplied parameters.
  */
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
index 453e94a..8b0505b 100644
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
index 478e5c7..c36ccf0 100644
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index 0e878fd..bc28b11 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -275,28 +275,6 @@
 	[IP_VS_TCP_S_LAST]		=	2*HZ,
 };
 
-
-#if 0
-
-/* FIXME: This is going to die */
-
-static int tcp_timeouts_dos[IP_VS_TCP_S_LAST+1] = {
-	[IP_VS_TCP_S_NONE]		=	2*HZ,
-	[IP_VS_TCP_S_ESTABLISHED]	=	8*60*HZ,
-	[IP_VS_TCP_S_SYN_SENT]		=	60*HZ,
-	[IP_VS_TCP_S_SYN_RECV]		=	10*HZ,
-	[IP_VS_TCP_S_FIN_WAIT]		=	60*HZ,
-	[IP_VS_TCP_S_TIME_WAIT]		=	60*HZ,
-	[IP_VS_TCP_S_CLOSE]		=	10*HZ,
-	[IP_VS_TCP_S_CLOSE_WAIT]	=	60*HZ,
-	[IP_VS_TCP_S_LAST_ACK]		=	30*HZ,
-	[IP_VS_TCP_S_LISTEN]		=	2*60*HZ,
-	[IP_VS_TCP_S_SYNACK]		=	100*HZ,
-	[IP_VS_TCP_S_LAST]		=	2*HZ,
-};
-
-#endif
-
 static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
 	[IP_VS_TCP_S_NONE]		=	"NONE",
 	[IP_VS_TCP_S_ESTABLISHED]	=	"ESTABLISHED",
@@ -448,7 +426,7 @@
 		struct ip_vs_dest *dest = cp->dest;
 
 		IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->"
-			  "%u.%u.%u.%u:%d state: %s->%s cnt:%d\n",
+			  "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n",
 			  pp->name,
 			  (state_off==TCP_DIR_OUTPUT)?"output ":"input ",
 			  th->syn? 'S' : '.',
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 8ae5f2e..89d9175 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -15,8 +15,11 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/kernel.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/udp.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c
index 6f7c50e..7775e6c 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/ipv4/ipvs/ip_vs_sh.c
@@ -34,8 +34,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 2e5ced3..1bca714 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -21,12 +21,14 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/inetdevice.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 */
+#include <linux/udp.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 3c2e963..bba1563 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -68,19 +68,14 @@
 	unsigned int initial_entries;
 	unsigned int hook_entry[NF_ARP_NUMHOOKS];
 	unsigned int underflow[NF_ARP_NUMHOOKS];
-	char entries[0] __attribute__((aligned(SMP_CACHE_BYTES)));
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(arpt_target);
 static LIST_HEAD(arpt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
 				      char *hdr_addr, int len)
 {
@@ -269,9 +264,7 @@
 	outdev = out ? out->name : nulldevname;
 
 	read_lock_bh(&table->lock);
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private,
-			       smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 	back = get_entry(table_base, table->private->underflow[hook]);
 
@@ -462,7 +455,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
  * there are loops.  Puts hook bitmask in comefrom.
  */
-static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks)
+static int mark_source_chains(struct arpt_table_info *newinfo,
+			      unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -472,7 +466,7 @@
 	for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct arpt_entry *e
-			= (struct arpt_entry *)(newinfo->entries + pos);
+			= (struct arpt_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -514,13 +508,13 @@
 						goto next;
 
 					e = (struct arpt_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct arpt_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -537,7 +531,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct arpt_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -689,6 +683,7 @@
 static int translate_table(const char *name,
 			   unsigned int valid_hooks,
 			   struct arpt_table_info *newinfo,
+			   void *entry0,
 			   unsigned int size,
 			   unsigned int number,
 			   const unsigned int *hook_entries,
@@ -710,11 +705,11 @@
 	i = 0;
 
 	/* Walk through entries, checking offsets. */
-	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				 check_entry_size_and_hooks,
 				 newinfo,
-				 newinfo->entries,
-				 newinfo->entries + size,
+				 entry0,
+				 entry0 + size,
 				 hook_entries, underflows, &i);
 	duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
 	if (ret != 0)
@@ -743,29 +738,26 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks)) {
+	if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
 		duprintf("Looping hook\n");
 		return -ELOOP;
 	}
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				 check_entry, name, size, &i);
 
 	if (ret != 0) {
-		ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				   cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -807,15 +799,42 @@
 	return 0;
 }
 
+static inline int set_entry_to_counter(const struct arpt_entry *e,
+				       struct arpt_counters total[],
+				       unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void get_counters(const struct arpt_table_info *t,
 			 struct arpt_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	ARPT_ENTRY_ITERATE(t->entries[curcpu],
+			   t->size,
+			   set_entry_to_counter,
+			   counters,
+			   &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		ARPT_ENTRY_ITERATE(t->entries[cpu],
 				   t->size,
 				   add_entry_to_counter,
 				   counters,
@@ -831,6 +850,7 @@
 	struct arpt_entry *e;
 	struct arpt_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	 * (other than comefrom, which userspace doesn't care
@@ -843,13 +863,13 @@
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	/* ... then copy entire thing ... */
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -859,7 +879,7 @@
 	for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
 		struct arpt_entry_target *t;
 
-		e = (struct arpt_entry *)(table->private->entries + off);
+		e = (struct arpt_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct arpt_entry, counters),
 				 &counters[num],
@@ -911,6 +931,47 @@
 	return ret;
 }
 
+static void free_table_info(struct arpt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct arpt_table_info *alloc_table_info(unsigned int size)
+{
+	struct arpt_table_info *newinfo;
+	int cpu;
+	
+	newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+							GFP_KERNEL,
+							cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size,
+							     cpu_to_node(cpu));
+
+		if (newinfo->entries[cpu] == NULL) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int do_replace(void __user *user, unsigned int len)
 {
 	int ret;
@@ -918,6 +979,7 @@
 	struct arpt_table *t;
 	struct arpt_table_info *newinfo, *oldinfo;
 	struct arpt_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -930,13 +992,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(tmp.size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -947,10 +1009,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct arpt_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -989,8 +1050,10 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct arpt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1002,11 +1065,11 @@
 	module_put(t->me);
 	up(&arpt_mutex);
  free_newinfo_counters_untrans:
-	ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
+	ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1030,6 +1093,7 @@
 	struct arpt_counters_info tmp, *paddc;
 	struct arpt_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1059,7 +1123,9 @@
 	}
 
 	i = 0;
-	ARPT_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_entry,
 			   t->private->size,
 			   add_counter_to_entry,
 			   paddc->counters,
@@ -1220,30 +1286,32 @@
 	struct arpt_table_info *newinfo;
 	static struct arpt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(repl->size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	memcpy(newinfo->entries, repl->entries, repl->size);
+
+	/* choose the copy on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, 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);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&arpt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1272,20 +1340,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void arpt_unregister_table(struct arpt_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&arpt_mutex);
 	LIST_DELETE(&arpt_tables, table);
 	up(&arpt_mutex);
 
 	/* Decrease module usage counts and free resources */
-	ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			   cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* The built-in targets: standard (NULL) and error. */
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index e52847f..0366eed 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -18,11 +18,13 @@
  *
  */
 
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <linux/moduleparam.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
index 744abb9..57956de 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
@@ -31,6 +31,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/list.h>
+#include <linux/seq_file.h>
 
 static DEFINE_RWLOCK(ip_ct_gre_lock);
 #define ASSERT_READ_LOCK(x)
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
index f2dcac7..46becbe 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/netfilter.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/seq_file.h>
 #include <net/checksum.h>
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index dd476b1..a88bcc5 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -27,6 +27,7 @@
 #endif
 #include <net/checksum.h>
 #include <net/ip.h>
+#include <net/route.h>
 
 #define ASSERT_READ_LOCK(x)
 #define ASSERT_WRITE_LOCK(x)
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 8acb7ed..4f95d47 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -44,6 +44,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -53,6 +54,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/ip.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 #include <asm/uaccess.h>
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 45886c8..2a26d16 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -83,11 +83,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -105,20 +100,15 @@
 	unsigned int underflow[NF_IP_NUMHOOKS];
 
 	/* ipt_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ipt_target);
 static LIST_HEAD(ipt_match);
 static LIST_HEAD(ipt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
@@ -290,8 +280,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -563,7 +552,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ipt_table_info *newinfo,
+		   unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -572,7 +562,7 @@
 	for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ipt_entry *e
-			= (struct ipt_entry *)(newinfo->entries + pos);
+			= (struct ipt_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -622,13 +612,13 @@
 						goto next;
 
 					e = (struct ipt_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ipt_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -645,7 +635,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ipt_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -855,6 +845,7 @@
 translate_table(const char *name,
 		unsigned int valid_hooks,
 		struct ipt_table_info *newinfo,
+		void *entry0,
 		unsigned int size,
 		unsigned int number,
 		const unsigned int *hook_entries,
@@ -875,11 +866,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				entry0,
+				entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -907,27 +898,24 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks))
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
 		return -ELOOP;
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -943,15 +931,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ipt_entry *table_base;
-		unsigned int i;
+		int cpu;
 
-		for_each_cpu(i) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
-
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ipt_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -986,16 +971,44 @@
 	return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ipt_entry *e,
+		     struct ipt_counters total[],
+		     unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void
 get_counters(const struct ipt_table_info *t,
 	     struct ipt_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	IPT_ENTRY_ITERATE(t->entries[curcpu],
+			  t->size,
+			  set_entry_to_counter,
+			  counters,
+			  &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IPT_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
@@ -1012,24 +1025,29 @@
 	struct ipt_entry *e;
 	struct ipt_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	   (other than comefrom, which userspace doesn't care
 	   about). */
 	countersize = sizeof(struct ipt_counters) * table->private->number;
-	counters = vmalloc(countersize);
+	counters = vmalloc_node(countersize, numa_node_id());
 
 	if (counters == NULL)
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	/* choose the copy that is on our node/cpu, ...
+	 * This choice is lazy (because current thread is
+	 * allowed to migrate to another cpu)
+	 */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	/* ... then copy entire thing ... */
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1041,7 +1059,7 @@
 		struct ipt_entry_match *m;
 		struct ipt_entry_target *t;
 
-		e = (struct ipt_entry *)(table->private->entries + off);
+		e = (struct ipt_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ipt_entry, counters),
 				 &counters[num],
@@ -1110,6 +1128,45 @@
 	return ret;
 }
 
+static void free_table_info(struct ipt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct ipt_table_info *alloc_table_info(unsigned int size)
+{
+	struct ipt_table_info *newinfo;
+	int cpu;
+
+	newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+				GFP_KERNEL,
+				cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu));
+		if (newinfo->entries[cpu] == 0) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1118,6 +1175,7 @@
 	struct ipt_table *t;
 	struct ipt_table_info *newinfo, *oldinfo;
 	struct ipt_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1130,13 +1188,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(tmp.size) * 
-			  	(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1147,10 +1205,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -1189,8 +1246,9 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ipt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1202,11 +1260,11 @@
 	module_put(t->me);
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
-	IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1239,6 +1297,7 @@
 	struct ipt_counters_info tmp, *paddc;
 	struct ipt_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1246,7 +1305,7 @@
 	if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters))
 		return -EINVAL;
 
-	paddc = vmalloc(len);
+	paddc = vmalloc_node(len, numa_node_id());
 	if (!paddc)
 		return -ENOMEM;
 
@@ -1268,7 +1327,9 @@
 	}
 
 	i = 0;
-	IPT_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1460,28 +1521,31 @@
 	struct ipt_table_info *newinfo;
 	static struct ipt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(repl->size) * 
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	/* choose the copy on our node/cpu
+	 * but dont care of preemption
+	 */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1510,20 +1574,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void ipt_unregister_table(struct ipt_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&ipt_mutex);
 	LIST_DELETE(&ipt_tables, table);
 	up(&ipt_mutex);
 
 	/* Decrease module usage counts and free resources */
-	IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 275a174..2786051 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -11,6 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/inetdevice.h>
 #include <linux/ip.h>
 #include <linux/timer.h>
 #include <linux/module.h>
@@ -18,6 +19,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/checksum.h>
+#include <net/route.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
diff --git a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c
index 1a53924..03f5548 100644
--- a/net/ipv4/netfilter/ipt_physdev.c
+++ b/net/ipv4/netfilter/ipt_physdev.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ipt_physdev.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 0d7dc66..39d49dc 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -38,6 +38,7 @@
 #include <net/protocol.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <net/sock.h>
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index a34e60e..e20be33 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -173,10 +173,10 @@
 					   struct request_sock *req,
 					   struct dst_entry *dst)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct sock *child;
 
-	child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
+	child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
 	if (child)
 		inet_csk_reqsk_queue_add(sk, req, child);
 	else
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 01444a0..16984d4 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -12,6 +12,7 @@
 #include <linux/sysctl.h>
 #include <linux/config.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
@@ -22,6 +23,7 @@
 extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_SYSCTL
+static int zero;
 static int tcp_retr1_max = 255; 
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
@@ -614,6 +616,15 @@
 		.strategy	= &sysctl_jiffies
 	},
 	{
+		.ctl_name	= NET_IPV4_IPFRAG_MAX_DIST,
+		.procname	= "ipfrag_max_dist",
+		.data		= &sysctl_ipfrag_max_dist,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.extra1		= &zero
+	},
+	{
 		.ctl_name	= NET_TCP_NO_METRICS_SAVE,
 		.procname	= "tcp_no_metrics_save",
 		.data		= &sysctl_tcp_nometrics_save,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ef98b14..00aa80e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1696,8 +1696,8 @@
 	int err = 0;
 
 	if (level != SOL_TCP)
-		return tp->af_specific->setsockopt(sk, level, optname,
-						   optval, optlen);
+		return icsk->icsk_af_ops->setsockopt(sk, level, optname,
+						     optval, optlen);
 
 	/* This is a string value all the others are int's */
 	if (optname == TCP_CONGESTION) {
@@ -1914,7 +1914,7 @@
 	info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
 	info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
 
-	info->tcpi_pmtu = tp->pmtu_cookie;
+	info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
 	info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
 	info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3;
 	info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2;
@@ -1939,8 +1939,8 @@
 	int val, len;
 
 	if (level != SOL_TCP)
-		return tp->af_specific->getsockopt(sk, level, optname,
-						   optval, optlen);
+		return icsk->icsk_af_ops->getsockopt(sk, level, optname,
+						     optval, optlen);
 
 	if (get_user(len, optlen))
 		return -EFAULT;
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 1d0cd86..035f209 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -30,8 +30,6 @@
 static int max_increment = 16;
 static int low_window = 14;
 static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
-static int low_utilization_threshold = 153;
-static int low_utilization_period = 2;
 static int initial_ssthresh = 100;
 static int smooth_part = 20;
 
@@ -43,10 +41,6 @@
 MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
 module_param(beta, int, 0644);
 MODULE_PARM_DESC(beta, "beta for multiplicative increase");
-module_param(low_utilization_threshold, int, 0644);
-MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode");
-module_param(low_utilization_period, int, 0644);
-MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)");
 module_param(initial_ssthresh, int, 0644);
 MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
 module_param(smooth_part, int, 0644);
@@ -60,11 +54,6 @@
 	u32	loss_cwnd;	/* congestion window at last loss */
 	u32	last_cwnd;	/* the last snd_cwnd */
 	u32	last_time;	/* time when updated last_cwnd */
-	u32	delay_min;	/* min delay */
-	u32	delay_max;	/* max delay */
-	u32	last_delay;
-	u8	low_utilization;/* 0: high; 1: low */
-	u32	low_utilization_start;	/* starting time of low utilization detection*/
 	u32	epoch_start;	/* beginning of an epoch */
 #define ACK_RATIO_SHIFT	4
 	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
@@ -77,11 +66,6 @@
 	ca->loss_cwnd = 0;
 	ca->last_cwnd = 0;
 	ca->last_time = 0;
-	ca->delay_min = 0;
-	ca->delay_max = 0;
-	ca->last_delay = 0;
-	ca->low_utilization = 0;
-	ca->low_utilization_start = 0;
 	ca->epoch_start = 0;
 	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
 }
@@ -143,8 +127,7 @@
 	}
 
 	/* if in slow start or link utilization is very low */
-	if ( ca->loss_cwnd == 0 ||
-	     (cwnd > ca->loss_cwnd && ca->low_utilization)) {
+	if (ca->loss_cwnd == 0) {
 		if (ca->cnt > 20) /* increase cwnd 5% per RTT */
 			ca->cnt = 20;
 	}
@@ -154,69 +137,12 @@
 		ca->cnt = 1;
 }
 
-
-/* Detect low utilization in congestion avoidance */
-static inline void bictcp_low_utilization(struct sock *sk, int flag)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	struct bictcp *ca = inet_csk_ca(sk);
-	u32 dist, delay;
-
-	/* No time stamp */
-	if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
-	     /* Discard delay samples right after fast recovery */
-	     tcp_time_stamp < ca->epoch_start + HZ ||
-	     /* this delay samples may not be accurate */
-	     flag == 0) {
-		ca->last_delay = 0;
-		goto notlow;
-	}
-
-	delay = ca->last_delay<<3;	/* use the same scale as tp->srtt*/
-	ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
-	if (delay == 0) 		/* no previous delay sample */
-		goto notlow;
-
-	/* first time call or link delay decreases */
-	if (ca->delay_min == 0 || ca->delay_min > delay) {
-		ca->delay_min = ca->delay_max = delay;
-		goto notlow;
-	}
-
-	if (ca->delay_max < delay)
-		ca->delay_max = delay;
-
-	/* utilization is low, if avg delay < dist*threshold
-	   for checking_period time */
-	dist = ca->delay_max - ca->delay_min;
-	if (dist <= ca->delay_min>>6 ||
-	    tp->srtt - ca->delay_min >=  (dist*low_utilization_threshold)>>10)
-		goto notlow;
-
-	if (ca->low_utilization_start == 0) {
-		ca->low_utilization = 0;
-		ca->low_utilization_start = tcp_time_stamp;
-	} else if ((s32)(tcp_time_stamp - ca->low_utilization_start)
-			> low_utilization_period*HZ) {
-		ca->low_utilization = 1;
-	}
-
-	return;
-
- notlow:
-	ca->low_utilization = 0;
-	ca->low_utilization_start = 0;
-
-}
-
 static void bictcp_cong_avoid(struct sock *sk, u32 ack,
 			      u32 seq_rtt, u32 in_flight, int data_acked)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct bictcp *ca = inet_csk_ca(sk);
 
-	bictcp_low_utilization(sk, data_acked);
-
 	if (!tcp_is_cwnd_limited(sk, in_flight))
 		return;
 
@@ -249,11 +175,6 @@
 
 	ca->epoch_start = 0;	/* end of epoch */
 
-	/* in case of wrong delay_max*/
-	if (ca->delay_min > 0 && ca->delay_max > ca->delay_min)
-		ca->delay_max = ca->delay_min
-			+ ((ca->delay_max - ca->delay_min)* 90) / 100;
-
 	/* Wmax and fast convergence */
 	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
 		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
@@ -289,14 +210,14 @@
 		bictcp_reset(inet_csk_ca(sk));
 }
 
-/* Track delayed acknowledgement ratio using sliding window
+/* Track delayed acknowledgment ratio using sliding window
  * ratio = (15*ratio + sample) / 16
  */
 static void bictcp_acked(struct sock *sk, u32 cnt)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 
-	if (cnt > 0 && 	icsk->icsk_ca_state == TCP_CA_Open) {
+	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
 		struct bictcp *ca = inet_csk_ca(sk);
 		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
 		ca->delayed_ack += cnt;
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index c7cc62c..e688c68 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -174,6 +174,34 @@
 	return err;
 }
 
+
+/*
+ * Linear increase during slow start
+ */
+void tcp_slow_start(struct tcp_sock *tp)
+{
+	if (sysctl_tcp_abc) {
+		/* RFC3465: Slow Start
+		 * TCP sender SHOULD increase cwnd by the number of
+		 * previously unacknowledged bytes ACKed by each incoming
+		 * acknowledgment, provided the increase is not more than L
+		 */
+		if (tp->bytes_acked < tp->mss_cache)
+			return;
+
+		/* We MAY increase by 2 if discovered delayed ack */
+		if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+		}
+	}
+	tp->bytes_acked = 0;
+
+	if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+		tp->snd_cwnd++;
+}
+EXPORT_SYMBOL_GPL(tcp_slow_start);
+
 /*
  * TCP Reno congestion control
  * This is special case used for fallback as well.
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
new file mode 100644
index 0000000..31a4986
--- /dev/null
+++ b/net/ipv4/tcp_cubic.c
@@ -0,0 +1,411 @@
+/*
+ * TCP CUBIC: Binary Increase Congestion control for TCP v2.0
+ *
+ * This is from the implementation of CUBIC TCP in
+ * Injong Rhee, Lisong Xu.
+ *  "CUBIC: A New TCP-Friendly High-Speed TCP Variant
+ *  in PFLDnet 2005
+ * Available from:
+ *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+ *
+ * Unless CUBIC is enabled and congestion window is large
+ * this behaves the same as the original Reno.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+#include <asm/div64.h>
+
+#define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
+					 * max_cwnd = snd_cwnd * beta
+					 */
+#define BICTCP_B		4	 /*
+					  * In binary search,
+					  * go to point (max+min)/N
+					  */
+#define	BICTCP_HZ		10	/* BIC HZ 2^10 = 1024 */
+
+static int fast_convergence = 1;
+static int max_increment = 16;
+static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
+static int initial_ssthresh = 100;
+static int bic_scale = 41;
+static int tcp_friendliness = 1;
+
+static u32 cube_rtt_scale;
+static u32 beta_scale;
+static u64 cube_factor;
+
+/* Note parameters that are used for precomputing scale factors are read-only */
+module_param(fast_convergence, int, 0644);
+MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
+module_param(max_increment, int, 0644);
+MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
+module_param(beta, int, 0444);
+MODULE_PARM_DESC(beta, "beta for multiplicative increase");
+module_param(initial_ssthresh, int, 0644);
+MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
+module_param(bic_scale, int, 0444);
+MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)");
+module_param(tcp_friendliness, int, 0644);
+MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
+
+#include <asm/div64.h>
+
+/* BIC TCP Parameters */
+struct bictcp {
+	u32	cnt;		/* increase cwnd by 1 after ACKs */
+	u32 	last_max_cwnd;	/* last maximum snd_cwnd */
+	u32	loss_cwnd;	/* congestion window at last loss */
+	u32	last_cwnd;	/* the last snd_cwnd */
+	u32	last_time;	/* time when updated last_cwnd */
+	u32	bic_origin_point;/* origin point of bic function */
+	u32	bic_K;		/* time to origin point from the beginning of the current epoch */
+	u32	delay_min;	/* min delay */
+	u32	epoch_start;	/* beginning of an epoch */
+	u32	ack_cnt;	/* number of acks */
+	u32	tcp_cwnd;	/* estimated tcp cwnd */
+#define ACK_RATIO_SHIFT	4
+	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
+};
+
+static inline void bictcp_reset(struct bictcp *ca)
+{
+	ca->cnt = 0;
+	ca->last_max_cwnd = 0;
+	ca->loss_cwnd = 0;
+	ca->last_cwnd = 0;
+	ca->last_time = 0;
+	ca->bic_origin_point = 0;
+	ca->bic_K = 0;
+	ca->delay_min = 0;
+	ca->epoch_start = 0;
+	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
+	ca->ack_cnt = 0;
+	ca->tcp_cwnd = 0;
+}
+
+static void bictcp_init(struct sock *sk)
+{
+	bictcp_reset(inet_csk_ca(sk));
+	if (initial_ssthresh)
+		tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
+}
+
+/* 64bit divisor, dividend and result. dynamic precision */
+static inline u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor)
+{
+	u_int32_t d = divisor;
+
+	if (divisor > 0xffffffffULL) {
+		unsigned int shift = fls(divisor >> 32);
+
+		d = divisor >> shift;
+		dividend >>= shift;
+	}
+
+	/* avoid 64 bit division if possible */
+	if (dividend >> 32)
+		do_div(dividend, d);
+	else
+		dividend = (uint32_t) dividend / d;
+
+	return dividend;
+}
+
+/*
+ * calculate the cubic root of x using Newton-Raphson
+ */
+static u32 cubic_root(u64 a)
+{
+	u32 x, x1;
+
+	/* Initial estimate is based on:
+	 * cbrt(x) = exp(log(x) / 3)
+	 */
+	x = 1u << (fls64(a)/3);
+
+	/*
+	 * Iteration based on:
+	 *                         2
+	 * x    = ( 2 * x  +  a / x  ) / 3
+	 *  k+1          k         k
+	 */
+	do {
+		x1 = x;
+		x = (2 * x + (uint32_t) div64_64(a, x*x)) / 3;
+	} while (abs(x1 - x) > 1);
+
+	return x;
+}
+
+/*
+ * Compute congestion window to use.
+ */
+static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+{
+	u64 offs;
+	u32 delta, t, bic_target, min_cnt, max_cnt;
+
+	ca->ack_cnt++;	/* count the number of ACKs */
+
+	if (ca->last_cwnd == cwnd &&
+	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
+		return;
+
+	ca->last_cwnd = cwnd;
+	ca->last_time = tcp_time_stamp;
+
+	if (ca->epoch_start == 0) {
+		ca->epoch_start = tcp_time_stamp;	/* record the beginning of an epoch */
+		ca->ack_cnt = 1;			/* start counting */
+		ca->tcp_cwnd = cwnd;			/* syn with cubic */
+
+		if (ca->last_max_cwnd <= cwnd) {
+			ca->bic_K = 0;
+			ca->bic_origin_point = cwnd;
+		} else {
+			/* Compute new K based on
+			 * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ)
+			 */
+			ca->bic_K = cubic_root(cube_factor
+					       * (ca->last_max_cwnd - cwnd));
+			ca->bic_origin_point = ca->last_max_cwnd;
+		}
+	}
+
+        /* cubic function - calc*/
+        /* calculate c * time^3 / rtt,
+         *  while considering overflow in calculation of time^3
+	 * (so time^3 is done by using 64 bit)
+	 * and without the support of division of 64bit numbers
+	 * (so all divisions are done by using 32 bit)
+         *  also NOTE the unit of those veriables
+         *	  time  = (t - K) / 2^bictcp_HZ
+         *	  c = bic_scale >> 10
+	 * rtt  = (srtt >> 3) / HZ
+	 * !!! The following code does not have overflow problems,
+	 * if the cwnd < 1 million packets !!!
+         */
+
+	/* change the unit from HZ to bictcp_HZ */
+        t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
+	     << BICTCP_HZ) / HZ;
+
+        if (t < ca->bic_K)		/* t - K */
+		offs = ca->bic_K - t;
+        else
+                offs = t - ca->bic_K;
+
+	/* c/rtt * (t-K)^3 */
+	delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ);
+        if (t < ca->bic_K)                                	/* below origin*/
+                bic_target = ca->bic_origin_point - delta;
+        else                                                	/* above origin*/
+                bic_target = ca->bic_origin_point + delta;
+
+        /* cubic function - calc bictcp_cnt*/
+        if (bic_target > cwnd) {
+		ca->cnt = cwnd / (bic_target - cwnd);
+        } else {
+                ca->cnt = 100 * cwnd;              /* very small increment*/
+        }
+
+	if (ca->delay_min > 0) {
+		/* max increment = Smax * rtt / 0.1  */
+		min_cnt = (cwnd * HZ * 8)/(10 * max_increment * ca->delay_min);
+		if (ca->cnt < min_cnt)
+			ca->cnt = min_cnt;
+	}
+
+        /* slow start and low utilization  */
+	if (ca->loss_cwnd == 0)		/* could be aggressive in slow start */
+		ca->cnt = 50;
+
+	/* TCP Friendly */
+	if (tcp_friendliness) {
+		u32 scale = beta_scale;
+		delta = (cwnd * scale) >> 3;
+	        while (ca->ack_cnt > delta) {		/* update tcp cwnd */
+	                ca->ack_cnt -= delta;
+        	        ca->tcp_cwnd++;
+		}
+
+		if (ca->tcp_cwnd > cwnd){	/* if bic is slower than tcp */
+			delta = ca->tcp_cwnd - cwnd;
+			max_cnt = cwnd / delta;
+			if (ca->cnt > max_cnt)
+				ca->cnt = max_cnt;
+		}
+        }
+
+	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
+	if (ca->cnt == 0)			/* cannot be zero */
+		ca->cnt = 1;
+}
+
+
+/* Keep track of minimum rtt */
+static inline void measure_delay(struct sock *sk)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+	u32 delay;
+
+	/* No time stamp */
+	if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
+	     /* Discard delay samples right after fast recovery */
+	    (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+		return;
+
+	delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	if (delay == 0)
+		delay = 1;
+
+	/* first time call or link delay decreases */
+	if (ca->delay_min == 0 || ca->delay_min > delay)
+		ca->delay_min = delay;
+}
+
+static void bictcp_cong_avoid(struct sock *sk, u32 ack,
+			      u32 seq_rtt, u32 in_flight, int data_acked)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	if (data_acked)
+		measure_delay(sk);
+
+	if (!tcp_is_cwnd_limited(sk, in_flight))
+		return;
+
+	if (tp->snd_cwnd <= tp->snd_ssthresh)
+		tcp_slow_start(tp);
+	else {
+		bictcp_update(ca, tp->snd_cwnd);
+
+		/* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+		 */
+		if (tp->snd_cwnd_cnt >= ca->cnt) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+		} else
+			tp->snd_cwnd_cnt++;
+	}
+
+}
+
+static u32 bictcp_recalc_ssthresh(struct sock *sk)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	ca->epoch_start = 0;	/* end of epoch */
+
+	/* Wmax and fast convergence */
+	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
+		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
+			/ (2 * BICTCP_BETA_SCALE);
+	else
+		ca->last_max_cwnd = tp->snd_cwnd;
+
+	ca->loss_cwnd = tp->snd_cwnd;
+
+	return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
+}
+
+static u32 bictcp_undo_cwnd(struct sock *sk)
+{
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd);
+}
+
+static u32 bictcp_min_cwnd(struct sock *sk)
+{
+	return tcp_sk(sk)->snd_ssthresh;
+}
+
+static void bictcp_state(struct sock *sk, u8 new_state)
+{
+	if (new_state == TCP_CA_Loss)
+		bictcp_reset(inet_csk_ca(sk));
+}
+
+/* Track delayed acknowledgment ratio using sliding window
+ * ratio = (15*ratio + sample) / 16
+ */
+static void bictcp_acked(struct sock *sk, u32 cnt)
+{
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+
+	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
+		struct bictcp *ca = inet_csk_ca(sk);
+		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+		ca->delayed_ack += cnt;
+	}
+}
+
+
+static struct tcp_congestion_ops cubictcp = {
+	.init		= bictcp_init,
+	.ssthresh	= bictcp_recalc_ssthresh,
+	.cong_avoid	= bictcp_cong_avoid,
+	.set_state	= bictcp_state,
+	.undo_cwnd	= bictcp_undo_cwnd,
+	.min_cwnd	= bictcp_min_cwnd,
+	.pkts_acked     = bictcp_acked,
+	.owner		= THIS_MODULE,
+	.name		= "cubic",
+};
+
+static int __init cubictcp_register(void)
+{
+	BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
+
+	/* Precompute a bunch of the scaling factors that are used per-packet
+	 * based on SRTT of 100ms
+	 */
+
+	beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
+
+	cube_rtt_scale = (bic_scale << 3) / 10;	/* 1024*c/rtt */
+
+	/* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
+	 *  so K = cubic_root( (wmax-cwnd)*rtt/c )
+	 * the unit of K is bictcp_HZ=2^10, not HZ
+	 *
+	 *  c = bic_scale >> 10
+	 *  rtt = 100ms
+	 *
+	 * the following code has been designed and tested for
+	 * cwnd < 1 million packets
+	 * RTT < 100 seconds
+	 * HZ < 1,000,00  (corresponding to 10 nano-second)
+	 */
+
+	/* 1/c * 2^2*bictcp_HZ * srtt */
+	cube_factor = 1ull << (10+3*BICTCP_HZ); /* 2^40 */
+
+	/* divide by bic_scale and by constant Srtt (100ms) */
+	do_div(cube_factor, bic_scale * 10);
+
+	return tcp_register_congestion_control(&cubictcp);
+}
+
+static void __exit cubictcp_unregister(void)
+{
+	tcp_unregister_congestion_control(&cubictcp);
+}
+
+module_init(cubictcp_register);
+module_exit(cubictcp_unregister);
+
+MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CUBIC TCP");
+MODULE_VERSION("2.0");
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index bf2e230..0a46123 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -115,8 +115,8 @@
 /* Adapt the MSS value used to make delayed ack decision to the 
  * real world.
  */ 
-static inline void tcp_measure_rcv_mss(struct sock *sk,
-				       const struct sk_buff *skb)
+static void tcp_measure_rcv_mss(struct sock *sk,
+				const struct sk_buff *skb)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	const unsigned int lss = icsk->icsk_ack.last_seg_size; 
@@ -246,8 +246,8 @@
 	return 0;
 }
 
-static inline void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
-				   struct sk_buff *skb)
+static void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
+			    struct sk_buff *skb)
 {
 	/* Check #1 */
 	if (tp->rcv_ssthresh < tp->window_clamp &&
@@ -341,6 +341,26 @@
 		tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
 }
 
+
+/* Initialize RCV_MSS value.
+ * RCV_MSS is an our guess about MSS used by the peer.
+ * We haven't any direct information about the MSS.
+ * It's better to underestimate the RCV_MSS rather than overestimate.
+ * Overestimations make us ACKing less frequently than needed.
+ * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
+ */
+void tcp_initialize_rcv_mss(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
+
+	hint = min(hint, tp->rcv_wnd/2);
+	hint = min(hint, TCP_MIN_RCVMSS);
+	hint = max(hint, TCP_MIN_MSS);
+
+	inet_csk(sk)->icsk_ack.rcv_mss = hint;
+}
+
 /* Receiver "autotuning" code.
  *
  * The algorithm for RTT estimation w/o timestamps is based on
@@ -735,6 +755,27 @@
 	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
 
+/* Set slow start threshold and cwnd not falling to slow start */
+void tcp_enter_cwr(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+
+	tp->prior_ssthresh = 0;
+	tp->bytes_acked = 0;
+	if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
+		tp->undo_marker = 0;
+		tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk);
+		tp->snd_cwnd = min(tp->snd_cwnd,
+				   tcp_packets_in_flight(tp) + 1U);
+		tp->snd_cwnd_cnt = 0;
+		tp->high_seq = tp->snd_nxt;
+		tp->snd_cwnd_stamp = tcp_time_stamp;
+		TCP_ECN_queue_cwr(tp);
+
+		tcp_set_ca_state(sk, TCP_CA_CWR);
+	}
+}
+
 /* Initialize metrics on socket. */
 
 static void tcp_init_metrics(struct sock *sk)
@@ -2070,8 +2111,8 @@
 		tcp_ack_no_tstamp(sk, seq_rtt, flag);
 }
 
-static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
-				  u32 in_flight, int good)
+static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
+			   u32 in_flight, int good)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	icsk->icsk_ca_ops->cong_avoid(sk, ack, rtt, in_flight, good);
@@ -2082,7 +2123,7 @@
  * RFC2988 recommends to restart timer to now+rto.
  */
 
-static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
+static void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
 {
 	if (!tp->packets_out) {
 		inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
@@ -2147,7 +2188,7 @@
 	return acked;
 }
 
-static inline u32 tcp_usrtt(const struct sk_buff *skb)
+static u32 tcp_usrtt(const struct sk_buff *skb)
 {
 	struct timeval tv, now;
 
@@ -2342,7 +2383,7 @@
 
 			if (nwin > tp->max_window) {
 				tp->max_window = nwin;
-				tcp_sync_mss(sk, tp->pmtu_cookie);
+				tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
 			}
 		}
 	}
@@ -2583,8 +2624,8 @@
 /* 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_sock *tp)
+static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
+				  struct tcp_sock *tp)
 {
 	if (th->doff == sizeof(struct tcphdr)>>2) {
 		tp->rx_opt.saw_tstamp = 0;
@@ -2804,8 +2845,7 @@
 	}
 }
 
-static __inline__ int
-tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
+static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
 {
 	if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) {
 		if (before(seq, sp->start_seq))
@@ -2817,7 +2857,7 @@
 	return 0;
 }
 
-static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
 	if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) {
 		if (before(seq, tp->rcv_nxt))
@@ -2832,7 +2872,7 @@
 	}
 }
 
-static inline void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
 	if (!tp->rx_opt.dsack)
 		tcp_dsack_set(tp, seq, end_seq);
@@ -2890,7 +2930,7 @@
 	}
 }
 
-static __inline__ void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
+static inline void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
 {
 	__u32 tmp;
 
@@ -3455,7 +3495,7 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
+static int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
 {
 	/* If the user specified a specific send buffer setting, do
 	 * not modify it.
@@ -3502,7 +3542,7 @@
 	sk->sk_write_space(sk);
 }
 
-static inline void tcp_check_space(struct sock *sk)
+static void tcp_check_space(struct sock *sk)
 {
 	if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) {
 		sock_reset_flag(sk, SOCK_QUEUE_SHRUNK);
@@ -3512,7 +3552,7 @@
 	}
 }
 
-static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
 {
 	tcp_push_pending_frames(sk, tp);
 	tcp_check_space(sk);
@@ -3544,7 +3584,7 @@
 	}
 }
 
-static __inline__ void tcp_ack_snd_check(struct sock *sk)
+static inline void tcp_ack_snd_check(struct sock *sk)
 {
 	if (!inet_csk_ack_scheduled(sk)) {
 		/* We sent a data segment already. */
@@ -3692,8 +3732,7 @@
 	return result;
 }
 
-static __inline__ int
-tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
 {
 	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
 		__tcp_checksum_complete_user(sk, skb);
@@ -3967,12 +4006,12 @@
 					 struct tcphdr *th, unsigned len)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	int saved_clamp = tp->rx_opt.mss_clamp;
 
 	tcp_parse_options(skb, &tp->rx_opt, 0);
 
 	if (th->ack) {
-		struct inet_connection_sock *icsk;
 		/* rfc793:
 		 * "If the state is SYN-SENT then
 		 *    first check the ACK bit
@@ -4061,7 +4100,7 @@
 		if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
 			tp->rx_opt.sack_ok |= 2;
 
-		tcp_sync_mss(sk, tp->pmtu_cookie);
+		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 		tcp_initialize_rcv_mss(sk);
 
 		/* Remember, tcp_poll() does not lock socket!
@@ -4072,7 +4111,7 @@
 		tcp_set_state(sk, TCP_ESTABLISHED);
 
 		/* Make sure socket is routed, for correct metrics.  */
-		tp->af_specific->rebuild_header(sk);
+		icsk->icsk_af_ops->rebuild_header(sk);
 
 		tcp_init_metrics(sk);
 
@@ -4098,8 +4137,6 @@
 			sk_wake_async(sk, 0, POLL_OUT);
 		}
 
-		icsk = inet_csk(sk);
-
 		if (sk->sk_write_pending ||
 		    icsk->icsk_accept_queue.rskq_defer_accept ||
 		    icsk->icsk_ack.pingpong) {
@@ -4173,7 +4210,7 @@
 		if (tp->ecn_flags&TCP_ECN_OK)
 			sock_set_flag(sk, SOCK_NO_LARGESEND);
 
-		tcp_sync_mss(sk, tp->pmtu_cookie);
+		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 		tcp_initialize_rcv_mss(sk);
 
 
@@ -4220,6 +4257,7 @@
 			  struct tcphdr *th, unsigned len)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	int queued = 0;
 
 	tp->rx_opt.saw_tstamp = 0;
@@ -4236,7 +4274,7 @@
 			goto discard;
 
 		if(th->syn) {
-			if(tp->af_specific->conn_request(sk, skb) < 0)
+			if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
 				return 1;
 
 			/* Now we have several options: In theory there is 
@@ -4349,7 +4387,7 @@
 				/* Make sure socket is routed, for
 				 * correct metrics.
 				 */
-				tp->af_specific->rebuild_header(sk);
+				icsk->icsk_af_ops->rebuild_header(sk);
 
 				tcp_init_metrics(sk);
 
@@ -4475,3 +4513,4 @@
 EXPORT_SYMBOL(tcp_parse_options);
 EXPORT_SYMBOL(tcp_rcv_established);
 EXPORT_SYMBOL(tcp_rcv_state_process);
+EXPORT_SYMBOL(tcp_initialize_rcv_mss);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 4d5021e..e9f83e5 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -69,6 +69,7 @@
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 #include <net/inet_common.h>
+#include <net/timewait_sock.h>
 #include <net/xfrm.h>
 
 #include <linux/inet.h>
@@ -86,8 +87,7 @@
 /* Socket used for sending RSTs */
 static struct socket *tcp_socket;
 
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-		       struct sk_buff *skb);
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
 
 struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
 	.lhash_lock	= RW_LOCK_UNLOCKED,
@@ -97,7 +97,8 @@
 
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 {
-	return inet_csk_get_port(&tcp_hashinfo, sk, snum);
+	return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+				 inet_csk_bind_conflict);
 }
 
 static void tcp_v4_hash(struct sock *sk)
@@ -118,202 +119,38 @@
 					  skb->h.th->source);
 }
 
-/* called with local bh disabled */
-static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
-				      struct inet_timewait_sock **twp)
+int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
 {
-	struct inet_sock *inet = inet_sk(sk);
-	u32 daddr = inet->rcv_saddr;
-	u32 saddr = inet->daddr;
-	int dif = sk->sk_bound_dev_if;
-	INET_ADDR_COOKIE(acookie, saddr, daddr)
-	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-	struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
+	const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+	struct tcp_sock *tp = tcp_sk(sk);
 
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
+	/* With PAWS, it is safe from the viewpoint
+	   of data integrity. Even without PAWS it is safe provided sequence
+	   spaces do not overlap i.e. at data rates <= 80Mbit/sec.
 
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-		tw = inet_twsk(sk2);
+	   Actually, the idea is close to VJ's one, only timestamp cache is
+	   held not per host, but per port pair and TW bucket is used as state
+	   holder.
 
-		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
-			const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-			struct tcp_sock *tp = tcp_sk(sk);
-
-			/* With PAWS, it is safe from the viewpoint
-			   of data integrity. Even without PAWS it
-			   is safe provided sequence spaces do not
-			   overlap i.e. at data rates <= 80Mbit/sec.
-
-			   Actually, the idea is close to VJ's one,
-			   only timestamp cache is held not per host,
-			   but per port pair and TW bucket is used
-			   as state holder.
-
-			   If TW bucket has been already destroyed we
-			   fall back to VJ's scheme and use initial
-			   timestamp retrieved from peer table.
-			 */
-			if (tcptw->tw_ts_recent_stamp &&
-			    (!twp || (sysctl_tcp_tw_reuse &&
-				      xtime.tv_sec -
-				      tcptw->tw_ts_recent_stamp > 1))) {
-				tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-				if (tp->write_seq == 0)
-					tp->write_seq = 1;
-				tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
-				tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-				sock_hold(sk2);
-				goto unique;
-			} else
-				goto not_unique;
-		}
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-unique:
-	/* Must record num and sport now. Otherwise we will see
-	 * in hash table socket with a funny identity. */
-	inet->num = lport;
-	inet->sport = htons(lport);
-	sk->sk_hash = hash;
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &tcp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
+	   If TW bucket has been already destroyed we fall back to VJ's scheme
+	   and use initial timestamp retrieved from peer table.
+	 */
+	if (tcptw->tw_ts_recent_stamp &&
+	    (twp == NULL || (sysctl_tcp_tw_reuse &&
+			     xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
+		tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
+		if (tp->write_seq == 0)
+			tp->write_seq = 1;
+		tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
+		tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
+		sock_hold(sktw);
+		return 1;
 	}
 
 	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	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 inline int tcp_v4_hash_connect(struct sock *sk)
-{
-	const unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (!snum) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
-		int range = high - low;
- 		int i;
-		int port;
-		static u32 hint;
-		u32 offset = hint + connect_port_offset(sk);
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
-		for (i = 1; i <= range; i++) {
-			port = low + (i + offset) % range;
- 			head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == port) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__tcp_v4_check_established(sk,
-									port,
-									&tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
- 			if (!tb) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 		}
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
-		hint += i;
-
- 		/* Head lock still held and bh's disabled */
- 		inet_bind_hash(sk, tb, port);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(port);
- 			__inet_hash(&tcp_hashinfo, sk, 0);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw) {
- 			inet_twsk_deschedule(tw, &tcp_death_row);;
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
- 	tb  = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-		__inet_hash(&tcp_hashinfo, sk, 0);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __tcp_v4_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
+EXPORT_SYMBOL_GPL(tcp_twsk_unique);
 
 /* This will initiate an outgoing connection. */
 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -383,9 +220,9 @@
 	inet->dport = usin->sin_port;
 	inet->daddr = daddr;
 
-	tp->ext_header_len = 0;
+	inet_csk(sk)->icsk_ext_hdr_len = 0;
 	if (inet->opt)
-		tp->ext_header_len = inet->opt->optlen;
+		inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
 
 	tp->rx_opt.mss_clamp = 536;
 
@@ -395,7 +232,7 @@
 	 * complete initialization after this.
 	 */
 	tcp_set_state(sk, TCP_SYN_SENT);
-	err = tcp_v4_hash_connect(sk);
+	err = inet_hash_connect(&tcp_death_row, sk);
 	if (err)
 		goto failure;
 
@@ -433,12 +270,10 @@
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
-static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
-				     u32 mtu)
+static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
 {
 	struct dst_entry *dst;
 	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
@@ -467,7 +302,7 @@
 	mtu = dst_mtu(dst);
 
 	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-	    tp->pmtu_cookie > mtu) {
+	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
 		tcp_sync_mss(sk, mtu);
 
 		/* Resend the TCP packet because it's
@@ -644,10 +479,10 @@
 }
 
 /* This routine computes an IPv4 TCP checksum. */
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-		       struct sk_buff *skb)
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
 	struct inet_sock *inet = inet_sk(sk);
+	struct tcphdr *th = skb->h.th;
 
 	if (skb->ip_summed == CHECKSUM_HW) {
 		th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0);
@@ -826,7 +661,8 @@
 	kfree(inet_rsk(req)->opt);
 }
 
-static inline void syn_flood_warning(struct sk_buff *skb)
+#ifdef CONFIG_SYN_COOKIES
+static void syn_flood_warning(struct sk_buff *skb)
 {
 	static unsigned long warntime;
 
@@ -837,12 +673,13 @@
 		       ntohs(skb->h.th->dest));
 	}
 }
+#endif
 
 /*
  * Save and compile IPv4 options into the request_sock if needed.
  */
-static inline struct ip_options *tcp_v4_save_options(struct sock *sk,
-						     struct sk_buff *skb)
+static struct ip_options *tcp_v4_save_options(struct sock *sk,
+					      struct sk_buff *skb)
 {
 	struct ip_options *opt = &(IPCB(skb)->opt);
 	struct ip_options *dopt = NULL;
@@ -869,6 +706,11 @@
 	.send_reset	=	tcp_v4_send_reset,
 };
 
+static struct timewait_sock_ops tcp_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct tcp_timewait_sock),
+	.twsk_unique	= tcp_twsk_unique,
+};
+
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq;
@@ -1053,9 +895,9 @@
 	ireq->opt	      = NULL;
 	newinet->mc_index     = inet_iif(skb);
 	newinet->mc_ttl	      = skb->nh.iph->ttl;
-	newtp->ext_header_len = 0;
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
 	if (newinet->opt)
-		newtp->ext_header_len = newinet->opt->optlen;
+		inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
 	newinet->id = newtp->write_seq ^ jiffies;
 
 	tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1314,16 +1156,6 @@
 	goto discard_it;
 }
 
-static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-	struct sockaddr_in *sin = (struct sockaddr_in *) uaddr;
-	struct inet_sock *inet = inet_sk(sk);
-
-	sin->sin_family		= AF_INET;
-	sin->sin_addr.s_addr	= inet->daddr;
-	sin->sin_port		= inet->dport;
-}
-
 /* VJ's idea. Save last timestamp seen from this destination
  * and hold it at least for normal timewait interval to use for duplicate
  * segment detection in subsequent connections, before they enter synchronized
@@ -1382,7 +1214,7 @@
 	return 0;
 }
 
-struct tcp_func ipv4_specific = {
+struct inet_connection_sock_af_ops ipv4_specific = {
 	.queue_xmit	=	ip_queue_xmit,
 	.send_check	=	tcp_v4_send_check,
 	.rebuild_header	=	inet_sk_rebuild_header,
@@ -1392,7 +1224,7 @@
 	.net_header_len	=	sizeof(struct iphdr),
 	.setsockopt	=	ip_setsockopt,
 	.getsockopt	=	ip_getsockopt,
-	.addr2sockaddr	=	v4_addr2sockaddr,
+	.addr2sockaddr	=	inet_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in),
 };
 
@@ -1433,7 +1265,8 @@
 	sk->sk_write_space = sk_stream_write_space;
 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
-	tp->af_specific = &ipv4_specific;
+	icsk->icsk_af_ops = &ipv4_specific;
+	icsk->icsk_sync_mss = tcp_sync_mss;
 
 	sk->sk_sndbuf = sysctl_tcp_wmem[1];
 	sk->sk_rcvbuf = sysctl_tcp_rmem[1];
@@ -1989,7 +1822,7 @@
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp_sock),
-	.twsk_obj_size		= sizeof(struct tcp_timewait_sock),
+	.twsk_prot		= &tcp_timewait_sock_ops,
 	.rsk_prot		= &tcp_request_sock_ops,
 };
 
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 1b66a2a..2b9b7f6 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -274,18 +274,18 @@
 void tcp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
+	const struct inet_connection_sock *icsk = inet_csk(sk);
 	const struct tcp_sock *tp = tcp_sk(sk);
 	int recycle_ok = 0;
 
 	if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
-		recycle_ok = tp->af_specific->remember_stamp(sk);
+		recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
 
 	if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
 		tw = inet_twsk_alloc(sk, state);
 
 	if (tw != NULL) {
 		struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-		const struct inet_connection_sock *icsk = inet_csk(sk);
 		const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
 
 		tw->tw_rcv_wscale	= tp->rx_opt.rcv_wscale;
@@ -298,10 +298,12 @@
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		if (tw->tw_family == PF_INET6) {
 			struct ipv6_pinfo *np = inet6_sk(sk);
-			struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+			struct inet6_timewait_sock *tw6;
 
-			ipv6_addr_copy(&tcp6tw->tw_v6_daddr, &np->daddr);
-			ipv6_addr_copy(&tcp6tw->tw_v6_rcv_saddr, &np->rcv_saddr);
+			tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+			tw6 = inet6_twsk((struct sock *)tw);
+			ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+			ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
 			tw->tw_ipv6only = np->ipv6only;
 		}
 #endif
@@ -456,7 +458,6 @@
 			   struct request_sock **prev)
 {
 	struct tcphdr *th = skb->h.th;
-	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_options_received tmp_opt;
@@ -613,7 +614,8 @@
 		 * 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);
+		child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,
+								 req, NULL);
 		if (child == NULL)
 			goto listen_overflow;
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index b7325e0..a7623ea 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -51,8 +51,8 @@
  */
 int sysctl_tcp_tso_win_divisor = 3;
 
-static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
-				    struct sk_buff *skb)
+static 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)
@@ -124,8 +124,8 @@
 	tp->snd_cwnd_used = 0;
 }
 
-static inline void tcp_event_data_sent(struct tcp_sock *tp,
-				       struct sk_buff *skb, struct sock *sk)
+static void tcp_event_data_sent(struct tcp_sock *tp,
+				struct sk_buff *skb, struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	const u32 now = tcp_time_stamp;
@@ -142,7 +142,7 @@
 		icsk->icsk_ack.pingpong = 1;
 }
 
-static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
+static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
 	tcp_dec_quickack_mode(sk, pkts);
 	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
@@ -212,7 +212,7 @@
  * value can be stuffed directly into th->window for an outgoing
  * frame.
  */
-static __inline__ u16 tcp_select_window(struct sock *sk)
+static u16 tcp_select_window(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	u32 cur_win = tcp_receive_window(tp);
@@ -250,6 +250,75 @@
 	return new_win;
 }
 
+static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
+					 __u32 tstamp)
+{
+	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->rx_opt.ts_recent);
+	}
+	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++ = htonl((TCPOPT_NOP  << 24) |
+			       (TCPOPT_NOP  << 16) |
+			       (TCPOPT_SACK <<  8) |
+			       (TCPOLEN_SACK_BASE + (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->rx_opt.dsack) {
+			tp->rx_opt.dsack = 0;
+			tp->rx_opt.eff_sacks--;
+		}
+	}
+}
+
+/* Construct a tcp options header for a SYN or SYN_ACK packet.
+ * If this is every changed make sure to change the definition of
+ * MAX_SYN_SIZE to match the new maximum number of options that you
+ * can generate.
+ */
+static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+				  int offer_wscale, int wscale, __u32 tstamp,
+				  __u32 ts_recent)
+{
+	/* We always get an MSS option.
+	 * The option bytes which will be seen in normal data
+	 * packets should timestamps be used, must be in the MSS
+	 * advertised.  But we subtract them from tp->mss_cache so
+	 * that calculations in tcp_sendmsg are simpler etc.
+	 * So account for this fact here if necessary.  If we
+	 * don't do this correctly, as a receiver we won't
+	 * recognize data packets as being full sized when we
+	 * should, and thus we won't abide by the delayed ACK
+	 * rules correctly.
+	 * SACKs don't matter, we never delay an ACK when we
+	 * have any of those going out.
+	 */
+	*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
+	if (ts) {
+		if(sack)
+			*ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
+						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+		else
+			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+		*ptr++ = htonl(tstamp);		/* TSVAL */
+		*ptr++ = htonl(ts_recent);	/* TSECR */
+	} else if(sack)
+		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
+	if (offer_wscale)
+		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
+}
 
 /* This routine actually transmits TCP packets queued in by
  * tcp_do_sendmsg().  This is used by both the initial
@@ -371,7 +440,7 @@
 		TCP_ECN_send(sk, tp, skb, tcp_header_size);
 	}
 
-	tp->af_specific->send_check(sk, th, skb->len, skb);
+	icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
 	if (likely(tcb->flags & TCPCB_FLAG_ACK))
 		tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
@@ -381,7 +450,7 @@
 
 	TCP_INC_STATS(TCP_MIB_OUTSEGS);
 
-	err = tp->af_specific->queue_xmit(skb, 0);
+	err = icsk->icsk_af_ops->queue_xmit(skb, 0);
 	if (unlikely(err <= 0))
 		return err;
 
@@ -621,7 +690,7 @@
    It is minimum of user_mss and mss received with SYN.
    It also does not include TCP options.
 
-   tp->pmtu_cookie is last pmtu, seen by this function.
+   inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function.
 
    tp->mss_cache is current effective sending mss, including
    all tcp options except for SACKs. It is evaluated,
@@ -631,26 +700,26 @@
    NOTE1. rfc1122 clearly states that advertised MSS
    DOES NOT include either tcp or ip options.
 
-   NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside
-   this function.			--ANK (980731)
+   NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
+   are READ ONLY outside this function.		--ANK (980731)
  */
 
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int mss_now;
-
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	/* Calculate base mss without TCP options:
 	   It is MMS_S - sizeof(tcphdr) of rfc1122
 	 */
-	mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr);
+	int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+		       sizeof(struct tcphdr));
 
 	/* Clamp it (mss_clamp does not include tcp options) */
 	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;
+	mss_now -= icsk->icsk_ext_hdr_len;
 
 	/* Then reserve room for full set of TCP options and 8 bytes of data */
 	if (mss_now < 48)
@@ -664,7 +733,7 @@
 		mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
 
 	/* And store cached results */
-	tp->pmtu_cookie = pmtu;
+	icsk->icsk_pmtu_cookie = pmtu;
 	tp->mss_cache = mss_now;
 
 	return mss_now;
@@ -694,7 +763,7 @@
 
 	if (dst) {
 		u32 mtu = dst_mtu(dst);
-		if (mtu != tp->pmtu_cookie)
+		if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
 			mss_now = tcp_sync_mss(sk, mtu);
 	}
 
@@ -705,9 +774,10 @@
 	xmit_size_goal = mss_now;
 
 	if (doing_tso) {
-		xmit_size_goal = 65535 -
-			tp->af_specific->net_header_len -
-			tp->ext_header_len - tp->tcp_header_len;
+		xmit_size_goal = (65535 -
+				  inet_csk(sk)->icsk_af_ops->net_header_len -
+				  inet_csk(sk)->icsk_ext_hdr_len -
+				  tp->tcp_header_len);
 
 		if (tp->max_window &&
 		    (xmit_size_goal > (tp->max_window >> 1)))
@@ -723,7 +793,7 @@
 
 /* Congestion window validation. (RFC2861) */
 
-static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
+static void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
 {
 	__u32 packets_out = tp->packets_out;
 
@@ -772,7 +842,7 @@
 /* This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
-static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
 {
 	int tso_segs = tcp_skb_pcount(skb);
 
@@ -1422,7 +1492,7 @@
 	   (sysctl_tcp_retrans_collapse != 0))
 		tcp_retrans_try_collapse(sk, skb, cur_mss);
 
-	if(tp->af_specific->rebuild_header(sk))
+	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
 		return -EHOSTUNREACH; /* Routing failure or similar. */
 
 	/* Some Solaris stacks overoptimize and ignore the FIN on a
@@ -1793,7 +1863,7 @@
 /* 
  * Do all connect socket setups that can be done AF independent.
  */ 
-static inline void tcp_connect_init(struct sock *sk)
+static void tcp_connect_init(struct sock *sk)
 {
 	struct dst_entry *dst = __sk_dst_get(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 13e7e6e..3b74034 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -330,6 +330,10 @@
 		vegas->cntRTT = 0;
 		vegas->minRTT = 0x7fffffff;
 	}
+	/* Use normal slow start */
+	else if (tp->snd_cwnd <= tp->snd_ssthresh) 
+		tcp_slow_start(tp);
+	
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2422a5f..223abaa 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -86,6 +86,7 @@
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/igmp.h>
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
@@ -846,20 +847,7 @@
 csum_copy_err:
 	UDP_INC_STATS_BH(UDP_MIB_INERRORS);
 
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
-
-	skb_free_datagram(sk, skb);
+	skb_kill_datagram(sk, skb, flags);
 
 	if (noblock)
 		return -EAGAIN;	
@@ -1094,7 +1082,7 @@
  * Otherwise, csum completion requires chacksumming packet body,
  * including udp header and folding it to skb->csum.
  */
-static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
+static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
 			     unsigned short ulen, u32 saddr, u32 daddr)
 {
 	if (uh->check == 0) {
@@ -1108,7 +1096,6 @@
 	/* Probably, we should checksum udp header (it should be in cache
 	 * in any case) and data in tiny packets (< rx copybreak).
 	 */
-	return 0;
 }
 
 /*
@@ -1141,8 +1128,7 @@
 	if (pskb_trim_rcsum(skb, ulen))
 		goto short_packet;
 
-	if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
-		goto csum_error;
+	udp_checksum_init(skb, uh, ulen, saddr, daddr);
 
 	if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
 		return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 6460eec..9601fd7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -8,7 +8,8 @@
 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
 		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-		ip6_flowlabel.o ipv6_syms.o netfilter.o
+		ip6_flowlabel.o ipv6_syms.o netfilter.o \
+		inet6_connection_sock.o
 
 ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
 	xfrm6_output.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a60585f..704fb73 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1195,7 +1195,7 @@
 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
 {
 	const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
-	const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2);
+	const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
 	u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
 	u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
 	int sk_ipv6only = ipv6_only_sock(sk);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index d954638..68afc53 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -167,6 +167,7 @@
 		sk->sk_reuse = 1;
 
 	inet = inet_sk(sk);
+	inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
 	if (SOCK_RAW == sock->type) {
 		inet->num = protocol;
@@ -389,6 +390,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(inet6_destroy_sock);
+
 /*
  *	This does both peername and sockname.
  */
@@ -431,7 +434,6 @@
 int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
-	int err = -EINVAL;
 
 	switch(cmd) 
 	{
@@ -450,16 +452,15 @@
 	case SIOCSIFDSTADDR:
 		return addrconf_set_dstaddr((void __user *) arg);
 	default:
-		if (!sk->sk_prot->ioctl ||
-		    (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD)
-			return(dev_ioctl(cmd,(void __user *) arg));		
-		return err;
+		if (!sk->sk_prot->ioctl)
+			return -ENOIOCTLCMD;
+		return sk->sk_prot->ioctl(sk, cmd, arg);
 	}
 	/*NOTREACHED*/
 	return(0);
 }
 
-struct proto_ops inet6_stream_ops = {
+const struct proto_ops inet6_stream_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -480,7 +481,7 @@
 	.sendpage =	tcp_sendpage
 };
 
-struct proto_ops inet6_dgram_ops = {
+const struct proto_ops inet6_dgram_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -508,7 +509,7 @@
 };
 
 /* Same as inet6_dgram_ops, sans udp_poll.  */
-static struct proto_ops inet6_sockraw_ops = {
+static const struct proto_ops inet6_sockraw_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -609,6 +610,79 @@
 	}
 }
 
+int inet6_sk_rebuild_header(struct sock *sk)
+{
+	int err;
+	struct dst_entry *dst;
+	struct ipv6_pinfo *np = inet6_sk(sk);
+
+	dst = __sk_dst_check(sk, np->dst_cookie);
+
+	if (dst == NULL) {
+		struct inet_sock *inet = inet_sk(sk);
+		struct in6_addr *final_p = NULL, final;
+		struct flowi fl;
+
+		memset(&fl, 0, sizeof(fl));
+		fl.proto = sk->sk_protocol;
+		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+		fl.fl6_flowlabel = np->flow_label;
+		fl.oif = sk->sk_bound_dev_if;
+		fl.fl_ip_dport = inet->dport;
+		fl.fl_ip_sport = inet->sport;
+
+		if (np->opt && np->opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+
+		err = ip6_dst_lookup(sk, &dst, &fl);
+		if (err) {
+			sk->sk_route_caps = 0;
+			return err;
+		}
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_err_soft = -err;
+			return err;
+		}
+
+		ip6_dst_store(sk, dst, NULL);
+		sk->sk_route_caps = dst->dev->features &
+			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header);
+
+int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct inet6_skb_parm *opt = IP6CB(skb);
+
+	if (np->rxopt.all) {
+		if ((opt->hop && (np->rxopt.bits.hopopts ||
+				  np->rxopt.bits.ohopopts)) ||
+		    ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) &&
+		     np->rxopt.bits.rxflow) ||
+		    (opt->srcrt && (np->rxopt.bits.srcrt ||
+		     np->rxopt.bits.osrcrt)) ||
+		    ((opt->dst1 || opt->dst0) &&
+		     (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
+			return 1;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
+
 int
 snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
 {
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f362973..13cc7f8 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <net/xfrm.h>
 #include <asm/scatterlist.h>
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 8bfbe99..6de8ee1 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -36,6 +36,7 @@
 #include <linux/random.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/icmpv6.h>
 
 static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index be6faf3..113374d 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -413,6 +413,8 @@
 	return opt;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
+
 /**********************************
   Hop-by-hop options.
  **********************************/
@@ -579,6 +581,8 @@
 	return opt2;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_dup_options);
+
 static int ipv6_renew_option(void *ohdr,
 			     struct ipv6_opt_hdr __user *newopt, int newoptlen,
 			     int inherit,
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
new file mode 100644
index 0000000..792f90f
--- /dev/null
+++ b/net/ipv6/inet6_connection_sock.c
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ *
+ *             Support for INET6 connection oriented protocols.
+ *
+ * Authors:    See the TCPv6 sources
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the 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/module.h>
+#include <linux/in6.h>
+#include <linux/ipv6.h>
+#include <linux/jhash.h>
+
+#include <net/addrconf.h>
+#include <net/inet_connection_sock.h>
+#include <net/inet_ecn.h>
+#include <net/inet_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/sock.h>
+
+int inet6_csk_bind_conflict(const struct sock *sk,
+			    const struct inet_bind_bucket *tb)
+{
+	const struct sock *sk2;
+	const struct hlist_node *node;
+
+	/* We must walk the whole port owner list in this case. -DaveM */
+	sk_for_each_bound(sk2, node, &tb->owners) {
+		if (sk != sk2 &&
+		    (!sk->sk_bound_dev_if ||
+		     !sk2->sk_bound_dev_if ||
+		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
+		    (!sk->sk_reuse || !sk2->sk_reuse ||
+		     sk2->sk_state == TCP_LISTEN) &&
+		     ipv6_rcv_saddr_equal(sk, sk2))
+			break;
+	}
+
+	return node != NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
+
+/*
+ * request_sock (formerly open request) hash tables.
+ */
+static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport,
+			   const u32 rnd, const u16 synq_hsize)
+{
+	u32 a = raddr->s6_addr32[0];
+	u32 b = raddr->s6_addr32[1];
+	u32 c = raddr->s6_addr32[2];
+
+	a += JHASH_GOLDEN_RATIO;
+	b += JHASH_GOLDEN_RATIO;
+	c += rnd;
+	__jhash_mix(a, b, c);
+
+	a += raddr->s6_addr32[3];
+	b += (u32)rport;
+	__jhash_mix(a, b, c);
+
+	return c & (synq_hsize - 1);
+}
+
+struct request_sock *inet6_csk_search_req(const struct sock *sk,
+					  struct request_sock ***prevp,
+					  const __u16 rport,
+					  const struct in6_addr *raddr,
+					  const struct in6_addr *laddr,
+					  const int iif)
+{
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+	struct request_sock *req, **prev;
+
+	for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport,
+						     lopt->hash_rnd,
+						     lopt->nr_table_entries)];
+	     (req = *prev) != NULL;
+	     prev = &req->dl_next) {
+		const struct inet6_request_sock *treq = inet6_rsk(req);
+
+		if (inet_rsk(req)->rmt_port == rport &&
+		    req->rsk_ops->family == AF_INET6 &&
+		    ipv6_addr_equal(&treq->rmt_addr, raddr) &&
+		    ipv6_addr_equal(&treq->loc_addr, laddr) &&
+		    (!treq->iif || treq->iif == iif)) {
+			BUG_TRAP(req->sk == NULL);
+			*prevp = prev;
+			return req;
+		}
+	}
+
+	return NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_search_req);
+
+void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+				    struct request_sock *req,
+				    const unsigned long timeout)
+{
+	struct inet_connection_sock *icsk = inet_csk(sk);
+	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+	const u32 h = inet6_synq_hash(&inet6_rsk(req)->rmt_addr,
+				      inet_rsk(req)->rmt_port,
+				      lopt->hash_rnd, lopt->nr_table_entries);
+
+	reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout);
+	inet_csk_reqsk_queue_added(sk, timeout);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add);
+
+void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
+
+	sin6->sin6_family = AF_INET6;
+	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
+	sin6->sin6_port	= inet_sk(sk)->dport;
+	/* We do not store received flowlabel for TCP */
+	sin6->sin6_flowinfo = 0;
+	sin6->sin6_scope_id = 0;
+	if (sk->sk_bound_dev_if &&
+	    ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+		sin6->sin6_scope_id = sk->sk_bound_dev_if;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
+
+int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
+{
+	struct sock *sk = skb->sk;
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct flowi fl;
+	struct dst_entry *dst;
+	struct in6_addr *final_p = NULL, final;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = sk->sk_protocol;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+	fl.fl6_flowlabel = np->flow_label;
+	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
+	fl.oif = sk->sk_bound_dev_if;
+	fl.fl_ip_sport = inet->sport;
+	fl.fl_ip_dport = inet->dport;
+
+	if (np->opt && np->opt->srcrt) {
+		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		final_p = &final;
+	}
+
+	dst = __sk_dst_check(sk, np->dst_cookie);
+
+	if (dst == NULL) {
+		int err = ip6_dst_lookup(sk, &dst, &fl);
+
+		if (err) {
+			sk->sk_err_soft = -err;
+			return err;
+		}
+
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_route_caps = 0;
+			return err;
+		}
+
+		ip6_dst_store(sk, dst, NULL);
+		sk->sk_route_caps = dst->dev->features &
+			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+	}
+
+	skb->dst = dst_clone(dst);
+
+	/* Restore final destination back after routing done */
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+
+	return ip6_xmit(sk, skb, &fl, np->opt, 0);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_xmit);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 01d5f46..4154f3a 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -5,7 +5,8 @@
  *
  *		Generic INET6 transport hashtables
  *
- * Authors:	Lotsa people, from code originally in tcp
+ * Authors:	Lotsa people, from code originally in tcp, generalised here
+ * 		by Arnaldo Carvalho de Melo <acme@mandriva.com>
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -14,12 +15,13 @@
  */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
+#include <linux/random.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
 #include <net/inet6_hashtables.h>
+#include <net/ip.h>
 
 struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
 				   const struct in6_addr *daddr,
@@ -79,3 +81,180 @@
 }
 
 EXPORT_SYMBOL_GPL(inet6_lookup);
+
+static int __inet6_check_established(struct inet_timewait_death_row *death_row,
+				     struct sock *sk, const __u16 lport,
+				     struct inet_timewait_sock **twp)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const struct inet_sock *inet = inet_sk(sk);
+	const struct ipv6_pinfo *np = inet6_sk(sk);
+	const struct in6_addr *daddr = &np->rcv_saddr;
+	const struct in6_addr *saddr = &np->daddr;
+	const int dif = sk->sk_bound_dev_if;
+	const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+	const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
+						inet->dport);
+	struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+	struct sock *sk2;
+	const struct hlist_node *node;
+	struct inet_timewait_sock *tw;
+
+	prefetch(head->chain.first);
+	write_lock(&head->lock);
+
+	/* Check TIME-WAIT sockets first. */
+	sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+		const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
+
+		tw = inet_twsk(sk2);
+
+		if(*((__u32 *)&(tw->tw_dport)) == ports		 &&
+		   sk2->sk_family	       == PF_INET6	 &&
+		   ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)	 &&
+		   ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
+		   sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
+			if (twsk_unique(sk, sk2, twp))
+				goto unique;
+			else
+				goto not_unique;
+		}
+	}
+	tw = NULL;
+
+	/* And established part... */
+	sk_for_each(sk2, node, &head->chain) {
+		if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+			goto not_unique;
+	}
+
+unique:
+	BUG_TRAP(sk_unhashed(sk));
+	__sk_add_node(sk, &head->chain);
+	sk->sk_hash = hash;
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(&head->lock);
+
+	if (twp != NULL) {
+		*twp = tw;
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+	} else if (tw != NULL) {
+		/* Silly. Should hash-dance instead... */
+		inet_twsk_deschedule(tw, death_row);
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+		inet_twsk_put(tw);
+	}
+	return 0;
+
+not_unique:
+	write_unlock(&head->lock);
+	return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet6_sk_port_offset(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	const struct ipv6_pinfo *np = inet6_sk(sk);
+	return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32,
+					  np->daddr.s6_addr32,
+					  inet->dport);
+}
+
+int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+		       struct sock *sk)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const unsigned short snum = inet_sk(sk)->num;
+ 	struct inet_bind_hashbucket *head;
+ 	struct inet_bind_bucket *tb;
+	int ret;
+
+ 	if (snum == 0) {
+ 		const int low = sysctl_local_port_range[0];
+ 		const int high = sysctl_local_port_range[1];
+		const int range = high - low;
+ 		int i, port;
+		static u32 hint;
+		const u32 offset = hint + inet6_sk_port_offset(sk);
+		struct hlist_node *node;
+ 		struct inet_timewait_sock *tw = NULL;
+
+ 		local_bh_disable();
+		for (i = 1; i <= range; i++) {
+			port = low + (i + offset) % range;
+ 			head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+ 			spin_lock(&head->lock);
+
+ 			/* Does not bother with rcv_saddr checks,
+ 			 * because the established check is already
+ 			 * unique enough.
+ 			 */
+			inet_bind_bucket_for_each(tb, node, &head->chain) {
+ 				if (tb->port == port) {
+ 					BUG_TRAP(!hlist_empty(&tb->owners));
+ 					if (tb->fastreuse >= 0)
+ 						goto next_port;
+ 					if (!__inet6_check_established(death_row,
+								       sk, port,
+								       &tw))
+ 						goto ok;
+ 					goto next_port;
+ 				}
+ 			}
+
+ 			tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+						     head, port);
+ 			if (!tb) {
+ 				spin_unlock(&head->lock);
+ 				break;
+ 			}
+ 			tb->fastreuse = -1;
+ 			goto ok;
+
+ 		next_port:
+ 			spin_unlock(&head->lock);
+ 		}
+ 		local_bh_enable();
+
+ 		return -EADDRNOTAVAIL;
+
+ok:
+		hint += i;
+
+ 		/* Head lock still held and bh's disabled */
+ 		inet_bind_hash(sk, tb, port);
+		if (sk_unhashed(sk)) {
+ 			inet_sk(sk)->sport = htons(port);
+ 			__inet6_hash(hinfo, sk);
+ 		}
+ 		spin_unlock(&head->lock);
+
+ 		if (tw) {
+ 			inet_twsk_deschedule(tw, death_row);
+ 			inet_twsk_put(tw);
+ 		}
+
+		ret = 0;
+		goto out;
+ 	}
+
+ 	head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+ 	tb   = inet_csk(sk)->icsk_bind_hash;
+	spin_lock_bh(&head->lock);
+
+	if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
+		__inet6_hash(hinfo, sk);
+		spin_unlock_bh(&head->lock);
+		return 0;
+	} else {
+		spin_unlock(&head->lock);
+		/* No definite answer... Walk to established hash table */
+		ret = __inet6_check_established(death_row, sk, snum, NULL);
+out:
+		local_bh_enable();
+		return ret;
+	}
+}
+
+EXPORT_SYMBOL_GPL(inet6_hash_connect);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 1cf0276..89d12b4 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -200,6 +200,8 @@
 	return NULL;
 }
 
+EXPORT_SYMBOL_GPL(fl6_sock_lookup);
+
 void fl6_free_socklist(struct sock *sk)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 8523c76..b4c4beb 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -775,6 +775,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(ip6_dst_lookup);
+
 static inline int ip6_ufo_append_data(struct sock *sk,
 			int getfrag(void *from, char *to, int offset, int len,
 			int odd, struct sk_buff *skb),
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 55917fb..626dd39 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 3620718..c63868d 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -163,17 +163,17 @@
 			sk_refcnt_debug_dec(sk);
 
 			if (sk->sk_protocol == IPPROTO_TCP) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 
 				local_bh_disable();
 				sock_prot_dec_use(sk->sk_prot);
 				sock_prot_inc_use(&tcp_prot);
 				local_bh_enable();
 				sk->sk_prot = &tcp_prot;
-				tp->af_specific = &ipv4_specific;
+				icsk->icsk_af_ops = &ipv4_specific;
 				sk->sk_socket->ops = &inet_stream_ops;
 				sk->sk_family = PF_INET;
-				tcp_sync_mss(sk, tp->pmtu_cookie);
+				tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 			} else {
 				local_bh_disable();
 				sock_prot_dec_use(sk->sk_prot);
@@ -317,14 +317,15 @@
 		}
 
 		retv = 0;
-		if (sk->sk_type == SOCK_STREAM) {
+		if (inet_sk(sk)->is_icsk) {
 			if (opt) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 				if (!((1 << sk->sk_state) &
 				      (TCPF_LISTEN | TCPF_CLOSE))
 				    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-					tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+					icsk->icsk_ext_hdr_len =
+						opt->opt_flen + opt->opt_nflen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 				}
 			}
 			opt = xchg(&np->opt, opt);
@@ -380,14 +381,15 @@
 			goto done;
 update:
 		retv = 0;
-		if (sk->sk_type == SOCK_STREAM) {
+		if (inet_sk(sk)->is_icsk) {
 			if (opt) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 				if (!((1 << sk->sk_state) &
 				      (TCPF_LISTEN | TCPF_CLOSE))
 				    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-					tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+					icsk->icsk_ext_hdr_len =
+						opt->opt_flen + opt->opt_nflen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 				}
 			}
 			opt = xchg(&np->opt, opt);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f829a4a..1cf305a 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -224,7 +224,7 @@
 
 	mc_lst->ifindex = dev->ifindex;
 	mc_lst->sfmode = MCAST_EXCLUDE;
-	mc_lst->sflock = RW_LOCK_UNLOCKED;
+	rwlock_init(&mc_lst->sflock);
 	mc_lst->sflist = NULL;
 
 	/*
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 95d4692..ea43ef1 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -15,6 +15,7 @@
  *      - new extension header parser code
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
@@ -86,11 +87,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -108,20 +104,15 @@
 	unsigned int underflow[NF_IP6_NUMHOOKS];
 
 	/* ip6t_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ip6t_target);
 static LIST_HEAD(ip6t_match);
 static LIST_HEAD(ip6t_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
@@ -376,8 +367,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -649,7 +639,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ip6t_table_info *newinfo,
+		   unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -658,7 +649,7 @@
 	for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ip6t_entry *e
-			= (struct ip6t_entry *)(newinfo->entries + pos);
+			= (struct ip6t_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -708,13 +699,13 @@
 						goto next;
 
 					e = (struct ip6t_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ip6t_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -731,7 +722,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ip6t_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -941,6 +932,7 @@
 translate_table(const char *name,
 		unsigned int valid_hooks,
 		struct ip6t_table_info *newinfo,
+		void *entry0,
 		unsigned int size,
 		unsigned int number,
 		const unsigned int *hook_entries,
@@ -961,11 +953,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				entry0,
+				entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -993,27 +985,24 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks))
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
 		return -ELOOP;
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -1029,15 +1018,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ip6t_entry *table_base;
-		unsigned int i;
+		int cpu;
 
-		for_each_cpu(i) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
-
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ip6t_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -1072,16 +1058,44 @@
 	return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ip6t_entry *e,
+		     struct ip6t_counters total[],
+		     unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void
 get_counters(const struct ip6t_table_info *t,
 	     struct ip6t_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	IP6T_ENTRY_ITERATE(t->entries[curcpu],
+			   t->size,
+			   set_entry_to_counter,
+			   counters,
+			   &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IP6T_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
@@ -1098,6 +1112,7 @@
 	struct ip6t_entry *e;
 	struct ip6t_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	   (other than comefrom, which userspace doesn't care
@@ -1109,13 +1124,13 @@
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	/* choose the copy that is on ourc node/cpu */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1127,7 +1142,7 @@
 		struct ip6t_entry_match *m;
 		struct ip6t_entry_target *t;
 
-		e = (struct ip6t_entry *)(table->private->entries + off);
+		e = (struct ip6t_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ip6t_entry, counters),
 				 &counters[num],
@@ -1196,6 +1211,46 @@
 	return ret;
 }
 
+static void free_table_info(struct ip6t_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct ip6t_table_info *alloc_table_info(unsigned int size)
+{
+	struct ip6t_table_info *newinfo;
+	int cpu;
+
+	newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+							GFP_KERNEL,
+							cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size,
+							     cpu_to_node(cpu));
+		if (newinfo->entries[cpu] == NULL) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1204,6 +1259,7 @@
 	struct ip6t_table *t;
 	struct ip6t_table_info *newinfo, *oldinfo;
 	struct ip6t_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1212,13 +1268,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(tmp.size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1229,10 +1285,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct ip6t_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -1271,8 +1326,9 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1284,11 +1340,11 @@
 	module_put(t->me);
 	up(&ip6t_mutex);
  free_newinfo_counters_untrans:
-	IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1321,6 +1377,7 @@
 	struct ip6t_counters_info tmp, *paddc;
 	struct ip6t_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1350,7 +1407,9 @@
 	}
 
 	i = 0;
-	IP6T_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_entry,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1543,28 +1602,29 @@
 	struct ip6t_table_info *newinfo;
 	static struct ip6t_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(repl->size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	/* choose the copy on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ip6t_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1593,20 +1653,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void ip6t_unregister_table(struct ip6t_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&ip6t_mutex);
 	LIST_DELETE(&ip6t_tables, table);
 	up(&ip6t_mutex);
 
 	/* Decrease module usage counts and free resources */
-	IP6T_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0cd1d1b..ae4653b 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/ip.h>
 #include <linux/spinlock.h>
 #include <linux/icmpv6.h>
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index dde3779..268918d 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
index 24bc0cd..65937de 100644
--- a/net/ipv6/netfilter/ip6t_esp.c
+++ b/net/ipv6/netfilter/ip6t_esp.c
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c2c52af..f3e5ffb 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -98,7 +98,7 @@
 #define FRAG6Q_HASHSZ	64
 
 static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
-static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(nf_ct_frag6_lock);
 static u32 nf_ct_frag6_hash_rnd;
 static LIST_HEAD(nf_ct_frag6_lru_list);
 int nf_ct_frag6_nqueues = 0;
@@ -371,7 +371,7 @@
 	init_timer(&fq->timer);
 	fq->timer.function = nf_ct_frag6_expire;
 	fq->timer.data = (long) fq;
-	fq->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&fq->lock);
 	atomic_set(&fq->refcnt, 1);
 
 	return nf_ct_frag6_intern(hash, fq);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a66900c..66f1d12 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -32,6 +32,7 @@
 #include <linux/icmpv6.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 #include <asm/bug.h>
@@ -433,25 +434,14 @@
 	return err;
 
 csum_copy_err:
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
+	skb_kill_datagram(sk, skb, flags);
 
 	/* Error for blocking case is chosen to masquerade
 	   as some normal condition.
 	 */
 	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
 	/* FIXME: increment a raw6 drops counter here */
-	goto out_free;
+	goto out;
 }
 
 static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8827389..2947bc5 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -48,6 +48,7 @@
 #include <net/tcp.h>
 #include <net/ndisc.h>
 #include <net/inet6_hashtables.h>
+#include <net/inet6_connection_sock.h>
 #include <net/ipv6.h>
 #include <net/transp_v6.h>
 #include <net/addrconf.h>
@@ -59,6 +60,7 @@
 #include <net/addrconf.h>
 #include <net/snmp.h>
 #include <net/dsfield.h>
+#include <net/timewait_sock.h>
 
 #include <asm/uaccess.h>
 
@@ -67,224 +69,33 @@
 
 static void	tcp_v6_send_reset(struct sk_buff *skb);
 static void	tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
-static void	tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
+static void	tcp_v6_send_check(struct sock *sk, int len, 
 				  struct sk_buff *skb);
 
 static int	tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
-static int	tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
 
-static struct tcp_func ipv6_mapped;
-static struct tcp_func ipv6_specific;
+static struct inet_connection_sock_af_ops ipv6_mapped;
+static struct inet_connection_sock_af_ops ipv6_specific;
 
-static inline int tcp_v6_bind_conflict(const struct sock *sk,
-				       const struct inet_bind_bucket *tb)
-{
-	const struct sock *sk2;
-	const struct hlist_node *node;
-
-	/* We must walk the whole port owner list in this case. -DaveM */
-	sk_for_each_bound(sk2, node, &tb->owners) {
-		if (sk != sk2 &&
-		    (!sk->sk_bound_dev_if ||
-		     !sk2->sk_bound_dev_if ||
-		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
-		    (!sk->sk_reuse || !sk2->sk_reuse ||
-		     sk2->sk_state == TCP_LISTEN) &&
-		     ipv6_rcv_saddr_equal(sk, sk2))
-			break;
-	}
-
-	return node != NULL;
-}
-
-/* Grrr, addr_type already calculated by caller, but I don't want
- * to add some silly "cookie" argument to this method just for that.
- * But it doesn't matter, the recalculation is in the rarest path
- * this function ever takes.
- */
 static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 {
-	struct inet_bind_hashbucket *head;
-	struct inet_bind_bucket *tb;
-	struct hlist_node *node;
-	int ret;
-
-	local_bh_disable();
-	if (snum == 0) {
-		int low = sysctl_local_port_range[0];
-		int high = sysctl_local_port_range[1];
-		int remaining = (high - low) + 1;
-		int rover = net_random() % (high - low) + low;
-
-		do {
-			head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
-			spin_lock(&head->lock);
-			inet_bind_bucket_for_each(tb, node, &head->chain)
-				if (tb->port == rover)
-					goto next;
-			break;
-		next:
-			spin_unlock(&head->lock);
-			if (++rover > high)
-				rover = low;
-		} while (--remaining > 0);
-
-		/* Exhausted local port range during search?  It is not
-		 * possible for us to be holding one of the bind hash
-		 * locks if this test triggers, because if 'remaining'
-		 * drops to zero, we broke out of the do/while loop at
-		 * the top level, not from the 'break;' statement.
-		 */
-		ret = 1;
-		if (unlikely(remaining <= 0))
-			goto fail;
-
-		/* OK, here is the one we will use. */
-		snum = rover;
-	} else {
-		head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
-		spin_lock(&head->lock);
-		inet_bind_bucket_for_each(tb, node, &head->chain)
-			if (tb->port == snum)
-				goto tb_found;
-	}
-	tb = NULL;
-	goto tb_not_found;
-tb_found:
-	if (tb && !hlist_empty(&tb->owners)) {
-		if (tb->fastreuse > 0 && sk->sk_reuse &&
-		    sk->sk_state != TCP_LISTEN) {
-			goto success;
-		} else {
-			ret = 1;
-			if (tcp_v6_bind_conflict(sk, tb))
-				goto fail_unlock;
-		}
-	}
-tb_not_found:
-	ret = 1;
-	if (tb == NULL) {
-	       	tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum);
-		if (tb == NULL)
-			goto fail_unlock;
-	}
-	if (hlist_empty(&tb->owners)) {
-		if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
-			tb->fastreuse = 1;
-		else
-			tb->fastreuse = 0;
-	} else if (tb->fastreuse &&
-		   (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
-		tb->fastreuse = 0;
-
-success:
-	if (!inet_csk(sk)->icsk_bind_hash)
-		inet_bind_hash(sk, tb, snum);
-	BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb);
-	ret = 0;
-
-fail_unlock:
-	spin_unlock(&head->lock);
-fail:
-	local_bh_enable();
-	return ret;
+	return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+				 inet6_csk_bind_conflict);
 }
 
-static __inline__ void __tcp_v6_hash(struct sock *sk)
-{
-	struct hlist_head *list;
-	rwlock_t *lock;
-
-	BUG_TRAP(sk_unhashed(sk));
-
-	if (sk->sk_state == TCP_LISTEN) {
-		list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)];
-		lock = &tcp_hashinfo.lhash_lock;
-		inet_listen_wlock(&tcp_hashinfo);
-	} else {
-		unsigned int hash;
-		sk->sk_hash = hash = inet6_sk_ehashfn(sk);
-		hash &= (tcp_hashinfo.ehash_size - 1);
-		list = &tcp_hashinfo.ehash[hash].chain;
-		lock = &tcp_hashinfo.ehash[hash].lock;
-		write_lock(lock);
-	}
-
-	__sk_add_node(sk, list);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(lock);
-}
-
-
 static void tcp_v6_hash(struct sock *sk)
 {
 	if (sk->sk_state != TCP_CLOSE) {
-		struct tcp_sock *tp = tcp_sk(sk);
-
-		if (tp->af_specific == &ipv6_mapped) {
+		if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) {
 			tcp_prot.hash(sk);
 			return;
 		}
 		local_bh_disable();
-		__tcp_v6_hash(sk);
+		__inet6_hash(&tcp_hashinfo, sk);
 		local_bh_enable();
 	}
 }
 
-/*
- * Open request hash tables.
- */
-
-static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd)
-{
-	u32 a, b, c;
-
-	a = raddr->s6_addr32[0];
-	b = raddr->s6_addr32[1];
-	c = raddr->s6_addr32[2];
-
-	a += JHASH_GOLDEN_RATIO;
-	b += JHASH_GOLDEN_RATIO;
-	c += rnd;
-	__jhash_mix(a, b, c);
-
-	a += raddr->s6_addr32[3];
-	b += (u32) rport;
-	__jhash_mix(a, b, c);
-
-	return c & (TCP_SYNQ_HSIZE - 1);
-}
-
-static struct request_sock *tcp_v6_search_req(const struct sock *sk,
-					      struct request_sock ***prevp,
-					      __u16 rport,
-					      struct in6_addr *raddr,
-					      struct in6_addr *laddr,
-					      int iif)
-{
-	const struct inet_connection_sock *icsk = inet_csk(sk);
-	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-	struct request_sock *req, **prev;  
-
-	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
-	     (req = *prev) != NULL;
-	     prev = &req->dl_next) {
-		const struct tcp6_request_sock *treq = tcp6_rsk(req);
-
-		if (inet_rsk(req)->rmt_port == rport &&
-		    req->rsk_ops->family == AF_INET6 &&
-		    ipv6_addr_equal(&treq->rmt_addr, raddr) &&
-		    ipv6_addr_equal(&treq->loc_addr, laddr) &&
-		    (!treq->iif || treq->iif == iif)) {
-			BUG_TRAP(req->sk == NULL);
-			*prevp = prev;
-			return req;
-		}
-	}
-
-	return NULL;
-}
-
 static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
 				   struct in6_addr *saddr, 
 				   struct in6_addr *daddr, 
@@ -308,195 +119,12 @@
 	}
 }
 
-static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
-				      struct inet_timewait_sock **twp)
-{
-	struct inet_sock *inet = inet_sk(sk);
-	const struct ipv6_pinfo *np = inet6_sk(sk);
-	const struct in6_addr *daddr = &np->rcv_saddr;
-	const struct in6_addr *saddr = &np->daddr;
-	const int dif = sk->sk_bound_dev_if;
-	const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-	struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
-
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
-
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-		const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2);
-
-		tw = inet_twsk(sk2);
-
-		if(*((__u32 *)&(tw->tw_dport))	== ports	&&
-		   sk2->sk_family		== PF_INET6	&&
-		   ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr)	&&
-		   ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)	&&
-		   sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
-			const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-			struct tcp_sock *tp = tcp_sk(sk);
-
-			if (tcptw->tw_ts_recent_stamp &&
-			    (!twp ||
-			     (sysctl_tcp_tw_reuse &&
-			      xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
-				/* See comment in tcp_ipv4.c */
-				tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-				if (!tp->write_seq)
-					tp->write_seq = 1;
-				tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
-				tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-				sock_hold(sk2);
-				goto unique;
-			} else
-				goto not_unique;
-		}
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-unique:
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sk->sk_hash = hash;
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &tcp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
-	}
-	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
-}
-
-static inline u32 tcpv6_port_offset(const struct sock *sk)
-{
-	const struct inet_sock *inet = inet_sk(sk);
-	const struct ipv6_pinfo *np = inet6_sk(sk);
-
-	return secure_tcpv6_port_ephemeral(np->rcv_saddr.s6_addr32,
-					   np->daddr.s6_addr32,
-					   inet->dport);
-}
-
-static int tcp_v6_hash_connect(struct sock *sk)
-{
-	unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (!snum) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
-		int range = high - low;
- 		int i;
-		int port;
-		static u32 hint;
-		u32 offset = hint + tcpv6_port_offset(sk);
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
-		for (i = 1; i <= range; i++) {
-			port = low + (i + offset) % range;
- 			head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == port) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__tcp_v6_check_established(sk,
-									port,
-									&tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
- 			if (!tb) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 		}
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
-		hint += i;
-
- 		/* Head lock still held and bh's disabled */
- 		inet_bind_hash(sk, tb, port);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(port);
- 			__tcp_v6_hash(sk);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw) {
- 			inet_twsk_deschedule(tw, &tcp_death_row);
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
- 	tb   = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-
-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-		__tcp_v6_hash(sk);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __tcp_v6_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
-
 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
 			  int addr_len)
 {
 	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
-	struct inet_sock *inet = inet_sk(sk);
+ 	struct inet_sock *inet = inet_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct in6_addr *saddr = NULL, *final_p = NULL, final;
@@ -571,7 +199,7 @@
 	 */
 
 	if (addr_type == IPV6_ADDR_MAPPED) {
-		u32 exthdrlen = tp->ext_header_len;
+		u32 exthdrlen = icsk->icsk_ext_hdr_len;
 		struct sockaddr_in sin;
 
 		SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
@@ -583,14 +211,14 @@
 		sin.sin_port = usin->sin6_port;
 		sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
 
-		tp->af_specific = &ipv6_mapped;
+		icsk->icsk_af_ops = &ipv6_mapped;
 		sk->sk_backlog_rcv = tcp_v4_do_rcv;
 
 		err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
 
 		if (err) {
-			tp->ext_header_len = exthdrlen;
-			tp->af_specific = &ipv6_specific;
+			icsk->icsk_ext_hdr_len = exthdrlen;
+			icsk->icsk_af_ops = &ipv6_specific;
 			sk->sk_backlog_rcv = tcp_v6_do_rcv;
 			goto failure;
 		} else {
@@ -643,16 +271,17 @@
 	sk->sk_route_caps = dst->dev->features &
 		~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
-	tp->ext_header_len = 0;
+	icsk->icsk_ext_hdr_len = 0;
 	if (np->opt)
-		tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
+		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+					  np->opt->opt_nflen);
 
 	tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
 	inet->dport = usin->sin6_port;
 
 	tcp_set_state(sk, TCP_SYN_SENT);
-	err = tcp_v6_hash_connect(sk);
+	err = inet6_hash_connect(&tcp_death_row, sk);
 	if (err)
 		goto late_failure;
 
@@ -758,7 +387,7 @@
 		} else
 			dst_hold(dst);
 
-		if (tp->pmtu_cookie > dst_mtu(dst)) {
+		if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
 			tcp_sync_mss(sk, dst_mtu(dst));
 			tcp_simple_retransmit(sk);
 		} /* else let the usual retransmit timer handle it */
@@ -775,8 +404,8 @@
 		if (sock_owned_by_user(sk))
 			goto out;
 
-		req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr,
-					&hdr->saddr, inet6_iif(skb));
+		req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr,
+					   &hdr->saddr, inet6_iif(skb));
 		if (!req)
 			goto out;
 
@@ -822,7 +451,7 @@
 static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
 			      struct dst_entry *dst)
 {
-	struct tcp6_request_sock *treq = tcp6_rsk(req);
+	struct inet6_request_sock *treq = inet6_rsk(req);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff * skb;
 	struct ipv6_txoptions *opt = NULL;
@@ -888,8 +517,8 @@
 
 static void tcp_v6_reqsk_destructor(struct request_sock *req)
 {
-	if (tcp6_rsk(req)->pktopts)
-		kfree_skb(tcp6_rsk(req)->pktopts);
+	if (inet6_rsk(req)->pktopts)
+		kfree_skb(inet6_rsk(req)->pktopts);
 }
 
 static struct request_sock_ops tcp6_request_sock_ops = {
@@ -901,26 +530,15 @@
 	.send_reset	=	tcp_v6_send_reset
 };
 
-static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
+static struct timewait_sock_ops tcp6_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct tcp6_timewait_sock),
+	.twsk_unique	= tcp_twsk_unique,
+};
+
+static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct inet6_skb_parm *opt = IP6CB(skb);
-
-	if (np->rxopt.all) {
-		if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
-		    ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
-		    (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
-		    ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
-			return 1;
-	}
-	return 0;
-}
-
-
-static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
-			      struct sk_buff *skb)
-{
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct tcphdr *th = skb->h.th;
 
 	if (skb->ip_summed == CHECKSUM_HW) {
 		th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
@@ -1091,8 +709,9 @@
 	struct sock *nsk;
 
 	/* Find possible connection requests. */
-	req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr,
-				&skb->nh.ipv6h->daddr, inet6_iif(skb));
+	req = inet6_csk_search_req(sk, &prev, th->source,
+				   &skb->nh.ipv6h->saddr,
+				   &skb->nh.ipv6h->daddr, inet6_iif(skb));
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
 
@@ -1116,23 +735,12 @@
 	return sk;
 }
 
-static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
-{
-	struct inet_connection_sock *icsk = inet_csk(sk);
-	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-	const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
-
-	reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT);
-	inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT);
-}
-
-
 /* FIXME: this is substantially similar to the ipv4 code.
  * Can some kind of merge be done? -- erics
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp6_request_sock *treq;
+	struct inet6_request_sock *treq;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_options_received tmp_opt;
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1157,7 +765,7 @@
 	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
 		goto drop;
 
-	req = reqsk_alloc(&tcp6_request_sock_ops);
+	req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
 	if (req == NULL)
 		goto drop;
 
@@ -1170,7 +778,7 @@
 	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
 	tcp_openreq_init(req, &tmp_opt, skb);
 
-	treq = tcp6_rsk(req);
+	treq = inet6_rsk(req);
 	ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
 	ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
 	TCP_ECN_create_request(req, skb->h.th);
@@ -1196,8 +804,7 @@
 	if (tcp_v6_send_synack(sk, req, NULL))
 		goto drop;
 
-	tcp_v6_synq_add(sk, req);
-
+	inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
 	return 0;
 
 drop:
@@ -1212,7 +819,7 @@
 					  struct request_sock *req,
 					  struct dst_entry *dst)
 {
-	struct tcp6_request_sock *treq = tcp6_rsk(req);
+	struct inet6_request_sock *treq = inet6_rsk(req);
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
 	struct inet_sock *newinet;
@@ -1247,7 +854,7 @@
 
 		ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
 
-		newtp->af_specific = &ipv6_mapped;
+		inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
 		newsk->sk_backlog_rcv = tcp_v4_do_rcv;
 		newnp->pktoptions  = NULL;
 		newnp->opt	   = NULL;
@@ -1261,10 +868,10 @@
 		 */
 
 		/* It is tricky place. Until this moment IPv4 tcp
-		   worked with IPv6 af_tcp.af_specific.
+		   worked with IPv6 icsk.icsk_af_ops.
 		   Sync it now.
 		 */
-		tcp_sync_mss(newsk, newtp->pmtu_cookie);
+		tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
 
 		return newsk;
 	}
@@ -1371,10 +978,10 @@
 			sock_kfree_s(sk, opt, opt->tot_len);
 	}
 
-	newtp->ext_header_len = 0;
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
 	if (newnp->opt)
-		newtp->ext_header_len = newnp->opt->opt_nflen +
-					newnp->opt->opt_flen;
+		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+						     newnp->opt->opt_flen);
 
 	tcp_sync_mss(newsk, dst_mtu(dst));
 	newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
@@ -1382,7 +989,7 @@
 
 	newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
 
-	__tcp_v6_hash(newsk);
+	__inet6_hash(&tcp_hashinfo, newsk);
 	inet_inherit_port(&tcp_hashinfo, sk, newsk);
 
 	return newsk;
@@ -1679,139 +1286,16 @@
 	goto discard_it;
 }
 
-static int tcp_v6_rebuild_header(struct sock *sk)
-{
-	int err;
-	struct dst_entry *dst;
-	struct ipv6_pinfo *np = inet6_sk(sk);
-
-	dst = __sk_dst_check(sk, np->dst_cookie);
-
-	if (dst == NULL) {
-		struct inet_sock *inet = inet_sk(sk);
-		struct in6_addr *final_p = NULL, final;
-		struct flowi fl;
-
-		memset(&fl, 0, sizeof(fl));
-		fl.proto = IPPROTO_TCP;
-		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-		fl.fl6_flowlabel = np->flow_label;
-		fl.oif = sk->sk_bound_dev_if;
-		fl.fl_ip_dport = inet->dport;
-		fl.fl_ip_sport = inet->sport;
-
-		if (np->opt && np->opt->srcrt) {
-			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-			ipv6_addr_copy(&final, &fl.fl6_dst);
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-			final_p = &final;
-		}
-
-		err = ip6_dst_lookup(sk, &dst, &fl);
-		if (err) {
-			sk->sk_route_caps = 0;
-			return err;
-		}
-		if (final_p)
-			ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-			sk->sk_err_soft = -err;
-			return err;
-		}
-
-		ip6_dst_store(sk, dst, NULL);
-		sk->sk_route_caps = dst->dev->features &
-			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-	}
-
-	return 0;
-}
-
-static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
-{
-	struct sock *sk = skb->sk;
-	struct inet_sock *inet = inet_sk(sk);
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct flowi fl;
-	struct dst_entry *dst;
-	struct in6_addr *final_p = NULL, final;
-
-	memset(&fl, 0, sizeof(fl));
-	fl.proto = IPPROTO_TCP;
-	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-	fl.fl6_flowlabel = np->flow_label;
-	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
-	fl.oif = sk->sk_bound_dev_if;
-	fl.fl_ip_sport = inet->sport;
-	fl.fl_ip_dport = inet->dport;
-
-	if (np->opt && np->opt->srcrt) {
-		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		ipv6_addr_copy(&final, &fl.fl6_dst);
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-		final_p = &final;
-	}
-
-	dst = __sk_dst_check(sk, np->dst_cookie);
-
-	if (dst == NULL) {
-		int err = ip6_dst_lookup(sk, &dst, &fl);
-
-		if (err) {
-			sk->sk_err_soft = -err;
-			return err;
-		}
-
-		if (final_p)
-			ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-			sk->sk_route_caps = 0;
-			return err;
-		}
-
-		ip6_dst_store(sk, dst, NULL);
-		sk->sk_route_caps = dst->dev->features &
-			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-	}
-
-	skb->dst = dst_clone(dst);
-
-	/* Restore final destination back after routing done */
-	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-
-	return ip6_xmit(sk, skb, &fl, np->opt, 0);
-}
-
-static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
-
-	sin6->sin6_family = AF_INET6;
-	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
-	sin6->sin6_port	= inet_sk(sk)->dport;
-	/* We do not store received flowlabel for TCP */
-	sin6->sin6_flowinfo = 0;
-	sin6->sin6_scope_id = 0;
-	if (sk->sk_bound_dev_if &&
-	    ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-		sin6->sin6_scope_id = sk->sk_bound_dev_if;
-}
-
 static int tcp_v6_remember_stamp(struct sock *sk)
 {
 	/* Alas, not yet... */
 	return 0;
 }
 
-static struct tcp_func ipv6_specific = {
-	.queue_xmit	=	tcp_v6_xmit,
+static struct inet_connection_sock_af_ops ipv6_specific = {
+	.queue_xmit	=	inet6_csk_xmit,
 	.send_check	=	tcp_v6_send_check,
-	.rebuild_header	=	tcp_v6_rebuild_header,
+	.rebuild_header	=	inet6_sk_rebuild_header,
 	.conn_request	=	tcp_v6_conn_request,
 	.syn_recv_sock	=	tcp_v6_syn_recv_sock,
 	.remember_stamp	=	tcp_v6_remember_stamp,
@@ -1819,7 +1303,7 @@
 
 	.setsockopt	=	ipv6_setsockopt,
 	.getsockopt	=	ipv6_getsockopt,
-	.addr2sockaddr	=	v6_addr2sockaddr,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
@@ -1827,7 +1311,7 @@
  *	TCP over IPv4 via INET6 API
  */
 
-static struct tcp_func ipv6_mapped = {
+static struct inet_connection_sock_af_ops ipv6_mapped = {
 	.queue_xmit	=	ip_queue_xmit,
 	.send_check	=	tcp_v4_send_check,
 	.rebuild_header	=	inet_sk_rebuild_header,
@@ -1838,7 +1322,7 @@
 
 	.setsockopt	=	ipv6_setsockopt,
 	.getsockopt	=	ipv6_getsockopt,
-	.addr2sockaddr	=	v6_addr2sockaddr,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
@@ -1877,8 +1361,9 @@
 
 	sk->sk_state = TCP_CLOSE;
 
-	tp->af_specific = &ipv6_specific;
+	icsk->icsk_af_ops = &ipv6_specific;
 	icsk->icsk_ca_ops = &tcp_init_congestion_ops;
+	icsk->icsk_sync_mss = tcp_sync_mss;
 	sk->sk_write_space = sk_stream_write_space;
 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
@@ -1900,14 +1385,13 @@
 static void get_openreq6(struct seq_file *seq, 
 			 struct sock *sk, struct request_sock *req, int i, int uid)
 {
-	struct in6_addr *dest, *src;
 	int ttd = req->expires - jiffies;
+	struct in6_addr *src = &inet6_rsk(req)->loc_addr;
+	struct in6_addr *dest = &inet6_rsk(req)->rmt_addr;
 
 	if (ttd < 0)
 		ttd = 0;
 
-	src = &tcp6_rsk(req)->loc_addr;
-	dest = &tcp6_rsk(req)->rmt_addr;
 	seq_printf(seq,
 		   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
 		   "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
@@ -1988,14 +1472,14 @@
 {
 	struct in6_addr *dest, *src;
 	__u16 destp, srcp;
-	struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+	struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
 	int ttd = tw->tw_ttd - jiffies;
 
 	if (ttd < 0)
 		ttd = 0;
 
-	dest = &tcp6tw->tw_v6_daddr;
-	src  = &tcp6tw->tw_v6_rcv_saddr;
+	dest = &tw6->tw_v6_daddr;
+	src  = &tw6->tw_v6_rcv_saddr;
 	destp = ntohs(tw->tw_dport);
 	srcp  = ntohs(tw->tw_sport);
 
@@ -2093,7 +1577,7 @@
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp6_sock),
-	.twsk_obj_size		= sizeof(struct tcp6_timewait_sock),
+	.twsk_prot		= &tcp6_timewait_sock_ops,
 	.rsk_prot		= &tcp6_request_sock_ops,
 };
 
@@ -2110,7 +1594,8 @@
 	.ops		=	&inet6_stream_ops,
 	.capability	=	-1,
 	.no_check	=	0,
-	.flags		=	INET_PROTOSW_PERMANENT,
+	.flags		=	INET_PROTOSW_PERMANENT |
+				INET_PROTOSW_ICSK,
 };
 
 void __init tcpv6_init(void)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5cc8731..d8538dc 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -36,6 +36,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/init.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 
 #include <net/sock.h>
@@ -300,20 +301,7 @@
 	return err;
 
 csum_copy_err:
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
-
-	skb_free_datagram(sk, skb);
+	skb_kill_datagram(sk, skb, flags);
 
 	if (flags & MSG_DONTWAIT) {
 		UDP6_INC_STATS_USER(UDP_MIB_INERRORS);
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 34b3bb8..0dc519b 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -75,7 +75,7 @@
 static struct datalink_proto *p8023_datalink;
 static struct datalink_proto *pSNAP_datalink;
 
-static struct proto_ops ipx_dgram_ops;
+static const struct proto_ops ipx_dgram_ops;
 
 LIST_HEAD(ipx_interfaces);
 DEFINE_SPINLOCK(ipx_interfaces_lock);
@@ -1884,7 +1884,7 @@
 		rc = -EINVAL;
 		break;
 	default:
-		rc = dev_ioctl(cmd, argp);
+		rc = -ENOIOCTLCMD;
 		break;
 	}
 
@@ -1901,7 +1901,7 @@
 	.owner		= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
 	.family		= PF_IPX,
 	.owner		= THIS_MODULE,
 	.release	= ipx_release,
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 6f92f9c..fbfa967 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -62,12 +62,12 @@
 
 static int irda_create(struct socket *sock, int protocol);
 
-static struct proto_ops irda_stream_ops;
-static struct proto_ops irda_seqpacket_ops;
-static struct proto_ops irda_dgram_ops;
+static const struct proto_ops irda_stream_ops;
+static const struct proto_ops irda_seqpacket_ops;
+static const struct proto_ops irda_dgram_ops;
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops irda_ultra_ops;
+static const struct proto_ops irda_ultra_ops;
 #define ULTRA_MAX_DATA 382
 #endif /* CONFIG_IRDA_ULTRA */
 
@@ -1438,8 +1438,9 @@
 			/*
 			 *	POSIX 1003.1g mandates this order.
 			 */
-			if (sk->sk_err)
-				ret = sock_error(sk);
+			ret = sock_error(sk);
+			if (ret)
+				break;
 			else if (sk->sk_shutdown & RCV_SHUTDOWN)
 				;
 			else if (noblock)
@@ -1821,7 +1822,7 @@
 		return -EINVAL;
 	default:
 		IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
-		return dev_ioctl(cmd, (void __user *) arg);
+		return -ENOIOCTLCMD;
 	}
 
 	/*NOTREACHED*/
@@ -2463,7 +2464,7 @@
 	.owner	= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2484,7 +2485,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2505,7 +2506,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2527,7 +2528,7 @@
 };
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 3903168..52efd04 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -113,7 +113,7 @@
 }
 
 
-static struct proto_ops pfkey_ops;
+static const struct proto_ops pfkey_ops;
 
 static void pfkey_insert(struct sock *sk)
 {
@@ -336,6 +336,7 @@
 	[SADB_X_EXT_NAT_T_SPORT]	= (u8) sizeof(struct sadb_x_nat_t_port),
 	[SADB_X_EXT_NAT_T_DPORT]	= (u8) sizeof(struct sadb_x_nat_t_port),
 	[SADB_X_EXT_NAT_T_OA]		= (u8) sizeof(struct sadb_address),
+	[SADB_X_EXT_SEC_CTX]		= (u8) sizeof(struct sadb_x_sec_ctx),
 };
 
 /* Verify sadb_address_{len,prefixlen} against sa_family.  */
@@ -383,6 +384,55 @@
 	return 0;
 }
 
+static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
+{
+	int len = 0;
+
+	len += sizeof(struct sadb_x_sec_ctx);
+	len += sec_ctx->sadb_x_ctx_len;
+	len += sizeof(uint64_t) - 1;
+	len /= sizeof(uint64_t);
+
+	return len;
+}
+
+static inline int verify_sec_ctx_len(void *p)
+{
+	struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
+	int len;
+
+	if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE)
+		return -EINVAL;
+
+	len = pfkey_sec_ctx_len(sec_ctx);
+
+	if (sec_ctx->sadb_x_sec_len != len)
+		return -EINVAL;
+
+	return 0;
+}
+
+static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx)
+{
+	struct xfrm_user_sec_ctx *uctx = NULL;
+	int ctx_size = sec_ctx->sadb_x_ctx_len;
+
+	uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
+
+	if (!uctx)
+		return NULL;
+
+	uctx->len = pfkey_sec_ctx_len(sec_ctx);
+	uctx->exttype = sec_ctx->sadb_x_sec_exttype;
+	uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
+	uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
+	uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
+	memcpy(uctx + 1, sec_ctx + 1,
+	       uctx->ctx_len);
+
+	return uctx;
+}
+
 static int present_and_same_family(struct sadb_address *src,
 				   struct sadb_address *dst)
 {
@@ -438,6 +488,10 @@
 				if (verify_address_len(p))
 					return -EINVAL;
 			}				
+			if (ext_type == SADB_X_EXT_SEC_CTX) {
+				if (verify_sec_ctx_len(p))
+					return -EINVAL;
+			}
 			ext_hdrs[ext_type-1] = p;
 		}
 		p   += ext_len;
@@ -586,6 +640,9 @@
 	struct sadb_key *key;
 	struct sadb_x_sa2 *sa2;
 	struct sockaddr_in *sin;
+	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_sec_ctx *xfrm_ctx;
+	int ctx_size = 0;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct sockaddr_in6 *sin6;
 #endif
@@ -609,6 +666,12 @@
 			sizeof(struct sadb_address)*2 + 
 				sockaddr_size*2 +
 					sizeof(struct sadb_x_sa2);
+
+	if ((xfrm_ctx = x->security)) {
+		ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+		size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
+	}
+
 	/* identity & sensitivity */
 
 	if ((x->props.family == AF_INET &&
@@ -899,6 +962,20 @@
 		n_port->sadb_x_nat_t_port_reserved = 0;
 	}
 
+	/* security context */
+	if (xfrm_ctx) {
+		sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb,
+				sizeof(struct sadb_x_sec_ctx) + ctx_size);
+		sec_ctx->sadb_x_sec_len =
+		  (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t);
+		sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+		sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+		sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+		memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+		       xfrm_ctx->ctx_len);
+	}
+
 	return skb;
 }
 
@@ -909,6 +986,7 @@
 	struct sadb_lifetime *lifetime;
 	struct sadb_sa *sa;
 	struct sadb_key *key;
+	struct sadb_x_sec_ctx *sec_ctx;
 	uint16_t proto;
 	int err;
 	
@@ -993,6 +1071,21 @@
 		x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;
 		x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
 	}
+
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx)
+			goto out;
+
+		err = security_xfrm_state_alloc(x, uctx);
+		kfree(uctx);
+
+		if (err)
+			goto out;
+	}
+
 	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
 	if (sa->sadb_sa_auth) {
 		int keysize = 0;
@@ -1720,6 +1813,18 @@
 	return 0;
 }
 
+static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
+{
+  struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+
+	if (xfrm_ctx) {
+		int len = sizeof(struct sadb_x_sec_ctx);
+		len += xfrm_ctx->ctx_len;
+		return PFKEY_ALIGN8(len);
+	}
+	return 0;
+}
+
 static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
 {
 	int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -1733,7 +1838,8 @@
 		(sockaddr_size * 2) +
 		sizeof(struct sadb_x_policy) +
 		(xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
-				(socklen * 2)));
+				(socklen * 2))) +
+		pfkey_xfrm_policy2sec_ctx_size(xp);
 }
 
 static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
@@ -1757,6 +1863,8 @@
 	struct sadb_lifetime *lifetime;
 	struct sadb_x_policy *pol;
 	struct sockaddr_in   *sin;
+	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_sec_ctx *xfrm_ctx;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct sockaddr_in6  *sin6;
 #endif
@@ -1941,6 +2049,21 @@
 			}
 		}
 	}
+
+	/* security context */
+	if ((xfrm_ctx = xp->security)) {
+		int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp);
+
+		sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size);
+		sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t);
+		sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+		sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+		sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+		memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+		       xfrm_ctx->ctx_len);
+	}
+
 	hdr->sadb_msg_len = size / sizeof(uint64_t);
 	hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
 }
@@ -1976,12 +2099,13 @@
 
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
-	int err;
+	int err = 0;
 	struct sadb_lifetime *lifetime;
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
 	struct km_event c;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2028,6 +2152,22 @@
 	if (xp->selector.dport)
 		xp->selector.dport_mask = ~0;
 
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx) {
+			err = -ENOBUFS;
+			goto out;
+		}
+
+		err = security_xfrm_policy_alloc(xp, uctx);
+		kfree(uctx);
+
+		if (err)
+			goto out;
+	}
+
 	xp->lft.soft_byte_limit = XFRM_INF;
 	xp->lft.hard_byte_limit = XFRM_INF;
 	xp->lft.soft_packet_limit = XFRM_INF;
@@ -2051,10 +2191,9 @@
 
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
 				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
-	if (err) {
-		kfree(xp);
-		return err;
-	}
+
+	if (err)
+		goto out;
 
 	if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
 		c.event = XFRM_MSG_UPDPOLICY;
@@ -2069,6 +2208,7 @@
 	return 0;
 
 out:
+	security_xfrm_policy_free(xp);
 	kfree(xp);
 	return err;
 }
@@ -2078,9 +2218,10 @@
 	int err;
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
-	struct xfrm_policy *xp;
+	struct xfrm_policy *xp, tmp;
 	struct xfrm_selector sel;
 	struct km_event c;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2109,7 +2250,24 @@
 	if (sel.dport)
 		sel.dport_mask = ~0;
 
-	xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	memset(&tmp, 0, sizeof(struct xfrm_policy));
+
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx)
+			return -ENOMEM;
+
+		err = security_xfrm_policy_alloc(&tmp, uctx);
+		kfree(uctx);
+
+		if (err)
+			return err;
+	}
+
+	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
+	security_xfrm_policy_free(&tmp);
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -2660,6 +2818,7 @@
 {
 	struct xfrm_policy *xp;
 	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	switch (family) {
 	case AF_INET:
@@ -2709,10 +2868,32 @@
 	    (*dir = parse_ipsecrequests(xp, pol)) < 0)
 		goto out;
 
+	/* security context too */
+	if (len >= (pol->sadb_x_policy_len*8 +
+	    sizeof(struct sadb_x_sec_ctx))) {
+		char *p = (char *)pol;
+		struct xfrm_user_sec_ctx *uctx;
+
+		p += pol->sadb_x_policy_len*8;
+		sec_ctx = (struct sadb_x_sec_ctx *)p;
+		if (len < pol->sadb_x_policy_len*8 +
+		    sec_ctx->sadb_x_sec_len)
+			goto out;
+		if ((*dir = verify_sec_ctx_len(p)))
+			goto out;
+		uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+		*dir = security_xfrm_policy_alloc(xp, uctx);
+		kfree(uctx);
+
+		if (*dir)
+			goto out;
+	}
+
 	*dir = pol->sadb_x_policy_dir-1;
 	return xp;
 
 out:
+	security_xfrm_policy_free(xp);
 	kfree(xp);
 	return NULL;
 }
@@ -2946,7 +3127,7 @@
 	return err;
 }
 
-static struct proto_ops pfkey_ops = {
+static const struct proto_ops pfkey_ops = {
 	.family		=	PF_KEY,
 	.owner		=	THIS_MODULE,
 	/* Operations that make no sense on pfkey sockets. */
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c3f0b07..8171c53 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -36,7 +36,7 @@
 static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 static u16 llc_ui_sap_link_no_max[256];
 static struct sockaddr_llc llc_ui_addrnull;
-static struct proto_ops llc_ui_ops;
+static const struct proto_ops llc_ui_ops;
 
 static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
 static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
@@ -566,10 +566,9 @@
 		/*
 		 * POSIX 1003.1g mandates this order.
 		 */
-		if (sk->sk_err) {
-			rc = sock_error(sk);
+		rc = sock_error(sk);
+		if (rc)
 			break;
-		}
 		rc = 0;
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
@@ -960,7 +959,7 @@
 static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
 			unsigned long arg)
 {
-	return dev_ioctl(cmd, (void __user *)arg);
+	return -ENOIOCTLCMD;
 }
 
 /**
@@ -1099,7 +1098,7 @@
 	.owner	= THIS_MODULE,
 };
 
-static struct proto_ops llc_ui_ops = {
+static const struct proto_ops llc_ui_ops = {
 	.family	     = PF_LLC,
 	.owner       = THIS_MODULE,
 	.release     = llc_ui_release,
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index cba6372..e10512e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -151,7 +151,7 @@
 		goto out_unlock;
 
 	INIT_HLIST_NODE(&inst->hlist);
-	inst->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&inst->lock);
 	/* needs to be two, since we _put() after creation */
 	atomic_set(&inst->use, 2);
 
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index f28460b..55afdda 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -148,7 +148,7 @@
 	atomic_set(&inst->id_sequence, 0);
 	/* needs to be two, since we _put() after creation */
 	atomic_set(&inst->use, 2);
-	inst->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&inst->lock);
 	INIT_LIST_HEAD(&inst->queue_list);
 
 	if (!try_module_get(THIS_MODULE))
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 96020d7..7849cac 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -293,7 +293,7 @@
 	return 0;
 }
 
-static struct proto_ops netlink_ops;
+static const struct proto_ops netlink_ops;
 
 static int netlink_insert(struct sock *sk, u32 pid)
 {
@@ -1656,7 +1656,7 @@
 	return notifier_chain_unregister(&netlink_chain, nb);
 }
                 
-static struct proto_ops netlink_ops = {
+static const struct proto_ops netlink_ops = {
 	.family =	PF_NETLINK,
 	.owner =	THIS_MODULE,
 	.release =	netlink_release,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 287cfcc..3b13784 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -441,7 +441,7 @@
 }
 
 static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
-				      int seq, int cmd)
+				      int seq, u8 cmd)
 {
 	struct sk_buff *skb;
 	int err;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index e5d82d7..63b0e4a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -63,7 +63,7 @@
 static HLIST_HEAD(nr_list);
 static DEFINE_SPINLOCK(nr_list_lock);
 
-static struct proto_ops nr_proto_ops;
+static const struct proto_ops nr_proto_ops;
 
 /*
  *	Socket removal during an interrupt is now safe.
@@ -1166,10 +1166,11 @@
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	lock_sock(sk);
 	switch (cmd) {
 	case TIOCOUTQ: {
 		long amount;
+
+		lock_sock(sk);
 		amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
 		if (amount < 0)
 			amount = 0;
@@ -1180,6 +1181,8 @@
 	case TIOCINQ: {
 		struct sk_buff *skb;
 		long amount = 0L;
+
+		lock_sock(sk);
 		/* These two are safe on a single CPU system as only user tasks fiddle here */
 		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
 			amount = skb->len;
@@ -1188,6 +1191,7 @@
 	}
 
 	case SIOCGSTAMP:
+		lock_sock(sk);
 		ret = sock_get_timestamp(sk, argp);
 		release_sock(sk);
 		return ret;
@@ -1202,21 +1206,17 @@
 	case SIOCSIFNETMASK:
 	case SIOCGIFMETRIC:
 	case SIOCSIFMETRIC:
-		release_sock(sk);
 		return -EINVAL;
 
 	case SIOCADDRT:
 	case SIOCDELRT:
 	case SIOCNRDECOBS:
-		release_sock(sk);
 		if (!capable(CAP_NET_ADMIN)) return -EPERM;
 		return nr_rt_ioctl(cmd, argp);
 
 	default:
-		release_sock(sk);
-		return dev_ioctl(cmd, argp);
+		return -ENOIOCTLCMD;
 	}
-	release_sock(sk);
 
 	return 0;
 }
@@ -1337,7 +1337,7 @@
 	.owner		=	THIS_MODULE,
 };
 
-static struct proto_ops nr_proto_ops = {
+static const struct proto_ops nr_proto_ops = {
 	.family		=	PF_NETROM,
 	.owner		=	THIS_MODULE,
 	.release	=	nr_release,
diff --git a/net/nonet.c b/net/nonet.c
index e5241dc..1230f0a 100644
--- a/net/nonet.c
+++ b/net/nonet.c
@@ -14,11 +14,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 
-void __init sock_init(void)
-{
-	printk(KERN_INFO "Linux NoNET1.0 for Linux 2.6\n");
-}
-
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
 {
 	return -ENXIO;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 3e24627..f69e5ed 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -251,10 +251,10 @@
 }
 
 
-static struct proto_ops packet_ops;
+static const struct proto_ops packet_ops;
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt;
+static const struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
 {
@@ -1521,7 +1521,7 @@
 #endif
 
 		default:
-			return dev_ioctl(cmd, (void __user *)arg);
+			return -ENOIOCTLCMD;
 	}
 	return 0;
 }
@@ -1784,7 +1784,7 @@
 
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt = {
+static const struct proto_ops packet_ops_spkt = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
@@ -1806,7 +1806,7 @@
 };
 #endif
 
-static struct proto_ops packet_ops = {
+static const struct proto_ops packet_ops = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 829fdbc..63090be 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1320,7 +1320,7 @@
 		return 0;
 
 	default:
-		return dev_ioctl(cmd, argp);
+		return -ENOIOCTLCMD;
 	}
 
 	return 0;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 82fb07a..ba52832 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -25,7 +25,7 @@
 
 #include <net/pkt_sched.h>
 
-#define VERSION "1.1"
+#define VERSION "1.2"
 
 /*	Network Emulation Queuing algorithm.
 	====================================
@@ -65,11 +65,12 @@
 	u32 jitter;
 	u32 duplicate;
 	u32 reorder;
+	u32 corrupt;
 
 	struct crndstate {
 		unsigned long last;
 		unsigned long rho;
-	} delay_cor, loss_cor, dup_cor, reorder_cor;
+	} delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor;
 
 	struct disttable {
 		u32  size;
@@ -183,6 +184,23 @@
 		q->duplicate = dupsave;
 	}
 
+	/*
+	 * Randomized packet corruption.
+	 * Make copy if needed since we are modifying
+	 * If packet is going to be hardware checksummed, then
+	 * do it now in software before we mangle it.
+	 */
+	if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
+		if (!(skb = skb_unshare(skb, GFP_ATOMIC))
+		    || (skb->ip_summed == CHECKSUM_HW
+			&& skb_checksum_help(skb, 0))) {
+			sch->qstats.drops++;
+			return NET_XMIT_DROP;
+		}
+
+		skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
+	}
+
 	if (q->gap == 0 		/* not doing reordering */
 	    || q->counter < q->gap 	/* inside last reordering gap */
 	    || q->reorder < get_crandom(&q->reorder_cor)) {
@@ -382,6 +400,20 @@
 	return 0;
 }
 
+static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr)
+{
+	struct netem_sched_data *q = qdisc_priv(sch);
+	const struct tc_netem_corrupt *r = RTA_DATA(attr);
+
+	if (RTA_PAYLOAD(attr) != sizeof(*r))
+		return -EINVAL;
+
+	q->corrupt = r->probability;
+	init_crandom(&q->corrupt_cor, r->correlation);
+	return 0;
+}
+
+/* Parse netlink message to set options */
 static int netem_change(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
@@ -432,13 +464,19 @@
 			if (ret)
 				return ret;
 		}
+
 		if (tb[TCA_NETEM_REORDER-1]) {
 			ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
 			if (ret)
 				return ret;
 		}
-	}
 
+		if (tb[TCA_NETEM_CORRUPT-1]) {
+			ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]);
+			if (ret)
+				return ret;
+		}
+	}
 
 	return 0;
 }
@@ -564,6 +602,7 @@
 	struct tc_netem_qopt qopt;
 	struct tc_netem_corr cor;
 	struct tc_netem_reorder reorder;
+	struct tc_netem_corrupt corrupt;
 
 	qopt.latency = q->latency;
 	qopt.jitter = q->jitter;
@@ -582,6 +621,10 @@
 	reorder.correlation = q->reorder_cor.rho;
 	RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
 
+	corrupt.probability = q->corrupt;
+	corrupt.correlation = q->corrupt_cor.rho;
+	RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+
 	rta->rta_len = skb->tail - b;
 
 	return skb->len;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 6cf0342..c4a2a8c 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -22,6 +22,7 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index dec68a6..9d05e13 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -110,7 +110,6 @@
 	asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
 	asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
 					* 1000;
-	asoc->pmtu = 0;
 	asoc->frag_point = 0;
 
 	/* Set the association max_retrans and RTO values from the
@@ -123,6 +122,25 @@
 
 	asoc->overall_error_count = 0;
 
+	/* Initialize the association's heartbeat interval based on the
+	 * sock configured value.
+	 */
+	asoc->hbinterval = msecs_to_jiffies(sp->hbinterval);
+
+	/* Initialize path max retrans value. */
+	asoc->pathmaxrxt = sp->pathmaxrxt;
+
+	/* Initialize default path MTU. */
+	asoc->pathmtu = sp->pathmtu;
+
+	/* Set association default SACK delay */
+	asoc->sackdelay = msecs_to_jiffies(sp->sackdelay);
+
+	/* Set the association default flags controlling
+	 * Heartbeat, SACK delay, and Path MTU Discovery.
+	 */
+	asoc->param_flags = sp->param_flags;
+
 	/* Initialize the maximum mumber of new data packets that can be sent
 	 * in a burst.
 	 */
@@ -144,8 +162,7 @@
 		= 5 * asoc->rto_max;
 
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
-	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
-		SCTP_DEFAULT_TIMEOUT_SACK;
+	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
 		sp->autoclose * HZ;
 	
@@ -540,23 +557,46 @@
 
 	sctp_transport_set_owner(peer, asoc);
 
+	/* Initialize the peer's heartbeat interval based on the
+	 * association configured value.
+	 */
+	peer->hbinterval = asoc->hbinterval;
+
+	/* Set the path max_retrans.  */
+	peer->pathmaxrxt = asoc->pathmaxrxt;
+
+	/* Initialize the peer's SACK delay timeout based on the
+	 * association configured value.
+	 */
+	peer->sackdelay = asoc->sackdelay;
+
+	/* Enable/disable heartbeat, SACK delay, and path MTU discovery
+	 * based on association setting.
+	 */
+	peer->param_flags = asoc->param_flags;
+
 	/* Initialize the pmtu of the transport. */
-	sctp_transport_pmtu(peer);
+	if (peer->param_flags & SPP_PMTUD_ENABLE)
+		sctp_transport_pmtu(peer);
+	else if (asoc->pathmtu)
+		peer->pathmtu = asoc->pathmtu;
+	else
+		peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 
 	/* If this is the first transport addr on this association,
 	 * initialize the association PMTU to the peer's PMTU.
 	 * If not and the current association PMTU is higher than the new
 	 * peer's PMTU, reset the association PMTU to the new peer's PMTU.
 	 */
-	if (asoc->pmtu)
-		asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu);
+	if (asoc->pathmtu)
+		asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu);
 	else
-		asoc->pmtu = peer->pmtu;
+		asoc->pathmtu = peer->pathmtu;
 
 	SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
-			  "%d\n", asoc, asoc->pmtu);
+			  "%d\n", asoc, asoc->pathmtu);
 
-	asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
+	asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
 
 	/* The asoc->peer.port might not be meaningful yet, but
 	 * initialize the packet structure anyway.
@@ -574,7 +614,7 @@
 	 *   (for example, implementations MAY use the size of the
 	 *   receiver advertised window).
 	 */
-	peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380));
+	peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
 
 	/* At this point, we may not have the receiver's advertised window,
 	 * so initialize ssthresh to the default value and it will be set
@@ -585,17 +625,6 @@
 	peer->partial_bytes_acked = 0;
 	peer->flight_size = 0;
 
-	/* By default, enable heartbeat for peer address. */
-	peer->hb_allowed = 1;
-
-	/* Initialize the peer's heartbeat interval based on the
-	 * sock configured value.
-	 */
-	peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);
-
-	/* Set the path max_retrans.  */
-	peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
-
 	/* Set the transport's RTO.initial value */
 	peer->rto = asoc->rto_initial;
 
@@ -1155,18 +1184,18 @@
 	/* Get the lowest pmtu of all the transports. */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
 		t = list_entry(pos, struct sctp_transport, transports);
-		if (!pmtu || (t->pmtu < pmtu))
-			pmtu = t->pmtu;
+		if (!pmtu || (t->pathmtu < pmtu))
+			pmtu = t->pathmtu;
 	}
 
 	if (pmtu) {
 		struct sctp_sock *sp = sctp_sk(asoc->base.sk);
-		asoc->pmtu = pmtu;
+		asoc->pathmtu = pmtu;
 		asoc->frag_point = sctp_frag_point(sp, pmtu);
 	}
 
 	SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
-			  __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
+			  __FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point);
 }
 
 /* Should we send a SACK to update our peer? */
@@ -1179,7 +1208,7 @@
 	case SCTP_STATE_SHUTDOWN_SENT:
 		if ((asoc->rwnd > asoc->a_rwnd) &&
 		    ((asoc->rwnd - asoc->a_rwnd) >=
-		     min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
+		     min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu)))
 			return 1;
 		break;
 	default:
diff --git a/net/sctp/input.c b/net/sctp/input.c
index b24ff2c..238f1bf 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -305,18 +305,36 @@
 void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
 			   struct sctp_transport *t, __u32 pmtu)
 {
-	if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
-		printk(KERN_WARNING "%s: Reported pmtu %d too low, "
-		       "using default minimum of %d\n", __FUNCTION__, pmtu,
-		       SCTP_DEFAULT_MINSEGMENT);
-		pmtu = SCTP_DEFAULT_MINSEGMENT;
+	if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
+		return;
+
+	if (t->param_flags & SPP_PMTUD_ENABLE) {
+		if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+			printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+			       "using default minimum of %d\n",
+			       __FUNCTION__, pmtu,
+			       SCTP_DEFAULT_MINSEGMENT);
+			/* Use default minimum segment size and disable
+			 * pmtu discovery on this transport.
+			 */
+			t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
+			t->param_flags = (t->param_flags & ~SPP_HB) |
+				SPP_PMTUD_DISABLE;
+		} else {
+			t->pathmtu = pmtu;
+		}
+
+		/* Update association pmtu. */
+		sctp_assoc_sync_pmtu(asoc);
 	}
 
-	if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) {
-		t->pmtu = pmtu;
-		sctp_assoc_sync_pmtu(asoc);
-		sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
-	}
+	/* Retransmit with the new pmtu setting.
+	 * Normally, if PMTU discovery is disabled, an ICMP Fragmentation
+	 * Needed will never be sent, but if a message was sent before
+	 * PMTU discovery was disabled that was larger than the PMTU, it
+	 * would not be fragmented, so it must be re-transmitted fragmented.	 
+	 */
+	sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
 }
 
 /*
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index fa3be2b..15c0516 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -866,7 +866,7 @@
 	return 2;
 }
 
-static struct proto_ops inet6_seqpacket_ops = {
+static const struct proto_ops inet6_seqpacket_ops = {
 	.family     = PF_INET6,
 	.owner      = THIS_MODULE,
 	.release    = inet6_release,
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 9313716..a40991e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -234,8 +234,8 @@
 		goto finish;
 
 	pmtu  = ((packet->transport->asoc) ?
-		 (packet->transport->asoc->pmtu) :
-		 (packet->transport->pmtu));
+		 (packet->transport->asoc->pathmtu) :
+		 (packet->transport->pathmtu));
 
 	too_big = (psize + chunk_len > pmtu);
 
@@ -482,7 +482,9 @@
 	if (!dst || (dst->obsolete > 1)) {
 		dst_release(dst);
 		sctp_transport_route(tp, NULL, sctp_sk(sk));
-		sctp_assoc_sync_pmtu(asoc);
+		if (asoc->param_flags & SPP_PMTUD_ENABLE) {
+			sctp_assoc_sync_pmtu(asoc);
+		}
 	}
 
 	nskb->dst = dst_clone(tp->dst);
@@ -492,7 +494,10 @@
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
 			  nskb->len);
 
-	(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+	if (tp->param_flags & SPP_PMTUD_ENABLE)
+		(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+	else
+		(*tp->af_specific->sctp_xmit)(nskb, tp, 1);
 
 out:
 	packet->size = packet->overhead;
@@ -577,7 +582,7 @@
 	 * 	if ((flightsize + Max.Burst * MTU) < cwnd)
 	 *		cwnd = flightsize + Max.Burst * MTU
 	 */
-	max_burst_bytes = asoc->max_burst * asoc->pmtu;
+	max_burst_bytes = asoc->max_burst * asoc->pathmtu;
 	if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
 		transport->cwnd = transport->flight_size + max_burst_bytes;
 		SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
@@ -622,7 +627,7 @@
 		 * data will fit or delay in hopes of bundling a full
 		 * sized packet.
 		 */
-		if (len < asoc->pmtu - packet->overhead) {
+		if (len < asoc->pathmtu - packet->overhead) {
 			retval = SCTP_XMIT_NAGLE_DELAY;
 			goto finish;
 		}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f775d78..de693b4 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -54,6 +54,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
 #include <net/sctp/sctp.h>
 #include <net/addrconf.h>
 #include <net/inet_common.h>
@@ -829,7 +830,7 @@
 };
 
 /* Socket operations.  */
-static struct proto_ops inet_seqpacket_ops = {
+static const struct proto_ops inet_seqpacket_ops = {
 	.family      = PF_INET,
 	.owner       = THIS_MODULE,
 	.release     = inet_release,       /* Needs to be wrapped... */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8239471..2d7d8a5 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -157,9 +157,12 @@
 {
 	__u32 ctsn, max_tsn_seen;
 	struct sctp_chunk *sack;
+	struct sctp_transport *trans = asoc->peer.last_data_from;
 	int error = 0;
 
-	if (force)
+	if (force || 
+	    (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) ||
+	    (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE)))
 		asoc->peer.sack_needed = 1;
 
 	ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
@@ -189,7 +192,22 @@
 	if (!asoc->peer.sack_needed) {
 		/* We will need a SACK for the next packet.  */
 		asoc->peer.sack_needed = 1;
-		goto out;
+
+		/* Set the SACK delay timeout based on the
+		 * SACK delay for the last transport
+		 * data was received from, or the default
+		 * for the association.
+		 */
+		if (trans)
+			asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+				trans->sackdelay;
+		else
+			asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+				asoc->sackdelay;
+
+		/* Restart the SACK timer. */
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 	} else {
 		if (asoc->a_rwnd > asoc->rwnd)
 			asoc->a_rwnd = asoc->rwnd;
@@ -205,7 +223,7 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 	}
-out:
+
 	return error;
 nomem:
 	error = -ENOMEM;
@@ -415,7 +433,7 @@
 	asoc->overall_error_count++;
 
 	if (transport->state != SCTP_INACTIVE &&
-	    (transport->error_count++ >= transport->max_retrans)) {
+	    (transport->error_count++ >= transport->pathmaxrxt)) {
 		SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
 					 " transport IP: port:%d failed.\n",
 					 asoc,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 475bfb4..557a7d9 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -900,7 +900,7 @@
 	 * HEARTBEAT is sent (see Section 8.3).
 	 */
 
-	if (transport->hb_allowed) {
+	if (transport->param_flags & SPP_HB_ENABLE) {
 		if (SCTP_DISPOSITION_NOMEM ==
 				sctp_sf_heartbeat(ep, asoc, type, arg,
 						  commands))
@@ -1051,7 +1051,7 @@
 		return SCTP_DISPOSITION_DISCARD;
 	}
 
-	max_interval = link->hb_interval + link->rto;
+	max_interval = link->hbinterval + link->rto;
 
 	/* Check if the timestamp looks valid.  */
 	if (time_after(hbinfo->sent_at, jiffies) ||
@@ -2691,14 +2691,9 @@
 	 * document allow. However, an SCTP transmitter MUST NOT be
 	 * more aggressive than the following algorithms allow.
 	 */
-	if (chunk->end_of_packet) {
+	if (chunk->end_of_packet)
 		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-		/* Start the SACK timer.  */
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-	}
-
 	return SCTP_DISPOSITION_CONSUME;
 
 discard_force:
@@ -2721,13 +2716,9 @@
 	return SCTP_DISPOSITION_DISCARD;
 
 discard_noforce:
-	if (chunk->end_of_packet) {
+	if (chunk->end_of_packet)
 		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-		/* Start the SACK timer.  */
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-	}
 	return SCTP_DISPOSITION_DISCARD;
 consume:
 	return SCTP_DISPOSITION_CONSUME;
@@ -3442,9 +3433,6 @@
 	 * send another. 
 	 */
 	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
-	/* Start the SACK timer.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-			SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 
 	return SCTP_DISPOSITION_CONSUME;
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9df888e..fc04d18 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1941,107 +1941,379 @@
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
  *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
-static int sctp_setsockopt_peer_addr_params(struct sock *sk,
-					    char __user *optval, int optlen)
+int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+				struct sctp_transport   *trans,
+				struct sctp_association *asoc,
+				struct sctp_sock        *sp,
+				int                      hb_change,
+				int                      pmtud_change,
+				int                      sackdelay_change)
 {
-	struct sctp_paddrparams params;
-	struct sctp_transport *trans;
 	int error;
 
-	if (optlen != sizeof(struct sctp_paddrparams))
-		return -EINVAL;
-	if (copy_from_user(&params, optval, optlen))
-		return -EFAULT;
-
-	/*
-	 * API 7. Socket Options (setting the default value for the endpoint)
-	 * All options that support specific settings on an association by
-	 * filling in either an association id variable or a sockaddr_storage
-	 * SHOULD also support setting of the same value for the entire endpoint
-	 * (i.e. future associations). To accomplish this the following logic is
-	 * used when setting one of these options:
-
-	 * c) If neither the sockaddr_storage or association identification is
-	 *    set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and
-	 *    the association identification is 0, the settings are a default
-	 *    and to be applied to the endpoint (all future associations).
-	 */
-
-	/* update default value for endpoint (all future associations) */
-	if (!params.spp_assoc_id && 
-	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		/* 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 (params.spp_pathmaxrxt)
-			sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
-						params.spp_pathmaxrxt;
-		return 0;
-	}
-
-	trans = sctp_addr_id2transport(sk, &params.spp_address,
-				       params.spp_assoc_id);
-	if (!trans)
-		return -EINVAL;
-
-	/* Applications can enable or disable heartbeats for any peer address
-	 * of an association, modify an address's heartbeat interval, force a
-	 * heartbeat to be sent immediately, and adjust the address's maximum
-	 * number of retransmissions sent before an address is considered
-	 * unreachable.
-	 *
-	 * The value of the heartbeat interval, in milliseconds. A value of
-	 * UINT32_MAX (4294967295), when modifying the parameter, specifies
-	 * that a heartbeat should be sent immediately to the peer address,
-	 * and the current interval should remain unchanged.
-	 */
-	if (0xffffffff == params.spp_hbinterval) {
+	if (params->spp_flags & SPP_HB_DEMAND && trans) {
 		error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
 		if (error)
 			return error;
-	} else {
-	/* The value of the heartbeat interval, in milliseconds. A value of 0,
-	 * when modifying the parameter, specifies that the heartbeat on this
-	 * address should be disabled.
-	 */
-		if (params.spp_hbinterval) {
-			trans->hb_allowed = 1;
-			trans->hb_interval = 
-				msecs_to_jiffies(params.spp_hbinterval);
-		} else
-			trans->hb_allowed = 0;
 	}
 
-	/* spp_pathmaxrxt contains the maximum number of retransmissions
-	 * before this address shall be considered unreachable.
-	 */
-	if (params.spp_pathmaxrxt)
-		trans->max_retrans = params.spp_pathmaxrxt;
+	if (params->spp_hbinterval) {
+		if (trans) {
+			trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+		} else if (asoc) {
+			asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+		} else {
+			sp->hbinterval = params->spp_hbinterval;
+		}
+	}
 
+	if (hb_change) {
+		if (trans) {
+			trans->param_flags =
+				(trans->param_flags & ~SPP_HB) | hb_change;
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_HB) | hb_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_HB) | hb_change;
+		}
+	}
+
+	if (params->spp_pathmtu) {
+		if (trans) {
+			trans->pathmtu = params->spp_pathmtu;
+			sctp_assoc_sync_pmtu(asoc);
+		} else if (asoc) {
+			asoc->pathmtu = params->spp_pathmtu;
+			sctp_frag_point(sp, params->spp_pathmtu);
+		} else {
+			sp->pathmtu = params->spp_pathmtu;
+		}
+	}
+
+	if (pmtud_change) {
+		if (trans) {
+			int update = (trans->param_flags & SPP_PMTUD_DISABLE) &&
+				(params->spp_flags & SPP_PMTUD_ENABLE);
+			trans->param_flags =
+				(trans->param_flags & ~SPP_PMTUD) | pmtud_change;
+			if (update) {
+				sctp_transport_pmtu(trans);
+				sctp_assoc_sync_pmtu(asoc);
+			}
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_PMTUD) | pmtud_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_PMTUD) | pmtud_change;
+		}
+	}
+
+	if (params->spp_sackdelay) {
+		if (trans) {
+			trans->sackdelay =
+				msecs_to_jiffies(params->spp_sackdelay);
+		} else if (asoc) {
+			asoc->sackdelay =
+				msecs_to_jiffies(params->spp_sackdelay);
+		} else {
+			sp->sackdelay = params->spp_sackdelay;
+		}
+	}
+
+	if (sackdelay_change) {
+		if (trans) {
+			trans->param_flags =
+				(trans->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		}
+	}
+
+	if (params->spp_pathmaxrxt) {
+		if (trans) {
+			trans->pathmaxrxt = params->spp_pathmaxrxt;
+		} else if (asoc) {
+			asoc->pathmaxrxt = params->spp_pathmaxrxt;
+		} else {
+			sp->pathmaxrxt = params->spp_pathmaxrxt;
+		}
+	}
+
+	return 0;
+}
+
+static int sctp_setsockopt_peer_addr_params(struct sock *sk,
+					    char __user *optval, int optlen)
+{
+	struct sctp_paddrparams  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+	int error;
+	int hb_change, pmtud_change, sackdelay_change;
+
+	if (optlen != sizeof(struct sctp_paddrparams))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, optlen))
+		return -EFAULT;
+
+	/* Validate flags and value parameters. */
+	hb_change        = params.spp_flags & SPP_HB;
+	pmtud_change     = params.spp_flags & SPP_PMTUD;
+	sackdelay_change = params.spp_flags & SPP_SACKDELAY;
+
+	if (hb_change        == SPP_HB ||
+	    pmtud_change     == SPP_PMTUD ||
+	    sackdelay_change == SPP_SACKDELAY ||
+	    params.spp_sackdelay > 500 ||
+	    (params.spp_pathmtu
+	    && params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT))
+		return -EINVAL;
+
+	/* If an address other than INADDR_ANY is specified, and
+	 * no transport is found, then the request is invalid.
+	 */
+	if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+		trans = sctp_addr_id2transport(sk, &params.spp_address,
+					       params.spp_assoc_id);
+		if (!trans)
+			return -EINVAL;
+	}
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+	 */
+	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	/* Heartbeat demand can only be sent on a transport or
+	 * association, but not a socket.
+	 */
+	if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc)
+		return -EINVAL;
+
+	/* Process parameters. */
+	error = sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+					    hb_change, pmtud_change,
+					    sackdelay_change);
+
+	if (error)
+		return error;
+
+	/* If changes are for association, also apply parameters to each
+	 * transport.
+	 */
+	if (!trans && asoc) {
+		struct list_head *pos;
+
+		list_for_each(pos, &asoc->peer.transport_addr_list) {
+			trans = list_entry(pos, struct sctp_transport,
+					   transports);
+			sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+						    hb_change, pmtud_change,
+						    sackdelay_change);
+		}
+	}
+
+	return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
+
+static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
+					    char __user *optval, int optlen)
+{
+	struct sctp_assoc_value  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+
+	if (optlen != sizeof(struct sctp_assoc_value))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, optlen))
+		return -EFAULT;
+
+	/* Validate value parameter. */
+	if (params.assoc_value > 500)
+		return -EINVAL;
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+ 	 */
+	asoc = sctp_id2assoc(sk, params.assoc_id);
+	if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	if (params.assoc_value) {
+		if (asoc) {
+			asoc->sackdelay =
+				msecs_to_jiffies(params.assoc_value);
+			asoc->param_flags = 
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_ENABLE;
+		} else {
+			sp->sackdelay = params.assoc_value;
+			sp->param_flags = 
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_ENABLE;
+		}
+	} else {
+		if (asoc) {
+			asoc->param_flags = 
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_DISABLE;
+		} else {
+			sp->param_flags = 
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_DISABLE;
+		}
+	}
+
+	/* If change is for association, also apply to each transport. */
+	if (asoc) {
+		struct list_head *pos;
+
+		list_for_each(pos, &asoc->peer.transport_addr_list) {
+			trans = list_entry(pos, struct sctp_transport,
+					   transports);
+			if (params.assoc_value) {
+				trans->sackdelay =
+					msecs_to_jiffies(params.assoc_value);
+				trans->param_flags = 
+					(trans->param_flags & ~SPP_SACKDELAY) |
+					SPP_SACKDELAY_ENABLE;
+			} else {
+				trans->param_flags = 
+					(trans->param_flags & ~SPP_SACKDELAY) |
+					SPP_SACKDELAY_DISABLE;
+			}
+		}
+	}
+ 
 	return 0;
 }
 
@@ -2334,7 +2606,7 @@
 	/* Update the frag_point of the existing associations. */
 	list_for_each(pos, &(sp->ep->asocs)) {
 		asoc = list_entry(pos, struct sctp_association, asocs);
-		asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); 
+		asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); 
 	}
 
 	return 0;
@@ -2491,6 +2763,10 @@
 		retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
 		break;
 
+	case SCTP_DELAYED_ACK_TIME:
+		retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen);
+		break;
+
 	case SCTP_INITMSG:
 		retval = sctp_setsockopt_initmsg(sk, optval, optlen);
 		break;
@@ -2715,8 +2991,13 @@
 	/* Default Peer Address Parameters.  These defaults can
 	 * be modified via SCTP_PEER_ADDR_PARAMS
 	 */
-	sp->paddrparam.spp_hbinterval = jiffies_to_msecs(sctp_hb_interval);
-	sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path;
+	sp->hbinterval  = jiffies_to_msecs(sctp_hb_interval);
+	sp->pathmaxrxt  = sctp_max_retrans_path;
+	sp->pathmtu     = 0; // allow default discovery
+	sp->sackdelay   = sctp_sack_timeout;
+	sp->param_flags = SPP_HB_ENABLE |
+	                  SPP_PMTUD_ENABLE |
+	                  SPP_SACKDELAY_ENABLE;
 
 	/* If enabled no SCTP message fragmentation will be performed.
 	 * Configure through SCTP_DISABLE_FRAGMENTS socket option.
@@ -2865,7 +3146,7 @@
 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
 	status.sstat_primary.spinfo_srtt = transport->srtt;
 	status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
-	status.sstat_primary.spinfo_mtu = transport->pmtu;
+	status.sstat_primary.spinfo_mtu = transport->pathmtu;
 
 	if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
 		status.sstat_primary.spinfo_state = SCTP_ACTIVE;
@@ -2924,7 +3205,7 @@
 	pinfo.spinfo_cwnd = transport->cwnd;
 	pinfo.spinfo_srtt = transport->srtt;
 	pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
-	pinfo.spinfo_mtu = transport->pmtu;
+	pinfo.spinfo_mtu = transport->pathmtu;
 
 	if (pinfo.spinfo_state == SCTP_UNKNOWN)
 		pinfo.spinfo_state = SCTP_ACTIVE;
@@ -3086,69 +3367,227 @@
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
  *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
 static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
-						char __user *optval, int __user *optlen)
+					    char __user *optval, int __user *optlen)
 {
-	struct sctp_paddrparams params;
-	struct sctp_transport *trans;
+	struct sctp_paddrparams  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
 
 	if (len != sizeof(struct sctp_paddrparams))
 		return -EINVAL;
+
 	if (copy_from_user(&params, optval, len))
 		return -EFAULT;
 
-	/* If no association id is specified retrieve the default value
-	 * for the endpoint that will be used for all future associations
+	/* If an address other than INADDR_ANY is specified, and
+	 * no transport is found, then the request is invalid.
 	 */
-	if (!params.spp_assoc_id &&
-	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval;
-		params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt;
-
-		goto done;
+	if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+		trans = sctp_addr_id2transport(sk, &params.spp_address,
+					       params.spp_assoc_id);
+		if (!trans) {
+			SCTP_DEBUG_PRINTK("Failed no transport\n");
+			return -EINVAL;
+		}
 	}
 
-	trans = sctp_addr_id2transport(sk, &params.spp_address,
-				       params.spp_assoc_id);
-	if (!trans)
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+	 */
+	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) {
+		SCTP_DEBUG_PRINTK("Failed no association\n");
+		return -EINVAL;
+	}
+
+	if (trans) {
+		/* Fetch transport values. */
+		params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval);
+		params.spp_pathmtu    = trans->pathmtu;
+		params.spp_pathmaxrxt = trans->pathmaxrxt;
+		params.spp_sackdelay  = jiffies_to_msecs(trans->sackdelay);
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = trans->param_flags;
+	} else if (asoc) {
+		/* Fetch association values. */
+		params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval);
+		params.spp_pathmtu    = asoc->pathmtu;
+		params.spp_pathmaxrxt = asoc->pathmaxrxt;
+		params.spp_sackdelay  = jiffies_to_msecs(asoc->sackdelay);
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = asoc->param_flags;
+	} else {
+		/* Fetch socket values. */
+		params.spp_hbinterval = sp->hbinterval;
+		params.spp_pathmtu    = sp->pathmtu;
+		params.spp_sackdelay  = sp->sackdelay;
+		params.spp_pathmaxrxt = sp->pathmaxrxt;
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = sp->param_flags;
+	}
+
+	if (copy_to_user(optval, &params, len))
+		return -EFAULT;
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+
+	return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
+static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len,
+					    char __user *optval,
+					    int __user *optlen)
+{
+	struct sctp_assoc_value  params;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+
+	if (len != sizeof(struct sctp_assoc_value))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, len))
+		return -EFAULT;
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+ 	 */
+	asoc = sctp_id2assoc(sk, params.assoc_id);
+	if (!asoc && params.assoc_id && sctp_style(sk, UDP))
 		return -EINVAL;
 
-	/* The value of the heartbeat interval, in milliseconds. A value of 0,
-	 * when modifying the parameter, specifies that the heartbeat on this
-	 * address should be disabled.
-	 */
-	if (!trans->hb_allowed)
-		params.spp_hbinterval = 0;
-	else
-		params.spp_hbinterval = jiffies_to_msecs(trans->hb_interval);
+	if (asoc) {
+		/* Fetch association values. */
+		if (asoc->param_flags & SPP_SACKDELAY_ENABLE)
+			params.assoc_value = jiffies_to_msecs(
+				asoc->sackdelay);
+		else
+			params.assoc_value = 0;
+	} else {
+		/* Fetch socket values. */
+		if (sp->param_flags & SPP_SACKDELAY_ENABLE)
+			params.assoc_value  = sp->sackdelay;
+		else
+			params.assoc_value  = 0;
+	}
 
-	/* spp_pathmaxrxt contains the maximum number of retransmissions
-	 * before this address shall be considered unreachable.
-	 */
-	params.spp_pathmaxrxt = trans->max_retrans;
-
-done:
 	if (copy_to_user(optval, &params, len))
 		return -EFAULT;
 
@@ -4015,6 +4454,10 @@
 		retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
 							  optlen);
 		break;
+	case SCTP_DELAYED_ACK_TIME:
+		retval = sctp_getsockopt_delayed_ack_time(sk, len, optval,
+							  optlen);
+		break;
 	case SCTP_INITMSG:
 		retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
 		break;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 268ddaf..68d73e2 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -86,10 +86,13 @@
 	peer->init_sent_count = 0;
 
 	peer->state = SCTP_ACTIVE;
-	peer->hb_allowed = 0;
+	peer->param_flags = SPP_HB_DISABLE |
+			    SPP_PMTUD_ENABLE |
+			    SPP_SACKDELAY_ENABLE;
+	peer->hbinterval  = 0;
 
 	/* Initialize the default path max_retrans.  */
-	peer->max_retrans = sctp_max_retrans_path;
+	peer->pathmaxrxt  = sctp_max_retrans_path;
 	peer->error_count = 0;
 
 	INIT_LIST_HEAD(&peer->transmitted);
@@ -229,10 +232,10 @@
 	dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);
 
 	if (dst) {
-		transport->pmtu = dst_mtu(dst);
+		transport->pathmtu = dst_mtu(dst);
 		dst_release(dst);
 	} else
-		transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+		transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Caches the dst entry and source address for a transport's destination
@@ -254,8 +257,11 @@
 		af->get_saddr(asoc, dst, daddr, &transport->saddr);
 
 	transport->dst = dst;
+	if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
+		return;
+	}
 	if (dst) {
-		transport->pmtu = dst_mtu(dst);
+		transport->pathmtu = dst_mtu(dst);
 
 		/* Initialize sk->sk_rcv_saddr, if the transport is the
 		 * association's active path for getsockname().
@@ -264,7 +270,7 @@
 			opt->pf->af->to_sk_saddr(&transport->saddr,
 						 asoc->base.sk);
 	} else
-		transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+		transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Hold a reference to a transport.  */
@@ -369,7 +375,7 @@
 
 	ssthresh = transport->ssthresh;
 	pba = transport->partial_bytes_acked;
-	pmtu = transport->asoc->pmtu;
+	pmtu = transport->asoc->pathmtu;
 
 	if (cwnd <= ssthresh) {
 		/* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less
@@ -441,8 +447,8 @@
 		 *      partial_bytes_acked = 0
 		 */
 		transport->ssthresh = max(transport->cwnd/2,
-					  4*transport->asoc->pmtu);
-		transport->cwnd = transport->asoc->pmtu;
+					  4*transport->asoc->pathmtu);
+		transport->cwnd = transport->asoc->pathmtu;
 		break;
 
 	case SCTP_LOWER_CWND_FAST_RTX:
@@ -459,7 +465,7 @@
 		 *      partial_bytes_acked = 0
 		 */
 		transport->ssthresh = max(transport->cwnd/2,
-					  4*transport->asoc->pmtu);
+					  4*transport->asoc->pathmtu);
 		transport->cwnd = transport->ssthresh;
 		break;
 
@@ -479,7 +485,7 @@
 		if ((jiffies - transport->last_time_ecne_reduced) >
 		    transport->rtt) {
 			transport->ssthresh = max(transport->cwnd/2,
-					  	  4*transport->asoc->pmtu);
+					  	  4*transport->asoc->pathmtu);
 			transport->cwnd = transport->ssthresh;
 			transport->last_time_ecne_reduced = jiffies;
 		}
@@ -496,7 +502,7 @@
 		 */
 		if ((jiffies - transport->last_time_used) > transport->rto)
 			transport->cwnd = max(transport->cwnd/2,
-						 4*transport->asoc->pmtu);
+						 4*transport->asoc->pathmtu);
 		break;
 	};
 
@@ -511,7 +517,7 @@
 unsigned long sctp_transport_timeout(struct sctp_transport *t)
 {
 	unsigned long timeout;
-	timeout = t->hb_interval + t->rto + sctp_jitter(t->rto);
+	timeout = t->hbinterval + t->rto + sctp_jitter(t->rto);
 	timeout += jiffies;
 	return timeout;
 }
diff --git a/net/socket.c b/net/socket.c
index 3145103..06fa217 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -640,92 +640,6 @@
 	kfree(iocb->private);
 }
 
-/*
- *	Read data from a socket. ubuf is a user mode pointer. We make sure the user
- *	area ubuf...ubuf+size-1 is writable before asking the protocol.
- */
-
-static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
-			 size_t size, loff_t pos)
-{
-	struct sock_iocb *x, siocb;
-	struct socket *sock;
-	int flags;
-
-	if (pos != 0)
-		return -ESPIPE;
-	if (size==0)		/* Match SYS5 behaviour */
-		return 0;
-
-	if (is_sync_kiocb(iocb))
-		x = &siocb;
-	else {
-		x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-		if (!x)
-			return -ENOMEM;
-		iocb->ki_dtor = sock_aio_dtor;
-	}
-	iocb->private = x;
-	x->kiocb = iocb;
-	sock = iocb->ki_filp->private_data; 
-
-	x->async_msg.msg_name = NULL;
-	x->async_msg.msg_namelen = 0;
-	x->async_msg.msg_iov = &x->async_iov;
-	x->async_msg.msg_iovlen = 1;
-	x->async_msg.msg_control = NULL;
-	x->async_msg.msg_controllen = 0;
-	x->async_iov.iov_base = ubuf;
-	x->async_iov.iov_len = size;
-	flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-
-	return __sock_recvmsg(iocb, sock, &x->async_msg, size, flags);
-}
-
-
-/*
- *	Write data to a socket. We verify that the user area ubuf..ubuf+size-1
- *	is readable by the user process.
- */
-
-static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
-			  size_t size, loff_t pos)
-{
-	struct sock_iocb *x, siocb;
-	struct socket *sock;
-	
-	if (pos != 0)
-		return -ESPIPE;
-	if(size==0)		/* Match SYS5 behaviour */
-		return 0;
-
-	if (is_sync_kiocb(iocb))
-		x = &siocb;
-	else {
-		x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-		if (!x)
-			return -ENOMEM;
-		iocb->ki_dtor = sock_aio_dtor;
-	}
-	iocb->private = x;
-	x->kiocb = iocb;
-	sock = iocb->ki_filp->private_data; 
-
-	x->async_msg.msg_name = NULL;
-	x->async_msg.msg_namelen = 0;
-	x->async_msg.msg_iov = &x->async_iov;
-	x->async_msg.msg_iovlen = 1;
-	x->async_msg.msg_control = NULL;
-	x->async_msg.msg_controllen = 0;
-	x->async_msg.msg_flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-	if (sock->type == SOCK_SEQPACKET)
-		x->async_msg.msg_flags |= MSG_EOR;
-	x->async_iov.iov_base = (void __user *)ubuf;
-	x->async_iov.iov_len = size;
-	
-	return __sock_sendmsg(iocb, sock, &x->async_msg, size);
-}
-
 static ssize_t sock_sendpage(struct file *file, struct page *page,
 			     int offset, size_t size, loff_t *ppos, int more)
 {
@@ -741,53 +655,135 @@
 	return sock->ops->sendpage(sock, page, offset, size, flags);
 }
 
-static int sock_readv_writev(int type,
-			     struct file * file, const struct iovec * iov,
-			     long count, size_t size)
+static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
+		char __user *ubuf, size_t size, struct sock_iocb *siocb)
+{
+	if (!is_sync_kiocb(iocb)) {
+		siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
+		if (!siocb)
+			return NULL;
+		iocb->ki_dtor = sock_aio_dtor;
+	}
+
+	siocb->kiocb = iocb;
+	siocb->async_iov.iov_base = ubuf;
+	siocb->async_iov.iov_len = size;
+
+	iocb->private = siocb;
+	return siocb;
+}
+
+static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
+		struct file *file, struct iovec *iov, unsigned long nr_segs)
+{
+	struct socket *sock = file->private_data;
+	size_t size = 0;
+	int i;
+
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
+
+	msg->msg_name = NULL;
+	msg->msg_namelen = 0;
+	msg->msg_control = NULL;
+	msg->msg_controllen = 0;
+	msg->msg_iov = (struct iovec *) iov;
+	msg->msg_iovlen = nr_segs;
+	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+
+	return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
+}
+
+static ssize_t sock_readv(struct file *file, const struct iovec *iov,
+			  unsigned long nr_segs, loff_t *ppos)
+{
+	struct kiocb iocb;
+	struct sock_iocb siocb;
+	struct msghdr msg;
+	int ret;
+
+        init_sync_kiocb(&iocb, NULL);
+	iocb.private = &siocb;
+
+	ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+	if (-EIOCBQUEUED == ret)
+		ret = wait_on_sync_kiocb(&iocb);
+	return ret;
+}
+
+static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
+			 size_t count, loff_t pos)
+{
+	struct sock_iocb siocb, *x;
+
+	if (pos != 0)
+		return -ESPIPE;
+	if (count == 0)		/* Match SYS5 behaviour */
+		return 0;
+
+	x = alloc_sock_iocb(iocb, ubuf, count, &siocb);
+	if (!x)
+		return -ENOMEM;
+	return do_sock_read(&x->async_msg, iocb, iocb->ki_filp,
+			&x->async_iov, 1);
+}
+
+static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
+		struct file *file, struct iovec *iov, unsigned long nr_segs)
+{
+	struct socket *sock = file->private_data;
+	size_t size = 0;
+	int i;
+
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
+
+	msg->msg_name = NULL;
+	msg->msg_namelen = 0;
+	msg->msg_control = NULL;
+	msg->msg_controllen = 0;
+	msg->msg_iov = (struct iovec *) iov;
+	msg->msg_iovlen = nr_segs;
+	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+	if (sock->type == SOCK_SEQPACKET)
+		msg->msg_flags |= MSG_EOR;
+
+	return __sock_sendmsg(iocb, sock, msg, size);
+}
+
+static ssize_t sock_writev(struct file *file, const struct iovec *iov,
+			   unsigned long nr_segs, loff_t *ppos)
 {
 	struct msghdr msg;
-	struct socket *sock;
+	struct kiocb iocb;
+	struct sock_iocb siocb;
+	int ret;
 
-	sock = file->private_data;
+	init_sync_kiocb(&iocb, NULL);
+	iocb.private = &siocb;
 
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_iov = (struct iovec *) iov;
-	msg.msg_iovlen = count;
-	msg.msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
-
-	/* read() does a VERIFY_WRITE */
-	if (type == VERIFY_WRITE)
-		return sock_recvmsg(sock, &msg, size, msg.msg_flags);
-
-	if (sock->type == SOCK_SEQPACKET)
-		msg.msg_flags |= MSG_EOR;
-
-	return sock_sendmsg(sock, &msg, size);
+	ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+	if (-EIOCBQUEUED == ret)
+		ret = wait_on_sync_kiocb(&iocb);
+	return ret;
 }
 
-static ssize_t sock_readv(struct file *file, const struct iovec *vector,
-			  unsigned long count, loff_t *ppos)
+static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
+			  size_t count, loff_t pos)
 {
-	size_t tot_len = 0;
-	int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-	return sock_readv_writev(VERIFY_WRITE,
-				 file, vector, count, tot_len);
-}
-	
-static ssize_t sock_writev(struct file *file, const struct iovec *vector,
-			   unsigned long count, loff_t *ppos)
-{
-	size_t tot_len = 0;
-	int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-	return sock_readv_writev(VERIFY_READ,
-				 file, vector, count, tot_len);
+	struct sock_iocb siocb, *x;
+
+	if (pos != 0)
+		return -ESPIPE;
+	if (count == 0)		/* Match SYS5 behaviour */
+		return 0;
+
+	x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb);
+	if (!x)
+		return -ENOMEM;
+
+	return do_sock_write(&x->async_msg, iocb, iocb->ki_filp,
+			&x->async_iov, 1);
 }
 
 
@@ -904,6 +900,13 @@
 			break;
 		default:
 			err = sock->ops->ioctl(sock, cmd, arg);
+
+			/*
+			 * If this ioctl is unknown try to hand it down
+			 * to the NIC driver.
+			 */
+			if (err == -ENOIOCTLCMD)
+				err = dev_ioctl(cmd, argp);
 			break;
 	}
 	return err;
@@ -2036,7 +2039,7 @@
 	return 0;
 }
 
-void __init sock_init(void)
+static int __init sock_init(void)
 {
 	/*
 	 *	Initialize sock SLAB cache.
@@ -2044,12 +2047,10 @@
 	 
 	sk_init();
 
-#ifdef SLAB_SKB
 	/*
 	 *	Initialize skbuff SLAB cache 
 	 */
 	skb_init();
-#endif
 
 	/*
 	 *	Initialize the protocols module. 
@@ -2058,15 +2059,19 @@
 	init_inodecache();
 	register_filesystem(&sock_fs_type);
 	sock_mnt = kern_mount(&sock_fs_type);
-	/* The real protocol initialization is performed when
-	 *  do_initcalls is run.  
+
+	/* The real protocol initialization is performed in later initcalls.
 	 */
 
 #ifdef CONFIG_NETFILTER
 	netfilter_init();
 #endif
+
+	return 0;
 }
 
+core_initcall(sock_init);	/* early initcall */
+
 #ifdef CONFIG_PROC_FS
 void socket_seq_show(struct seq_file *seq)
 {
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index c6a5191..d68eba4 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -758,7 +758,7 @@
 	struct svc_serv	*serv = svsk->sk_server;
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
-	struct proto_ops *ops;
+	const struct proto_ops *ops;
 	struct svc_sock	*newsvsk;
 	int		err, slen;
 
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index acc73ba..5f6ae79 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -121,7 +121,7 @@
 int sysctl_unix_max_dgram_qlen = 10;
 
 struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-DEFINE_RWLOCK(unix_table_lock);
+DEFINE_SPINLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE])
@@ -130,7 +130,7 @@
 
 /*
  *  SMP locking strategy:
- *    hash table is protected with rwlock unix_table_lock
+ *    hash table is protected with spinlock unix_table_lock
  *    each socket state is protected by separate rwlock.
  */
 
@@ -214,16 +214,16 @@
 
 static inline void unix_remove_socket(struct sock *sk)
 {
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	__unix_remove_socket(sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
 {
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	__unix_insert_socket(list, sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@ -250,11 +250,11 @@
 {
 	struct sock *s;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	s = __unix_find_socket_byname(sunname, len, type, hash);
 	if (s)
 		sock_hold(s);
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	return s;
 }
 
@@ -263,7 +263,7 @@
 	struct sock *s;
 	struct hlist_node *node;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	sk_for_each(s, node,
 		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
 		struct dentry *dentry = unix_sk(s)->dentry;
@@ -276,7 +276,7 @@
 	}
 	s = NULL;
 found:
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	return s;
 }
 
@@ -473,7 +473,7 @@
 static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
 				  struct msghdr *, size_t);
 
-static struct proto_ops unix_stream_ops = {
+static const struct proto_ops unix_stream_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -494,7 +494,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops unix_dgram_ops = {
+static const struct proto_ops unix_dgram_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -515,7 +515,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops unix_seqpacket_ops = {
+static const struct proto_ops unix_seqpacket_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -564,7 +564,7 @@
 	u	  = unix_sk(sk);
 	u->dentry = NULL;
 	u->mnt	  = NULL;
-	rwlock_init(&u->lock);
+	spin_lock_init(&u->lock);
 	atomic_set(&u->inflight, sock ? 0 : -1);
 	init_MUTEX(&u->readsem); /* single task reading lock */
 	init_waitqueue_head(&u->peer_wait);
@@ -642,12 +642,12 @@
 	addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
 	addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
 
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	ordernum = (ordernum+1)&0xFFFFF;
 
 	if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
 				      addr->hash)) {
-		write_unlock(&unix_table_lock);
+		spin_unlock(&unix_table_lock);
 		/* Sanity yield. It is unusual case, but yet... */
 		if (!(ordernum&0xFF))
 			yield();
@@ -658,7 +658,7 @@
 	__unix_remove_socket(sk);
 	u->addr = addr;
 	__unix_insert_socket(&unix_socket_table[addr->hash], sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	err = 0;
 
 out:	up(&u->readsem);
@@ -791,7 +791,7 @@
 		addr->hash = UNIX_HASH_SIZE;
 	}
 
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 
 	if (!sunaddr->sun_path[0]) {
 		err = -EADDRINUSE;
@@ -814,7 +814,7 @@
 	__unix_insert_socket(list, sk);
 
 out_unlock:
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 out_up:
 	up(&u->readsem);
 out:
@@ -1063,10 +1063,12 @@
 	/* Set credentials */
 	sk->sk_peercred = other->sk_peercred;
 
-	sock_hold(newsk);
-	unix_peer(sk)	= newsk;
 	sock->state	= SS_CONNECTED;
 	sk->sk_state	= TCP_ESTABLISHED;
+	sock_hold(newsk);
+
+	smp_mb__after_atomic_inc();	/* sock_hold() does an atomic_inc() */
+	unix_peer(sk)	= newsk;
 
 	unix_state_wunlock(sk);
 
@@ -1414,7 +1416,7 @@
 	} else {
 		sunaddr = NULL;
 		err = -ENOTCONN;
-		other = unix_peer_get(sk);
+		other = unix_peer(sk);
 		if (!other)
 			goto out_err;
 	}
@@ -1476,7 +1478,6 @@
 		other->sk_data_ready(other, size);
 		sent+=size;
 	}
-	sock_put(other);
 
 	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
@@ -1491,8 +1492,6 @@
 		send_sig(SIGPIPE,current,0);
 	err = -EPIPE;
 out_err:
-        if (other)
-		sock_put(other);
 	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
 	return sent ? : err;
@@ -1860,7 +1859,7 @@
 		}
 
 		default:
-			err = dev_ioctl(cmd, (void __user *)arg);
+			err = -ENOIOCTLCMD;
 			break;
 	}
 	return err;
@@ -1917,7 +1916,7 @@
 
 static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
 }
 
@@ -1932,7 +1931,7 @@
 
 static void unix_seq_stop(struct seq_file *seq, void *v)
 {
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static int unix_seq_show(struct seq_file *seq, void *v)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 6ffc64e..411802b 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -182,7 +182,7 @@
 	if (down_trylock(&unix_gc_sem))
 		return;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 
 	forall_unix_sockets(i, s)
 	{
@@ -301,7 +301,7 @@
 		}
 		u->gc_tree = GC_ORPHAN;
 	}
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 
 	/*
 	 *	Here we are. Hitlist is filled. Die.
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 59fec59..7a43ae4 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -181,7 +181,7 @@
 #endif
 
 static int sk_count;
-extern struct proto_ops wanpipe_ops;
+extern const struct proto_ops wanpipe_ops;
 static unsigned long find_free_critical;
 
 static void wanpipe_unlink_driver(struct sock *sk);
@@ -1839,7 +1839,7 @@
 #endif
 
 		default:
-			return dev_ioctl(cmd,(void __user *) arg);
+			return -ENOIOCTLCMD;
 	}
 	/*NOTREACHED*/
 }
@@ -2546,7 +2546,7 @@
 	return 0;
 }
 
-struct proto_ops wanpipe_ops = {
+const struct proto_ops wanpipe_ops = {
 	.family = 	PF_WANPIPE,
 	.owner =	THIS_MODULE,
 	.release = 	wanpipe_release,
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 020d73c..16459c7 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -64,7 +64,7 @@
 HLIST_HEAD(x25_list);
 DEFINE_RWLOCK(x25_list_lock);
 
-static struct proto_ops x25_proto_ops;
+static const struct proto_ops x25_proto_ops;
 
 static struct x25_address null_x25_address = {"               "};
 
@@ -1378,7 +1378,7 @@
 		}
 
  		default:
-			rc = dev_ioctl(cmd, argp);
+			rc = -ENOIOCTLCMD;
 			break;
 	}
 
@@ -1391,7 +1391,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
 	.family =	AF_X25,
 	.owner =	THIS_MODULE,
 	.release =	x25_release,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d19e274..64a4473 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -10,7 +10,7 @@
  * 	YOSHIFUJI Hideaki
  * 		Split up af-specific portion
  *	Derek Atkins <derek@ihtfp.com>		Add the post_input processor
- * 	
+ *
  */
 
 #include <asm/bug.h>
@@ -256,6 +256,7 @@
 	if (del_timer(&policy->timer))
 		BUG();
 
+	security_xfrm_policy_free(policy);
 	kfree(policy);
 }
 EXPORT_SYMBOL(__xfrm_policy_destroy);
@@ -350,7 +351,8 @@
 
 	write_lock_bh(&xfrm_policy_lock);
 	for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
-		if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) {
+		if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
+		    xfrm_sec_ctx_match(pol->security, policy->security)) {
 			if (excl) {
 				write_unlock_bh(&xfrm_policy_lock);
 				return -EEXIST;
@@ -416,14 +418,15 @@
 }
 EXPORT_SYMBOL(xfrm_policy_insert);
 
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-				      int delete)
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+					  struct xfrm_sec_ctx *ctx, int delete)
 {
 	struct xfrm_policy *pol, **p;
 
 	write_lock_bh(&xfrm_policy_lock);
 	for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
-		if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) {
+		if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
+		    (xfrm_sec_ctx_match(ctx, pol->security))) {
 			xfrm_pol_hold(pol);
 			if (delete)
 				*p = pol->next;
@@ -438,7 +441,7 @@
 	}
 	return pol;
 }
-EXPORT_SYMBOL(xfrm_policy_bysel);
+EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
 {
@@ -519,7 +522,7 @@
 
 /* Find policy to apply to this flow. */
 
-static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
+static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
 			       void **objp, atomic_t **obj_refp)
 {
 	struct xfrm_policy *pol;
@@ -533,9 +536,12 @@
 			continue;
 
 		match = xfrm_selector_match(sel, fl, family);
+
 		if (match) {
-			xfrm_pol_hold(pol);
-			break;
+ 			if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) {
+				xfrm_pol_hold(pol);
+				break;
+			}
 		}
 	}
 	read_unlock_bh(&xfrm_policy_lock);
@@ -543,15 +549,37 @@
 		*obj_refp = &pol->refcnt;
 }
 
-static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
+static inline int policy_to_flow_dir(int dir)
+{
+	if (XFRM_POLICY_IN == FLOW_DIR_IN &&
+ 	    XFRM_POLICY_OUT == FLOW_DIR_OUT &&
+ 	    XFRM_POLICY_FWD == FLOW_DIR_FWD)
+ 		return dir;
+ 	switch (dir) {
+ 	default:
+ 	case XFRM_POLICY_IN:
+ 		return FLOW_DIR_IN;
+ 	case XFRM_POLICY_OUT:
+ 		return FLOW_DIR_OUT;
+ 	case XFRM_POLICY_FWD:
+ 		return FLOW_DIR_FWD;
+	};
+}
+
+static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid)
 {
 	struct xfrm_policy *pol;
 
 	read_lock_bh(&xfrm_policy_lock);
 	if ((pol = sk->sk_policy[dir]) != NULL) {
-		int match = xfrm_selector_match(&pol->selector, fl,
+ 		int match = xfrm_selector_match(&pol->selector, fl,
 						sk->sk_family);
+ 		int err = 0;
+
 		if (match)
+		  err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir));
+
+ 		if (match && !err)
 			xfrm_pol_hold(pol);
 		else
 			pol = NULL;
@@ -624,6 +652,10 @@
 
 	if (newp) {
 		newp->selector = old->selector;
+		if (security_xfrm_policy_clone(old, newp)) {
+			kfree(newp);
+			return NULL;  /* ENOMEM */
+		}
 		newp->lft = old->lft;
 		newp->curlft = old->curlft;
 		newp->action = old->action;
@@ -735,22 +767,6 @@
 	return err;
 }
 
-static inline int policy_to_flow_dir(int dir)
-{
-	if (XFRM_POLICY_IN == FLOW_DIR_IN &&
-	    XFRM_POLICY_OUT == FLOW_DIR_OUT &&
-	    XFRM_POLICY_FWD == FLOW_DIR_FWD)
-		return dir;
-	switch (dir) {
-	default:
-	case XFRM_POLICY_IN:
-		return FLOW_DIR_IN;
-	case XFRM_POLICY_OUT:
-		return FLOW_DIR_OUT;
-	case XFRM_POLICY_FWD:
-		return FLOW_DIR_FWD;
-	};
-}
 
 static int stale_bundle(struct dst_entry *dst);
 
@@ -769,19 +785,20 @@
 	int err;
 	u32 genid;
 	u16 family = dst_orig->ops->family;
+	u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
+	u32 sk_sid = security_sk_sid(sk, fl, dir);
 restart:
 	genid = atomic_read(&flow_cache_genid);
 	policy = NULL;
 	if (sk && sk->sk_policy[1])
-		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid);
 
 	if (!policy) {
 		/* To accelerate a bit...  */
 		if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
 			return 0;
 
-		policy = flow_cache_lookup(fl, family,
-					   policy_to_flow_dir(XFRM_POLICY_OUT),
+		policy = flow_cache_lookup(fl, sk_sid, family, dir,
 					   xfrm_policy_lookup);
 	}
 
@@ -962,16 +979,20 @@
 {
 	struct xfrm_policy *pol;
 	struct flowi fl;
+	u8 fl_dir = policy_to_flow_dir(dir);
+	u32 sk_sid;
 
 	if (_decode_session(skb, &fl, family) < 0)
 		return 0;
 
+	sk_sid = security_sk_sid(sk, &fl, fl_dir);
+
 	/* First, check used SA against their selectors. */
 	if (skb->sp) {
 		int i;
 
 		for (i=skb->sp->len-1; i>=0; i--) {
-		  struct sec_decap_state *xvec = &(skb->sp->x[i]);
+			struct sec_decap_state *xvec = &(skb->sp->x[i]);
 			if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
 				return 0;
 
@@ -986,11 +1007,10 @@
 
 	pol = NULL;
 	if (sk && sk->sk_policy[dir])
-		pol = xfrm_sk_policy_lookup(sk, dir, &fl);
+		pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid);
 
 	if (!pol)
-		pol = flow_cache_lookup(&fl, family,
-					policy_to_flow_dir(dir),
+		pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir,
 					xfrm_policy_lookup);
 
 	if (!pol)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 479effc..e12d0be 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -10,7 +10,7 @@
  * 		Split up af-specific functions
  *	Derek Atkins <derek@ihtfp.com>
  *		Add UDP Encapsulation
- * 	
+ *
  */
 
 #include <linux/workqueue.h>
@@ -70,6 +70,7 @@
 		x->type->destructor(x);
 		xfrm_put_type(x->type);
 	}
+	security_xfrm_state_free(x);
 	kfree(x);
 }
 
@@ -343,7 +344,8 @@
 			      selector.
 			 */
 			if (x->km.state == XFRM_STATE_VALID) {
-				if (!xfrm_selector_match(&x->sel, fl, family))
+				if (!xfrm_selector_match(&x->sel, fl, family) ||
+				    !xfrm_sec_ctx_match(pol->security, x->security))
 					continue;
 				if (!best ||
 				    best->km.dying > x->km.dying ||
@@ -354,7 +356,8 @@
 				acquire_in_progress = 1;
 			} else if (x->km.state == XFRM_STATE_ERROR ||
 				   x->km.state == XFRM_STATE_EXPIRED) {
-				if (xfrm_selector_match(&x->sel, fl, family))
+ 				if (xfrm_selector_match(&x->sel, fl, family) &&
+				    xfrm_sec_ctx_match(pol->security, x->security))
 					error = -ESRCH;
 			}
 		}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0cdd9a0..92e2b80 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -7,7 +7,7 @@
  * 	Kazunori MIYAZAWA @USAGI
  * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
  * 		IPv6 support
- * 	
+ *
  */
 
 #include <linux/module.h>
@@ -88,6 +88,34 @@
 	return 0;
 }
 
+
+static inline int verify_sec_ctx_len(struct rtattr **xfrma)
+{
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
+	struct xfrm_user_sec_ctx *uctx;
+	int len = 0;
+
+	if (!rt)
+		return 0;
+
+	if (rt->rta_len < sizeof(*uctx))
+		return -EINVAL;
+
+	uctx = RTA_DATA(rt);
+
+	if (uctx->ctx_len > PAGE_SIZE)
+		return -EINVAL;
+
+	len += sizeof(struct xfrm_user_sec_ctx);
+	len += uctx->ctx_len;
+
+	if (uctx->len != len)
+		return -EINVAL;
+
+	return 0;
+}
+
+
 static int verify_newsa_info(struct xfrm_usersa_info *p,
 			     struct rtattr **xfrma)
 {
@@ -145,6 +173,8 @@
 		goto out;
 	if ((err = verify_encap_tmpl(xfrma)))
 		goto out;
+	if ((err = verify_sec_ctx_len(xfrma)))
+		goto out;
 
 	err = -EINVAL;
 	switch (p->mode) {
@@ -209,6 +239,30 @@
 	return 0;
 }
 
+
+static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
+{
+	struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+	int len = 0;
+
+	if (xfrm_ctx) {
+		len += sizeof(struct xfrm_user_sec_ctx);
+		len += xfrm_ctx->ctx_len;
+	}
+	return len;
+}
+
+static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
+{
+	struct xfrm_user_sec_ctx *uctx;
+
+	if (!u_arg)
+		return 0;
+
+	uctx = RTA_DATA(u_arg);
+	return security_xfrm_state_alloc(x, uctx);
+}
+
 static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
 	memcpy(&x->id, &p->id, sizeof(x->id));
@@ -253,6 +307,9 @@
 	if (err)
 		goto error;
 
+	if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
+		goto error;
+
 	x->km.seq = p->seq;
 
 	return x;
@@ -272,11 +329,11 @@
 	int err;
 	struct km_event c;
 
-	err = verify_newsa_info(p, (struct rtattr **) xfrma);
+	err = verify_newsa_info(p, (struct rtattr **)xfrma);
 	if (err)
 		return err;
 
-	x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
+	x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
 	if (!x)
 		return err;
 
@@ -390,6 +447,19 @@
 	if (x->encap)
 		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
+	if (x->security) {
+		int ctx_size = sizeof(struct xfrm_sec_ctx) +
+				x->security->ctx_len;
+		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+		uctx->exttype = XFRMA_SEC_CTX;
+		uctx->len = ctx_size;
+		uctx->ctx_doi = x->security->ctx_doi;
+		uctx->ctx_alg = x->security->ctx_alg;
+		uctx->ctx_len = x->security->ctx_len;
+		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
+	}
 	nlh->nlmsg_len = skb->tail - b;
 out:
 	sp->this_idx++;
@@ -603,6 +673,18 @@
 	return verify_policy_dir(p->dir);
 }
 
+static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
+{
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+	struct xfrm_user_sec_ctx *uctx;
+
+	if (!rt)
+		return 0;
+
+	uctx = RTA_DATA(rt);
+	return security_xfrm_policy_alloc(pol, uctx);
+}
+
 static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
 			   int nr)
 {
@@ -681,7 +763,10 @@
 	}
 
 	copy_from_user_policy(xp, p);
-	err = copy_from_user_tmpl(xp, xfrma);
+
+	if (!(err = copy_from_user_tmpl(xp, xfrma)))
+		err = copy_from_user_sec_ctx(xp, xfrma);
+
 	if (err) {
 		*errp = err;
 		kfree(xp);
@@ -702,8 +787,11 @@
 	err = verify_newpolicy_info(p);
 	if (err)
 		return err;
+	err = verify_sec_ctx_len((struct rtattr **)xfrma);
+	if (err)
+		return err;
 
-	xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err);
+	xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
 	if (!xp)
 		return err;
 
@@ -761,6 +849,27 @@
 	return -1;
 }
 
+static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb)
+{
+	if (xp->security) {
+		int ctx_size = sizeof(struct xfrm_sec_ctx) +
+				xp->security->ctx_len;
+		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+		uctx->exttype = XFRMA_SEC_CTX;
+		uctx->len = ctx_size;
+		uctx->ctx_doi = xp->security->ctx_doi;
+		uctx->ctx_alg = xp->security->ctx_alg;
+		uctx->ctx_len = xp->security->ctx_len;
+		memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len);
+	}
+	return 0;
+
+ rtattr_failure:
+	return -1;
+}
+
 static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
 {
 	struct xfrm_dump_info *sp = ptr;
@@ -782,6 +891,8 @@
 	copy_to_user_policy(xp, p, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
 out:
@@ -852,8 +963,25 @@
 
 	if (p->index)
 		xp = xfrm_policy_byid(p->dir, p->index, delete);
-	else
-		xp = xfrm_policy_bysel(p->dir, &p->sel, delete);
+	else {
+		struct rtattr **rtattrs = (struct rtattr **)xfrma;
+		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
+		struct xfrm_policy tmp;
+
+		err = verify_sec_ctx_len(rtattrs);
+		if (err)
+			return err;
+
+		memset(&tmp, 0, sizeof(struct xfrm_policy));
+		if (rt) {
+			struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
+				return err;
+		}
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
+		security_xfrm_policy_free(&tmp);
+	}
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -1224,6 +1352,8 @@
 
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
 	return skb->len;
@@ -1241,6 +1371,7 @@
 
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
+	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -1324,6 +1455,8 @@
 	copy_to_user_policy(xp, &upe->pol, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 	upe->hard = !!hard;
 
 	nlh->nlmsg_len = skb->tail - b;
@@ -1341,6 +1474,7 @@
 
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
+	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
diff --git a/security/Kconfig b/security/Kconfig
index 64d3f1e..34f5934 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,19 @@
 	  implement socket and networking access controls.
 	  If you are unsure how to answer this question, answer N.
 
+config SECURITY_NETWORK_XFRM
+	bool "XFRM (IPSec) Networking Security Hooks"
+	depends on XFRM && SECURITY_NETWORK
+	help
+	  This enables the XFRM (IPSec) networking security hooks.
+	  If enabled, a security module can use these hooks to
+	  implement per-packet access controls based on labels
+	  derived from IPSec policy.  Non-IPSec communications are
+	  designated as unlabelled, and only sockets authorized
+	  to communicate unlabelled data can send without using
+	  IPSec.
+	  If you are unsure how to answer this question, answer N.
+
 config SECURITY_CAPABILITIES
 	tristate "Default Linux Capabilities"
 	depends on SECURITY
diff --git a/security/dummy.c b/security/dummy.c
index 3ca5f2b..a15c547 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -776,8 +776,42 @@
 static inline void dummy_sk_free_security (struct sock *sk)
 {
 }
+
+static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return 0;
+}
+
+static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp)
+{
+}
+
+static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static void dummy_xfrm_state_free_security(struct xfrm_state *x)
+{
+}
+
+static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return 0;
+}
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
 static int dummy_register_security (const char *name, struct security_operations *ops)
 {
 	return -EINVAL;
@@ -970,7 +1004,16 @@
 	set_to_dummy_if_null(ops, socket_getpeersec);
 	set_to_dummy_if_null(ops, sk_alloc_security);
 	set_to_dummy_if_null(ops, sk_free_security);
-#endif	/* CONFIG_SECURITY_NETWORK */
+	set_to_dummy_if_null(ops, sk_getsid);
+ #endif	/* CONFIG_SECURITY_NETWORK */
+#ifdef  CONFIG_SECURITY_NETWORK_XFRM
+	set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
+	set_to_dummy_if_null(ops, xfrm_policy_clone_security);
+	set_to_dummy_if_null(ops, xfrm_policy_free_security);
+	set_to_dummy_if_null(ops, xfrm_state_alloc_security);
+	set_to_dummy_if_null(ops, xfrm_state_free_security);
+	set_to_dummy_if_null(ops, xfrm_policy_lookup);
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
 #ifdef CONFIG_KEYS
 	set_to_dummy_if_null(ops, key_alloc);
 	set_to_dummy_if_null(ops, key_free);
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index b038cd0..06d54d9 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -8,5 +8,7 @@
 
 selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
 
+selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
+
 EXTRA_CFLAGS += -Isecurity/selinux/include
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fc77443..3d496ea 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -73,6 +73,7 @@
 #include "avc.h"
 #include "objsec.h"
 #include "netif.h"
+#include "xfrm.h"
 
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
@@ -3349,6 +3350,10 @@
 		err = avc_has_perm(sock_sid, port_sid,
 				   sock_class, recv_perm, &ad);
 	}
+
+	if (!err)
+		err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+
 out:	
 	return err;
 }
@@ -3401,6 +3406,24 @@
 	sk_free_security(sk);
 }
 
+static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	struct inode_security_struct *isec;
+	u32 sock_sid = SECINITSID_ANY_SOCKET;
+
+	if (!sk)
+		return selinux_no_sk_sid(fl);
+
+	read_lock_bh(&sk->sk_callback_lock);
+	isec = get_sock_isec(sk);
+
+	if (isec)
+		sock_sid = isec->sid;
+
+	read_unlock_bh(&sk->sk_callback_lock);
+	return sock_sid;
+}
+
 static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
 {
 	int err = 0;
@@ -3536,6 +3559,11 @@
 		                   send_perm, &ad) ? NF_DROP : NF_ACCEPT;
 	}
 
+	if (err != NF_ACCEPT)
+		goto out;
+
+	err = selinux_xfrm_postroute_last(isec->sid, skb);
+
 out:
 	return err;
 }
@@ -4380,6 +4408,16 @@
 	.socket_getpeersec =		selinux_socket_getpeersec,
 	.sk_alloc_security =		selinux_sk_alloc_security,
 	.sk_free_security =		selinux_sk_free_security,
+	.sk_getsid = 			selinux_sk_getsid_security,
+#endif
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+	.xfrm_policy_alloc_security =	selinux_xfrm_policy_alloc,
+	.xfrm_policy_clone_security =	selinux_xfrm_policy_clone,
+	.xfrm_policy_free_security =	selinux_xfrm_policy_free,
+	.xfrm_state_alloc_security =	selinux_xfrm_state_alloc,
+	.xfrm_state_free_security =	selinux_xfrm_state_free,
+	.xfrm_policy_lookup = 		selinux_xfrm_policy_lookup,
 #endif
 };
 
@@ -4491,6 +4529,7 @@
 		panic("SELinux: nf_register_hook for IPv6: error %d\n", err);
 
 #endif	/* IPV6 */
+
 out:
 	return err;
 }
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 1deb59e..71aeb12 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -238,3 +238,5 @@
    S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
+   S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELFROM, "relabelfrom")
+   S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELTO, "relabelto")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index a78b5d5..d1d0996 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -908,6 +908,8 @@
 
 #define ASSOCIATION__SENDTO                       0x00000001UL
 #define ASSOCIATION__RECVFROM                     0x00000002UL
+#define ASSOCIATION__RELABELFROM                  0x00000004UL
+#define ASSOCIATION__RELABELTO                    0x00000008UL
 
 #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL      0x00000001UL
 #define NETLINK_KOBJECT_UEVENT_SOCKET__READ       0x00000002UL
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
new file mode 100644
index 0000000..8e87996
--- /dev/null
+++ b/security/selinux/include/xfrm.h
@@ -0,0 +1,54 @@
+/*
+ * SELinux support for the XFRM LSM hooks
+ *
+ * Author : Trent Jaeger, <jaegert@us.ibm.com>
+ */
+#ifndef _SELINUX_XFRM_H_
+#define _SELINUX_XFRM_H_
+
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
+void selinux_xfrm_policy_free(struct xfrm_policy *xp);
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+void selinux_xfrm_state_free(struct xfrm_state *x);
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+
+/*
+ * Extract the security blob from the sock (it's actually on the socket)
+ */
+static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
+{
+	if (!sk->sk_socket)
+		return NULL;
+
+	return SOCK_INODE(sk->sk_socket)->i_security;
+}
+
+
+static inline u32 selinux_no_sk_sid(struct flowi *fl)
+{
+	/* NOTE: no sock occurs on ICMP reply, forwards, ... */
+	/* icmp_reply: authorize as kernel packet */
+	if (fl && fl->proto == IPPROTO_ICMP) {
+		return SECINITSID_KERNEL;
+	}
+
+	return SECINITSID_ANY_SOCKET;
+}
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
+#else
+static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+	return 0;
+}
+
+static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+	return NF_ACCEPT;
+}
+#endif
+
+#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
new file mode 100644
index 0000000..c4d87d4
--- /dev/null
+++ b/security/selinux/xfrm.c
@@ -0,0 +1,311 @@
+/*
+ *  NSA Security-Enhanced Linux (SELinux) security module
+ *
+ *  This file contains the SELinux XFRM hook function implementations.
+ *
+ *  Authors:  Serge Hallyn <sergeh@us.ibm.com>
+ *	      Trent Jaeger <jaegert@us.ibm.com>
+ *
+ *  Copyright (C) 2005 International Business Machines 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.
+ */
+
+/*
+ * USAGE:
+ * NOTES:
+ *   1. Make sure to enable the following options in your kernel config:
+ *	CONFIG_SECURITY=y
+ *	CONFIG_SECURITY_NETWORK=y
+ *	CONFIG_SECURITY_NETWORK_XFRM=y
+ *	CONFIG_SECURITY_SELINUX=m/y
+ * ISSUES:
+ *   1. Caching packets, so they are not dropped during negotiation
+ *   2. Emulating a reasonable SO_PEERSEC across machines
+ *   3. Testing addition of sk_policy's with security context via setsockopt
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/types.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <asm/semaphore.h>
+
+#include "avc.h"
+#include "objsec.h"
+#include "xfrm.h"
+
+
+/*
+ * Returns true if an LSM/SELinux context
+ */
+static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
+{
+	return (ctx &&
+		(ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
+		(ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
+}
+
+/*
+ * Returns true if the xfrm contains a security blob for SELinux
+ */
+static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
+{
+	return selinux_authorizable_ctx(x->security);
+}
+
+/*
+ * LSM hook implementation that authorizes that a socket can be used
+ * with the corresponding xfrm_sec_ctx and direction.
+ */
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	int rc = 0;
+	u32 sel_sid = SECINITSID_UNLABELED;
+	struct xfrm_sec_ctx *ctx;
+
+	/* Context sid is either set to label or ANY_ASSOC */
+	if ((ctx = xp->security)) {
+		if (!selinux_authorizable_ctx(ctx))
+			return -EINVAL;
+
+		sel_sid = ctx->ctx_sid;
+	}
+
+	rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION,
+			  ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM :
+			   ((dir == FLOW_DIR_OUT) ?  ASSOCIATION__SENDTO :
+			    (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))),
+			  NULL);
+
+	return rc;
+}
+
+/*
+ * Security blob allocation for xfrm_policy and xfrm_state
+ * CTX does not have a meaningful value on input
+ */
+static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx)
+{
+	int rc = 0;
+	struct task_security_struct *tsec = current->security;
+	struct xfrm_sec_ctx *ctx;
+
+	BUG_ON(!uctx);
+	BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX);
+
+	if (uctx->ctx_len >= PAGE_SIZE)
+		return -ENOMEM;
+
+	*ctxp = ctx = kmalloc(sizeof(*ctx) +
+			      uctx->ctx_len,
+			      GFP_KERNEL);
+
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->ctx_doi = uctx->ctx_doi;
+	ctx->ctx_len = uctx->ctx_len;
+	ctx->ctx_alg = uctx->ctx_alg;
+
+	memcpy(ctx->ctx_str,
+	       uctx+1,
+	       ctx->ctx_len);
+	rc = security_context_to_sid(ctx->ctx_str,
+				     ctx->ctx_len,
+				     &ctx->ctx_sid);
+
+	if (rc)
+		goto out;
+
+	/*
+	 * Does the subject have permission to set security or permission to
+	 * do the relabel?
+	 * Must be permitted to relabel from default socket type (process type)
+	 * to specified context
+	 */
+	rc = avc_has_perm(tsec->sid, tsec->sid,
+			  SECCLASS_ASSOCIATION,
+			  ASSOCIATION__RELABELFROM, NULL);
+	if (rc)
+		goto out;
+
+	rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+			  SECCLASS_ASSOCIATION,
+			  ASSOCIATION__RELABELTO, NULL);
+	if (rc)
+		goto out;
+
+	return rc;
+
+out:
+	*ctxp = 0;
+	kfree(ctx);
+	return rc;
+}
+
+/*
+ * LSM hook implementation that allocs and transfers uctx spec to
+ * xfrm_policy.
+ */
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx)
+{
+	int err;
+
+	BUG_ON(!xp);
+
+	err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx);
+	return err;
+}
+
+
+/*
+ * LSM hook implementation that copies security data structure from old to
+ * new for policy cloning.
+ */
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	struct xfrm_sec_ctx *old_ctx, *new_ctx;
+
+	old_ctx = old->security;
+
+	if (old_ctx) {
+		new_ctx = new->security = kmalloc(sizeof(*new_ctx) +
+						  old_ctx->ctx_len,
+						  GFP_KERNEL);
+
+		if (!new_ctx)
+			return -ENOMEM;
+
+		memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
+		memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
+	}
+	return 0;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_policy security information.
+ */
+void selinux_xfrm_policy_free(struct xfrm_policy *xp)
+{
+	struct xfrm_sec_ctx *ctx = xp->security;
+	if (ctx)
+		kfree(ctx);
+}
+
+/*
+ * LSM hook implementation that allocs and transfers sec_ctx spec to
+ * xfrm_state.
+ */
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx)
+{
+	int err;
+
+	BUG_ON(!x);
+
+	err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx);
+	return err;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_state security information.
+ */
+void selinux_xfrm_state_free(struct xfrm_state *x)
+{
+	struct xfrm_sec_ctx *ctx = x->security;
+	if (ctx)
+		kfree(ctx);
+}
+
+/*
+ * LSM hook that controls access to unlabelled packets.  If
+ * a xfrm_state is authorizable (defined by macro) then it was
+ * already authorized by the IPSec process.  If not, then
+ * we need to check for unlabelled access since this may not have
+ * gone thru the IPSec process.
+ */
+int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+	int i, rc = 0;
+	struct sec_path *sp;
+
+	sp = skb->sp;
+
+	if (sp) {
+		/*
+		 * __xfrm_policy_check does not approve unless xfrm_policy_ok
+		 * says that spi's match for policy and the socket.
+		 *
+		 *  Only need to verify the existence of an authorizable sp.
+		 */
+		for (i = 0; i < sp->len; i++) {
+			struct xfrm_state *x = sp->x[i].xvec;
+
+			if (x && selinux_authorizable_xfrm(x))
+				goto accept;
+		}
+	}
+
+	/* check SELinux sock for unlabelled access */
+	rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+			  ASSOCIATION__RECVFROM, NULL);
+	if (rc)
+		goto drop;
+
+accept:
+	return 0;
+
+drop:
+	return rc;
+}
+
+/*
+ * POSTROUTE_LAST hook's XFRM processing:
+ * If we have no security association, then we need to determine
+ * whether the socket is allowed to send to an unlabelled destination.
+ * If we do have a authorizable security association, then it has already been
+ * checked in xfrm_policy_lookup hook.
+ */
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+	struct dst_entry *dst;
+	int rc = 0;
+
+	dst = skb->dst;
+
+	if (dst) {
+		struct dst_entry *dst_test;
+
+		for (dst_test = dst; dst_test != 0;
+		     dst_test = dst_test->child) {
+			struct xfrm_state *x = dst_test->xfrm;
+
+			if (x && selinux_authorizable_xfrm(x))
+				goto accept;
+		}
+	}
+
+	rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+			  ASSOCIATION__SENDTO, NULL);
+	if (rc)
+		goto drop;
+
+accept:
+	return NF_ACCEPT;
+
+drop:
+	return NF_DROP;
+}
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 99dae02..22f8bb6 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1996,7 +1996,6 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"snd-usb-audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index cf77313..a3967f7 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -409,7 +409,6 @@
 
 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
 static struct usb_driver snd_usX2Y_usb_driver = {
- 	.owner =	THIS_MODULE,
 	.name =		"snd-usb-usx2y",
 	.probe =	snd_usX2Y_probe,
 	.disconnect =	snd_usX2Y_disconnect,