[kernel] r11390 - in dists/trunk/linux-2.6/debian/patches: bugfix/all features/all series

Maximilian Attems maks at alioth.debian.org
Thu May 15 10:10:58 UTC 2008


Author: maks
Date: Thu May 15 10:10:41 2008
New Revision: 11390

Log:
update to 2.6.26-rc2-git4

great the atl1 patches have been merged, so nuke them.
comment a arm disable patch that conflicts with upstream dvb Kconfig fixes.


Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.26-rc2-git4
Removed:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.26-rc2-git2
   dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-atl1-PHY-power-save-mode.patch
   dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-atl1-shutdown-callback.patch
   dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-atl1-suspend-resume.patch
   dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-atl1-version.patch
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.26-rc2-git4
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.26-rc2-git4	Thu May 15 10:10:41 2008
@@ -0,0 +1,44512 @@
+diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
+index c298a66..824fc02 100644
+--- a/Documentation/cgroups.txt
++++ b/Documentation/cgroups.txt
+@@ -310,8 +310,8 @@ and then start a subshell 'sh' in that cgroup:
+   cd /dev/cgroup
+   mkdir Charlie
+   cd Charlie
+-  /bin/echo 2-3 > cpus
+-  /bin/echo 1 > mems
++  /bin/echo 2-3 > cpuset.cpus
++  /bin/echo 1 > cpuset.mems
+   /bin/echo $$ > tasks
+   sh
+   # The subshell 'sh' is now running in cgroup Charlie
+diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
+index 3c35d45..5b3f31f 100644
+--- a/Documentation/feature-removal-schedule.txt
++++ b/Documentation/feature-removal-schedule.txt
+@@ -289,6 +289,14 @@ Who:	Glauber Costa <gcosta at redhat.com>
+ 
+ ---------------------------
+ 
++What:	old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE)
++When:	2.6.28
++Why:	This driver still uses the old interface and has been replaced
++	by CONFIG_SERIAL_MCF.
++Who:	Sebastian Siewior <sebastian at breakpoint.cc>
++
++---------------------------
++
+ What:	/sys/o2cb symlink
+ When:	January 2010
+ Why:	/sys/fs/o2cb is the proper location for this information - /sys/o2cb
+diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
+index 22d8b19..2126de3 100644
+--- a/Documentation/hwmon/adt7473
++++ b/Documentation/hwmon/adt7473
+@@ -69,7 +69,8 @@ point2: Set the pwm speed at a higher temperature bound.
+ 
+ The ADT7473 will scale the pwm between the lower and higher pwm speed when
+ the temperature is between the two temperature boundaries.  PWM values range
+-from 0 (off) to 255 (full speed).
++from 0 (off) to 255 (full speed).  Fan speed will be set to maximum when the
++temperature sensor associated with the PWM control exceeds temp#_max.
+ 
+ Notes
+ -----
+diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
+index e5a819a..f5b7127 100644
+--- a/Documentation/memory-barriers.txt
++++ b/Documentation/memory-barriers.txt
+@@ -994,7 +994,17 @@ The Linux kernel has eight basic CPU memory barriers:
+ 	DATA DEPENDENCY	read_barrier_depends()	smp_read_barrier_depends()
+ 
+ 
+-All CPU memory barriers unconditionally imply compiler barriers.
++All memory barriers except the data dependency barriers imply a compiler
++barrier. Data dependencies do not impose any additional compiler ordering.
++
++Aside: In the case of data dependencies, the compiler would be expected to
++issue the loads in the correct order (eg. `a[b]` would have to load the value
++of b before loading a[b]), however there is no guarantee in the C specification
++that the compiler may not speculate the value of b (eg. is equal to 1) and load
++a before b (eg. tmp = a[1]; if (b != 1) tmp = a[b]; ). There is also the
++problem of a compiler reloading b after having loaded a[b], thus having a newer
++copy of b than a[b]. A consensus has not yet been reached about these problems,
++however the ACCESS_ONCE macro is a good place to start looking.
+ 
+ SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
+ systems because it is assumed that a CPU will appear to be self-consistent,
+diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
+index 929b90c..191194e 100644
+--- a/Documentation/video4linux/CARDLIST.cx23885
++++ b/Documentation/video4linux/CARDLIST.cx23885
+@@ -5,6 +5,6 @@
+   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
+   5 -> Hauppauge WinTV-HVR1500Q                            [0070:7790,0070:7797]
+   6 -> Hauppauge WinTV-HVR1500                             [0070:7710,0070:7717]
+-  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1]
++  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1,0070:71d3]
+   8 -> Hauppauge WinTV-HVR1700                             [0070:8101]
+   9 -> Hauppauge WinTV-HVR1400                             [0070:8010]
+diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
+index f40e092..1d6a245 100644
+--- a/Documentation/video4linux/CARDLIST.em28xx
++++ b/Documentation/video4linux/CARDLIST.em28xx
+@@ -14,4 +14,4 @@
+  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
+  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
+  15 -> V-Gear PocketTV                          (em2800)
+- 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513]
++ 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513,2040:6517,2040:651b,2040:651f]
+diff --git a/MAINTAINERS b/MAINTAINERS
+index f5583dc..bc1c008 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -367,12 +367,12 @@ S:	Maintained for 2.4; PCI support for 2.6.
+ AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
+ P:	Thomas Dahlmann
+ M:	thomas.dahlmann at amd.com
+-L:	info-linux at geode.amd.com	(subscribers-only)
++L:	linux-geode at lists.infradead.org (moderated for non-subscribers)
+ S:	Supported
+ 
+ AMD GEODE PROCESSOR/CHIPSET SUPPORT
+ P:	Jordan Crouse
+-L:	info-linux at geode.amd.com	(subscribers-only)
++L:	linux-geode at lists.infradead.org (moderated for non-subscribers)
+ W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
+ S:	Supported
+ 
+@@ -1230,6 +1230,15 @@ P:	Jaya Kumar
+ M:	jayakumar.alsa at gmail.com
+ S:	Maintained
+ 
++CX18 VIDEO4LINUX DRIVER
++P:	Hans Verkuil, Andy Walls
++M:	hverkuil at xs4all.nl, awalls at radix.net
++L:	ivtv-devel at ivtvdriver.org
++L:	ivtv-users at ivtvdriver.org
++L:	video4linux-list at redhat.com
++W:	http://linuxtv.org
++S:	Maintained
++
+ CYBERPRO FB DRIVER
+ P:	Russell King
+ M:	rmk at arm.linux.org.uk
+diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
+index 728bb8f..0babb64 100644
+--- a/arch/arm/mach-at91/at91sam9261_devices.c
++++ b/arch/arm/mach-at91/at91sam9261_devices.c
+@@ -544,10 +544,10 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+ 		struct resource *fb_res = &lcdc_resources[2];
+ 		size_t fb_len = fb_res->end - fb_res->start + 1;
+ 
+-		fb = ioremap_writecombine(fb_res->start, fb_len);
++		fb = ioremap(fb_res->start, fb_len);
+ 		if (fb) {
+ 			memset(fb, 0, fb_len);
+-			iounmap(fb, fb_len);
++			iounmap(fb);
+ 		}
+ 	}
+ 	lcdc_data = *data;
+diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
+index 0546898..450db30 100644
+--- a/arch/arm/mach-at91/at91sam9rl_devices.c
++++ b/arch/arm/mach-at91/at91sam9rl_devices.c
+@@ -332,13 +332,6 @@ static struct resource lcdc_resources[] = {
+ 		.end	= AT91SAM9RL_ID_LCDC,
+ 		.flags	= IORESOURCE_IRQ,
+ 	},
+-#if defined(CONFIG_FB_INTSRAM)
+-	[2] = {
+-		.start	= AT91SAM9RL_SRAM_BASE,
+-		.end	= AT91SAM9RL_SRAM_BASE + AT91SAM9RL_SRAM_SIZE - 1,
+-		.flags	= IORESOURCE_MEM,
+-	},
+-#endif
+ };
+ 
+ static struct platform_device at91_lcdc_device = {
+@@ -381,20 +374,6 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+ 	at91_set_B_periph(AT91_PIN_PC24, 0);	/* LCDD22 */
+ 	at91_set_B_periph(AT91_PIN_PC25, 0);	/* LCDD23 */
+ 
+-#ifdef CONFIG_FB_INTSRAM
+-	{
+-		void __iomem *fb;
+-		struct resource *fb_res = &lcdc_resources[2];
+-		size_t fb_len = fb_res->end - fb_res->start + 1;
+-
+-		fb = ioremap_writecombine(fb_res->start, fb_len);
+-		if (fb) {
+-			memset(fb, 0, fb_len);
+-			iounmap(fb, fb_len);
+-		}
+-	}
+-#endif
+-
+ 	lcdc_data = *data;
+ 	platform_device_register(&at91_lcdc_device);
+ }
+diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
+index 07eb4c4..8e84415 100644
+--- a/arch/m68knommu/Kconfig
++++ b/arch/m68knommu/Kconfig
+@@ -671,6 +671,9 @@ config ROMKERNEL
+ 
+ endchoice
+ 
++if COLDFIRE
++source "kernel/Kconfig.preempt"
++endif
+ source "mm/Kconfig"
+ 
+ endmenu
+diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
+index 5592e0b..93e6923 100644
+--- a/arch/m68knommu/kernel/vmlinux.lds.S
++++ b/arch/m68knommu/kernel/vmlinux.lds.S
+@@ -114,6 +114,16 @@ SECTIONS {
+ 		*(__kcrctab_gpl)
+ 		__stop___kcrctab_gpl = .;
+ 
++		/* Kernel symbol table: Normal unused symbols */
++		__start___kcrctab_unused = .;
++		*(__kcrctab_unused)
++		__stop___kcrctab_unused = .;
++
++		/* Kernel symbol table: GPL-only unused symbols */
++		__start___kcrctab_unused_gpl = .;
++		*(__kcrctab_unused_gpl)
++		__stop___kcrctab_unused_gpl = .;
++
+ 		/* Kernel symbol table: GPL-future symbols */
+ 		__start___kcrctab_gpl_future = .;
+ 		*(__kcrctab_gpl_future)
+diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
+index 90e2d7a..dd0e19d 100644
+--- a/arch/mips/au1000/common/Makefile
++++ b/arch/mips/au1000/common/Makefile
+@@ -1,9 +1,8 @@
+ #
+-#  Copyright 2000 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #
+-# Makefile for the Alchemy Au1000 CPU, generic files.
++# Makefile for the Alchemy Au1xx0 CPUs, generic files.
+ #
+ 
+ obj-y += prom.o irq.o puts.o time.o reset.o \
+diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
+index 37a10a0..c7ca159 100644
+--- a/arch/mips/au1000/common/au1xxx_irqmap.c
++++ b/arch/mips/au1000/common/au1xxx_irqmap.c
+@@ -40,20 +40,20 @@
+ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 
+ #if defined(CONFIG_SOC_AU1000)
+-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -62,32 +62,32 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+ 
+ #elif defined(CONFIG_SOC_AU1500)
+ 
+-	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+-	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -100,26 +100,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+ 
+ #elif defined(CONFIG_SOC_AU1100)
+ 
+-	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -128,33 +128,33 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
+-	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
++	/* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
++	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+ 
+ #elif defined(CONFIG_SOC_AU1550)
+ 
+-	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+-	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
+-	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -163,26 +163,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
++	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+-	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 
+ #elif defined(CONFIG_SOC_AU1200)
+ 
+-	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
+-	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
+-	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+@@ -191,10 +191,10 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+-	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
++	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 },
+ 	{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
+-	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+-	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
++	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
+ 
+ #else
+ #error "Error: Unknown Alchemy SOC"
+@@ -203,4 +203,3 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
+ };
+ 
+ int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);
+-
+diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c
+index 3ce6cac..46f8ee0 100644
+--- a/arch/mips/au1000/common/clocks.c
++++ b/arch/mips/au1000/common/clocks.c
+@@ -1,10 +1,9 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Simple Au1000 clocks routines.
++ *	Simple Au1xx0 clocks routines.
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *		ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute	 it and/or modify it
+  *  under  the terms of	 the GNU General  Public License as published by the
+@@ -30,8 +29,8 @@
+ #include <linux/module.h>
+ #include <asm/mach-au1x00/au1000.h>
+ 
+-static unsigned int au1x00_clock; // Hz
+-static unsigned int lcd_clock;    // KHz
++static unsigned int au1x00_clock; /*  Hz */
++static unsigned int lcd_clock;    /* KHz */
+ static unsigned long uart_baud_base;
+ 
+ /*
+@@ -47,8 +46,6 @@ unsigned int get_au1x00_speed(void)
+ 	return au1x00_clock;
+ }
+ 
+-
+-
+ /*
+  * The UART baud base is not known at compile time ... if
+  * we want to be able to use the same code on different
+@@ -73,24 +70,23 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
+ void set_au1x00_lcd_clock(void)
+ {
+ 	unsigned int static_cfg0;
+-	unsigned int sys_busclk =
+-		(get_au1x00_speed()/1000) /
+-		((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
++	unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
++				  ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
+ 
+ 	static_cfg0 = au_readl(MEM_STCFG0);
+ 
+-	if (static_cfg0 & (1<<11))
++	if (static_cfg0 & (1 << 11))
+ 		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
+ 	else
+ 		lcd_clock = sys_busclk / 4;
+ 
+ 	if (lcd_clock > 50000) /* Epson MAX */
+-		printk("warning: LCD clock too high (%d KHz)\n", lcd_clock);
++		printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
++				    lcd_clock);
+ }
+ 
+ unsigned int get_au1x00_lcd_clock(void)
+ {
+ 	return lcd_clock;
+ }
+-
+ EXPORT_SYMBOL(get_au1x00_lcd_clock);
+diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
+index 8c93a05..ba6430b 100644
+--- a/arch/mips/au1000/common/cputable.c
++++ b/arch/mips/au1000/common/cputable.c
+@@ -14,7 +14,7 @@
+ 
+ #include <asm/mach-au1x00/au1000.h>
+ 
+-struct cpu_spec* cur_cpu_spec[NR_CPUS];
++struct cpu_spec *cur_cpu_spec[NR_CPUS];
+ 
+ /* With some thought, we can probably use the mask to reduce the
+  * size of the table.
+@@ -39,8 +39,7 @@ struct cpu_spec cpu_specs[] = {
+ 	{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
+ };
+ 
+-void
+-set_cpuspec(void)
++void set_cpuspec(void)
+ {
+ 	struct	cpu_spec *sp;
+ 	u32	prid;
+diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
+index 53377df..42d5552 100644
+--- a/arch/mips/au1000/common/dbdma.c
++++ b/arch/mips/au1000/common/dbdma.c
+@@ -53,12 +53,11 @@
+  */
+ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
+ 
+-/* I couldn't find a macro that did this......
+-*/
++/* I couldn't find a macro that did this... */
+ #define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
+ 
+ static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+-static int dbdma_initialized=0;
++static int dbdma_initialized;
+ static void au1xxx_dbdma_init(void);
+ 
+ static dbdev_tab_t dbdev_tab[] = {
+@@ -149,7 +148,7 @@ static dbdev_tab_t dbdev_tab[] = {
+ 
+ 	{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ 
+-#endif // CONFIG_SOC_AU1200
++#endif /* CONFIG_SOC_AU1200 */
+ 
+ 	{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ 	{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+@@ -177,8 +176,7 @@ static dbdev_tab_t dbdev_tab[] = {
+ 
+ static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
+ 
+-static dbdev_tab_t *
+-find_dbdev_id(u32 id)
++static dbdev_tab_t *find_dbdev_id(u32 id)
+ {
+ 	int i;
+ 	dbdev_tab_t *p;
+@@ -190,29 +188,27 @@ find_dbdev_id(u32 id)
+ 	return NULL;
+ }
+ 
+-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
++void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+ {
+-        return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
++	return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ }
+ EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
+ 
+-u32
+-au1xxx_ddma_add_device(dbdev_tab_t *dev)
++u32 au1xxx_ddma_add_device(dbdev_tab_t *dev)
+ {
+ 	u32 ret = 0;
+-	dbdev_tab_t *p=NULL;
+-	static u16 new_id=0x1000;
++	dbdev_tab_t *p;
++	static u16 new_id = 0x1000;
+ 
+ 	p = find_dbdev_id(~0);
+-	if ( NULL != p )
+-	{
++	if (NULL != p) {
+ 		memcpy(p, dev, sizeof(dbdev_tab_t));
+ 		p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id);
+ 		ret = p->dev_id;
+ 		new_id++;
+ #if 0
+-		printk("add_device: id:%x flags:%x padd:%x\n",
+-				p->dev_id, p->dev_flags, p->dev_physaddr );
++		printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n",
++				  p->dev_id, p->dev_flags, p->dev_physaddr);
+ #endif
+ 	}
+ 
+@@ -220,10 +216,8 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev)
+ }
+ EXPORT_SYMBOL(au1xxx_ddma_add_device);
+ 
+-/* Allocate a channel and return a non-zero descriptor if successful.
+-*/
+-u32
+-au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
++/* Allocate a channel and return a non-zero descriptor if successful. */
++u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+        void (*callback)(int, void *), void *callparam)
+ {
+ 	unsigned long   flags;
+@@ -234,7 +228,8 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ 	chan_tab_t	*ctp;
+ 	au1x_dma_chan_t *cp;
+ 
+-	/* We do the intialization on the first channel allocation.
++	/*
++	 * We do the intialization on the first channel allocation.
+ 	 * We have to wait because of the interrupt handler initialization
+ 	 * which can't be done successfully during board set up.
+ 	 */
+@@ -242,16 +237,17 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ 		au1xxx_dbdma_init();
+ 	dbdma_initialized = 1;
+ 
+-	if ((stp = find_dbdev_id(srcid)) == NULL)
++	stp = find_dbdev_id(srcid);
++	if (stp == NULL)
+ 		return 0;
+-	if ((dtp = find_dbdev_id(destid)) == NULL)
++	dtp = find_dbdev_id(destid);
++	if (dtp == NULL)
+ 		return 0;
+ 
+ 	used = 0;
+ 	rv = 0;
+ 
+-	/* Check to see if we can get both channels.
+-	*/
++	/* Check to see if we can get both channels. */
+ 	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+ 	if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
+ 	     (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
+@@ -261,35 +257,30 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ 		     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
+ 			/* Got destination */
+ 			dtp->dev_flags |= DEV_FLAGS_INUSE;
+-		}
+-		else {
+-			/* Can't get dest.  Release src.
+-			*/
++		} else {
++			/* Can't get dest.  Release src. */
+ 			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ 			used++;
+ 		}
+-	}
+-	else {
++	} else
+ 		used++;
+-	}
+ 	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+ 
+ 	if (!used) {
+-		/* Let's see if we can allocate a channel for it.
+-		*/
++		/* Let's see if we can allocate a channel for it. */
+ 		ctp = NULL;
+ 		chan = 0;
+ 		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+-		for (i=0; i<NUM_DBDMA_CHANS; i++) {
++		for (i = 0; i < NUM_DBDMA_CHANS; i++)
+ 			if (chan_tab_ptr[i] == NULL) {
+-				/* If kmalloc fails, it is caught below same
++				/*
++				 * If kmalloc fails, it is caught below same
+ 				 * as a channel not available.
+ 				 */
+ 				ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
+ 				chan_tab_ptr[i] = ctp;
+ 				break;
+ 			}
+-		}
+ 		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+ 
+ 		if (ctp != NULL) {
+@@ -304,8 +295,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ 			ctp->chan_callback = callback;
+ 			ctp->chan_callparam = callparam;
+ 
+-			/* Initialize channel configuration.
+-			*/
++			/* Initialize channel configuration. */
+ 			i = 0;
+ 			if (stp->dev_intlevel)
+ 				i |= DDMA_CFG_SED;
+@@ -326,8 +316,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ 			 * operations.
+ 			 */
+ 			rv = (u32)(&chan_tab_ptr[chan]);
+-		}
+-		else {
++		} else {
+ 			/* Release devices */
+ 			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ 			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+@@ -337,11 +326,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
+ 
+-/* Set the device width if source or destination is a FIFO.
++/*
++ * Set the device width if source or destination is a FIFO.
+  * Should be 8, 16, or 32 bits.
+  */
+-u32
+-au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
++u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+ {
+ 	u32		rv;
+ 	chan_tab_t	*ctp;
+@@ -365,10 +354,8 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
+ 
+-/* Allocate a descriptor ring, initializing as much as possible.
+-*/
+-u32
+-au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
++/* Allocate a descriptor ring, initializing as much as possible. */
++u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ {
+ 	int			i;
+ 	u32			desc_base, srcid, destid;
+@@ -378,43 +365,45 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 	dbdev_tab_t		*stp, *dtp;
+ 	au1x_ddma_desc_t	*dp;
+ 
+-	/* I guess we could check this to be within the
++	/*
++	 * I guess we could check this to be within the
+ 	 * range of the table......
+ 	 */
+ 	ctp = *((chan_tab_t **)chanid);
+ 	stp = ctp->chan_src;
+ 	dtp = ctp->chan_dest;
+ 
+-	/* The descriptors must be 32-byte aligned.  There is a
++	/*
++	 * The descriptors must be 32-byte aligned.  There is a
+ 	 * possibility the allocation will give us such an address,
+ 	 * and if we try that first we are likely to not waste larger
+ 	 * slabs of memory.
+ 	 */
+ 	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
+-			GFP_KERNEL|GFP_DMA);
++				 GFP_KERNEL|GFP_DMA);
+ 	if (desc_base == 0)
+ 		return 0;
+ 
+ 	if (desc_base & 0x1f) {
+-		/* Lost....do it again, allocate extra, and round
++		/*
++		 * Lost....do it again, allocate extra, and round
+ 		 * the address base.
+ 		 */
+ 		kfree((const void *)desc_base);
+ 		i = entries * sizeof(au1x_ddma_desc_t);
+ 		i += (sizeof(au1x_ddma_desc_t) - 1);
+-		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
++		desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA);
++		if (desc_base == 0)
+ 			return 0;
+ 
+ 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+ 	}
+ 	dp = (au1x_ddma_desc_t *)desc_base;
+ 
+-	/* Keep track of the base descriptor.
+-	*/
++	/* Keep track of the base descriptor. */
+ 	ctp->chan_desc_base = dp;
+ 
+-	/* Initialize the rings with as much information as we know.
+-	 */
++	/* Initialize the rings with as much information as we know. */
+ 	srcid = stp->dev_id;
+ 	destid = dtp->dev_id;
+ 
+@@ -426,11 +415,12 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 	cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
+ 	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
+ 
+-        /* is it mem to mem transfer? */
+-        if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+-           ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
+-               cmd0 |= DSCR_CMD0_MEM;
+-        }
++	/* Is it mem to mem transfer? */
++	if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) ||
++	     (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
++	    ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) ||
++	     (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS)))
++		cmd0 |= DSCR_CMD0_MEM;
+ 
+ 	switch (stp->dev_devwidth) {
+ 	case 8:
+@@ -458,15 +448,17 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 		break;
+ 	}
+ 
+-	/* If the device is marked as an in/out FIFO, ensure it is
++	/*
++	 * If the device is marked as an in/out FIFO, ensure it is
+ 	 * set non-coherent.
+ 	 */
+ 	if (stp->dev_flags & DEV_FLAGS_IN)
+-		cmd0 |= DSCR_CMD0_SN;		/* Source in fifo */
++		cmd0 |= DSCR_CMD0_SN;		/* Source in FIFO */
+ 	if (dtp->dev_flags & DEV_FLAGS_OUT)
+-		cmd0 |= DSCR_CMD0_DN;		/* Destination out fifo */
++		cmd0 |= DSCR_CMD0_DN;		/* Destination out FIFO */
+ 
+-	/* Set up source1.  For now, assume no stride and increment.
++	/*
++	 * Set up source1.  For now, assume no stride and increment.
+ 	 * A channel attribute update can change this later.
+ 	 */
+ 	switch (stp->dev_tsize) {
+@@ -485,19 +477,19 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 		break;
+ 	}
+ 
+-	/* If source input is fifo, set static address.
+-	*/
++	/* If source input is FIFO, set static address.	*/
+ 	if (stp->dev_flags & DEV_FLAGS_IN) {
+-		if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
++		if (stp->dev_flags & DEV_FLAGS_BURSTABLE)
+ 			src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
+ 		else
+-		src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+-
++			src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+ 	}
++
+ 	if (stp->dev_physaddr)
+ 		src0 = stp->dev_physaddr;
+ 
+-	/* Set up dest1.  For now, assume no stride and increment.
++	/*
++	 * Set up dest1.  For now, assume no stride and increment.
+ 	 * A channel attribute update can change this later.
+ 	 */
+ 	switch (dtp->dev_tsize) {
+@@ -516,22 +508,24 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 		break;
+ 	}
+ 
+-	/* If destination output is fifo, set static address.
+-	*/
++	/* If destination output is FIFO, set static address. */
+ 	if (dtp->dev_flags & DEV_FLAGS_OUT) {
+-		if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
+-	                dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+-				else
+-		dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
++		if (dtp->dev_flags & DEV_FLAGS_BURSTABLE)
++			dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
++		else
++			dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+ 	}
++
+ 	if (dtp->dev_physaddr)
+ 		dest0 = dtp->dev_physaddr;
+ 
+ #if 0
+-		printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+-			dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
++		printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x "
++				  "source1:%x dest0:%x dest1:%x\n",
++				  dtp->dev_id, stp->dev_id, cmd0, cmd1, src0,
++				  src1, dest0, dest1);
+ #endif
+-	for (i=0; i<entries; i++) {
++	for (i = 0; i < entries; i++) {
+ 		dp->dscr_cmd0 = cmd0;
+ 		dp->dscr_cmd1 = cmd1;
+ 		dp->dscr_source0 = src0;
+@@ -545,49 +539,49 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+ 		dp++;
+ 	}
+ 
+-	/* Make last descrptor point to the first.
+-	*/
++	/* Make last descrptor point to the first. */
+ 	dp--;
+ 	dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
+ 	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+ 
+-	return (u32)(ctp->chan_desc_base);
++	return (u32)ctp->chan_desc_base;
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
+ 
+-/* Put a source buffer into the DMA ring.
++/*
++ * Put a source buffer into the DMA ring.
+  * This updates the source pointer and byte count.  Normally used
+  * for memory to fifo transfers.
+  */
+-u32
+-_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
++u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+ {
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+ 
+-	/* I guess we could check this to be within the
++	/*
++	 * I guess we could check this to be within the
+ 	 * range of the table......
+ 	 */
+-	ctp = *((chan_tab_t **)chanid);
++	ctp = *(chan_tab_t **)chanid;
+ 
+-	/* We should have multiple callers for a particular channel,
++	/*
++	 * We should have multiple callers for a particular channel,
+ 	 * an interrupt doesn't affect this pointer nor the descriptor,
+ 	 * so no locking should be needed.
+ 	 */
+ 	dp = ctp->put_ptr;
+ 
+-	/* If the descriptor is valid, we are way ahead of the DMA
++	/*
++	 * If the descriptor is valid, we are way ahead of the DMA
+ 	 * engine, so just return an error condition.
+ 	 */
+-	if (dp->dscr_cmd0 & DSCR_CMD0_V) {
++	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ 		return 0;
+-	}
+ 
+-	/* Load up buffer address and byte count.
+-	*/
++	/* Load up buffer address and byte count. */
+ 	dp->dscr_source0 = virt_to_phys(buf);
+ 	dp->dscr_cmd1 = nbytes;
+-	/* Check flags  */
++	/* Check flags */
+ 	if (flags & DDMA_FLAGS_IE)
+ 		dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ 	if (flags & DDMA_FLAGS_NOIE)
+@@ -595,23 +589,21 @@ _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+ 
+ 	/*
+ 	 * There is an errata on the Au1200/Au1550 parts that could result
+-	 * in "stale" data being DMA'd. It has to do with the snoop logic on
+-	 * the dache eviction buffer.  NONCOHERENT_IO is on by default for
+-	 * these parts. If it is fixedin the future, these dma_cache_inv will
++	 * in "stale" data being DMA'ed. It has to do with the snoop logic on
++	 * the cache eviction buffer.  DMA_NONCOHERENT is on by default for
++	 * these parts. If it is fixed in the future, these dma_cache_inv will
+ 	 * just be nothing more than empty macros. See io.h.
+-	 * */
++	 */
+ 	dma_cache_wback_inv((unsigned long)buf, nbytes);
+-        dp->dscr_cmd0 |= DSCR_CMD0_V;        /* Let it rip */
++	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+ 	au_sync();
+ 	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+-        ctp->chan_ptr->ddma_dbell = 0;
++	ctp->chan_ptr->ddma_dbell = 0;
+ 
+-	/* Get next descriptor pointer.
+-	*/
++	/* Get next descriptor pointer.	*/
+ 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 
+-	/* return something not zero.
+-	*/
++	/* Return something non-zero. */
+ 	return nbytes;
+ }
+ EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
+@@ -654,81 +646,77 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
+ 	dp->dscr_dest0 = virt_to_phys(buf);
+ 	dp->dscr_cmd1 = nbytes;
+ #if 0
+-	printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+-			dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+-			dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
++	printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
++			  dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
++			  dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
+ #endif
+ 	/*
+ 	 * There is an errata on the Au1200/Au1550 parts that could result in
+-	 * "stale" data being DMA'd. It has to do with the snoop logic on the
+-	 * dache eviction buffer. NONCOHERENT_IO is on by default for these
+-	 * parts. If it is fixedin the future, these dma_cache_inv will just
++	 * "stale" data being DMA'ed. It has to do with the snoop logic on the
++	 * cache eviction buffer.  DMA_NONCOHERENT is on by default for these
++	 * parts. If it is fixed in the future, these dma_cache_inv will just
+ 	 * be nothing more than empty macros. See io.h.
+-	 * */
++	 */
+ 	dma_cache_inv((unsigned long)buf, nbytes);
+ 	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+ 	au_sync();
+ 	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
+-        ctp->chan_ptr->ddma_dbell = 0;
++	ctp->chan_ptr->ddma_dbell = 0;
+ 
+-	/* Get next descriptor pointer.
+-	*/
++	/* Get next descriptor pointer.	*/
+ 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 
+-	/* return something not zero.
+-	*/
++	/* Return something non-zero. */
+ 	return nbytes;
+ }
+ EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
+ 
+-/* Get a destination buffer into the DMA ring.
++/*
++ * Get a destination buffer into the DMA ring.
+  * Normally used to get a full buffer from the ring during fifo
+  * to memory transfers.  This does not set the valid bit, you will
+  * have to put another destination buffer to keep the DMA going.
+  */
+-u32
+-au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
++u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+ {
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+ 	u32			rv;
+ 
+-	/* I guess we could check this to be within the
++	/*
++	 * I guess we could check this to be within the
+ 	 * range of the table......
+ 	 */
+ 	ctp = *((chan_tab_t **)chanid);
+ 
+-	/* We should have multiple callers for a particular channel,
++	/*
++	 * We should have multiple callers for a particular channel,
+ 	 * an interrupt doesn't affect this pointer nor the descriptor,
+ 	 * so no locking should be needed.
+ 	 */
+ 	dp = ctp->get_ptr;
+ 
+-	/* If the descriptor is valid, we are way ahead of the DMA
++	/*
++	 * If the descriptor is valid, we are way ahead of the DMA
+ 	 * engine, so just return an error condition.
+ 	 */
+ 	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ 		return 0;
+ 
+-	/* Return buffer address and byte count.
+-	*/
++	/* Return buffer address and byte count. */
+ 	*buf = (void *)(phys_to_virt(dp->dscr_dest0));
+ 	*nbytes = dp->dscr_cmd1;
+ 	rv = dp->dscr_stat;
+ 
+-	/* Get next descriptor pointer.
+-	*/
++	/* Get next descriptor pointer.	*/
+ 	ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 
+-	/* return something not zero.
+-	*/
++	/* Return something non-zero. */
+ 	return rv;
+ }
+-
+ EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest);
+ 
+-void
+-au1xxx_dbdma_stop(u32 chanid)
++void au1xxx_dbdma_stop(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+ 	au1x_dma_chan_t *cp;
+@@ -743,7 +731,7 @@ au1xxx_dbdma_stop(u32 chanid)
+ 		udelay(1);
+ 		halt_timeout++;
+ 		if (halt_timeout > 100) {
+-			printk("warning: DMA channel won't halt\n");
++			printk(KERN_WARNING "warning: DMA channel won't halt\n");
+ 			break;
+ 		}
+ 	}
+@@ -753,12 +741,12 @@ au1xxx_dbdma_stop(u32 chanid)
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_stop);
+ 
+-/* Start using the current descriptor pointer.  If the dbdma encounters
+- * a not valid descriptor, it will stop.  In this case, we can just
++/*
++ * Start using the current descriptor pointer.  If the DBDMA encounters
++ * a non-valid descriptor, it will stop.  In this case, we can just
+  * continue by adding a buffer to the list and starting again.
+  */
+-void
+-au1xxx_dbdma_start(u32 chanid)
++void au1xxx_dbdma_start(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+ 	au1x_dma_chan_t *cp;
+@@ -773,8 +761,7 @@ au1xxx_dbdma_start(u32 chanid)
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_start);
+ 
+-void
+-au1xxx_dbdma_reset(u32 chanid)
++void au1xxx_dbdma_reset(u32 chanid)
+ {
+ 	chan_tab_t		*ctp;
+ 	au1x_ddma_desc_t	*dp;
+@@ -784,14 +771,14 @@ au1xxx_dbdma_reset(u32 chanid)
+ 	ctp = *((chan_tab_t **)chanid);
+ 	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+ 
+-	/* Run through the descriptors and reset the valid indicator.
+-	*/
++	/* Run through the descriptors and reset the valid indicator. */
+ 	dp = ctp->chan_desc_base;
+ 
+ 	do {
+ 		dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+-		/* reset our SW status -- this is used to determine
+-		 * if a descriptor is in use by upper level SW. Since
++		/*
++		 * Reset our software status -- this is used to determine
++		 * if a descriptor is in use by upper level software. Since
+ 		 * posting can reset 'V' bit.
+ 		 */
+ 		dp->sw_status = 0;
+@@ -800,8 +787,7 @@ au1xxx_dbdma_reset(u32 chanid)
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_reset);
+ 
+-u32
+-au1xxx_get_dma_residue(u32 chanid)
++u32 au1xxx_get_dma_residue(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+ 	au1x_dma_chan_t *cp;
+@@ -810,18 +796,15 @@ au1xxx_get_dma_residue(u32 chanid)
+ 	ctp = *((chan_tab_t **)chanid);
+ 	cp = ctp->chan_ptr;
+ 
+-	/* This is only valid if the channel is stopped.
+-	*/
++	/* This is only valid if the channel is stopped. */
+ 	rv = cp->ddma_bytecnt;
+ 	au_sync();
+ 
+ 	return rv;
+ }
+-
+ EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue);
+ 
+-void
+-au1xxx_dbdma_chan_free(u32 chanid)
++void au1xxx_dbdma_chan_free(u32 chanid)
+ {
+ 	chan_tab_t	*ctp;
+ 	dbdev_tab_t	*stp, *dtp;
+@@ -842,8 +825,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
+ }
+ EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
+ 
+-static irqreturn_t
+-dbdma_interrupt(int irq, void *dev_id)
++static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
+ {
+ 	u32 intstat;
+ 	u32 chan_index;
+@@ -859,13 +841,12 @@ dbdma_interrupt(int irq, void *dev_id)
+ 	cp = ctp->chan_ptr;
+ 	dp = ctp->cur_ptr;
+ 
+-	/* Reset interrupt.
+-	*/
++	/* Reset interrupt. */
+ 	cp->ddma_irq = 0;
+ 	au_sync();
+ 
+ 	if (ctp->chan_callback)
+-		(ctp->chan_callback)(irq, ctp->chan_callparam);
++		ctp->chan_callback(irq, ctp->chan_callparam);
+ 
+ 	ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 	return IRQ_RETVAL(1);
+@@ -890,47 +871,47 @@ static void au1xxx_dbdma_init(void)
+ 
+ 	if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
+ 			"Au1xxx dbdma", (void *)dbdma_gptr))
+-		printk("Can't get 1550 dbdma irq");
++		printk(KERN_ERR "Can't get 1550 dbdma irq");
+ }
+ 
+-void
+-au1xxx_dbdma_dump(u32 chanid)
++void au1xxx_dbdma_dump(u32 chanid)
+ {
+-	chan_tab_t		*ctp;
+-	au1x_ddma_desc_t	*dp;
+-	dbdev_tab_t		*stp, *dtp;
+-	au1x_dma_chan_t *cp;
+-		u32			i = 0;
++	chan_tab_t	 *ctp;
++	au1x_ddma_desc_t *dp;
++	dbdev_tab_t	 *stp, *dtp;
++	au1x_dma_chan_t  *cp;
++	u32 i		 = 0;
+ 
+ 	ctp = *((chan_tab_t **)chanid);
+ 	stp = ctp->chan_src;
+ 	dtp = ctp->chan_dest;
+ 	cp = ctp->chan_ptr;
+ 
+-	printk("Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+-		(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
+-	printk("desc base %x, get %x, put %x, cur %x\n",
+-		(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+-		(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+-
+-	printk("dbdma chan %x\n", (u32)cp);
+-	printk("cfg %08x, desptr %08x, statptr %08x\n",
+-		cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+-	printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+-		cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
+-
+-
+-	/* Run through the descriptors
+-	*/
++	printk(KERN_DEBUG "Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
++			  (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
++			  dtp - dbdev_tab);
++	printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
++			  (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
++			  (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
++
++	printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp);
++	printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n",
++			  cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
++	printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
++			  cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat,
++			  cp->ddma_bytecnt);
++
++	/* Run through the descriptors */
+ 	dp = ctp->chan_desc_base;
+ 
+ 	do {
+-                printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+-                        i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+-                printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+-                        dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
+-                printk("stat %08x, nxtptr %08x\n",
+-                        dp->dscr_stat, dp->dscr_nxtptr);
++		printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
++				  i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
++		printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
++				  dp->dscr_source0, dp->dscr_source1,
++				  dp->dscr_dest0, dp->dscr_dest1);
++		printk(KERN_DEBUG "stat %08x, nxtptr %08x\n",
++				  dp->dscr_stat, dp->dscr_nxtptr);
+ 		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 	} while (dp != ctp->chan_desc_base);
+ }
+@@ -938,32 +919,33 @@ au1xxx_dbdma_dump(u32 chanid)
+ /* Put a descriptor into the DMA ring.
+  * This updates the source/destination pointers and byte count.
+  */
+-u32
+-au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
++u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
+ {
+ 	chan_tab_t *ctp;
+ 	au1x_ddma_desc_t *dp;
+-	u32 nbytes=0;
++	u32 nbytes = 0;
+ 
+-	/* I guess we could check this to be within the
+-	* range of the table......
+-	*/
++	/*
++	 * I guess we could check this to be within the
++	 * range of the table......
++	 */
+ 	ctp = *((chan_tab_t **)chanid);
+ 
+-	/* We should have multiple callers for a particular channel,
+-	* an interrupt doesn't affect this pointer nor the descriptor,
+-	* so no locking should be needed.
+-	*/
++	/*
++	 * We should have multiple callers for a particular channel,
++	 * an interrupt doesn't affect this pointer nor the descriptor,
++	 * so no locking should be needed.
++	 */
+ 	dp = ctp->put_ptr;
+ 
+-	/* If the descriptor is valid, we are way ahead of the DMA
+-	* engine, so just return an error condition.
+-	*/
++	/*
++	 * If the descriptor is valid, we are way ahead of the DMA
++	 * engine, so just return an error condition.
++	 */
+ 	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ 		return 0;
+ 
+-	/* Load up buffer addresses and byte count.
+-	*/
++	/* Load up buffer addresses and byte count. */
+ 	dp->dscr_dest0 = dscr->dscr_dest0;
+ 	dp->dscr_source0 = dscr->dscr_source0;
+ 	dp->dscr_dest1 = dscr->dscr_dest1;
+@@ -975,14 +957,11 @@ au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
+ 	dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
+ 	ctp->chan_ptr->ddma_dbell = 0;
+ 
+-	/* Get next descriptor pointer.
+-	*/
++	/* Get next descriptor pointer.	*/
+ 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ 
+-	/* return something not zero.
+-	*/
++	/* Return something non-zero. */
+ 	return nbytes;
+ }
+ 
+ #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
+-
+diff --git a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c
+index eae1bb2..af5be7d 100644
+--- a/arch/mips/au1000/common/dbg_io.c
++++ b/arch/mips/au1000/common/dbg_io.c
+@@ -1,3 +1,4 @@
++#include <linux/types.h>
+ 
+ #include <asm/mach-au1x00/au1000.h>
+ 
+@@ -8,12 +9,6 @@
+  * uart to be used for debugging.
+  */
+ #define DEBUG_BASE  UART_DEBUG_BASE
+-/**/
+-
+-/* we need uint32 uint8 */
+-/* #include "types.h" */
+-typedef         unsigned char uint8;
+-typedef         unsigned int  uint32;
+ 
+ #define         UART16550_BAUD_2400             2400
+ #define         UART16550_BAUD_4800             4800
+@@ -51,17 +46,15 @@ typedef         unsigned int  uint32;
+ #define UART_MOD_CNTRL	0x100	/* Module Control */
+ 
+ /* memory-mapped read/write of the port */
+-#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
+-#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
++#define UART16550_READ(y)     (au_readl(DEBUG_BASE + y) & 0xff)
++#define UART16550_WRITE(y, z) (au_writel(z & 0xff, DEBUG_BASE + y))
+ 
+ extern unsigned long calc_clock(void);
+ 
+-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
++void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
+ {
+-
+-	if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
++	if (UART16550_READ(UART_MOD_CNTRL) != 0x3)
+ 		UART16550_WRITE(UART_MOD_CNTRL, 3);
+-	}
+ 	calc_clock();
+ 
+ 	/* disable interrupts */
+@@ -69,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+ 
+ 	/* set up baud rate */
+ 	{
+-		uint32 divisor;
++		u32 divisor;
+ 
+ 		/* set divisor */
+ 		divisor = get_au1x00_uart_baud_base() / baud;
+@@ -80,9 +73,9 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+ 	UART16550_WRITE(UART_LCR, (data | parity | stop));
+ }
+ 
+-static int remoteDebugInitialized = 0;
++static int remoteDebugInitialized;
+ 
+-uint8 getDebugChar(void)
++u8 getDebugChar(void)
+ {
+ 	if (!remoteDebugInitialized) {
+ 		remoteDebugInitialized = 1;
+@@ -92,15 +85,13 @@ uint8 getDebugChar(void)
+ 			  UART16550_STOP_1BIT);
+ 	}
+ 
+-	while((UART16550_READ(UART_LSR) & 0x1) == 0);
++	while ((UART16550_READ(UART_LSR) & 0x1) == 0);
+ 	return UART16550_READ(UART_RX);
+ }
+ 
+ 
+-int putDebugChar(uint8 byte)
++int putDebugChar(u8 byte)
+ {
+-//	int i;
+-
+ 	if (!remoteDebugInitialized) {
+ 		remoteDebugInitialized = 1;
+ 		debugInit(UART16550_BAUD_115200,
+@@ -109,9 +100,8 @@ int putDebugChar(uint8 byte)
+ 			  UART16550_STOP_1BIT);
+ 	}
+ 
+-	while ((UART16550_READ(UART_LSR)&0x40) == 0);
++	while ((UART16550_READ(UART_LSR) & 0x40) == 0);
+ 	UART16550_WRITE(UART_TX, byte);
+-	//for (i=0;i<0xfff;i++);
+ 
+ 	return 1;
+ }
+diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
+index 95f69ea..d6fbda2 100644
+--- a/arch/mips/au1000/common/dma.c
++++ b/arch/mips/au1000/common/dma.c
+@@ -1,12 +1,11 @@
+ /*
+  *
+  * BRIEF MODULE DESCRIPTION
+- *      A DMA channel allocator for Au1000. API is modeled loosely off of
++ *      A DMA channel allocator for Au1x00. API is modeled loosely off of
+  *      linux/kernel/dma.c.
+  *
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	stevel at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  * Copyright (C) 2005 Ralf Baechle (ralf at linux-mips.org)
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+@@ -39,7 +38,8 @@
+ #include <asm/mach-au1x00/au1000.h>
+ #include <asm/mach-au1x00/au1000_dma.h>
+ 
+-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
++#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
++    defined(CONFIG_SOC_AU1100)
+ /*
+  * A note on resource allocation:
+  *
+@@ -56,7 +56,6 @@
+  * returned from request_dma.
+  */
+ 
+-
+ DEFINE_SPINLOCK(au1000_dma_spin_lock);
+ 
+ struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
+@@ -71,7 +70,7 @@ struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
+ };
+ EXPORT_SYMBOL(au1000_dma_table);
+ 
+-// Device FIFO addresses and default DMA modes
++/* Device FIFO addresses and default DMA modes */
+ static const struct dma_dev {
+ 	unsigned int fifo_addr;
+ 	unsigned int dma_mode;
+@@ -80,8 +79,8 @@ static const struct dma_dev {
+ 	{UART0_ADDR + UART_RX, 0},
+ 	{0, 0},
+ 	{0, 0},
+-	{AC97C_DATA, DMA_DW16 },          // coherent
+-	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
++	{AC97C_DATA, DMA_DW16 },          /* coherent */
++	{AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
+ 	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
+ 	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
+ 	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
+@@ -101,10 +100,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+ 	struct dma_chan *chan;
+ 
+ 	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+-		if ((chan = get_dma_chan(i)) != NULL) {
++		chan = get_dma_chan(i);
++		if (chan != NULL)
+ 			len += sprintf(buf + len, "%2d: %s\n",
+ 				       i, chan->dev_str);
+-		}
+ 	}
+ 
+ 	if (fpos >= len) {
+@@ -113,18 +112,19 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+ 		return 0;
+ 	}
+ 	*start = buf + fpos;
+-	if ((len -= fpos) > length)
++	len -= fpos;
++	if (len > length)
+ 		return length;
+ 	*eof = 1;
+ 	return len;
+ }
+ 
+-// Device FIFO addresses and default DMA modes - 2nd bank
++/* Device FIFO addresses and default DMA modes - 2nd bank */
+ static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
+-	{SD0_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+-	{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},	// coherent
+-	{SD1_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+-	{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}	// coherent
++	{ SD0_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
++	{ SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 },	/* coherent */
++	{ SD1_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
++	{ SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }	/* coherent */
+ };
+ 
+ void dump_au1000_dma_channel(unsigned int dmanr)
+@@ -150,7 +150,6 @@ void dump_au1000_dma_channel(unsigned int dmanr)
+ 	       au_readl(chan->io + DMA_BUFFER1_COUNT));
+ }
+ 
+-
+ /*
+  * Finds a free channel, and binds the requested device to it.
+  * Returns the allocated channel number, or negative on error.
+@@ -169,14 +168,14 @@ int request_au1000_dma(int dev_id, const char *dev_str,
+ 	if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
+ 		return -EINVAL;
+ #else
+- 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
++	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+ 		return -EINVAL;
+ #endif
+ 
+-	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
++	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
+ 		if (au1000_dma_table[i].dev_id < 0)
+ 			break;
+-	}
++
+ 	if (i == NUM_AU1000_DMA_CHANNELS)
+ 		return -ENODEV;
+ 
+@@ -185,15 +184,15 @@ int request_au1000_dma(int dev_id, const char *dev_str,
+ 	if (dev_id >= DMA_NUM_DEV) {
+ 		dev_id -= DMA_NUM_DEV;
+ 		dev = &dma_dev_table_bank2[dev_id];
+-	} else {
++	} else
+ 		dev = &dma_dev_table[dev_id];
+-	}
+ 
+ 	if (irqhandler) {
+ 		chan->irq = AU1000_DMA_INT_BASE + i;
+ 		chan->irq_dev = irq_dev_id;
+-		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+-				       dev_str, chan->irq_dev))) {
++		ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
++				  chan->irq_dev);
++		if (ret) {
+ 			chan->irq = 0;
+ 			chan->irq_dev = NULL;
+ 			return ret;
+@@ -203,7 +202,7 @@ int request_au1000_dma(int dev_id, const char *dev_str,
+ 		chan->irq_dev = NULL;
+ 	}
+ 
+-	// fill it in
++	/* fill it in */
+ 	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
+ 	chan->dev_id = dev_id;
+ 	chan->dev_str = dev_str;
+@@ -220,8 +219,9 @@ EXPORT_SYMBOL(request_au1000_dma);
+ void free_au1000_dma(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan) {
+-		printk("Trying to free DMA%d\n", dmanr);
++		printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
+ 		return;
+ 	}
+ 
+@@ -235,4 +235,4 @@ void free_au1000_dma(unsigned int dmanr)
+ }
+ EXPORT_SYMBOL(free_au1000_dma);
+ 
+-#endif // AU1000 AU1500 AU1100
++#endif /* AU1000 AU1500 AU1100 */
+diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
+index 5254525..b485d94 100644
+--- a/arch/mips/au1000/common/gpio.c
++++ b/arch/mips/au1000/common/gpio.c
+@@ -69,7 +69,7 @@ static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
+ 
+ static int au1xxx_gpio1_read(unsigned gpio)
+ {
+-	return ((gpio1->pinstaterd >> gpio) & 0x01);
++	return (gpio1->pinstaterd >> gpio) & 0x01;
+ }
+ 
+ static void au1xxx_gpio1_write(unsigned gpio, int value)
+@@ -104,7 +104,6 @@ int au1xxx_gpio_get_value(unsigned gpio)
+ 	else
+ 		return au1xxx_gpio1_read(gpio);
+ }
+-
+ EXPORT_SYMBOL(au1xxx_gpio_get_value);
+ 
+ void au1xxx_gpio_set_value(unsigned gpio, int value)
+@@ -118,7 +117,6 @@ void au1xxx_gpio_set_value(unsigned gpio, int value)
+ 	else
+ 		au1xxx_gpio1_write(gpio, value);
+ }
+-
+ EXPORT_SYMBOL(au1xxx_gpio_set_value);
+ 
+ int au1xxx_gpio_direction_input(unsigned gpio)
+@@ -132,7 +130,6 @@ int au1xxx_gpio_direction_input(unsigned gpio)
+ 
+ 	return au1xxx_gpio1_direction_input(gpio);
+ }
+-
+ EXPORT_SYMBOL(au1xxx_gpio_direction_input);
+ 
+ int au1xxx_gpio_direction_output(unsigned gpio, int value)
+@@ -146,5 +143,4 @@ int au1xxx_gpio_direction_output(unsigned gpio, int value)
+ 
+ 	return au1xxx_gpio1_direction_output(gpio, value);
+ }
+-
+ EXPORT_SYMBOL(au1xxx_gpio_direction_output);
+diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
+index f062699..40c6cec 100644
+--- a/arch/mips/au1000/common/irq.c
++++ b/arch/mips/au1000/common/irq.c
+@@ -210,10 +210,8 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
+ 	au_sync();
+ }
+ 
+-
+ static inline void mask_and_ack_level_irq(unsigned int irq_nr)
+ {
+-
+ 	local_disable_irq(irq_nr);
+ 	au_sync();
+ #if defined(CONFIG_MIPS_PB1000)
+@@ -263,14 +261,14 @@ void restore_local_and_enable(int controller, unsigned long mask)
+ 	unsigned long flags, new_mask;
+ 
+ 	spin_lock_irqsave(&irq_lock, flags);
+-	for (i = 0; i < 32; i++) {
++	for (i = 0; i < 32; i++)
+ 		if (mask & (1 << i)) {
+ 			if (controller)
+ 				local_enable_irq(i + 32);
+ 			else
+ 				local_enable_irq(i);
+ 		}
+-	}
++
+ 	if (controller)
+ 		new_mask = au_readl(IC1_MASKSET);
+ 	else
+diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c
+index 7e966b3..7866cf5 100644
+--- a/arch/mips/au1000/common/pci.c
++++ b/arch/mips/au1000/common/pci.c
+@@ -2,9 +2,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	Alchemy/AMD Au1x00 PCI support.
+  *
+- * Copyright 2001-2003, 2007 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  * Copyright (C) 2004 by Ralf Baechle (ralf at linux-mips.org)
+  *
+@@ -86,9 +85,9 @@ static int __init au1x_pci_setup(void)
+ 		u32 prid = read_c0_prid();
+ 
+ 		if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
+-		       au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
+-			         Au1500_PCI_CFG);
+-		       printk("Non-coherent PCI accesses enabled\n");
++			au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
++				  Au1500_PCI_CFG);
++			printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
+ 		}
+ 	}
+ #endif
+diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
+index 31d2a22..8cae775 100644
+--- a/arch/mips/au1000/common/platform.c
++++ b/arch/mips/au1000/common/platform.c
+@@ -269,8 +269,8 @@ static struct platform_device au1x00_pcmcia_device = {
+ #ifdef SMBUS_PSC_BASE
+ static struct resource pbdb_smbus_resources[] = {
+ 	{
+-		.start	= SMBUS_PSC_BASE,
+-		.end	= SMBUS_PSC_BASE + 0x24 - 1,
++		.start	= CPHYSADDR(SMBUS_PSC_BASE),
++		.end	= CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ };
+@@ -302,16 +302,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ #endif
+ };
+ 
+-int __init au1xxx_platform_init(void)
++static int __init au1xxx_platform_init(void)
+ {
+ 	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
+ 	int i;
+ 
+ 	/* Fill up uartclk. */
+-	for (i = 0; au1x00_uart_data[i].flags ; i++)
++	for (i = 0; au1x00_uart_data[i].flags; i++)
+ 		au1x00_uart_data[i].uartclk = uartclk;
+ 
+-	return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
++	return platform_add_devices(au1xxx_platform_devices,
++				    ARRAY_SIZE(au1xxx_platform_devices));
+ }
+ 
+ arch_initcall(au1xxx_platform_init);
+diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
+index a8cd2c1..2166b9e 100644
+--- a/arch/mips/au1000/common/power.c
++++ b/arch/mips/au1000/common/power.c
+@@ -1,10 +1,9 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Au1000 Power Management routines.
++ *	Au1xx0 Power Management routines.
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *		ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  Some of the routines are right out of init/main.c, whose
+  *  copyrights apply here.
+@@ -43,10 +42,10 @@
+ #ifdef CONFIG_PM
+ 
+ #define DEBUG 1
+-#ifdef DEBUG
+-#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __func__, ## args)
++#ifdef	DEBUG
++#define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
+ #else
+-#  define DPRINTK(fmt, args...)
++#define DPRINTK(fmt, args...)
+ #endif
+ 
+ static void au1000_calibrate_delay(void);
+@@ -57,7 +56,8 @@ extern void local_enable_irq(unsigned int irq_nr);
+ 
+ static DEFINE_SPINLOCK(pm_lock);
+ 
+-/* We need to save/restore a bunch of core registers that are
++/*
++ * We need to save/restore a bunch of core registers that are
+  * either volatile or reset to some state across a processor sleep.
+  * If reading a register doesn't provide a proper result for a
+  * later restore, we have to provide a function for loading that
+@@ -78,24 +78,25 @@ static unsigned int	sleep_usbhost_enable;
+ static unsigned int	sleep_usbdev_enable;
+ static unsigned int	sleep_static_memctlr[4][3];
+ 
+-/* Define this to cause the value you write to /proc/sys/pm/sleep to
++/*
++ * Define this to cause the value you write to /proc/sys/pm/sleep to
+  * set the TOY timer for the amount of time you want to sleep.
+  * This is done mainly for testing, but may be useful in other cases.
+  * The value is number of 32KHz ticks to sleep.
+  */
+ #define SLEEP_TEST_TIMEOUT 1
+-#ifdef SLEEP_TEST_TIMEOUT
+-static	int	sleep_ticks;
++#ifdef	SLEEP_TEST_TIMEOUT
++static int sleep_ticks;
+ void wakeup_counter0_set(int ticks);
+ #endif
+ 
+-static void
+-save_core_regs(void)
++static void save_core_regs(void)
+ {
+ 	extern void save_au1xxx_intctl(void);
+ 	extern void pm_eth0_shutdown(void);
+ 
+-	/* Do the serial ports.....these really should be a pm_*
++	/*
++	 * Do the serial ports.....these really should be a pm_*
+ 	 * registered function by the driver......but of course the
+ 	 * standard serial driver doesn't understand our Au1xxx
+ 	 * unique registers.
+@@ -106,27 +107,24 @@ save_core_regs(void)
+ 	sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
+ 	sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
+ 
+-	/* Shutdown USB host/device.
+-	*/
++	/* Shutdown USB host/device. */
+ 	sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
+ 
+-	/* There appears to be some undocumented reset register....
+-	*/
++	/* There appears to be some undocumented reset register.... */
+ 	au_writel(0, 0xb0100004); au_sync();
+ 	au_writel(0, USB_HOST_CONFIG); au_sync();
+ 
+ 	sleep_usbdev_enable = au_readl(USBD_ENABLE);
+ 	au_writel(0, USBD_ENABLE); au_sync();
+ 
+-	/* Save interrupt controller state.
+-	*/
++	/* Save interrupt controller state. */
+ 	save_au1xxx_intctl();
+ 
+-	/* Clocks and PLLs.
+-	*/
++	/* Clocks and PLLs. */
+ 	sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
+ 
+-	/* We don't really need to do this one, but unless we
++	/*
++	 * We don't really need to do this one, but unless we
+ 	 * write it again it won't have a valid value if we
+ 	 * happen to read it.
+ 	 */
+@@ -134,8 +132,7 @@ save_core_regs(void)
+ 
+ 	sleep_pin_function = au_readl(SYS_PINFUNC);
+ 
+-	/* Save the static memory controller configuration.
+-	*/
++	/* Save the static memory controller configuration. */
+ 	sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
+ 	sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
+ 	sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
+@@ -150,8 +147,7 @@ save_core_regs(void)
+ 	sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
+ }
+ 
+-static void
+-restore_core_regs(void)
++static void restore_core_regs(void)
+ {
+ 	extern void restore_au1xxx_intctl(void);
+ 	extern void wakeup_counter0_adjust(void);
+@@ -160,8 +156,7 @@ restore_core_regs(void)
+ 	au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
+ 	au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
+ 
+-	/* Restore the static memory controller configuration.
+-	*/
++	/* Restore the static memory controller configuration. */
+ 	au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
+ 	au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
+ 	au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
+@@ -175,7 +170,8 @@ restore_core_regs(void)
+ 	au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
+ 	au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
+ 
+-	/* Enable the UART if it was enabled before sleep.
++	/*
++	 * Enable the UART if it was enabled before sleep.
+ 	 * I guess I should define module control bits........
+ 	 */
+ 	if (sleep_uart0_enable & 0x02) {
+@@ -202,7 +198,7 @@ void wakeup_from_suspend(void)
+ int au_sleep(void)
+ {
+ 	unsigned long wakeup, flags;
+-	extern	void	save_and_sleep(void);
++	extern void save_and_sleep(void);
+ 
+ 	spin_lock_irqsave(&pm_lock, flags);
+ 
+@@ -210,23 +206,22 @@ int au_sleep(void)
+ 
+ 	flush_cache_all();
+ 
+-	/** The code below is all system dependent and we should probably
++	/**
++	 ** The code below is all system dependent and we should probably
+ 	 ** have a function call out of here to set this up.  You need
+ 	 ** to configure the GPIO or timer interrupts that will bring
+ 	 ** you out of sleep.
+ 	 ** For testing, the TOY counter wakeup is useful.
+ 	 **/
+-
+ #if 0
+ 	au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
+ 
+-	/* gpio 6 can cause a wake up event */
++	/* GPIO 6 can cause a wake up event */
+ 	wakeup = au_readl(SYS_WAKEMSK);
+ 	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
+-	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
++	wakeup |= 1 << 6;	/* turn on  GPIO  6 wakeup */
+ #else
+-	/* For testing, allow match20 to wake us up.
+-	*/
++	/* For testing, allow match20 to wake us up. */
+ #ifdef SLEEP_TEST_TIMEOUT
+ 	wakeup_counter0_set(sleep_ticks);
+ #endif
+@@ -240,7 +235,8 @@ int au_sleep(void)
+ 
+ 	save_and_sleep();
+ 
+-	/* after a wakeup, the cpu vectors back to 0x1fc00000 so
++	/*
++	 * After a wakeup, the cpu vectors back to 0x1fc00000, so
+ 	 * it's up to the boot code to get us back here.
+ 	 */
+ 	restore_core_regs();
+@@ -248,24 +244,22 @@ int au_sleep(void)
+ 	return 0;
+ }
+ 
+-static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
+-		       void __user *buffer, size_t * len, loff_t *ppos)
++static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
++		       void __user *buffer, size_t *len, loff_t *ppos)
+ {
+ #ifdef SLEEP_TEST_TIMEOUT
+ #define TMPBUFLEN2 16
+ 	char buf[TMPBUFLEN2], *p;
+ #endif
+ 
+-	if (!write) {
++	if (!write)
+ 		*len = 0;
+-	} else {
++	else {
+ #ifdef SLEEP_TEST_TIMEOUT
+-		if (*len > TMPBUFLEN2 - 1) {
++		if (*len > TMPBUFLEN2 - 1)
+ 			return -EFAULT;
+-		}
+-		if (copy_from_user(buf, buffer, *len)) {
++		if (copy_from_user(buf, buffer, *len))
+ 			return -EFAULT;
+-		}
+ 		buf[*len] = 0;
+ 		p = buf;
+ 		sleep_ticks = simple_strtoul(p, &p, 0);
+@@ -276,8 +270,8 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
+ 	return 0;
+ }
+ 
+-static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+-		      void __user *buffer, size_t * len, loff_t *ppos)
++static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
++		      void __user *buffer, size_t *len, loff_t *ppos)
+ {
+ 	int retval = 0, i;
+ 	unsigned long val, pll;
+@@ -285,14 +279,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+ #define MAX_CPU_FREQ 396
+ 	char buf[TMPBUFLEN], *p;
+ 	unsigned long flags, intc0_mask, intc1_mask;
+-	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
+-	    old_refresh;
++	unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
+ 	unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
++	unsigned long baud_rate;
+ 
+ 	spin_lock_irqsave(&pm_lock, flags);
+-	if (!write) {
++	if (!write)
+ 		*len = 0;
+-	} else {
++	else {
+ 		/* Parse the new frequency */
+ 		if (*len > TMPBUFLEN - 1) {
+ 			spin_unlock_irqrestore(&pm_lock, flags);
+@@ -312,7 +306,7 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+ 
+ 		pll = val / 12;
+ 		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */
+-			/* revisit this for higher speed cpus */
++			/* Revisit this for higher speed CPUs */
+ 			spin_unlock_irqrestore(&pm_lock, flags);
+ 			return -EFAULT;
+ 		}
+@@ -321,30 +315,28 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+ 		old_cpu_freq = get_au1x00_speed();
+ 
+ 		new_cpu_freq = pll * 12 * 1000000;
+-	        new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
++	        new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
++							    & 0x03) + 2) * 16));
+ 		set_au1x00_speed(new_cpu_freq);
+ 		set_au1x00_uart_baud_base(new_baud_base);
+ 
+ 		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
+-		new_refresh =
+-		    ((old_refresh * new_cpu_freq) /
+-		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
++		new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
++			      (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
+ 
+ 		au_writel(pll, SYS_CPUPLL);
+ 		au_sync_delay(1);
+ 		au_writel(new_refresh, MEM_SDREFCFG);
+ 		au_sync_delay(1);
+ 
+-		for (i = 0; i < 4; i++) {
+-			if (au_readl
+-			    (UART_BASE + UART_MOD_CNTRL +
+-			     i * 0x00100000) == 3) {
+-				old_clk =
+-				    au_readl(UART_BASE + UART_CLK +
+-					  i * 0x00100000);
+-				// baud_rate = baud_base/clk
++		for (i = 0; i < 4; i++)
++			if (au_readl(UART_BASE + UART_MOD_CNTRL +
++				     i * 0x00100000) == 3) {
++				old_clk = au_readl(UART_BASE + UART_CLK +
++						   i * 0x00100000);
+ 				baud_rate = old_baud_base / old_clk;
+-				/* we won't get an exact baud rate and the error
++				/*
++				 * We won't get an exact baud rate and the error
+ 				 * could be significant enough that our new
+ 				 * calculation will result in a clock that will
+ 				 * give us a baud rate that's too far off from
+@@ -359,18 +351,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+ 				else if (baud_rate > 17000)
+ 					baud_rate = 19200;
+ 				else
+-					(baud_rate = 9600);
+-				// new_clk = new_baud_base/baud_rate
++					baud_rate = 9600;
+ 				new_clk = new_baud_base / baud_rate;
+-				au_writel(new_clk,
+-				       UART_BASE + UART_CLK +
+-				       i * 0x00100000);
++				au_writel(new_clk, UART_BASE + UART_CLK +
++					  i * 0x00100000);
+ 				au_sync_delay(10);
+ 			}
+-		}
+ 	}
+ 
+-
+ 	/*
+ 	 * We don't want _any_ interrupts other than match20. Otherwise our
+ 	 * au1000_calibrate_delay() calculation will be off, potentially a lot.
+@@ -428,14 +416,15 @@ static int __init pm_init(void)
+ 
+ __initcall(pm_init);
+ 
+-
+ /*
+  * This is right out of init/main.c
+  */
+ 
+-/* This is the number of bits of precision for the loops_per_jiffy.  Each
+-   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
+-   better than 1% */
++/*
++ * This is the number of bits of precision for the loops_per_jiffy.
++ * Each bit takes on average 1.5/HZ seconds.  This (like the original)
++ * is a little better than 1%.
++ */
+ #define LPS_PREC 8
+ 
+ static void au1000_calibrate_delay(void)
+@@ -443,14 +432,14 @@ static void au1000_calibrate_delay(void)
+ 	unsigned long ticks, loopbit;
+ 	int lps_precision = LPS_PREC;
+ 
+-	loops_per_jiffy = (1 << 12);
++	loops_per_jiffy = 1 << 12;
+ 
+ 	while (loops_per_jiffy <<= 1) {
+-		/* wait for "start of" clock tick */
++		/* Wait for "start of" clock tick */
+ 		ticks = jiffies;
+ 		while (ticks == jiffies)
+ 			/* nothing */ ;
+-		/* Go .. */
++		/* Go ... */
+ 		ticks = jiffies;
+ 		__delay(loops_per_jiffy);
+ 		ticks = jiffies - ticks;
+@@ -458,8 +447,10 @@ static void au1000_calibrate_delay(void)
+ 			break;
+ 	}
+ 
+-/* Do a binary approximation to get loops_per_jiffy set to equal one clock
+-   (up to lps_precision bits) */
++	/*
++	 * Do a binary approximation to get loops_per_jiffy set to be equal
++	 * one clock (up to lps_precision bits)
++	 */
+ 	loops_per_jiffy >>= 1;
+ 	loopbit = loops_per_jiffy;
+ 	while (lps_precision-- && (loopbit >>= 1)) {
+@@ -472,4 +463,4 @@ static void au1000_calibrate_delay(void)
+ 			loops_per_jiffy &= ~loopbit;
+ 	}
+ }
+-#endif				/* CONFIG_PM */
++#endif	/* CONFIG_PM */
+diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
+index f10af82..18b310b 100644
+--- a/arch/mips/au1000/common/prom.c
++++ b/arch/mips/au1000/common/prom.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *    PROM library initialisation code, supports YAMON and U-Boot.
+  *
+- * Copyright 2000, 2001, 2006 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  * This file was derived from Carsten Langgaard's
+  * arch/mips/mips-boards/xx files.
+@@ -57,7 +56,7 @@ void prom_init_cmdline(void)
+ 	actr = 1; /* Always ignore argv[0] */
+ 
+ 	cp = &(arcs_cmdline[0]);
+-	while(actr < prom_argc) {
++	while (actr < prom_argc) {
+ 		strcpy(cp, prom_argv[actr]);
+ 		cp += strlen(prom_argv[actr]);
+ 		*cp++ = ' ';
+@@ -84,10 +83,8 @@ char *prom_getenv(char *envname)
+ 		if (yamon) {
+ 			if (strcmp(envname, *env++) == 0)
+ 				return *env;
+-		} else {
+-			if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+-				return *env + i + 1;
+-		}
++		} else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
++			return *env + i + 1;
+ 		env++;
+ 	}
+ 
+@@ -110,13 +107,13 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+ {
+ 	int i;
+ 
+-	for(i = 0; i < 6; i++) {
++	for (i = 0; i < 6; i++) {
+ 		unsigned char num;
+ 
+-		if((*str == '.') || (*str == ':'))
++		if ((*str == '.') || (*str == ':'))
+ 			str++;
+-		num = str2hexnum(*str++) << 4;
+-		num |= (str2hexnum(*str++));
++		num  = str2hexnum(*str++) << 4;
++		num |= str2hexnum(*str++);
+ 		ea[i] = num;
+ 	}
+ }
+diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
+index e34c67e..55bbe24 100644
+--- a/arch/mips/au1000/common/puts.c
++++ b/arch/mips/au1000/common/puts.c
+@@ -1,11 +1,10 @@
+ /*
+  *
+  * BRIEF MODULE DESCRIPTION
+- *	Low level uart routines to directly access a 16550 uart.
++ *	Low level UART routines to directly access Alchemy UART.
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -40,12 +39,12 @@
+ 
+ static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
+ 
+-
+ #ifdef SLOW_DOWN
+ static inline void slow_down(void)
+ {
+-    int k;
+-    for (k=0; k<10000; k++);
++	int k;
++
++	for (k = 0; k < 10000; k++);
+ }
+ #else
+ #define slow_down()
+@@ -54,16 +53,16 @@ static inline void slow_down(void)
+ void
+ prom_putchar(const unsigned char c)
+ {
+-    unsigned char ch;
+-    int i = 0;
++	unsigned char ch;
++	int i = 0;
++
++	do {
++		ch = com1[SER_CMD];
++		slow_down();
++		i++;
++		if (i > TIMEOUT)
++			break;
++	} while (0 == (ch & TX_BUSY));
+ 
+-    do {
+-        ch = com1[SER_CMD];
+-        slow_down();
+-        i++;
+-        if (i>TIMEOUT) {
+-            break;
+-        }
+-    } while (0 == (ch & TX_BUSY));
+-    com1[SER_DATA] = c;
++	com1[SER_DATA] = c;
+ }
+diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c
+index 60cec53..d555429 100644
+--- a/arch/mips/au1000/common/reset.c
++++ b/arch/mips/au1000/common/reset.c
+@@ -1,11 +1,10 @@
+ /*
+  *
+  * BRIEF MODULE DESCRIPTION
+- *	Au1000 reset routines.
++ *	Au1xx0 reset routines.
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2006, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -28,10 +27,11 @@
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
++#include <asm/cacheflush.h>
++
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ extern int au_sleep(void);
+-extern void (*flush_cache_all)(void);
+ 
+ void au1000_restart(char *command)
+ {
+@@ -40,8 +40,8 @@ void au1000_restart(char *command)
+ 	u32 prid = read_c0_prid();
+ 
+ 	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
+-	switch (prid & 0xFF000000)
+-	{
++
++	switch (prid & 0xFF000000) {
+ 	case 0x00000000: /* Au1000 */
+ 		au_writel(0x02, 0xb0000010); /* ac97_enable */
+ 		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+@@ -138,9 +138,6 @@ void au1000_restart(char *command)
+ 		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+ 		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+ 		break;
+-
+-	default:
+-		break;
+ 	}
+ 
+ 	set_c0_status(ST0_BEV | ST0_ERL);
+@@ -158,25 +155,25 @@ void au1000_restart(char *command)
+ void au1000_halt(void)
+ {
+ #if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
+-	/* power off system */
+-	printk("\n** Powering off...\n");
+-	au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
++	/* Power off system */
++	printk(KERN_NOTICE "\n** Powering off...\n");
++	au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
+ 	au_sync();
+-	while(1); /* should not get here */
++	while (1); /* should not get here */
+ #else
+ 	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+ #ifdef CONFIG_MIPS_MIRAGE
+ 	au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
+ #endif
+ #ifdef CONFIG_MIPS_DB1200
+-	au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C);
++	au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
+ #endif
+ #ifdef CONFIG_PM
+ 	au_sleep();
+ 
+-	/* should not get here */
+-	printk(KERN_ERR "Unable to put cpu in sleep mode\n");
+-	while(1);
++	/* Should not get here */
++	printk(KERN_ERR "Unable to put CPU in sleep mode\n");
++	while (1);
+ #else
+ 	while (1)
+ 		__asm__(".set\tmips3\n\t"
+diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
+index 0e86f7a..1ac6b06 100644
+--- a/arch/mips/au1000/common/setup.c
++++ b/arch/mips/au1000/common/setup.c
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000, 2007-2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com
+  *
+  * Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
+  *
+@@ -48,7 +47,7 @@ void __init plat_mem_setup(void)
+ {
+ 	struct	cpu_spec *sp;
+ 	char *argptr;
+-	unsigned long prid, cpufreq, bclk = 1;
++	unsigned long prid, cpufreq, bclk;
+ 
+ 	set_cpuspec();
+ 	sp = cur_cpu_spec[0];
+@@ -66,42 +65,39 @@ void __init plat_mem_setup(void)
+ 		cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
+ 	printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
+ 
+-	bclk = sp->cpu_bclk;
+-	if (bclk)
+-	{
++	if (sp->cpu_bclk) {
+ 		/* Enable BCLK switching */
+-		bclk = au_readl(0xB190003C);
+-		au_writel(bclk | 0x60, 0xB190003C);
+-		printk("BCLK switching enabled!\n");
++		bclk = au_readl(SYS_POWERCTRL);
++		au_writel(bclk | 0x60, SYS_POWERCTRL);
++		printk(KERN_INFO "BCLK switching enabled!\n");
+ 	}
+ 
+-	if (sp->cpu_od) {
+-		/* Various early Au1000 Errata corrected by this */
+-		set_c0_config(1<<19); /* Set Config[OD] */
+-	}
+-	else {
++	if (sp->cpu_od)
++		/* Various early Au1xx0 errata corrected by this */
++		set_c0_config(1 << 19); /* Set Config[OD] */
++	else
+ 		/* Clear to obtain best system bus performance */
+-		clear_c0_config(1<<19); /* Clear Config[OD] */
+-	}
++		clear_c0_config(1 << 19); /* Clear Config[OD] */
+ 
+ 	argptr = prom_getcmdline();
+ 
+ #ifdef CONFIG_SERIAL_8250_CONSOLE
+-	if ((argptr = strstr(argptr, "console=")) == NULL) {
++	argptr = strstr(argptr, "console=");
++	if (argptr == NULL) {
+ 		argptr = prom_getcmdline();
+ 		strcat(argptr, " console=ttyS0,115200");
+ 	}
+ #endif
+ 
+ #ifdef CONFIG_FB_AU1100
+-    if ((argptr = strstr(argptr, "video=")) == NULL) {
+-        argptr = prom_getcmdline();
+-        /* default panel */
+-        /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+-    }
++	argptr = strstr(argptr, "video=");
++	if (argptr == NULL) {
++		argptr = prom_getcmdline();
++		/* default panel */
++		/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
++	}
+ #endif
+ 
+-
+ #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
+ 	/* au1000 does not support vra, au1500 and au1100 do */
+ 	strcat(argptr, " au1000_audio=vra");
+@@ -129,7 +125,7 @@ void __init plat_mem_setup(void)
+ /* This routine should be valid for all Au1x based boards */
+ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+ {
+-	/* Don't fixup 36 bit addresses */
++	/* Don't fixup 36-bit addresses */
+ 	if ((phys_addr >> 32) != 0)
+ 		return phys_addr;
+ 
+@@ -145,17 +141,17 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+ 	}
+ #endif
+ 
+-	/* All Au1x SOCs have a pcmcia controller */
+-	/* We setup our 32 bit pseudo addresses to be equal to the
+-	 * 36 bit addr >> 4, to make it easier to check the address
++	/*
++	 * All Au1xx0 SOCs have a PCMCIA controller.
++	 * We setup our 32-bit pseudo addresses to be equal to the
++	 * 36-bit addr >> 4, to make it easier to check the address
+ 	 * and fix it.
+-	 * The Au1x socket 0 phys attribute address is 0xF 4000 0000.
++	 * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
+ 	 * The pseudo address we use is 0xF400 0000. Any address over
+-	 * 0xF400 0000 is a pcmcia pseudo address.
++	 * 0xF400 0000 is a PCMCIA pseudo address.
+ 	 */
+-	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) {
++	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
+ 		return (phys_t)(phys_addr << 4);
+-	}
+ 
+ 	/* default nop */
+ 	return phys_addr;
+diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
+index bdb6d73..563d939 100644
+--- a/arch/mips/au1000/common/time.c
++++ b/arch/mips/au1000/common/time.c
+@@ -25,11 +25,9 @@
+  *
+  * Setting up the clock on the MIPS boards.
+  *
+- * Update.  Always configure the kernel with CONFIG_NEW_TIME_C.  This
+- * will use the user interface gettimeofday() functions from the
+- * arch/mips/kernel/time.c, and we provide the clock interrupt processing
+- * and the timer offset compute functions.  If CONFIG_PM is selected,
+- * we also ensure the 32KHz timer is available.   -- Dan
++ * We provide the clock interrupt processing and the timer offset compute
++ * functions.  If CONFIG_PM is selected, we also ensure the 32KHz timer is
++ * available.  -- Dan
+  */
+ 
+ #include <linux/types.h>
+@@ -47,8 +45,7 @@ extern int allow_au1k_wait; /* default off for CP0 Counter */
+ #if HZ < 100 || HZ > 1000
+ #error "unsupported HZ value! Must be in [100,1000]"
+ #endif
+-#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
+-extern void startup_match20_interrupt(irq_handler_t handler);
++#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */
+ static unsigned long last_pc0, last_match20;
+ #endif
+ 
+@@ -61,7 +58,7 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
+ {
+ 	unsigned long pc0;
+ 	int time_elapsed;
+-	static int jiffie_drift = 0;
++	static int jiffie_drift;
+ 
+ 	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+ 		/* should never happen! */
+@@ -70,13 +67,11 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
+ 	}
+ 
+ 	pc0 = au_readl(SYS_TOYREAD);
+-	if (pc0 < last_match20) {
++	if (pc0 < last_match20)
+ 		/* counter overflowed */
+ 		time_elapsed = (0xffffffff - last_match20) + pc0;
+-	}
+-	else {
++	else
+ 		time_elapsed = pc0 - last_match20;
+-	}
+ 
+ 	while (time_elapsed > 0) {
+ 		do_timer(1);
+@@ -92,8 +87,9 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
+ 	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+ 	au_sync();
+ 
+-	/* our counter ticks at 10.009765625 ms/tick, we we're running
+-	 * almost 10uS too slow per tick.
++	/*
++	 * Our counter ticks at 10.009765625 ms/tick, we we're running
++	 * almost 10 uS too slow per tick.
+ 	 */
+ 
+ 	if (jiffie_drift >= 999) {
+@@ -117,20 +113,17 @@ struct irqaction counter0_action = {
+ /* When we wakeup from sleep, we have to "catch up" on all of the
+  * timer ticks we have missed.
+  */
+-void
+-wakeup_counter0_adjust(void)
++void wakeup_counter0_adjust(void)
+ {
+ 	unsigned long pc0;
+ 	int time_elapsed;
+ 
+ 	pc0 = au_readl(SYS_TOYREAD);
+-	if (pc0 < last_match20) {
++	if (pc0 < last_match20)
+ 		/* counter overflowed */
+ 		time_elapsed = (0xffffffff - last_match20) + pc0;
+-	}
+-	else {
++	else
+ 		time_elapsed = pc0 - last_match20;
+-	}
+ 
+ 	while (time_elapsed > 0) {
+ 		time_elapsed -= MATCH20_INC;
+@@ -143,10 +136,8 @@ wakeup_counter0_adjust(void)
+ 
+ }
+ 
+-/* This is just for debugging to set the timer for a sleep delay.
+-*/
+-void
+-wakeup_counter0_set(int ticks)
++/* This is just for debugging to set the timer for a sleep delay. */
++void wakeup_counter0_set(int ticks)
+ {
+ 	unsigned long pc0;
+ 
+@@ -157,21 +148,22 @@ wakeup_counter0_set(int ticks)
+ }
+ #endif
+ 
+-/* I haven't found anyone that doesn't use a 12 MHz source clock,
++/*
++ * I haven't found anyone that doesn't use a 12 MHz source clock,
+  * but just in case.....
+  */
+ #define AU1000_SRC_CLK	12000000
+ 
+ /*
+  * We read the real processor speed from the PLL.  This is important
+- * because it is more accurate than computing it from the 32KHz
++ * because it is more accurate than computing it from the 32 KHz
+  * counter, if it exists.  If we don't have an accurate processor
+  * speed, all of the peripherals that derive their clocks based on
+  * this advertised speed will introduce error and sometimes not work
+  * properly.  This function is futher convoluted to still allow configurations
+  * to do that in case they have really, really old silicon with a
+- * write-only PLL register, that we need the 32KHz when power management
+- * "wait" is enabled, and we need to detect if the 32KHz isn't present
++ * write-only PLL register, that we need the 32 KHz when power management
++ * "wait" is enabled, and we need to detect if the 32 KHz isn't present
+  * but requested......got it? :-)		-- Dan
+  */
+ unsigned long calc_clock(void)
+@@ -182,8 +174,7 @@ unsigned long calc_clock(void)
+ 
+ 	spin_lock_irqsave(&time_lock, flags);
+ 
+-	/* Power management cares if we don't have a 32KHz counter.
+-	*/
++	/* Power management cares if we don't have a 32 KHz counter. */
+ 	no_au1xxx_32khz = 0;
+ 	counter = au_readl(SYS_COUNTER_CNTRL);
+ 	if (counter & SYS_CNTRL_E0) {
+@@ -193,7 +184,7 @@ unsigned long calc_clock(void)
+ 
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+ 		/* RTC now ticks at 32.768/16 kHz */
+-		au_writel(trim_divide-1, SYS_RTCTRIM);
++		au_writel(trim_divide - 1, SYS_RTCTRIM);
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+ 
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+@@ -215,9 +206,11 @@ unsigned long calc_clock(void)
+ #endif
+ 	else
+ 		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
++	/* On Alchemy CPU:counter ratio is 1:1 */
+ 	mips_hpt_frequency = cpu_speed;
+-	// Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
+-	set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
++	/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
++	set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
++							  & 0x03) + 2) * 16));
+ 	spin_unlock_irqrestore(&time_lock, flags);
+ 	return cpu_speed;
+ }
+@@ -228,10 +221,10 @@ void __init plat_time_init(void)
+ 
+ 	est_freq += 5000;    /* round */
+ 	est_freq -= est_freq%10000;
+-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+-	       (est_freq%1000000)*100/1000000);
+- 	set_au1x00_speed(est_freq);
+- 	set_au1x00_lcd_clock(); // program the LCD clock
++	printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
++	       est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
++	set_au1x00_speed(est_freq);
++	set_au1x00_lcd_clock(); /* program the LCD clock */
+ 
+ #ifdef CONFIG_PM
+ 	/*
+@@ -243,30 +236,29 @@ void __init plat_time_init(void)
+ 	 * counter 0 interrupt as a special irq and it doesn't show
+ 	 * up under /proc/interrupts.
+ 	 *
+-	 * Check to ensure we really have a 32KHz oscillator before
++	 * Check to ensure we really have a 32 KHz oscillator before
+ 	 * we do this.
+ 	 */
+ 	if (no_au1xxx_32khz)
+-		printk("WARNING: no 32KHz clock found.\n");
++		printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
+ 	else {
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+ 		au_writel(0, SYS_TOYWRITE);
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+ 
+-		au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
++		au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
+ 		au_writel(~0, SYS_WAKESRC);
+ 		au_sync();
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+ 
+-		/* setup match20 to interrupt once every HZ */
++		/* Setup match20 to interrupt once every HZ */
+ 		last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
+ 		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+ 		au_sync();
+ 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+ 		setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
+ 
+-		/* We can use the real 'wait' instruction.
+-		*/
++		/* We can use the real 'wait' instruction. */
+ 		allow_au1k_wait = 1;
+ 	}
+ 
+diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile
+index 51d62bd..274db3b 100644
+--- a/arch/mips/au1000/db1x00/Makefile
++++ b/arch/mips/au1000/db1x00/Makefile
+@@ -1,8 +1,8 @@
+ #
+-#  Copyright 2000 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
++#
++# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
+ #
+-# Makefile for the Alchemy Semiconductor Db1x00 board.
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c
+index b7dcbad..9e5ccbb 100644
+--- a/arch/mips/au1000/db1x00/board_setup.c
++++ b/arch/mips/au1000/db1x00/board_setup.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	Alchemy Db1x00 board setup.
+  *
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -37,49 +36,49 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ 
+ void board_reset(void)
+ {
+-	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
++	/* Hit BCSR.SW_RESET[RESET] */
+ 	bcsr->swreset = 0x0000;
+ }
+ 
+ void __init board_setup(void)
+ {
+-	u32 pin_func;
++	u32 pin_func = 0;
+ 
+-	pin_func = 0;
+-	/* not valid for 1550 */
+-
+-#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+-	/* set IRFIRSEL instead of GPIO15 */
+-	pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
++	/* Not valid for Au1550 */
++#if defined(CONFIG_IRDA) && \
++   (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
++	/* Set IRFIRSEL instead of GPIO15 */
++	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
+ 	au_writel(pin_func, SYS_PINFUNC);
+-	/* power off until the driver is in use */
++	/* Power off until the driver is in use */
+ 	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
+-	bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
++	bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
+ 	au_sync();
+ #endif
+ 	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
+ 
+ #ifdef CONFIG_MIPS_MIRAGE
+-	/* enable GPIO[31:0] inputs */
++	/* Enable GPIO[31:0] inputs */
+ 	au_writel(0, SYS_PININPUTEN);
+ 
+-	/* GPIO[20] is output, tristate the other input primary GPIO's */
+-	au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
++	/* GPIO[20] is output, tristate the other input primary GPIOs */
++	au_writel(~(1 << 20), SYS_TRIOUTCLR);
+ 
+-	/* set GPIO[210:208] instead of SSI_0 */
+-	pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
++	/* Set GPIO[210:208] instead of SSI_0 */
++	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
+ 
+-	/* set GPIO[215:211] for LED's */
+-	pin_func |= (u32)((5<<2));
++	/* Set GPIO[215:211] for LEDs */
++	pin_func |= 5 << 2;
+ 
+-	/* set GPIO[214:213] for more LED's */
+-	pin_func |= (u32)((5<<12));
++	/* Set GPIO[214:213] for more LEDs */
++	pin_func |= 5 << 12;
+ 
+-	/* set GPIO[207:200] instead of PCMCIA/LCD */
+-	pin_func |= (u32)((3<<17));
++	/* Set GPIO[207:200] instead of PCMCIA/LCD */
++	pin_func |= SYS_PF_LCD | SYS_PF_PC;
+ 	au_writel(pin_func, SYS_PINFUNC);
+ 
+-	/* Enable speaker amplifier.  This should
++	/*
++	 * Enable speaker amplifier.  This should
+ 	 * be part of the audio driver.
+ 	 */
+ 	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
+@@ -89,21 +88,21 @@ void __init board_setup(void)
+ 	au_sync();
+ 
+ #ifdef CONFIG_MIPS_DB1000
+-    printk("AMD Alchemy Au1000/Db1000 Board\n");
++	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_DB1500
+-    printk("AMD Alchemy Au1500/Db1500 Board\n");
++	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_DB1100
+-    printk("AMD Alchemy Au1100/Db1100 Board\n");
++	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_BOSPORUS
+-    printk("AMD Alchemy Bosporus Board\n");
++	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_MIRAGE
+-    printk("AMD Alchemy Mirage Board\n");
++	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_DB1550
+-    printk("AMD Alchemy Au1550/Db1550 Board\n");
++	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
+ #endif
+ }
+diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
+index d3b967c..5ebe0de 100644
+--- a/arch/mips/au1000/db1x00/init.c
++++ b/arch/mips/au1000/db1x00/init.c
+@@ -2,9 +2,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	PB1000 board setup
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -49,8 +48,8 @@ void __init prom_init(void)
+ 	unsigned long memsize;
+ 
+ 	prom_argc = fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 
+@@ -58,6 +57,6 @@ void __init prom_init(void)
+ 	if (!memsize_str)
+ 		memsize = 0x04000000;
+ 	else
+-		memsize = simple_strtol(memsize_str, NULL, 0);
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
+index eaa50c7..94c090e 100644
+--- a/arch/mips/au1000/db1x00/irqmap.c
++++ b/arch/mips/au1000/db1x00/irqmap.c
+@@ -32,32 +32,32 @@
+ 
+ #ifdef CONFIG_MIPS_DB1500
+ char irq_tab_alchemy[][5] __initdata = {
+- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371   */
++	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
+ };
+ #endif
+ 
+ #ifdef CONFIG_MIPS_BOSPORUS
+ char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
+- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++	[11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI  */
++	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741   */
++	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
+ };
+ #endif
+ 
+ #ifdef CONFIG_MIPS_MIRAGE
+ char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
+- [12] =	{ -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
+- [13] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
++	[11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
++	[12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
++	[13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
+ };
+ #endif
+ 
+ #ifdef CONFIG_MIPS_DB1550
+ char irq_tab_alchemy[][5] __initdata = {
+- [11] =	{ -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
+- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
++	[11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
++	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
++	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+ };
+ #endif
+ 
+diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile
+index 85a9094..7c67b3d 100644
+--- a/arch/mips/au1000/mtx-1/Makefile
++++ b/arch/mips/au1000/mtx-1/Makefile
+@@ -1,7 +1,6 @@
+ #
+ #  Copyright 2003 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #       Bruno Randolf <bruno.randolf at 4g-systems.biz>
+ #
+ # Makefile for 4G Systems MTX-1 board.
+diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c
+index 5736354..3f80791 100644
+--- a/arch/mips/au1000/mtx-1/board_setup.c
++++ b/arch/mips/au1000/mtx-1/board_setup.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	4G Systems MTX-1 board setup.
+  *
+- * Copyright 2003 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2003, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *         Bruno Randolf <bruno.randolf at 4g-systems.biz>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+@@ -34,7 +33,7 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ extern int (*board_pci_idsel)(unsigned int devsel, int assert);
+-int    mtx1_pci_idsel(unsigned int devsel, int assert);
++int mtx1_pci_idsel(unsigned int devsel, int assert);
+ 
+ void board_reset(void)
+ {
+@@ -45,36 +44,36 @@ void board_reset(void)
+ void __init board_setup(void)
+ {
+ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+-	// enable USB power switch
+-	au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
+-	au_writel( 0x100000, GPIO2_OUTPUT );
++	/* Enable USB power switch */
++	au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
++	au_writel(0x100000, GPIO2_OUTPUT);
+ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+ 
+ #ifdef CONFIG_PCI
+ #if defined(__MIPSEB__)
+-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
++	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+ #else
+ 	au_writel(0xf, Au1500_PCI_CFG);
+ #endif
+ #endif
+ 
+-	// initialize sys_pinfunc:
+-	au_writel( SYS_PF_NI2, SYS_PINFUNC );
++	/* Initialize sys_pinfunc */
++	au_writel(SYS_PF_NI2, SYS_PINFUNC);
+ 
+-	// initialize GPIO
+-	au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR );
+-	au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF
+-	au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF
+-	au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
+-	au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF
++	/* Initialize GPIO */
++	au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
++	au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */
++	au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */
++	au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
++	au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */
+ 
+-	// enable LED and set it to green
+-	au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR );
+-	au_writel( 0x18000800, GPIO2_OUTPUT );
++	/* Enable LED and set it to green */
++	au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR);
++	au_writel(0x18000800, GPIO2_OUTPUT);
+ 
+ 	board_pci_idsel = mtx1_pci_idsel;
+ 
+-	printk("4G Systems MTX-1 Board\n");
++	printk(KERN_INFO "4G Systems MTX-1 Board\n");
+ }
+ 
+ int
+@@ -82,20 +81,18 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
+ {
+ #define MTX_IDSEL_ONLY_0_AND_3 0
+ #if MTX_IDSEL_ONLY_0_AND_3
+-       if (devsel != 0 && devsel != 3) {
+-               printk("*** not 0 or 3\n");
+-               return 0;
+-       }
++	if (devsel != 0 && devsel != 3) {
++		printk(KERN_ERR "*** not 0 or 3\n");
++		return 0;
++	}
+ #endif
+ 
+-       if (assert && devsel != 0) {
+-               // suppress signal to cardbus
+-               au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF
+-       }
+-       else {
+-               au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
+-       }
+-       au_sync_udelay(1);
+-       return 1;
++	if (assert && devsel != 0)
++		/* Suppress signal to Cardbus */
++		au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */
++	else
++		au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
++	au_sync_udelay(1);
++	return 1;
+ }
+ 
+diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
+index c015cbc..33a4aeb 100644
+--- a/arch/mips/au1000/mtx-1/init.c
++++ b/arch/mips/au1000/mtx-1/init.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	4G Systems MTX-1 board setup
+  *
+- * Copyright 2003 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2003, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *         Bruno Randolf <bruno.randolf at 4g-systems.biz>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+@@ -47,8 +46,8 @@ void __init prom_init(void)
+ 	unsigned long memsize;
+ 
+ 	prom_argc = fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 
+@@ -56,6 +55,6 @@ void __init prom_init(void)
+ 	if (!memsize_str)
+ 		memsize = 0x04000000;
+ 	else
+-		memsize = simple_strtol(memsize_str, NULL, 0);
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
+index 78d70c4..f2bf029 100644
+--- a/arch/mips/au1000/mtx-1/irqmap.c
++++ b/arch/mips/au1000/mtx-1/irqmap.c
+@@ -31,18 +31,18 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ char irq_tab_alchemy[][5] __initdata = {
+- [0] = { -1, INTA, INTA, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
+- [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+- [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
+- [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+- [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
+- [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+- [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
+- [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
++	[0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
++	[1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
++	[2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
++	[3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
++	[4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
++	[5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
++	[6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
++	[7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+ };
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
++       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
+        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+        { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+        { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
+index a7edbf0..9807be3 100644
+--- a/arch/mips/au1000/mtx-1/platform.c
++++ b/arch/mips/au1000/mtx-1/platform.c
+@@ -21,11 +21,10 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+ #include <linux/leds.h>
++#include <linux/gpio.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/input.h>
+ 
+-#include <asm/gpio.h>
+-
+ static struct gpio_keys_button mtx1_gpio_button[] = {
+ 	{
+ 		.gpio = 207,
+diff --git a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile
+index daa1a50..99bbec0 100644
+--- a/arch/mips/au1000/pb1000/Makefile
++++ b/arch/mips/au1000/pb1000/Makefile
+@@ -1,8 +1,8 @@
+ #
+-#  Copyright 2000 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
++#
++# Makefile for the Alchemy Semiconductor Pb1000 board.
+ #
+-# Makefile for the Alchemy Semiconductor PB1000 board.
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c
+index 33f15ac..25df167 100644
+--- a/arch/mips/au1000/pb1000/board_setup.c
++++ b/arch/mips/au1000/pb1000/board_setup.c
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -40,128 +39,126 @@ void __init board_setup(void)
+ 	u32 sys_freqctrl, sys_clksrc;
+ 	u32 prid = read_c0_prid();
+ 
+-	// set AUX clock to 12MHz * 8 = 96 MHz
++	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ 	au_writel(8, SYS_AUXPLL);
+ 	au_writel(0, SYS_PINSTATERD);
+ 	udelay(100);
+ 
+ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+-	/* zero and disable FREQ2 */
++	/* Zero and disable FREQ2 */
+ 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 	sys_freqctrl &= ~0xFFF00000;
+ 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+-	/* zero and disable USBH/USBD clocks */
++	/* Zero and disable USBH/USBD clocks */
+ 	sys_clksrc = au_readl(SYS_CLKSRC);
+-	sys_clksrc &= ~0x00007FE0;
++	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
++		        SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ 	au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+ 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 	sys_freqctrl &= ~0xFFF00000;
+ 
+ 	sys_clksrc = au_readl(SYS_CLKSRC);
+-	sys_clksrc &= ~0x00007FE0;
++	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
++		        SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ 
+-	switch (prid & 0x000000FF)
+-	{
++	switch (prid & 0x000000FF) {
+ 	case 0x00: /* DA */
+ 	case 0x01: /* HA */
+ 	case 0x02: /* HB */
+-	/* CPU core freq to 48MHz to slow it way down... */
+-	au_writel(4, SYS_CPUPLL);
++		/* CPU core freq to 48 MHz to slow it way down... */
++		au_writel(4, SYS_CPUPLL);
+ 
+-	/*
+-	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
+-	 */
+-	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+-	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
++		/*
++		 * Setup 48 MHz FREQ2 from CPUPLL for USB Host
++		 * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
++		 */
++		sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
++		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+-	/* CPU core freq to 384MHz */
+-	au_writel(0x20, SYS_CPUPLL);
++		/* CPU core freq to 384 MHz */
++		au_writel(0x20, SYS_CPUPLL);
+ 
+-	printk("Au1000: 48MHz OHCI workaround enabled\n");
++		printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
+ 		break;
+ 
+-	default:  /* HC and newer */
+-	// FREQ2 = aux/2 = 48 MHz
+-	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
++	default: /* HC and newer */
++		/* FREQ2 = aux / 2 = 48 MHz */
++		sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
++				 SYS_FC_FE2 | SYS_FC_FS2;
++		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 		break;
+ 	}
+ 
+ 	/*
+-	 * Route 48MHz FREQ2 into USB Host and/or Device
++	 * Route 48 MHz FREQ2 into USB Host and/or Device
+ 	 */
+-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+-	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+-#endif
++	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
+ 	au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+-	// configure pins GPIO[14:9] as GPIO
+-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
++	/* Configure pins GPIO[14:9] as GPIO */
++	pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
+ 
+-	// 2nd USB port is USB host
+-	pin_func |= 0x8000;
++	/* 2nd USB port is USB host */
++	pin_func |= SYS_PF_USB;
+ 
+ 	au_writel(pin_func, SYS_PINFUNC);
+ 	au_writel(0x2800, SYS_TRIOUTCLR);
+ 	au_writel(0x0030, SYS_OUTPUTCLR);
+ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+ 
+-	// make gpio 15 an input (for interrupt line)
+-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
+-	// we don't need I2S, so make it available for GPIO[31:29]
+-	pin_func |= (1<<5);
++	/* Make GPIO 15 an input (for interrupt line) */
++	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
++	/* We don't need I2S, so make it available for GPIO[31:29] */
++	pin_func |= SYS_PF_I2S;
+ 	au_writel(pin_func, SYS_PINFUNC);
+ 
+ 	au_writel(0x8000, SYS_TRIOUTCLR);
+ 
+-	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
++	static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
+ 	au_writel(static_cfg0, MEM_STCFG0);
+ 
+-	// configure RCE2* for LCD
++	/* configure RCE2* for LCD */
+ 	au_writel(0x00000004, MEM_STCFG2);
+ 
+-	// MEM_STTIME2
++	/* MEM_STTIME2 */
+ 	au_writel(0x09000000, MEM_STTIME2);
+ 
+-	// Set 32-bit base address decoding for RCE2*
++	/* Set 32-bit base address decoding for RCE2* */
+ 	au_writel(0x10003ff0, MEM_STADDR2);
+ 
+-	// PCI CPLD setup
+-	// expand CE0 to cover PCI
++	/*
++	 * PCI CPLD setup
++	 * Expand CE0 to cover PCI
++	 */
+ 	au_writel(0x11803e40, MEM_STADDR1);
+ 
+-	// burst visibility on
++	/* Burst visibility on */
+ 	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+ 
+-	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+-	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
++	au_writel(0x83, MEM_STCFG1);	     /* ewait enabled, flash timing */
++	au_writel(0x33030a10, MEM_STTIME1);  /* slower timing for FPGA */
+ 
+-	/* setup the static bus controller */
++	/* Setup the static bus controller */
+ 	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+ 	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+ 	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+ 
+-#ifdef CONFIG_PCI
+-	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+-	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+-	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
+-	au_sync_delay(1);
+-#endif
+-
+-	/* Enable Au1000 BCLK switching - note: sed1356 must not use
+-	 * its BCLK (Au1000 LCLK) for any timings */
+-	switch (prid & 0x000000FF)
+-	{
++	/*
++	 * Enable Au1000 BCLK switching - note: sed1356 must not use
++	 * its BCLK (Au1000 LCLK) for any timings
++	 */
++	switch (prid & 0x000000FF) {
+ 	case 0x00: /* DA */
+ 	case 0x01: /* HA */
+ 	case 0x02: /* HB */
+ 		break;
+ 	default:  /* HC and newer */
+-		/* Enable sys bus clock divider when IDLE state or no bus
+-		   activity. */
++		/*
++		 * Enable sys bus clock divider when IDLE state or no bus
++		 * activity.
++		 */
+ 		au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+ 		break;
+ 	}
+diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
+index 549447d..3837365 100644
+--- a/arch/mips/au1000/pb1000/init.c
++++ b/arch/mips/au1000/pb1000/init.c
+@@ -1,10 +1,9 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	PB1000 board setup
++ *	Pb1000 board setup
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -44,16 +43,15 @@ void __init prom_init(void)
+ 	unsigned char *memsize_str;
+ 	unsigned long memsize;
+ 
+-	prom_argc = (int) fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argc = (int)fw_arg0;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
++	if (!memsize_str)
+ 		memsize = 0x04000000;
+-	} else {
+-		memsize = simple_strtol(memsize_str, NULL, 0);
+-	}
++	else
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/pb1100/Makefile b/arch/mips/au1000/pb1100/Makefile
+index 996236d..793e97c 100644
+--- a/arch/mips/au1000/pb1100/Makefile
++++ b/arch/mips/au1000/pb1100/Makefile
+@@ -1,8 +1,8 @@
+ #
+-#  Copyright 2000,2001 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #
+ # Makefile for the Alchemy Semiconductor Pb1100 board.
++#
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c
+index 656164c..c0bfd59 100644
+--- a/arch/mips/au1000/pb1100/board_setup.c
++++ b/arch/mips/au1000/pb1100/board_setup.c
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright 2002 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2002, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -32,15 +31,15 @@
+ 
+ void board_reset(void)
+ {
+-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+-    au_writel(0x00000000, 0xAE00001C);
++	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
++	au_writel(0x00000000, PB1100_RST_VDDI);
+ }
+ 
+ void __init board_setup(void)
+ {
+-	volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;
++	volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
+ 
+-	// set AUX clock to 12MHz * 8 = 96 MHz
++	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ 	au_writel(8, SYS_AUXPLL);
+ 	au_writel(0, SYS_PININPUTEN);
+ 	udelay(100);
+@@ -49,44 +48,47 @@ void __init board_setup(void)
+ 	{
+ 		u32 pin_func, sys_freqctrl, sys_clksrc;
+ 
+-		// configure pins GPIO[14:9] as GPIO
+-		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
++		/* Configure pins GPIO[14:9] as GPIO */
++		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
+ 
+-		/* zero and disable FREQ2 */
++		/* Zero and disable FREQ2 */
+ 		sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 		sys_freqctrl &= ~0xFFF00000;
+ 		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+-		/* zero and disable USBH/USBD/IrDA clock */
++		/* Zero and disable USBH/USBD/IrDA clock */
+ 		sys_clksrc = au_readl(SYS_CLKSRC);
+-		sys_clksrc &= ~0x0000001F;
++		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
+ 		au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+ 		sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 		sys_freqctrl &= ~0xFFF00000;
+ 
+ 		sys_clksrc = au_readl(SYS_CLKSRC);
+-		sys_clksrc &= ~0x0000001F;
++		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
+ 
+-		// FREQ2 = aux/2 = 48 MHz
+-		sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
++		/* FREQ2 = aux / 2 = 48 MHz */
++		sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
++				SYS_FC_FE2 | SYS_FC_FS2;
+ 		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+ 		/*
+-		 * Route 48MHz FREQ2 into USBH/USBD/IrDA
++		 * Route 48 MHz FREQ2 into USBH/USBD/IrDA
+ 		 */
+-		sys_clksrc |= ((4<<2) | (0<<1) | 0 );
++		sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
+ 		au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+-		/* setup the static bus controller */
++		/* Setup the static bus controller */
+ 		au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+ 		au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+ 		au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+ 
+-		// get USB Functionality pin state (device vs host drive pins)
+-		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+-		// 2nd USB port is USB host
+-		pin_func |= 0x8000;
++		/*
++		 * Get USB Functionality pin state (device vs host drive pins).
++		 */
++		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
++		/* 2nd USB port is USB host. */
++		pin_func |= SYS_PF_USB;
+ 		au_writel(pin_func, SYS_PINFUNC);
+ 	}
+ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+@@ -94,12 +96,12 @@ void __init board_setup(void)
+ 	/* Enable sys bus clock divider when IDLE state or no bus activity. */
+ 	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+ 
+-	// Enable the RTC if not already enabled
++	/* Enable the RTC if not already enabled. */
+ 	if (!(readb(base + 0x28) & 0x20)) {
+ 		writeb(readb(base + 0x28) | 0x20, base + 0x28);
+ 		au_sync();
+ 	}
+-	// Put the clock in BCD mode
++	/* Put the clock in BCD mode. */
+ 	if (readb(base + 0x2C) & 0x4) { /* reg B */
+ 		writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
+ 		au_sync();
+diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
+index c913446..8355483 100644
+--- a/arch/mips/au1000/pb1100/init.c
++++ b/arch/mips/au1000/pb1100/init.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	Pb1100 board setup
+  *
+- * Copyright 2002 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2002, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -46,8 +45,8 @@ void __init prom_init(void)
+ 	unsigned long memsize;
+ 
+ 	prom_argc = fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg3;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg3;
+ 
+ 	prom_init_cmdline();
+ 
+@@ -55,7 +54,7 @@ void __init prom_init(void)
+ 	if (!memsize_str)
+ 		memsize = 0x04000000;
+ 	else
+-		memsize = simple_strtol(memsize_str, NULL, 0);
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c
+index b5021e3..9b7dd8b 100644
+--- a/arch/mips/au1000/pb1100/irqmap.c
++++ b/arch/mips/au1000/pb1100/irqmap.c
+@@ -1,6 +1,6 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Au1xxx irq map table
++ *	Au1xx0 IRQ map table
+  *
+  * Copyright 2003 Embedded Edge, LLC
+  *		dan at embeddededge.com
+@@ -31,10 +31,10 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-	{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
+-	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
+-	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
+-	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
++	{ AU1000_GPIO_9,  INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
++	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
++	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
++	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
+ };
+ 
+ int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
+diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
+index 4fe02ea..d678adf 100644
+--- a/arch/mips/au1000/pb1200/Makefile
++++ b/arch/mips/au1000/pb1200/Makefile
+@@ -1,5 +1,5 @@
+ #
+-# Makefile for the Alchemy Semiconductor PB1200 board.
++# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
+ #
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
+index 4493a79..6cb2115 100644
+--- a/arch/mips/au1000/pb1200/board_setup.c
++++ b/arch/mips/au1000/pb1200/board_setup.c
+@@ -27,16 +27,8 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
+ 
+-#include <au1000.h>
+ #include <prom.h>
+-
+-#ifdef CONFIG_MIPS_PB1200
+-#include <asm/mach-pb1x00/pb1200.h>
+-#endif
+-
+-#ifdef CONFIG_MIPS_DB1200
+-#include <asm/mach-db1x00/db1200.h>
+-#endif
++#include <au1xxx.h>
+ 
+ extern void _board_init_irq(void);
+ extern void (*board_init_irq)(void);
+@@ -53,56 +45,57 @@ void __init board_setup(void)
+ 
+ #if 0
+ 	{
+-	u32 pin_func;
+-
+-	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+-	 * but it is board specific code, so put it here.
+-	 */
+-	pin_func = au_readl(SYS_PINFUNC);
+-	au_sync();
+-	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+-	au_writel(pin_func, SYS_PINFUNC);
+-
+-	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+-	au_sync();
++		u32 pin_func;
++
++		/*
++		 * Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
++		 * but it is board specific code, so put it here.
++		 */
++		pin_func = au_readl(SYS_PINFUNC);
++		au_sync();
++		pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
++		au_writel(pin_func, SYS_PINFUNC);
++
++		au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
++		au_sync();
+ 	}
+ #endif
+ 
+ #if defined(CONFIG_I2C_AU1550)
+ 	{
+-	u32 freq0, clksrc;
+-	u32 pin_func;
+-
+-	/* Select SMBUS in CPLD */
+-	bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
+-
+-	pin_func = au_readl(SYS_PINFUNC);
+-	au_sync();
+-	pin_func &= ~(3<<17 | 1<<4);
+-	/* Set GPIOs correctly */
+-	pin_func |= 2<<17;
+-	au_writel(pin_func, SYS_PINFUNC);
+-	au_sync();
+-
+-	/* The i2c driver depends on 50Mhz clock */
+-	freq0 = au_readl(SYS_FREQCTRL0);
+-	au_sync();
+-	freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+-	freq0 |= (3<<SYS_FC_FRDIV1_BIT);
+-	/* 396Mhz / (3+1)*2 == 49.5Mhz */
+-	au_writel(freq0, SYS_FREQCTRL0);
+-	au_sync();
+-	freq0 |= SYS_FC_FE1;
+-	au_writel(freq0, SYS_FREQCTRL0);
+-	au_sync();
+-
+-	clksrc = au_readl(SYS_CLKSRC);
+-	au_sync();
+-	clksrc &= ~0x01f00000;
+-	/* bit 22 is EXTCLK0 for PSC0 */
+-	clksrc |= (0x3 << 22);
+-	au_writel(clksrc, SYS_CLKSRC);
+-	au_sync();
++		u32 freq0, clksrc;
++		u32 pin_func;
++
++		/* Select SMBus in CPLD */
++		bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
++
++		pin_func = au_readl(SYS_PINFUNC);
++		au_sync();
++		pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
++		/* Set GPIOs correctly */
++		pin_func |= 2 << 17;
++		au_writel(pin_func, SYS_PINFUNC);
++		au_sync();
++
++		/* The I2C driver depends on 50 MHz clock */
++		freq0 = au_readl(SYS_FREQCTRL0);
++		au_sync();
++		freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
++		freq0 |= 3 << SYS_FC_FRDIV1_BIT;
++		/* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
++		au_writel(freq0, SYS_FREQCTRL0);
++		au_sync();
++		freq0 |= SYS_FC_FE1;
++		au_writel(freq0, SYS_FREQCTRL0);
++		au_sync();
++
++		clksrc = au_readl(SYS_CLKSRC);
++		au_sync();
++		clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
++		/* Bit 22 is EXTCLK0 for PSC0 */
++		clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
++		au_writel(clksrc, SYS_CLKSRC);
++		au_sync();
+ 	}
+ #endif
+ 
+@@ -116,27 +109,27 @@ void __init board_setup(void)
+ #endif
+ #endif
+ 
+-	/* The Pb1200 development board uses external MUX for PSC0 to
+-	support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+-	*/
++	/*
++	 * The Pb1200 development board uses external MUX for PSC0 to
++	 * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
++	 */
+ #ifdef CONFIG_I2C_AU1550
+-	bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
++	bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
+ #endif
+ 	au_sync();
+ 
+ #ifdef CONFIG_MIPS_PB1200
+-	printk("AMD Alchemy Pb1200 Board\n");
++	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
+ #endif
+ #ifdef CONFIG_MIPS_DB1200
+-	printk("AMD Alchemy Db1200 Board\n");
++	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
+ #endif
+ 
+ 	/* Setup Pb1200 External Interrupt Controller */
+ 	board_init_irq = _board_init_irq;
+ }
+ 
+-int
+-board_au1200fb_panel(void)
++int board_au1200fb_panel(void)
+ {
+ 	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ 	int p;
+@@ -147,23 +140,23 @@ board_au1200fb_panel(void)
+ 	return p;
+ }
+ 
+-int
+-board_au1200fb_panel_init(void)
++int board_au1200fb_panel_init(void)
+ {
+ 	/* Apply power */
+-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-	bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+-	/*printk("board_au1200fb_panel_init()\n"); */
++	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++
++	bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
++	/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
+ 	return 0;
+ }
+ 
+-int
+-board_au1200fb_panel_shutdown(void)
++int board_au1200fb_panel_shutdown(void)
+ {
+ 	/* Remove power */
+-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+-	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
+-	/*printk("board_au1200fb_panel_shutdown()\n"); */
++	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++
++	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
++			 BCSR_BOARD_LCDBL);
++	/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
+ 	return 0;
+ }
+-
+diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
+index 72af550..09fd63b 100644
+--- a/arch/mips/au1000/pb1200/init.c
++++ b/arch/mips/au1000/pb1200/init.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	PB1200 board setup
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -45,16 +44,15 @@ void __init prom_init(void)
+ 	unsigned char *memsize_str;
+ 	unsigned long memsize;
+ 
+-	prom_argc = (int) fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argc = (int)fw_arg0;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
++	if (!memsize_str)
+ 		memsize = 0x08000000;
+-	} else {
+-		memsize = simple_strtol(memsize_str, NULL, 0);
+-	}
++	else
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
+index e61eb8e..2a505ad 100644
+--- a/arch/mips/au1000/pb1200/irqmap.c
++++ b/arch/mips/au1000/pb1200/irqmap.c
+@@ -39,25 +39,25 @@
+ #endif
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-	{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
++	/* This is external interrupt cascade */
++	{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 },
+ };
+ 
+ int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
+ 
+ /*
+- *	Support for External interrupts on the PbAu1200 Development platform.
++ * Support for External interrupts on the Pb1200 Development platform.
+  */
+-static volatile int pb1200_cascade_en=0;
++static volatile int pb1200_cascade_en;
+ 
+-irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
++irqreturn_t pb1200_cascade_handler(int irq, void *dev_id)
+ {
+ 	unsigned short bisr = bcsr->int_status;
+ 	int extirq_nr = 0;
+ 
+-	/* Clear all the edge interrupts. This has no effect on level */
++	/* Clear all the edge interrupts. This has no effect on level. */
+ 	bcsr->int_status = bisr;
+-	for( ; bisr; bisr &= (bisr-1) )
+-	{
++	for ( ; bisr; bisr &= bisr - 1) {
+ 		extirq_nr = PB1200_INT_BEGIN + __ffs(bisr);
+ 		/* Ack and dispatch IRQ */
+ 		do_IRQ(extirq_nr);
+@@ -68,26 +68,20 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
+ 
+ inline void pb1200_enable_irq(unsigned int irq_nr)
+ {
+-	bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+-	bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
++	bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
++	bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
+ }
+ 
+ inline void pb1200_disable_irq(unsigned int irq_nr)
+ {
+-	bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
+-	bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
++	bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
++	bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
+ }
+ 
+ static unsigned int pb1200_setup_cascade(void)
+ {
+-	int err;
+-
+-	err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
+-			  0, "Pb1200 Cascade", &pb1200_cascade_handler);
+-	if (err)
+-		return err;
+-
+-	return 0;
++	return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
++			   0, "Pb1200 Cascade", &pb1200_cascade_handler);
+ }
+ 
+ static unsigned int pb1200_startup_irq(unsigned int irq)
+@@ -132,23 +126,23 @@ void _board_init_irq(void)
+ 	unsigned int irq;
+ 
+ #ifdef CONFIG_MIPS_PB1200
+-	/* We have a problem with CPLD rev3. Enable a workaround */
++	/* We have a problem with CPLD rev 3. */
+ 	if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
+-		printk("updated to latest revision. This software will not\n");
+-		printk("work on anything less than CPLD rev4\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
+-		printk("\nWARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
++		printk(KERN_ERR "updated to latest revision. This software will\n");
++		printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
++		printk(KERN_ERR "WARNING!!!\n");
+ 		panic("Game over.  Your score is 0.");
+ 	}
+ #endif
+@@ -161,6 +155,6 @@ void _board_init_irq(void)
+ 
+ 	/*
+ 	 * GPIO_7 can not be hooked here, so it is hooked upon first
+-	 * request of any source attached to the cascade
++	 * request of any source attached to the cascade.
+ 	 */
+ }
+diff --git a/arch/mips/au1000/pb1500/Makefile b/arch/mips/au1000/pb1500/Makefile
+index 97a7308..602f38d 100644
+--- a/arch/mips/au1000/pb1500/Makefile
++++ b/arch/mips/au1000/pb1500/Makefile
+@@ -1,8 +1,8 @@
+ #
+-#  Copyright 2000,2001 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #
+ # Makefile for the Alchemy Semiconductor Pb1500 board.
++#
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c
+index 24c652e..035771c 100644
+--- a/arch/mips/au1000/pb1500/board_setup.c
++++ b/arch/mips/au1000/pb1500/board_setup.c
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -32,8 +31,8 @@
+ 
+ void board_reset(void)
+ {
+-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+-    au_writel(0x00000000, 0xAE00001C);
++	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
++	au_writel(0x00000000, PB1500_RST_VDDI);
+ }
+ 
+ void __init board_setup(void)
+@@ -42,7 +41,7 @@ void __init board_setup(void)
+ 	u32 sys_freqctrl, sys_clksrc;
+ 
+ 	sys_clksrc = sys_freqctrl = pin_func = 0;
+-	// set AUX clock to 12MHz * 8 = 96 MHz
++	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ 	au_writel(8, SYS_AUXPLL);
+ 	au_writel(0, SYS_PINSTATERD);
+ 	udelay(100);
+@@ -51,51 +50,48 @@ void __init board_setup(void)
+ 
+ 	/* GPIO201 is input for PCMCIA card detect */
+ 	/* GPIO203 is input for PCMCIA interrupt request */
+-	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);
++	au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR);
+ 
+-	/* zero and disable FREQ2 */
++	/* Zero and disable FREQ2 */
+ 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 	sys_freqctrl &= ~0xFFF00000;
+ 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+ 	/* zero and disable USBH/USBD clocks */
+ 	sys_clksrc = au_readl(SYS_CLKSRC);
+-	sys_clksrc &= ~0x00007FE0;
++	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
++			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ 	au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+ 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ 	sys_freqctrl &= ~0xFFF00000;
+ 
+ 	sys_clksrc = au_readl(SYS_CLKSRC);
+-	sys_clksrc &= ~0x00007FE0;
++	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
++			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ 
+-	// FREQ2 = aux/2 = 48 MHz
+-	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
++	/* FREQ2 = aux/2 = 48 MHz */
++	sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
+ 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ 
+ 	/*
+ 	 * Route 48MHz FREQ2 into USB Host and/or Device
+ 	 */
+-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+-	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+-#endif
++	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
+ 	au_writel(sys_clksrc, SYS_CLKSRC);
+ 
+-
+-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+-	// 2nd USB port is USB host
+-	pin_func |= 0x8000;
++	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
++	/* 2nd USB port is USB host */
++	pin_func |= SYS_PF_USB;
+ 	au_writel(pin_func, SYS_PINFUNC);
+ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+ 
+-
+-
+ #ifdef CONFIG_PCI
+-	// Setup PCI bus controller
++	/* Setup PCI bus controller */
+ 	au_writel(0, Au1500_PCI_CMEM);
+ 	au_writel(0x00003fff, Au1500_CFG_BASE);
+ #if defined(__MIPSEB__)
+-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
++	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+ #else
+ 	au_writel(0xf, Au1500_PCI_CFG);
+ #endif
+@@ -112,11 +108,11 @@ void __init board_setup(void)
+ 
+ 	/* Enable the RTC if not already enabled */
+ 	if (!(au_readl(0xac000028) & 0x20)) {
+-		printk("enabling clock ...\n");
++		printk(KERN_INFO "enabling clock ...\n");
+ 		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
+ 	}
+ 	/* Put the clock in BCD mode */
+-	if (au_readl(0xac00002C) & 0x4) { /* reg B */
++	if (au_readl(0xac00002c) & 0x4) { /* reg B */
+ 		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
+ 		au_sync();
+ 	}
+diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
+index 488507c..49f51e1 100644
+--- a/arch/mips/au1000/pb1500/init.c
++++ b/arch/mips/au1000/pb1500/init.c
+@@ -1,11 +1,10 @@
+ /*
+  *
+  * BRIEF MODULE DESCRIPTION
+- *	PB1500 board setup
++ *	Pb1500 board setup
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -45,16 +44,15 @@ void __init prom_init(void)
+ 	unsigned char *memsize_str;
+ 	unsigned long memsize;
+ 
+-	prom_argc = (int) fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argc = (int)fw_arg0;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
++	if (!memsize_str)
+ 		memsize = 0x04000000;
+-	} else {
+-		memsize = simple_strtol(memsize_str, NULL, 0);
+-	}
++	else
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
+index 4817ab4..39c4682 100644
+--- a/arch/mips/au1000/pb1500/irqmap.c
++++ b/arch/mips/au1000/pb1500/irqmap.c
+@@ -31,12 +31,12 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ char irq_tab_alchemy[][5] __initdata = {
+- [12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
+- [13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
++	[12] = { -1, INTA, INTX, INTX, INTX },   /* IDSEL 12 - HPT370	*/
++	[13] = { -1, INTA, INTB, INTC, INTD },   /* IDSEL 13 - PCI slot */
+ };
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/au1000/pb1550/Makefile b/arch/mips/au1000/pb1550/Makefile
+index aa35bc6..7d8beca 100644
+--- a/arch/mips/au1000/pb1550/Makefile
++++ b/arch/mips/au1000/pb1550/Makefile
+@@ -1,9 +1,8 @@
+ #
+-#  Copyright 2000 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Copyright 2000, 2008 MontaVista Software Inc.
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #
+-# Makefile for the Alchemy Semiconductor PB1000 board.
++# Makefile for the Alchemy Semiconductor Pb1550 board.
+ #
+ 
+ lib-y := init.o board_setup.o irqmap.o
+diff --git a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c
+index 45d6087..0ed76b6 100644
+--- a/arch/mips/au1000/pb1550/board_setup.c
++++ b/arch/mips/au1000/pb1550/board_setup.c
+@@ -3,9 +3,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	Alchemy Pb1550 board setup.
+  *
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -35,15 +34,16 @@
+ 
+ void board_reset(void)
+ {
+-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+-	au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C);
++	/* Hit BCSR.SYSTEM[RESET] */
++	au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
+ }
+ 
+ void __init board_setup(void)
+ {
+ 	u32 pin_func;
+ 
+-	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
++	/*
++	 * Enable PSC1 SYNC for AC'97.  Normaly done in audio driver,
+ 	 * but it is board specific code, so put it here.
+ 	 */
+ 	pin_func = au_readl(SYS_PINFUNC);
+@@ -51,8 +51,8 @@ void __init board_setup(void)
+ 	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ 	au_writel(pin_func, SYS_PINFUNC);
+ 
+-	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
++	au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
+ 	au_sync();
+ 
+-	printk("AMD Alchemy Pb1550 Board\n");
++	printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
+ }
+diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
+index f6b2fc5..1b5f584 100644
+--- a/arch/mips/au1000/pb1550/init.c
++++ b/arch/mips/au1000/pb1550/init.c
+@@ -1,11 +1,10 @@
+ /*
+  *
+  * BRIEF MODULE DESCRIPTION
+- *	PB1550 board setup
++ *	Pb1550 board setup
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -45,16 +44,15 @@ void __init prom_init(void)
+ 	unsigned char *memsize_str;
+ 	unsigned long memsize;
+ 
+-	prom_argc = (int) fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argc = (int)fw_arg0;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
++	if (!memsize_str)
+ 		memsize = 0x08000000;
+-	} else {
+-		memsize = simple_strtol(memsize_str, NULL, 0);
+-	}
++	else
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
+index e1dac37..a02a4d1 100644
+--- a/arch/mips/au1000/pb1550/irqmap.c
++++ b/arch/mips/au1000/pb1550/irqmap.c
+@@ -1,6 +1,6 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Au1xxx irq map table
++ *	Au1xx0 IRQ map table
+  *
+  * Copyright 2003 Embedded Edge, LLC
+  *		dan at embeddededge.com
+@@ -31,8 +31,8 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ char irq_tab_alchemy[][5] __initdata = {
+- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
++	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left)  */
++	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+ };
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+diff --git a/arch/mips/au1000/xxs1500/Makefile b/arch/mips/au1000/xxs1500/Makefile
+index 44d7f70..db3c526 100644
+--- a/arch/mips/au1000/xxs1500/Makefile
++++ b/arch/mips/au1000/xxs1500/Makefile
+@@ -1,7 +1,6 @@
+ #
+ #  Copyright 2003 MontaVista Software Inc.
+-#  Author: MontaVista Software, Inc.
+-#     	ppopov at mvista.com or source at mvista.com
++#  Author: MontaVista Software, Inc. <source at mvista.com>
+ #
+ # Makefile for MyCable XXS1500 board.
+ #
+diff --git a/arch/mips/au1000/xxs1500/board_setup.c b/arch/mips/au1000/xxs1500/board_setup.c
+index 79d1798..4c587ac 100644
+--- a/arch/mips/au1000/xxs1500/board_setup.c
++++ b/arch/mips/au1000/xxs1500/board_setup.c
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright 2000-2003 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2000-2003, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -39,40 +38,40 @@ void __init board_setup(void)
+ {
+ 	u32 pin_func;
+ 
+-	// set multiple use pins (UART3/GPIO) to UART (it's used as UART too)
+-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3);
++	/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
++	pin_func  = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
+ 	pin_func |= SYS_PF_UR3;
+ 	au_writel(pin_func, SYS_PINFUNC);
+ 
+-	// enable UART
+-	au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE)
++	/* Enable UART */
++	au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
+ 	mdelay(10);
+-	au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable"
++	au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
+ 	mdelay(10);
+ 
+-	// enable DTR = USB power up
+-	au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01???
++	/* Enable DTR = USB power up */
++	au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
+ 
+ #ifdef CONFIG_PCMCIA_XXS1500
+-	/* setup pcmcia signals */
++	/* Setup PCMCIA signals */
+ 	au_writel(0, SYS_PININPUTEN);
+ 
+-	/* gpio 0, 1, and 4 are inputs */
+-	au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR);
++	/* GPIO 0, 1, and 4 are inputs */
++	au_writel(1 | (1 << 1) | (1 << 4), SYS_TRIOUTCLR);
+ 
+-	/* enable GPIO2 if not already enabled */
++	/* Enable GPIO2 if not already enabled */
+ 	au_writel(1, GPIO2_ENABLE);
+-	/* gpio2 208/9/10/11 are inputs */
+-	au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR);
++	/* GPIO2 208/9/10/11 are inputs */
++	au_writel((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11), GPIO2_DIR);
+ 
+-	/* turn off power */
+-	au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT);
++	/* Turn off power */
++	au_writel((au_readl(GPIO2_PINSTATE) & ~(1 << 14)) | (1 << 30),
++		  GPIO2_OUTPUT);
+ #endif
+ 
+-
+ #ifdef CONFIG_PCI
+ #if defined(__MIPSEB__)
+-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
++	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+ #else
+ 	au_writel(0xf, Au1500_PCI_CFG);
+ #endif
+diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
+index 24fc6e1..b849bf5 100644
+--- a/arch/mips/au1000/xxs1500/init.c
++++ b/arch/mips/au1000/xxs1500/init.c
+@@ -2,9 +2,8 @@
+  * BRIEF MODULE DESCRIPTION
+  *	XXS1500 board setup
+  *
+- * Copyright 2003 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2003, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -45,8 +44,8 @@ void __init prom_init(void)
+ 	unsigned long memsize;
+ 
+ 	prom_argc = fw_arg0;
+-	prom_argv = (char **) fw_arg1;
+-	prom_envp = (char **) fw_arg2;
++	prom_argv = (char **)fw_arg1;
++	prom_envp = (char **)fw_arg2;
+ 
+ 	prom_init_cmdline();
+ 
+@@ -54,6 +53,6 @@ void __init prom_init(void)
+ 	if (!memsize_str)
+ 		memsize = 0x04000000;
+ 	else
+-		memsize = simple_strtol(memsize_str, NULL, 0);
++		memsize = strict_strtol(memsize_str, 0, NULL);
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+ }
+diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c
+index dd6e3d1..edf06ed 100644
+--- a/arch/mips/au1000/xxs1500/irqmap.c
++++ b/arch/mips/au1000/xxs1500/irqmap.c
+@@ -31,7 +31,7 @@
+ #include <asm/mach-au1x00/au1000.h>
+ 
+ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
++	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
+ 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+ 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c
+index 82f9e90..62bfb45 100644
+--- a/arch/mips/emma2rh/markeins/setup.c
++++ b/arch/mips/emma2rh/markeins/setup.c
+@@ -76,7 +76,9 @@ static void markeins_machine_power_off(void)
+ 	while (1) ;
+ }
+ 
+-static unsigned long clock[4] = { 166500000, 187312500, 199800000, 210600000 };
++static unsigned long __initdata emma2rh_clock[4] = {
++	166500000, 187312500, 199800000, 210600000
++};
+ 
+ static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+ {
+@@ -85,7 +87,8 @@ static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+ 	/* detect from boot strap */
+ 	reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
+ 	reg = (reg >> 4) & 0x3;
+-	return clock[reg];
++
++	return emma2rh_clock[reg];
+ }
+ 
+ void __init plat_time_init(void)
+diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
+index 45545be..cc02440 100644
+--- a/arch/mips/kernel/Makefile
++++ b/arch/mips/kernel/Makefile
+@@ -56,9 +56,9 @@ obj-$(CONFIG_MIPS_MT_SMP)	+= smp-mt.o
+ obj-$(CONFIG_MIPS_CMP)		+= smp-cmp.o
+ obj-$(CONFIG_CPU_MIPSR2)	+= spram.o
+ 
+-obj-$(CONFIG_MIPS_APSP_KSPD)	+= kspd.o
+ obj-$(CONFIG_MIPS_VPE_LOADER)	+= vpe.o
+ obj-$(CONFIG_MIPS_VPE_APSP_API)	+= rtlx.o
++obj-$(CONFIG_MIPS_APSP_KSPD)	+= kspd.o
+ 
+ obj-$(CONFIG_I8259)		+= i8259.o
+ obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
+diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
+index a1b48af..02b7713 100644
+--- a/arch/mips/kernel/cpu-bugs64.c
++++ b/arch/mips/kernel/cpu-bugs64.c
+@@ -38,7 +38,7 @@ static inline void align_mod(const int align, const int mod)
+ 		".endr\n\t"
+ 		".set	pop"
+ 		:
+-		: GCC_IMM_ASM(align), GCC_IMM_ASM(mod));
++		: GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod));
+ }
+ 
+ static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
+diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
+index 290d8e3..469c723 100644
+--- a/arch/mips/kernel/irixelf.c
++++ b/arch/mips/kernel/irixelf.c
+@@ -578,7 +578,7 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
+  * process and the system, here we map the page and fill the
+  * structure
+  */
+-static void irix_map_prda_page(void)
++static int irix_map_prda_page(void)
+ {
+ 	unsigned long v;
+ 	struct prda *pp;
+@@ -587,8 +587,8 @@ static void irix_map_prda_page(void)
+ 	v =  do_brk(PRDA_ADDRESS, PAGE_SIZE);
+ 	up_write(&current->mm->mmap_sem);
+ 
+-	if (v < 0)
+-		return;
++	if (v != PRDA_ADDRESS)
++		return v;		/* v must be an error code */
+ 
+ 	pp = (struct prda *) v;
+ 	pp->prda_sys.t_pid  = task_pid_vnr(current);
+@@ -596,6 +596,8 @@ static void irix_map_prda_page(void)
+ 	pp->prda_sys.t_rpid = task_pid_vnr(current);
+ 
+ 	/* We leave the rest set to zero */
++
++	return 0;
+ }
+ 
+ 
+@@ -781,7 +783,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+ 	 * IRIX maps a page at 0x200000 which holds some system
+ 	 * information.  Programs depend on this.
+ 	 */
+-	irix_map_prda_page();
++	if (irix_map_prda_page())
++		goto out_free_dentry;
+ 
+ 	padzero(elf_bss);
+ 
+diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
+index ceb62dc..b0591ae 100644
+--- a/arch/mips/kernel/kspd.c
++++ b/arch/mips/kernel/kspd.c
+@@ -257,7 +257,7 @@ void sp_work_handle_request(void)
+ 
+ 		vcwd = vpe_getcwd(tclimit);
+ 
+- 		/* change to the cwd of the process that loaded the SP program */
++		/* change to cwd of the process that loaded the SP program */
+ 		old_fs = get_fs();
+ 		set_fs(KERNEL_DS);
+ 		sys_chdir(vcwd);
+@@ -323,6 +323,9 @@ static void sp_cleanup(void)
+ 			set >>= 1;
+ 		}
+ 	}
++
++	/* Put daemon cwd back to root to avoid umount problems */
++	sys_chdir("/");
+ }
+ 
+ static int channel_open = 0;
+diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
+index 0233798..b88f1c1 100644
+--- a/arch/mips/kernel/rtlx.c
++++ b/arch/mips/kernel/rtlx.c
+@@ -72,6 +72,15 @@ static void rtlx_dispatch(void)
+ static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
+ {
+ 	int i;
++	unsigned int flags, vpeflags;
++
++	/* Ought not to be strictly necessary for SMTC builds */
++	local_irq_save(flags);
++	vpeflags = dvpe();
++	set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
++	irq_enable_hazard();
++	evpe(vpeflags);
++	local_irq_restore(flags);
+ 
+ 	for (i = 0; i < RTLX_CHANNELS; i++) {
+ 			wake_up(&channel_wqs[i].lx_queue);
+@@ -108,7 +117,8 @@ static void __used dump_rtlx(void)
+ static int rtlx_init(struct rtlx_info *rtlxi)
+ {
+ 	if (rtlxi->id != RTLX_ID) {
+-		printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id);
++		printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
++			rtlxi, rtlxi->id);
+ 		return -ENOEXEC;
+ 	}
+ 
+@@ -162,18 +172,17 @@ int rtlx_open(int index, int can_sleep)
+ 
+ 	if (rtlx == NULL) {
+ 		if( (p = vpe_get_shared(tclimit)) == NULL) {
+-			if (can_sleep) {
+-				__wait_event_interruptible(channel_wqs[index].lx_queue,
+-				                           (p = vpe_get_shared(tclimit)),
+-				                           ret);
+-				if (ret)
+-					goto out_fail;
+-			} else {
+-				printk(KERN_DEBUG "No SP program loaded, and device "
+-					"opened with O_NONBLOCK\n");
+-				ret = -ENOSYS;
++		    if (can_sleep) {
++			__wait_event_interruptible(channel_wqs[index].lx_queue,
++				(p = vpe_get_shared(tclimit)), ret);
++			if (ret)
+ 				goto out_fail;
+-			}
++		    } else {
++			printk(KERN_DEBUG "No SP program loaded, and device "
++					"opened with O_NONBLOCK\n");
++			ret = -ENOSYS;
++			goto out_fail;
++		    }
+ 		}
+ 
+ 		smp_rmb();
+@@ -182,7 +191,9 @@ int rtlx_open(int index, int can_sleep)
+ 				DEFINE_WAIT(wait);
+ 
+ 				for (;;) {
+-					prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE);
++					prepare_to_wait(
++						&channel_wqs[index].lx_queue,
++						&wait, TASK_INTERRUPTIBLE);
+ 					smp_rmb();
+ 					if (*p != NULL)
+ 						break;
+@@ -195,7 +206,7 @@ int rtlx_open(int index, int can_sleep)
+ 				}
+ 				finish_wait(&channel_wqs[index].lx_queue, &wait);
+ 			} else {
+-				printk(" *vpe_get_shared is NULL. "
++				pr_err(" *vpe_get_shared is NULL. "
+ 				       "Has an SP program been loaded?\n");
+ 				ret = -ENOSYS;
+ 				goto out_fail;
+@@ -203,8 +214,9 @@ int rtlx_open(int index, int can_sleep)
+ 		}
+ 
+ 		if ((unsigned int)*p < KSEG0) {
+-			printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
+-			       "maybe an error code %d\n", (int)*p);
++			printk(KERN_WARNING "vpe_get_shared returned an "
++			       "invalid pointer maybe an error code %d\n",
++			       (int)*p);
+ 			ret = -ENOSYS;
+ 			goto out_fail;
+ 		}
+@@ -232,6 +244,10 @@ out_ret:
+ 
+ int rtlx_release(int index)
+ {
++	if (rtlx == NULL) {
++		pr_err("rtlx_release() with null rtlx\n");
++		return 0;
++	}
+ 	rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
+ 	return 0;
+ }
+@@ -251,8 +267,8 @@ unsigned int rtlx_read_poll(int index, int can_sleep)
+ 			int ret = 0;
+ 
+ 			__wait_event_interruptible(channel_wqs[index].lx_queue,
+-			                           chan->lx_read != chan->lx_write || sp_stopping,
+-			                           ret);
++				(chan->lx_read != chan->lx_write) ||
++				sp_stopping, ret);
+ 			if (ret)
+ 				return ret;
+ 
+@@ -282,7 +298,9 @@ static inline int write_spacefree(int read, int write, int size)
+ unsigned int rtlx_write_poll(int index)
+ {
+ 	struct rtlx_channel *chan = &rtlx->channel[index];
+-	return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
++
++	return write_spacefree(chan->rt_read, chan->rt_write,
++				chan->buffer_size);
+ }
+ 
+ ssize_t rtlx_read(int index, void __user *buff, size_t count)
+@@ -344,8 +362,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
+ 	rt_read = rt->rt_read;
+ 
+ 	/* total number of bytes to copy */
+-	count = min(count,
+-		    (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
++	count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
++							rt->buffer_size));
+ 
+ 	/* first bit from write pointer to the end of the buffer, or count */
+ 	fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
+@@ -514,6 +532,11 @@ static int __init rtlx_module_init(void)
+ 
+ 	if (cpu_has_vint)
+ 		set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
++	else {
++		pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
++		err = -ENODEV;
++		goto out_chrdev;
++	}
+ 
+ 	rtlx_irq.dev_id = rtlx;
+ 	setup_irq(rtlx_irq_num, &rtlx_irq);
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index 39f3dfe..c6a063b 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -331,6 +331,7 @@ static void __init bootmem_init(void)
+ 	/*
+ 	 * Determine low and high memory ranges
+ 	 */
++	max_pfn = max_low_pfn;
+ 	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
+ #ifdef CONFIG_HIGHMEM
+ 		highstart_pfn = PFN_DOWN(HIGHMEM_START);
+diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
+index 33780cc..63370cd 100644
+--- a/arch/mips/kernel/smp.c
++++ b/arch/mips/kernel/smp.c
+@@ -87,8 +87,8 @@ struct plat_smp_ops *mp_ops;
+ 
+ __cpuinit void register_smp_ops(struct plat_smp_ops *ops)
+ {
+-	if (ops)
+-		printk(KERN_WARNING "Overriding previous set SMP ops\n");
++	if (mp_ops)
++		printk(KERN_WARNING "Overriding previously set SMP ops\n");
+ 
+ 	mp_ops = ops;
+ }
+diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
+index 39804c5..2794501 100644
+--- a/arch/mips/kernel/vpe.c
++++ b/arch/mips/kernel/vpe.c
+@@ -269,7 +269,7 @@ static void *alloc_progmem(unsigned long len)
+ 	 * This means you must tell Linux to use less memory than you
+ 	 * physically have, for example by passing a mem= boot argument.
+ 	 */
+-	addr = pfn_to_kaddr(max_pfn);
++	addr = pfn_to_kaddr(max_low_pfn);
+ 	memset(addr, 0, len);
+ #else
+ 	/* simple grab some mem for now */
+@@ -781,10 +781,15 @@ static int vpe_run(struct vpe * v)
+ 	/* take system out of configuration state */
+ 	clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ 
++	/*
++	 * SMTC/SMVP kernels manage VPE enable independently,
++	 * but uniprocessor kernels need to turn it on, even
++	 * if that wasn't the pre-dvpe() state.
++	 */
+ #ifdef CONFIG_SMP
+-	evpe(EVPE_ENABLE);
+-#else
+ 	evpe(vpeflags);
++#else
++	evpe(EVPE_ENABLE);
+ #endif
+ 	emt(dmt_flag);
+ 	local_irq_restore(flags);
+@@ -840,7 +845,7 @@ static int vpe_elfload(struct vpe * v)
+ 
+ 	/* Sanity checks against insmoding binaries or wrong arch,
+ 	   weird elf version */
+-	if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
++	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
+ 	    || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
+ 	    || !elf_check_arch(hdr)
+ 	    || hdr->e_shentsize != sizeof(*sechdrs)) {
+@@ -947,12 +952,14 @@ static int vpe_elfload(struct vpe * v)
+ 		struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
+ 
+ 		for (i = 0; i < hdr->e_phnum; i++) {
+-			if (phdr->p_type != PT_LOAD)
+-				continue;
+-
+-			memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
+-			memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
+-			phdr++;
++			if (phdr->p_type == PT_LOAD) {
++				memcpy((void *)phdr->p_paddr,
++				       (char *)hdr + phdr->p_offset,
++				       phdr->p_filesz);
++				memset((void *)phdr->p_paddr + phdr->p_filesz,
++				       0, phdr->p_memsz - phdr->p_filesz);
++		    }
++		    phdr++;
+ 		}
+ 
+ 		for (i = 0; i < hdr->e_shnum; i++) {
+@@ -1107,7 +1114,7 @@ static int vpe_release(struct inode *inode, struct file *filp)
+ 		return -ENODEV;
+ 
+ 	hdr = (Elf_Ehdr *) v->pbuffer;
+-	if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
++	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
+ 		if (vpe_elfload(v) >= 0) {
+ 			vpe_run(v);
+ 		} else {
+diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
+index 10dd2af..8f2cd8e 100644
+--- a/arch/mips/mm/highmem.c
++++ b/arch/mips/mm/highmem.c
+@@ -116,4 +116,3 @@ EXPORT_SYMBOL(__kmap);
+ EXPORT_SYMBOL(__kunmap);
+ EXPORT_SYMBOL(__kmap_atomic);
+ EXPORT_SYMBOL(__kunmap_atomic);
+-EXPORT_SYMBOL(__kmap_atomic_to_page);
+diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
+index da8cbb6..b40df7d 100644
+--- a/arch/mips/oprofile/op_model_mipsxx.c
++++ b/arch/mips/oprofile/op_model_mipsxx.c
+@@ -281,7 +281,7 @@ static inline int n_counters(void)
+ 
+ static void reset_counters(void *arg)
+ {
+-	int counters = (int)arg;
++	int counters = (int)(long)arg;
+ 	switch (counters) {
+ 	case 4:
+ 		w_c0_perfctrl3(0);
+@@ -313,7 +313,7 @@ static int __init mipsxx_init(void)
+ 	if (!cpu_has_mipsmt_pertccounters)
+ 		counters = counters_total_to_per_cpu(counters);
+ #endif
+-	on_each_cpu(reset_counters, (void *)counters, 0, 1);
++	on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
+ 
+ 	op_model_mipsxx_ops.num_counters = counters;
+ 	switch (current_cpu_type()) {
+@@ -382,7 +382,7 @@ static void mipsxx_exit(void)
+ 	int counters = op_model_mipsxx_ops.num_counters;
+ 
+ 	counters = counters_per_cpu_to_total(counters);
+-	on_each_cpu(reset_counters, (void *)counters, 0, 1);
++	on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
+ 
+ 	perf_irq = save_perf_irq;
+ }
+diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
+index 00c36c9..e2ddfc4 100644
+--- a/arch/mips/pci/fixup-au1000.c
++++ b/arch/mips/pci/fixup-au1000.c
+@@ -1,10 +1,9 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Board specific pci fixups.
++ *	Board specific PCI fixups.
+  *
+- * Copyright 2001-2003 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001-2003, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
+index 1314bd5..9a57c5a 100644
+--- a/arch/mips/pci/ops-au1000.c
++++ b/arch/mips/pci/ops-au1000.c
+@@ -1,10 +1,9 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Alchemy/AMD Au1x00 PCI support.
++ *	Alchemy/AMD Au1xx0 PCI support.
+  *
+- * Copyright 2001-2003, 2007 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  Support for all devices (greater than 16) added by David Gathright.
+  *
+@@ -28,6 +27,7 @@
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
++
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+@@ -36,9 +36,9 @@
+ 
+ #include <asm/mach-au1x00/au1000.h>
+ 
+-#undef DEBUG
+-#ifdef DEBUG
+-#define DBG(x...) printk(x)
++#undef	DEBUG
++#ifdef	DEBUG
++#define DBG(x...) printk(KERN_DEBUG x)
+ #else
+ #define DBG(x...)
+ #endif
+@@ -46,7 +46,6 @@
+ #define PCI_ACCESS_READ  0
+ #define PCI_ACCESS_WRITE 1
+ 
+-
+ int (*board_pci_idsel)(unsigned int devsel, int assert);
+ 
+ void mod_wired_entry(int entry, unsigned long entrylo0,
+@@ -92,10 +91,9 @@ void __init au1x_pci_cfg_init(void)
+ }
+ 
+ static int config_access(unsigned char access_type, struct pci_bus *bus,
+-			 unsigned int dev_fn, unsigned char where,
+-			 u32 * data)
++			 unsigned int dev_fn, unsigned char where, u32 *data)
+ {
+-#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
++#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+ 	unsigned int device = PCI_SLOT(dev_fn);
+ 	unsigned int function = PCI_FUNC(dev_fn);
+ 	unsigned long offset, status;
+@@ -114,38 +112,36 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
+ 			Au1500_PCI_STATCMD);
+ 	au_sync_udelay(1);
+ 
+-	/* Allow board vendors to implement their own off-chip idsel.
++	/*
++	 * Allow board vendors to implement their own off-chip IDSEL.
+ 	 * If it doesn't succeed, may as well bail out at this point.
+ 	 */
+-	if (board_pci_idsel) {
+-		if (board_pci_idsel(device, 1) == 0) {
+-			*data = 0xffffffff;
+-			local_irq_restore(flags);
+-			return -1;
+-		}
++	if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
++		*data = 0xffffffff;
++		local_irq_restore(flags);
++		return -1;
+ 	}
+ 
+-        /* setup the config window */
+-        if (bus->number == 0) {
+-                cfg_base = ((1<<device)<<11);
+-        } else {
+-                cfg_base = 0x80000000 | (bus->number<<16) | (device<<11);
+-        }
++	/* Setup the config window */
++	if (bus->number == 0)
++		cfg_base = (1 << device) << 11;
++	else
++		cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
+ 
+-        /* setup the lower bits of the 36 bit address */
+-        offset = (function << 8) | (where & ~0x3);
+-	/* pick up any address that falls below the page mask */
++	/* Setup the lower bits of the 36-bit address */
++	offset = (function << 8) | (where & ~0x3);
++	/* Pick up any address that falls below the page mask */
+ 	offset |= cfg_base & ~PAGE_MASK;
+ 
+-	/* page boundary */
++	/* Page boundary */
+ 	cfg_base = cfg_base & PAGE_MASK;
+ 
+ 	/*
+ 	 * To improve performance, if the current device is the same as
+ 	 * the last device accessed, we don't touch the TLB.
+ 	 */
+-	entryLo0 = (6 << 26)  | (cfg_base >> 6) | (2 << 3) | 7;
+-	entryLo1 = (6 << 26)  | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
++	entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
++	entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
+ 	if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
+ 		mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
+ 				(unsigned long)pci_cfg_vm->addr, PM_4K);
+@@ -153,38 +149,37 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
+ 		last_entryLo1 = entryLo1;
+ 	}
+ 
+-	if (access_type == PCI_ACCESS_WRITE) {
++	if (access_type == PCI_ACCESS_WRITE)
+ 		au_writel(*data, (int)(pci_cfg_vm->addr + offset));
+-	} else {
++	else
+ 		*data = au_readl((int)(pci_cfg_vm->addr + offset));
+-	}
++
+ 	au_sync_udelay(2);
+ 
+-	DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n",
+-			access_type, bus->number, device, where, *data, offset);
++	DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
++	    access_type, bus->number, device, where, *data, offset);
+ 
+-	/* check master abort */
++	/* Check master abort */
+ 	status = au_readl(Au1500_PCI_STATCMD);
+ 
+-	if (status & (1<<29)) {
++	if (status & (1 << 29)) {
+ 		*data = 0xffffffff;
+ 		error = -1;
+ 		DBG("Au1x Master Abort\n");
+ 	} else if ((status >> 28) & 0xf) {
+-		DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf));
++		DBG("PCI ERR detected: device %u, status %lx\n",
++		    device, (status >> 28) & 0xf);
+ 
+-		/* clear errors */
++		/* Clear errors */
+ 		au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
+ 
+ 		*data = 0xffffffff;
+ 		error = -1;
+ 	}
+ 
+-	/* Take away the idsel.
+-	*/
+-	if (board_pci_idsel) {
++	/* Take away the IDSEL. */
++	if (board_pci_idsel)
+ 		(void)board_pci_idsel(device, 0);
+-	}
+ 
+ 	local_irq_restore(flags);
+ 	return error;
+@@ -192,7 +187,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
+ }
+ 
+ static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
+-			    int where, u8 * val)
++			    int where,	u8 *val)
+ {
+ 	u32 data;
+ 	int ret;
+@@ -206,9 +201,8 @@ static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
+ 	return ret;
+ }
+ 
+-
+ static int read_config_word(struct pci_bus *bus, unsigned int devfn,
+-			    int where, u16 * val)
++			    int where, u16 *val)
+ {
+ 	u32 data;
+ 	int ret;
+@@ -221,7 +215,7 @@ static int read_config_word(struct pci_bus *bus, unsigned int devfn,
+ }
+ 
+ static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
+-			     int where, u32 * val)
++			     int where, u32 *val)
+ {
+ 	int ret;
+ 
+@@ -229,9 +223,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
+ 	return ret;
+ }
+ 
+-static int
+-write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
+-		  u8 val)
++static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
++			     int where, u8 val)
+ {
+ 	u32 data = 0;
+ 
+@@ -239,7 +232,7 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
+ 		return -1;
+ 
+ 	data = (data & ~(0xff << ((where & 3) << 3))) |
+-	    (val << ((where & 3) << 3));
++	       (val << ((where & 3) << 3));
+ 
+ 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ 		return -1;
+@@ -247,9 +240,8 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int
+-write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
+-		  u16 val)
++static int write_config_word(struct pci_bus *bus, unsigned int devfn,
++			     int where, u16 val)
+ {
+ 	u32 data = 0;
+ 
+@@ -257,18 +249,16 @@ write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
+ 		return -1;
+ 
+ 	data = (data & ~(0xffff << ((where & 3) << 3))) |
+-	    (val << ((where & 3) << 3));
++	       (val << ((where & 3) << 3));
+ 
+ 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ 		return -1;
+ 
+-
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-static int
+-write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
+-		   u32 val)
++static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
++			      int where, u32 val)
+ {
+ 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
+ 		return -1;
+@@ -277,18 +267,20 @@ write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
+ }
+ 
+ static int config_read(struct pci_bus *bus, unsigned int devfn,
+-		       int where, int size, u32 * val)
++		       int where, int size, u32 *val)
+ {
+ 	switch (size) {
+ 	case 1: {
+ 			u8 _val;
+ 			int rc = read_config_byte(bus, devfn, where, &_val);
++
+ 			*val = _val;
+ 			return rc;
+ 		}
+-       case 2: {
++	case 2: {
+ 			u16 _val;
+ 			int rc = read_config_word(bus, devfn, where, &_val);
++
+ 			*val = _val;
+ 			return rc;
+ 		}
+@@ -310,7 +302,6 @@ static int config_write(struct pci_bus *bus, unsigned int devfn,
+ 	}
+ }
+ 
+-
+ struct pci_ops au1x_pci_ops = {
+ 	config_read,
+ 	config_write
+diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+index ab96a2d..11769b5 100644
+--- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
++++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+@@ -126,9 +126,6 @@ static irqreturn_t hwbutton_handler(int irq, void *data)
+ 	struct hwbutton_interrupt *hirq = data;
+ 	unsigned long cic_ext = *CIC_EXT_CFG_REG;
+ 
+-	if (irq != hirq->irq)
+-		return IRQ_NONE;
+-
+ 	if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
+ 		/* Interrupt: pin is now HI */
+ 		CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
+@@ -164,7 +161,7 @@ static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
+ 	*CIC_EXT_CFG_REG = cic_ext;
+ 
+ 	return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
+-				hirq->name, (void *)hirq);
++			   hirq->name, hirq);
+ }
+ 
+ static int __init msp_hwbutton_setup(void)
+diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
+index 25d3baf..9cebc9e 100644
+--- a/arch/mips/sgi-ip27/ip27-timer.c
++++ b/arch/mips/sgi-ip27/ip27-timer.c
+@@ -158,7 +158,7 @@ static void rt_set_mode(enum clock_event_mode mode,
+ 	}
+ }
+ 
+-unsigned int rt_timer_irq;
++int rt_timer_irq;
+ 
+ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
+ {
+@@ -219,7 +219,7 @@ static void __cpuinit hub_rt_clock_event_init(void)
+ 
+ static void __init hub_rt_clock_event_global_init(void)
+ {
+-	unsigned int irq;
++	int irq;
+ 
+ 	do {
+ 		smp_wmb();
+diff --git a/arch/mn10300/boot/install.sh b/arch/mn10300/boot/install.sh
+index 072951c..abba309 100644
+--- a/arch/mn10300/boot/install.sh
++++ b/arch/mn10300/boot/install.sh
+@@ -26,42 +26,42 @@ rm -fr $4/../usr/include/linux $4/../usr/include/asm
+ install -c -m 0755 $2 $4/vmlinuz
+ install -c -m 0755 $5 $4/boot.rom
+ install -c -m 0755 -d $4/../usr/include/linux
+-cd $TOPDIR/include/linux
++cd ${srctree}/include/linux
+ for i in `find . -maxdepth 1 -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/byteorder
+-cd $TOPDIR/include/linux/byteorder
++cd ${srctree}/include/linux/byteorder
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/byteorder
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/lockd
+-cd $TOPDIR/include/linux/lockd
++cd ${srctree}/include/linux/lockd
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/lockd
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/netfilter_ipv4
+-cd $TOPDIR/include/linux/netfilter_ipv4
++cd ${srctree}/include/linux/netfilter_ipv4
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/netfilter_ipv4
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/nfsd
+-cd $TOPDIR/include/linux/nfsd
++cd ${srctree}/include/linux/nfsd
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/nfsd/$i
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/raid
+-cd $TOPDIR/include/linux/raid
++cd ${srctree}/include/linux/raid
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/raid
+ done
+ install -c -m 0755 -d $4/../usr/include/linux/sunrpc
+-cd $TOPDIR/include/linux/sunrpc
++cd ${srctree}/include/linux/sunrpc
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/linux/sunrpc
+ done
+ install -c -m 0755 -d $4/../usr/include/asm
+-cd $TOPDIR/include/asm
++cd ${srctree}/include/asm
+ for i in `find . -name '*.h' -print`; do
+   install -c -m 0644 $i $4/../usr/include/asm
+ done
+diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
+index 1f01284..b0ed709 100644
+--- a/arch/parisc/mm/init.c
++++ b/arch/parisc/mm/init.c
+@@ -606,7 +606,7 @@ void show_mem(void)
+ 		int i, j;
+ 
+ 		for (i = 0; i < npmem_ranges; i++) {
+-			zl = node_zonelist(i);
++			zl = node_zonelist(i, 0);
+ 			for (j = 0; j < MAX_NR_ZONES; j++) {
+ 				struct zoneref *z;
+ 				struct zone *zone;
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+index d14cebf..2346d27 100644
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -105,6 +105,9 @@ PHONY += systbl_chk
+ systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
+ 	$(call cmd,systbl_chk)
+ 
++
++ifeq ($(CONFIG_PPC_MERGE),y)
++
+ $(obj)/built-in.o:		prom_init_check
+ 
+ quiet_cmd_prom_init_check = CALL    $<
+@@ -114,4 +117,7 @@ PHONY += prom_init_check
+ prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o
+ 	$(call cmd,prom_init_check)
+ 
++endif
++
++
+ clean-files := vmlinux.lds
+diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
+index 81738a4..e44d553 100644
+--- a/arch/powerpc/kernel/cputable.c
++++ b/arch/powerpc/kernel/cputable.c
+@@ -1484,6 +1484,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
+ 		.dcache_bsize		= 32,
+ 		.machine_check		= machine_check_e200,
+ 		.platform		= "ppc5554",
++	}
+ #endif /* CONFIG_E200 */
+ #ifdef CONFIG_E500
+ 	{	/* e500 */
+@@ -1533,6 +1534,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
+ 		.dcache_bsize		= 32,
+ 		.machine_check		= machine_check_e500,
+ 		.platform		= "powerpc",
++	}
+ #endif /* CONFIG_E500 */
+ #endif /* CONFIG_PPC32 */
+ };
+diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
+index f1d2cdc..c71d37d 100644
+--- a/arch/powerpc/lib/Makefile
++++ b/arch/powerpc/lib/Makefile
+@@ -10,6 +10,7 @@ ifeq ($(CONFIG_PPC_MERGE),y)
+ obj-y			:= string.o alloc.o \
+ 			   checksum_$(CONFIG_WORD_SIZE).o
+ obj-$(CONFIG_PPC32)	+= div64.o copy_32.o
++obj-$(CONFIG_HAS_IOMEM)	+= devres.o
+ endif
+ 
+ obj-$(CONFIG_PPC64)	+= copypage_64.o copyuser_64.o \
+@@ -23,4 +24,3 @@ obj-$(CONFIG_SMP)	+= locks.o
+ endif
+ 
+ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
+-obj-$(CONFIG_HAS_IOMEM)	+= devres.o
+diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
+index 8df7f0e..2352d13 100644
+--- a/arch/ppc/Makefile
++++ b/arch/ppc/Makefile
+@@ -43,7 +43,7 @@ KBUILD_AFLAGS += $(cpu-as-y)
+ KBUILD_CFLAGS += $(cpu-as-y)
+ 
+ # Default to the common case.
+-KBUILD_DEFCONFIG := common_defconfig
++KBUILD_DEFCONFIG := ebony_defconfig
+ 
+ head-y				:= arch/ppc/kernel/head.o
+ head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
+diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
+index 16ac11c..602c268 100644
+--- a/arch/ppc/kernel/ppc_ksyms.c
++++ b/arch/ppc/kernel/ppc_ksyms.c
+@@ -24,6 +24,7 @@
+ #include <asm/checksum.h>
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
++#include <asm/cacheflush.h>
+ #include <linux/adb.h>
+ #include <linux/cuda.h>
+ #include <linux/pmu.h>
+diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
+index bfddfde..51e8094 100644
+--- a/arch/ppc/kernel/setup.c
++++ b/arch/ppc/kernel/setup.c
+@@ -36,6 +36,7 @@
+ #include <asm/nvram.h>
+ #include <asm/xmon.h>
+ #include <asm/ocp.h>
++#include <asm/irq.h>
+ 
+ #define USES_PPC_SYS (defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
+ 		      defined(CONFIG_PPC_MPC52xx))
+diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
+index 18495e7..d687b0f 100644
+--- a/arch/ppc/platforms/residual.c
++++ b/arch/ppc/platforms/residual.c
+@@ -38,6 +38,7 @@
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/pci.h>
++#include <linux/proc_fs.h>
+ 
+ #include <asm/sections.h>
+ #include <asm/mmu.h>
+diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
+index d453c3a..832641b 100644
+--- a/arch/sh/kernel/kgdb_stub.c
++++ b/arch/sh/kernel/kgdb_stub.c
+@@ -330,14 +330,6 @@ static char *ebin_to_mem(const char *buf, char *mem, int count)
+ 	return mem;
+ }
+ 
+-/* Pack a hex byte */
+-static char *pack_hex_byte(char *pkt, int byte)
+-{
+-	*pkt++ = hexchars[(byte >> 4) & 0xf];
+-	*pkt++ = hexchars[(byte & 0xf)];
+-	return pkt;
+-}
+-
+ /* Scan for the start char '$', read the packet and check the checksum */
+ static void get_packet(char *buffer, int buflen)
+ {
+diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
+index b27b5b5..ab818cd 100644
+--- a/arch/sparc/kernel/rtrap.S
++++ b/arch/sparc/kernel/rtrap.S
+@@ -139,7 +139,7 @@ ret_trap_userwins_ok:
+ 	LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
+ 	or	%t_pc, %t_npc, %g2
+ 	andcc	%g2, 0x3, %g0
+-	sethi	%hi(PSR_SYCALL), %g2
++	sethi	%hi(PSR_SYSCALL), %g2
+ 	be	1f
+ 	 andn	%t_psr, %g2, %t_psr
+ 
+diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
+index e995491..3c6b49a 100644
+--- a/arch/sparc/kernel/sys_sparc.c
++++ b/arch/sparc/kernel/sys_sparc.c
+@@ -219,7 +219,7 @@ out:
+ 	return err;
+ }
+ 
+-int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
++int sparc_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (ARCH_SUN4C_SUN4 &&
+ 	    (len > 0x20000000 ||
+@@ -295,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+-	if (ARCH_SUN4C_SUN4) {
+-		if (old_len > 0x20000000 || new_len > 0x20000000)
+-			goto out;
+-		if (addr < 0xe0000000 && addr + old_len > 0x20000000)
+-			goto out;
+-	}
+-	if (old_len > TASK_SIZE - PAGE_SIZE ||
+-	    new_len > TASK_SIZE - PAGE_SIZE)
++
++	if (unlikely(sparc_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (ARCH_SUN4C_SUN4 &&
+-		    new_addr < 0xe0000000 &&
+-		    new_addr + new_len > 0x20000000)
+-			goto out_sem;
+-		if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
+-			goto out_sem;
+-	} else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
+-		    addr + new_len > 0x20000000) ||
+-		   addr + new_len > TASK_SIZE - PAGE_SIZE) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				     vma ? vma->vm_pgoff : 0,
+-				     map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
+index b9b785f..16689b2 100644
+--- a/arch/sparc64/kernel/rtrap.S
++++ b/arch/sparc64/kernel/rtrap.S
+@@ -46,7 +46,7 @@ __handle_user_windows:
+ 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+ 		ldx			[%g6 + TI_FLAGS], %l0
+ 
+-1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
++1:		andcc			%l0, _TIF_SIGPENDING, %g0
+ 		be,pt			%xcc, __handle_user_windows_continue
+ 		 nop
+ 		mov			%l5, %o1
+@@ -86,7 +86,7 @@ __handle_perfctrs:
+ 		 wrpr			%g0, RTRAP_PSTATE, %pstate
+ 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
+ 		ldx			[%g6 + TI_FLAGS], %l0
+-1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
++1:		andcc			%l0, _TIF_SIGPENDING, %g0
+ 
+ 		be,pt			%xcc, __handle_perfctrs_continue
+ 		 sethi			%hi(TSTATE_PEF), %o0
+@@ -195,7 +195,7 @@ __handle_preemption_continue:
+ 		 andcc			%l1, %o0, %g0
+ 		andcc			%l0, _TIF_NEED_RESCHED, %g0
+ 		bne,pn			%xcc, __handle_preemption
+-		 andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
++		 andcc			%l0, _TIF_SIGPENDING, %g0
+ 		bne,pn			%xcc, __handle_signal
+ __handle_signal_continue:
+ 		 ldub			[%g6 + TI_WSAVED], %o2
+diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
+index 2378482..6e4dc67 100644
+--- a/arch/sparc64/kernel/signal.c
++++ b/arch/sparc64/kernel/signal.c
+@@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set)
+ 
+ 	current->state = TASK_INTERRUPTIBLE;
+ 	schedule();
+-	set_thread_flag(TIF_RESTORE_SIGMASK);
++
++	set_restore_sigmask();
++
+ 	return -ERESTARTNOHAND;
+ }
+ 
+@@ -537,7 +539,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
+ 	} else
+ 		restart_syscall = 0;
+ 
+-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
++	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
+ 		oldset = &current->saved_sigmask;
+ 	else
+ 		oldset = &current->blocked;
+@@ -566,13 +568,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
+ 			syscall_restart(orig_i0, regs, &ka.sa);
+ 		handle_signal(signr, &ka, &info, oldset, regs);
+ 
+-		/* a signal was successfully delivered; the saved
++		/* A signal was successfully delivered; the saved
+ 		 * sigmask will have been stored in the signal frame,
+ 		 * and will be restored by sigreturn, so we can simply
+-		 * clear the TIF_RESTORE_SIGMASK flag.
++		 * clear the TS_RESTORE_SIGMASK flag.
+ 		 */
+-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+-			clear_thread_flag(TIF_RESTORE_SIGMASK);
++		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ 		return;
+ 	}
+ 	if (restart_syscall &&
+@@ -591,17 +592,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
+ 		regs->tnpc -= 4;
+ 	}
+ 
+-	/* if there's no signal to deliver, we just put the saved sigmask
++	/* If there's no signal to deliver, we just put the saved sigmask
+ 	 * back
+ 	 */
+-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+-		clear_thread_flag(TIF_RESTORE_SIGMASK);
++	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
++		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ 	}
+ }
+ 
+ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
+ {
+-	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
++	if (thread_info_flags & _TIF_SIGPENDING)
+ 		do_signal(regs, orig_i0);
+ }
+diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
+index 3f19e9a..97cdd1b 100644
+--- a/arch/sparc64/kernel/signal32.c
++++ b/arch/sparc64/kernel/signal32.c
+@@ -788,13 +788,12 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+ 			syscall_restart32(orig_i0, regs, &ka.sa);
+ 		handle_signal32(signr, &ka, &info, oldset, regs);
+ 
+-		/* a signal was successfully delivered; the saved
++		/* A signal was successfully delivered; the saved
+ 		 * sigmask will have been stored in the signal frame,
+ 		 * and will be restored by sigreturn, so we can simply
+-		 * clear the TIF_RESTORE_SIGMASK flag.
++		 * clear the TS_RESTORE_SIGMASK flag.
+ 		 */
+-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+-			clear_thread_flag(TIF_RESTORE_SIGMASK);
++		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ 		return;
+ 	}
+ 	if (restart_syscall &&
+@@ -813,11 +812,11 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+ 		regs->tnpc -= 4;
+ 	}
+ 
+-	/* if there's no signal to deliver, we just put the saved sigmask
++	/* If there's no signal to deliver, we just put the saved sigmask
+ 	 * back
+ 	 */
+-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+-		clear_thread_flag(TIF_RESTORE_SIGMASK);
++	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
++		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ 	}
+ }
+diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
+index 0dbc941..ac1bff5 100644
+--- a/arch/sparc64/kernel/sys_sparc.c
++++ b/arch/sparc64/kernel/sys_sparc.c
+@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
+ 	return ret;
+ }
+ 
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags)
++int sparc64_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (test_thread_flag(TIF_32BIT)) {
+ 		if (len >= STACK_TOP32)
+@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 
+ 	if (test_thread_flag(TIF_32BIT))
+ 		goto out;
+ 	if (unlikely(new_len >= VA_EXCLUDE_START))
+ 		goto out;
+-	if (unlikely(invalid_64bit_range(addr, old_len)))
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (invalid_64bit_range(new_addr, new_len))
+-			goto out_sem;
+-	} else if (invalid_64bit_range(addr, new_len)) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
+index 1aa4288..ba5bd62 100644
+--- a/arch/sparc64/kernel/sys_sparc32.c
++++ b/arch/sparc64/kernel/sys_sparc32.c
+@@ -867,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, u32 __new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 	unsigned long new_addr = __new_addr;
+ 
+-	if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
+ 		goto out;
+-	if (addr > STACK_TOP32 - old_len)
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (new_addr > STACK_TOP32 - new_len)
+-			goto out_sem;
+-	} else if (addr > STACK_TOP32 - new_len) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
+index ec3e2c7..a9828d7 100644
+--- a/arch/sparc64/mm/init.c
++++ b/arch/sparc64/mm/init.c
+@@ -610,8 +610,6 @@ static void __init remap_kernel(void)
+ 
+ static void __init inherit_prom_mappings(void)
+ {
+-	read_obp_translations();
+-
+ 	/* Now fixup OBP's idea about where we really are mapped. */
+ 	printk("Remapping the kernel... ");
+ 	remap_kernel();
+@@ -1747,7 +1745,17 @@ void __init paging_init(void)
+ 
+ 	lmb_init();
+ 
+-	/* Find available physical memory... */
++	/* Find available physical memory...
++	 *
++	 * Read it twice in order to work around a bug in openfirmware.
++	 * The call to grab this table itself can cause openfirmware to
++	 * allocate memory, which in turn can take away some space from
++	 * the list of available memory.  Reading it twice makes sure
++	 * we really do get the final value.
++	 */
++	read_obp_translations();
++	read_obp_memory("reg", &pall[0], &pall_ents);
++	read_obp_memory("available", &pavail[0], &pavail_ents);
+ 	read_obp_memory("available", &pavail[0], &pavail_ents);
+ 
+ 	phys_base = 0xffffffffffffffffUL;
+@@ -1788,8 +1796,6 @@ void __init paging_init(void)
+ 	
+ 	inherit_prom_mappings();
+ 	
+-	read_obp_memory("reg", &pall[0], &pall_ents);
+-
+ 	init_kpte_bitmap();
+ 
+ 	/* Ok, we can use our TLB miss and window trap handlers safely.  */
+diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
+index 3a4b396..1b238eb 100644
+--- a/arch/um/Kconfig.char
++++ b/arch/um/Kconfig.char
+@@ -145,14 +145,14 @@ config LEGACY_PTYS
+ 	  systems, it is safe to say N.
+ 
+ config RAW_DRIVER
+-        tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
++        tristate "RAW driver (/dev/raw/rawN)"
++	depends on BLOCK
+         help
+           The raw driver permits block devices to be bound to /dev/raw/rawN.
+           Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
+           See the raw(8) manpage for more details.
+ 
+-          The raw driver is deprecated and will be removed soon.
+-          Applications should simply open the device (eg /dev/hda1)
++          Applications should preferably open the device (eg /dev/hda1)
+           with the O_DIRECT flag.
+ 
+ config MAX_RAW_DEVS
+diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
+index 0257640..cfeb3f4 100644
+--- a/arch/um/drivers/chan_user.c
++++ b/arch/um/drivers/chan_user.c
+@@ -11,6 +11,7 @@
+ #include <termios.h>
+ #include <sys/ioctl.h>
+ #include "chan_user.h"
++#include "kern_constants.h"
+ #include "os.h"
+ #include "um_malloc.h"
+ #include "user.h"
+diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
+index ca8c9e1..f5701fd 100644
+--- a/arch/um/drivers/cow_sys.h
++++ b/arch/um/drivers/cow_sys.h
+@@ -8,7 +8,7 @@
+ 
+ static inline void *cow_malloc(int size)
+ {
+-	return kmalloc(size, UM_GFP_KERNEL);
++	return uml_kmalloc(size, UM_GFP_KERNEL);
+ }
+ 
+ static inline void cow_free(void *ptr)
+diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
+index f23c109..f8e85e0 100644
+--- a/arch/um/drivers/daemon_user.c
++++ b/arch/um/drivers/daemon_user.c
+@@ -34,7 +34,7 @@ static struct sockaddr_un *new_addr(void *name, int len)
+ {
+ 	struct sockaddr_un *sun;
+ 
+-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
++	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+ 	if (sun == NULL) {
+ 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
+ 		       "failed\n");
+@@ -83,7 +83,7 @@ static int connect_to_switch(struct daemon_data *pri)
+ 		goto out_close;
+ 	}
+ 
+-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
++	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+ 	if (sun == NULL) {
+ 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
+ 		       "failed\n");
+diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
+index 0a2bb5b..f5a981a 100644
+--- a/arch/um/drivers/fd.c
++++ b/arch/um/drivers/fd.c
+@@ -40,7 +40,7 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
+ 		return NULL;
+ 	}
+ 
+-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
++	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ 	if (data == NULL)
+ 		return NULL;
+ 
+diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
+index ff1b22b..368219c 100644
+--- a/arch/um/drivers/hostaudio_kern.c
++++ b/arch/um/drivers/hostaudio_kern.c
+@@ -154,7 +154,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
+ 	case SNDCTL_DSP_SUBDIVIDE:
+ 	case SNDCTL_DSP_SETFRAGMENT:
+ 		if (get_user(data, (int __user *) arg))
+-			return EFAULT;
++			return -EFAULT;
+ 		break;
+ 	default:
+ 		break;
+diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
+index 5f647d7..ee19e91 100644
+--- a/arch/um/drivers/mcast_user.c
++++ b/arch/um/drivers/mcast_user.c
+@@ -15,6 +15,7 @@
+ #include <unistd.h>
+ #include <errno.h>
+ #include <netinet/in.h>
++#include "kern_constants.h"
+ #include "mcast.h"
+ #include "net_user.h"
+ #include "um_malloc.h"
+@@ -24,7 +25,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
+ {
+ 	struct sockaddr_in *sin;
+ 
+-	sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
++	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+ 	if (sin == NULL) {
+ 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
+ 		       "failed\n");
+diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
+index abf2653..9415dd9 100644
+--- a/arch/um/drivers/net_user.c
++++ b/arch/um/drivers/net_user.c
+@@ -222,7 +222,7 @@ static void change(char *dev, char *what, unsigned char *addr,
+ 		netmask[2], netmask[3]);
+ 
+ 	output_len = UM_KERN_PAGE_SIZE;
+-	output = kmalloc(output_len, UM_GFP_KERNEL);
++	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
+ 	if (output == NULL)
+ 		printk(UM_KERN_ERR "change : failed to allocate output "
+ 		       "buffer\n");
+diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
+index d269ca3..b49bf56 100644
+--- a/arch/um/drivers/port_user.c
++++ b/arch/um/drivers/port_user.c
+@@ -47,7 +47,7 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
+ 	if (kern_data == NULL)
+ 		return NULL;
+ 
+-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
++	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ 	if (data == NULL)
+ 		goto err;
+ 
+diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
+index 49c79dd..1113911 100644
+--- a/arch/um/drivers/pty.c
++++ b/arch/um/drivers/pty.c
+@@ -29,7 +29,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
+ {
+ 	struct pty_chan *data;
+ 
+-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
++	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ 	if (data == NULL)
+ 		return NULL;
+ 
+diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
+index 71f0959..4949044 100644
+--- a/arch/um/drivers/random.c
++++ b/arch/um/drivers/random.c
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 2005 Jeff Dike <jdike at addtoit.com> */
++/* Copyright (C) 2005 - 2008 Jeff Dike <jdike@{linux.intel,addtoit}.com> */
++
+ /* Much of this ripped from drivers/char/hw_random.c, see there for other
+  * copyright.
+  *
+@@ -8,16 +9,18 @@
+ #include <linux/sched.h>
+ #include <linux/module.h>
+ #include <linux/fs.h>
++#include <linux/interrupt.h>
+ #include <linux/miscdevice.h>
+ #include <linux/delay.h>
+ #include <asm/uaccess.h>
++#include "irq_kern.h"
+ #include "os.h"
+ 
+ /*
+  * core module and version information
+  */
+ #define RNG_VERSION "1.0.0"
+-#define RNG_MODULE_NAME "random"
++#define RNG_MODULE_NAME "hw_random"
+ 
+ #define RNG_MISCDEV_MINOR		183 /* official */
+ 
+@@ -26,47 +29,67 @@
+  * protects against a module being loaded twice at the same time.
+  */
+ static int random_fd = -1;
++static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
+ 
+ static int rng_dev_open (struct inode *inode, struct file *filp)
+ {
+ 	/* enforce read-only access to this chrdev */
+ 	if ((filp->f_mode & FMODE_READ) == 0)
+ 		return -EINVAL;
+-	if (filp->f_mode & FMODE_WRITE)
++	if ((filp->f_mode & FMODE_WRITE) != 0)
+ 		return -EINVAL;
+ 
+ 	return 0;
+ }
+ 
++static atomic_t host_sleep_count = ATOMIC_INIT(0);
++
+ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
+-                             loff_t * offp)
++			     loff_t *offp)
+ {
+-        u32 data;
+-        int n, ret = 0, have_data;
+-
+-        while(size){
+-                n = os_read_file(random_fd, &data, sizeof(data));
+-                if(n > 0){
+-                        have_data = n;
+-                        while (have_data && size) {
+-                                if (put_user((u8)data, buf++)) {
+-                                        ret = ret ? : -EFAULT;
+-                                        break;
+-                                }
+-                                size--;
+-                                ret++;
+-                                have_data--;
+-                                data>>=8;
+-                        }
+-                }
+-                else if(n == -EAGAIN){
+-                        if (filp->f_flags & O_NONBLOCK)
+-                                return ret ? : -EAGAIN;
+-
+-                        if(need_resched())
+-                                schedule_timeout_interruptible(1);
+-                }
+-                else return n;
++	u32 data;
++	int n, ret = 0, have_data;
++
++	while (size) {
++		n = os_read_file(random_fd, &data, sizeof(data));
++		if (n > 0) {
++			have_data = n;
++			while (have_data && size) {
++				if (put_user((u8) data, buf++)) {
++					ret = ret ? : -EFAULT;
++					break;
++				}
++				size--;
++				ret++;
++				have_data--;
++				data >>= 8;
++			}
++		}
++		else if (n == -EAGAIN) {
++			DECLARE_WAITQUEUE(wait, current);
++
++			if (filp->f_flags & O_NONBLOCK)
++				return ret ? : -EAGAIN;
++
++			atomic_inc(&host_sleep_count);
++			reactivate_fd(random_fd, RANDOM_IRQ);
++			add_sigio_fd(random_fd);
++
++			add_wait_queue(&host_read_wait, &wait);
++			set_task_state(current, TASK_INTERRUPTIBLE);
++
++			schedule();
++			set_task_state(current, TASK_RUNNING);
++			remove_wait_queue(&host_read_wait, &wait);
++
++			if (atomic_dec_and_test(&host_sleep_count)) {
++				ignore_sigio_fd(random_fd);
++				deactivate_fd(random_fd, RANDOM_IRQ);
++			}
++		}
++		else
++			return n;
++
+ 		if (signal_pending (current))
+ 			return ret ? : -ERESTARTSYS;
+ 	}
+@@ -86,6 +109,13 @@ static struct miscdevice rng_miscdev = {
+ 	&rng_chrdev_ops,
+ };
+ 
++static irqreturn_t random_interrupt(int irq, void *data)
++{
++	wake_up(&host_read_wait);
++
++	return IRQ_HANDLED;
++}
++
+ /*
+  * rng_init - initialize RNG module
+  */
+@@ -93,28 +123,33 @@ static int __init rng_init (void)
+ {
+ 	int err;
+ 
+-        err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
+-        if(err < 0)
+-                goto out;
++	err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
++	if (err < 0)
++		goto out;
+ 
+-        random_fd = err;
++	random_fd = err;
+ 
+-        err = os_set_fd_block(random_fd, 0);
+-        if(err)
++	err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
++			     IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
++			     NULL);
++	if (err)
+ 		goto err_out_cleanup_hw;
+ 
++	sigio_broken(random_fd, 1);
++
+ 	err = misc_register (&rng_miscdev);
+ 	if (err) {
+-		printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
++		printk (KERN_ERR RNG_MODULE_NAME ": misc device register "
++			"failed\n");
+ 		goto err_out_cleanup_hw;
+ 	}
++out:
++	return err;
+ 
+- out:
+-        return err;
+-
+- err_out_cleanup_hw:
+-        random_fd = -1;
+-        goto out;
++err_out_cleanup_hw:
++	os_close_file(random_fd);
++	random_fd = -1;
++	goto out;
+ }
+ 
+ /*
+@@ -122,6 +157,7 @@ static int __init rng_init (void)
+  */
+ static void __exit rng_cleanup (void)
+ {
++	os_close_file(random_fd);
+ 	misc_deregister (&rng_miscdev);
+ }
+ 
+diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
+index 8b80505..a1c2d2c 100644
+--- a/arch/um/drivers/slip_user.c
++++ b/arch/um/drivers/slip_user.c
+@@ -96,7 +96,7 @@ static int slip_tramp(char **argv, int fd)
+ 	pid = err;
+ 
+ 	output_len = UM_KERN_PAGE_SIZE;
+-	output = kmalloc(output_len, UM_GFP_KERNEL);
++	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
+ 	if (output == NULL) {
+ 		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
+ 		       "buffer\n");
+diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
+index c930fed..495858a 100644
+--- a/arch/um/drivers/tty.c
++++ b/arch/um/drivers/tty.c
+@@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
+ 	}
+ 	str++;
+ 
+-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
++	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ 	if (data == NULL)
+ 		return NULL;
+ 	*data = ((struct tty_chan) { .dev 	= str,
+diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
+index 5e45e39..44ad160 100644
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -1178,8 +1178,8 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
+ 	 * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
+ 	 * for the original diagnosis.
+ 	 */
+-	if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
+-			   sizeof(unsigned long) - 1))
++	if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
++					 sizeof(unsigned long)) - 1))
+ 		(*cow_offset)--;
+ 
+ 	bitmap_words[0] = bitmap[*cow_offset];
+diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
+index 8a1c18a..da2caa5 100644
+--- a/arch/um/drivers/xterm.c
++++ b/arch/um/drivers/xterm.c
+@@ -30,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
+ {
+ 	struct xterm_chan *data;
+ 
+-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
++	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ 	if (data == NULL)
+ 		return NULL;
+ 	*data = ((struct xterm_chan) { .pid 		= -1,
+diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
+index cac542d..58e852d 100644
+--- a/arch/um/include/as-layout.h
++++ b/arch/um/include/as-layout.h
+@@ -23,16 +23,16 @@
+  */
+ 
+ #ifdef __ASSEMBLY__
+-#define _AC(X, Y)	(Y)
++#define _UML_AC(X, Y)	(Y)
+ #else
+-#define __AC(X, Y)	(X (Y))
+-#define _AC(X, Y)	__AC(X, Y)
++#define __UML_AC(X, Y)	(X(Y))
++#define _UML_AC(X, Y)	__UML_AC(X, Y)
+ #endif
+ 
+-#define STUB_START _AC(, 0x100000)
+-#define STUB_CODE _AC((unsigned long), STUB_START)
+-#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
+-#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
++#define STUB_START _UML_AC(, 0x100000)
++#define STUB_CODE _UML_AC((unsigned long), STUB_START)
++#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
++#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
+ 
+ #ifndef __ASSEMBLY__
+ 
+diff --git a/arch/um/include/line.h b/arch/um/include/line.h
+index 979b73e..311a0d3 100644
+--- a/arch/um/include/line.h
++++ b/arch/um/include/line.h
+@@ -58,11 +58,11 @@ struct line {
+ };
+ 
+ #define LINE_INIT(str, d) \
+-	{ .count_lock =	SPIN_LOCK_UNLOCKED, \
++	{ .count_lock =	__SPIN_LOCK_UNLOCKED((str).count_lock), \
+ 	  .init_str =	str,	\
+ 	  .init_pri =	INIT_STATIC, \
+ 	  .valid =	1, \
+-	  .lock =	SPIN_LOCK_UNLOCKED, \
++	  .lock =	__SPIN_LOCK_UNLOCKED((str).lock), \
+ 	  .driver =	d }
+ 
+ extern void line_close(struct tty_struct *tty, struct file * filp);
+diff --git a/arch/um/include/os.h b/arch/um/include/os.h
+index 32c799e..e2716ac 100644
+--- a/arch/um/include/os.h
++++ b/arch/um/include/os.h
+@@ -290,6 +290,7 @@ extern void os_set_ioignore(void);
+ extern int add_sigio_fd(int fd);
+ extern int ignore_sigio_fd(int fd);
+ extern void maybe_sigio_broken(int fd, int read);
++extern void sigio_broken(int fd, int read);
+ 
+ /* sys-x86_64/prctl.c */
+ extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+diff --git a/arch/um/include/process.h b/arch/um/include/process.h
+index 5af9157..bb873a5 100644
+--- a/arch/um/include/process.h
++++ b/arch/um/include/process.h
+@@ -1,5 +1,5 @@
+ /* 
+- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike at karaya.com)
++ * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+  * Licensed under the GPL
+  */
+ 
+@@ -8,18 +8,10 @@
+ 
+ #include <signal.h>
+ 
+-extern void sig_handler(int sig, struct sigcontext sc);
+-extern void alarm_handler(int sig, struct sigcontext sc);
++/* Copied from linux/compiler-gcc.h since we can't include it directly */
++#define barrier() __asm__ __volatile__("": : :"memory")
+ 
+-#endif
++extern void sig_handler(int sig, struct sigcontext *sc);
++extern void alarm_handler(int sig, struct sigcontext *sc);
+ 
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only.  This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-file-style: "linux"
+- * End:
+- */
++#endif
+diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
+index cd2327d..3d31bba 100644
+--- a/arch/um/include/skas_ptrace.h
++++ b/arch/um/include/skas_ptrace.h
+@@ -1,5 +1,5 @@
+ /* 
+- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike at karaya.com)
++ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+  * Licensed under the GPL
+  */
+ 
+@@ -12,14 +12,3 @@
+ #include "sysdep/skas_ptrace.h"
+ 
+ #endif
+-
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only.  This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-file-style: "linux"
+- * End:
+- */
+diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
+index 7565072..ef56247 100644
+--- a/arch/um/include/sysdep-i386/ptrace_user.h
++++ b/arch/um/include/sysdep-i386/ptrace_user.h
+@@ -41,38 +41,10 @@
+ #define PT_SP_OFFSET PT_OFFSET(UESP)
+ #define PT_SP(regs) ((regs)[UESP])
+ 
+-#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
++#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE)
+ 
+ #ifndef FRAME_SIZE
+ #define FRAME_SIZE (17)
+ #endif
+-#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
+-
+-#define FP_FRAME_SIZE (27)
+-#define FPX_FRAME_SIZE (128)
+-
+-#ifdef PTRACE_GETREGS
+-#define UM_HAVE_GETREGS
+-#endif
+-
+-#ifdef PTRACE_SETREGS
+-#define UM_HAVE_SETREGS
+-#endif
+-
+-#ifdef PTRACE_GETFPREGS
+-#define UM_HAVE_GETFPREGS
+-#endif
+-
+-#ifdef PTRACE_SETFPREGS
+-#define UM_HAVE_SETFPREGS
+-#endif
+-
+-#ifdef PTRACE_GETFPXREGS
+-#define UM_HAVE_GETFPXREGS
+-#endif
+-
+-#ifdef PTRACE_SETFPXREGS
+-#define UM_HAVE_SETFPXREGS
+-#endif
+ 
+ #endif
+diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
+index 67e7712..f583c87 100644
+--- a/arch/um/include/sysdep-i386/sigcontext.h
++++ b/arch/um/include/sysdep-i386/sigcontext.h
+@@ -10,7 +10,7 @@
+ 
+ #define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
+ 
+-#define GET_FAULTINFO_FROM_SC(fi,sc) \
++#define GET_FAULTINFO_FROM_SC(fi, sc) \
+ 	{ \
+ 		(fi).cr2 = SC_CR2(sc); \
+ 		(fi).error_code = SC_ERR(sc); \
+diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
+index 45c0bd8..4dbccdb 100644
+--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
++++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
+@@ -48,7 +48,8 @@
+ #define PT_ORIG_RAX_OFFSET (ORIG_RAX)
+ #define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
+ 
+-/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
++/*
++ * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+  * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
+  * 2.4 name and value for 2.4 host compatibility.
+  */
+@@ -56,7 +57,8 @@
+ #define PTRACE_OLDSETOPTIONS 21
+ #endif
+ 
+-/* These are before the system call, so the system call number is RAX
++/*
++ * These are before the system call, so the system call number is RAX
+  * rather than ORIG_RAX, and arg4 is R10 rather than RCX
+  */
+ #define REGS_SYSCALL_NR PT_INDEX(RAX)
+@@ -73,14 +75,3 @@
+ #define FP_SIZE (HOST_FP_SIZE)
+ 
+ #endif
+-
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only.  This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-file-style: "linux"
+- * End:
+- */
+diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
+index 0ad17cb..c554d70 100644
+--- a/arch/um/include/um_malloc.h
++++ b/arch/um/include/um_malloc.h
+@@ -8,15 +8,12 @@
+ 
+ #include "kern_constants.h"
+ 
+-extern void *__kmalloc(int size, int flags);
+-static inline void *kmalloc(int size, int flags)
+-{
+-	return __kmalloc(size, flags);
+-}
+-
++extern void *uml_kmalloc(int size, int flags);
+ extern void kfree(const void *ptr);
+ 
+ extern void *vmalloc(unsigned long size);
+ extern void vfree(void *ptr);
+ 
+ #endif /* __UM_MALLOC_H__ */
++
++
+diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
+index 26090b7..9975e1a 100644
+--- a/arch/um/kernel/dyn.lds.S
++++ b/arch/um/kernel/dyn.lds.S
+@@ -1,4 +1,5 @@
+ #include <asm-generic/vmlinux.lds.h>
++#include <asm/page.h>
+ 
+ OUTPUT_FORMAT(ELF_FORMAT)
+ OUTPUT_ARCH(ELF_ARCH)
+@@ -21,7 +22,7 @@ SECTIONS
+ 	_einittext = .;
+   }
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+ 
+   /* Read-only sections, merged into text segment: */
+   .hash           : { *(.hash) }
+@@ -68,9 +69,9 @@ SECTIONS
+     /* .gnu.warning sections are handled specially by elf32.em.  */
+     *(.gnu.warning)
+ 
+-    . = ALIGN(4096);
++    . = ALIGN(PAGE_SIZE);
+   } =0x90909090
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .syscall_stub : {
+ 	__syscall_stub_start = .;
+ 	*(.__syscall_stub*)
+diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
+index 2eea1ff..b0ee646 100644
+--- a/arch/um/kernel/mem.c
++++ b/arch/um/kernel/mem.c
+@@ -375,3 +375,8 @@ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ 	return pmd;
+ }
+ #endif
++
++void *uml_kmalloc(int size, int flags)
++{
++	return kmalloc(size, flags);
++}
+diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
+index 0d0cea2..c3e2f36 100644
+--- a/arch/um/kernel/time.c
++++ b/arch/um/kernel/time.c
+@@ -75,7 +75,7 @@ static irqreturn_t um_timer(int irq, void *dev)
+ 
+ static cycle_t itimer_read(void)
+ {
+-	return os_nsecs();
++	return os_nsecs() / 1000;
+ }
+ 
+ static struct clocksource itimer_clocksource = {
+@@ -83,7 +83,7 @@ static struct clocksource itimer_clocksource = {
+ 	.rating		= 300,
+ 	.read		= itimer_read,
+ 	.mask		= CLOCKSOURCE_MASK(64),
+-	.mult		= 1,
++	.mult		= 1000,
+ 	.shift		= 0,
+ 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+ };
+diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
+index 56deed6..9db85b2 100644
+--- a/arch/um/kernel/um_arch.c
++++ b/arch/um/kernel/um_arch.c
+@@ -150,7 +150,7 @@ __uml_setup("root=", uml_root_setup,
+ static int __init no_skas_debug_setup(char *line, int *add)
+ {
+ 	printf("'debug' is not necessary to gdb UML in skas mode - run \n");
+-	printf("'gdb linux'");
++	printf("'gdb linux'\n");
+ 
+ 	return 0;
+ }
+@@ -258,6 +258,7 @@ int __init linux_main(int argc, char **argv)
+ {
+ 	unsigned long avail, diff;
+ 	unsigned long virtmem_size, max_physmem;
++	unsigned long stack;
+ 	unsigned int i;
+ 	int add;
+ 	char * mode;
+@@ -348,7 +349,9 @@ int __init linux_main(int argc, char **argv)
+ 	}
+ 
+ 	virtmem_size = physmem_size;
+-	avail = TASK_SIZE - start_vm;
++	stack = (unsigned long) argv;
++	stack &= ~(1024 * 1024 - 1);
++	avail = stack - start_vm;
+ 	if (physmem_size > avail)
+ 		virtmem_size = avail;
+ 	end_vm = start_vm + virtmem_size;
+diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
+index 5828c1d..11b8352 100644
+--- a/arch/um/kernel/uml.lds.S
++++ b/arch/um/kernel/uml.lds.S
+@@ -1,4 +1,5 @@
+ #include <asm-generic/vmlinux.lds.h>
++#include <asm/page.h>
+ 
+ OUTPUT_FORMAT(ELF_FORMAT)
+ OUTPUT_ARCH(ELF_ARCH)
+@@ -26,7 +27,7 @@ SECTIONS
+ 	INIT_TEXT
+ 	_einittext = .;
+   }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+ 
+   .text      :
+   {
+@@ -39,7 +40,7 @@ SECTIONS
+     *(.gnu.linkonce.t*)
+   }
+ 
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE);
+   .syscall_stub : {
+ 	__syscall_stub_start = .;
+ 	*(.__syscall_stub*)
+@@ -79,7 +80,7 @@ SECTIONS
+   .sdata     : { *(.sdata) }
+   _edata  =  .;
+   PROVIDE (edata = .);
+-  . = ALIGN(0x1000);
++  . = ALIGN(PAGE_SIZE);
+   .sbss      :
+   {
+    __bss_start = .;
+diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
+index 6fb0b17..cc72cb2 100644
+--- a/arch/um/os-Linux/drivers/ethertap_user.c
++++ b/arch/um/os-Linux/drivers/ethertap_user.c
+@@ -52,7 +52,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
+ 		return;
+ 	}
+ 
+-	output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
++	output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+ 	if (output == NULL)
+ 		printk(UM_KERN_ERR "etap_change : Failed to allocate output "
+ 		       "buffer\n");
+@@ -165,7 +165,7 @@ static int etap_open(void *data)
+ 	err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
+ 			 control_fds[1], data_fds[0], data_fds[1]);
+ 	output_len = UM_KERN_PAGE_SIZE;
+-	output = kmalloc(output_len, UM_GFP_KERNEL);
++	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
+ 	read_output(control_fds[0], output, output_len);
+ 
+ 	if (output == NULL)
+diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
+index f25c29a..74ca7aa 100644
+--- a/arch/um/os-Linux/helper.c
++++ b/arch/um/os-Linux/helper.c
+@@ -71,8 +71,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
+ 	data.pre_data = pre_data;
+ 	data.argv = argv;
+ 	data.fd = fds[1];
+-	data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+-					kmalloc(PATH_MAX, UM_GFP_KERNEL);
++	data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
++					uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
+ 	pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
+ 	if (pid < 0) {
+ 		ret = -errno;
+diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
+index abb9b0f..eee69b9 100644
+--- a/arch/um/os-Linux/main.c
++++ b/arch/um/os-Linux/main.c
+@@ -199,7 +199,7 @@ void *__wrap_malloc(int size)
+ 		return __real_malloc(size);
+ 	else if (size <= UM_KERN_PAGE_SIZE)
+ 		/* finding contiguous pages can be hard*/
+-		ret = kmalloc(size, UM_GFP_KERNEL);
++		ret = uml_kmalloc(size, UM_GFP_KERNEL);
+ 	else ret = vmalloc(size);
+ 
+ 	/*
+diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
+index abf47a7..eb8f2e4 100644
+--- a/arch/um/os-Linux/sigio.c
++++ b/arch/um/os-Linux/sigio.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
++ * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+  * Licensed under the GPL
+  */
+ 
+@@ -15,6 +15,7 @@
+ #include "kern_util.h"
+ #include "init.h"
+ #include "os.h"
++#include "process.h"
+ #include "sigio.h"
+ #include "um_malloc.h"
+ #include "user.h"
+@@ -109,7 +110,7 @@ static int need_poll(struct pollfds *polls, int n)
+ 	if (n <= polls->size)
+ 		return 0;
+ 
+-	new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
++	new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
+ 	if (new == NULL) {
+ 		printk(UM_KERN_ERR "need_poll : failed to allocate new "
+ 		       "pollfds\n");
+@@ -243,7 +244,7 @@ static struct pollfd *setup_initial_poll(int fd)
+ {
+ 	struct pollfd *p;
+ 
+-	p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
++	p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
+ 	if (p == NULL) {
+ 		printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
+ 		       "poll\n");
+@@ -338,20 +339,10 @@ out_close1:
+ 	close(l_write_sigio_fds[1]);
+ }
+ 
+-/* Changed during early boot */
+-static int pty_output_sigio = 0;
+-static int pty_close_sigio = 0;
+-
+-void maybe_sigio_broken(int fd, int read)
++void sigio_broken(int fd, int read)
+ {
+ 	int err;
+ 
+-	if (!isatty(fd))
+-		return;
+-
+-	if ((read || pty_output_sigio) && (!read || pty_close_sigio))
+-		return;
+-
+ 	write_sigio_workaround();
+ 
+ 	sigio_lock();
+@@ -370,6 +361,21 @@ out:
+ 	sigio_unlock();
+ }
+ 
++/* Changed during early boot */
++static int pty_output_sigio;
++static int pty_close_sigio;
++
++void maybe_sigio_broken(int fd, int read)
++{
++	if (!isatty(fd))
++		return;
++
++	if ((read || pty_output_sigio) && (!read || pty_close_sigio))
++		return;
++
++	sigio_broken(fd, read);
++}
++
+ static void sigio_cleanup(void)
+ {
+ 	if (write_sigio_pid == -1)
+@@ -383,7 +389,7 @@ static void sigio_cleanup(void)
+ __uml_exitcall(sigio_cleanup);
+ 
+ /* Used as a flag during SIGIO testing early in boot */
+-static volatile int got_sigio = 0;
++static int got_sigio;
+ 
+ static void __init handler(int sig)
+ {
+@@ -498,7 +504,8 @@ static void tty_output(int master, int slave)
+ 	if (errno != EAGAIN)
+ 		printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
+ 		       errno);
+-	while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
++	while (((n = read(slave, buf, sizeof(buf))) > 0) &&
++	       !({ barrier(); got_sigio; }))
+ 		;
+ 
+ 	if (got_sigio) {
+diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
+index 3f1694b..5aade60 100644
+--- a/arch/um/os-Linux/signal.c
++++ b/arch/um/os-Linux/signal.c
+@@ -12,6 +12,7 @@
+ #include "as-layout.h"
+ #include "kern_util.h"
+ #include "os.h"
++#include "process.h"
+ #include "sysdep/barrier.h"
+ #include "sysdep/sigcontext.h"
+ #include "user.h"
+diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
+index 1e8cba6..6be028c 100644
+--- a/arch/um/os-Linux/skas/process.c
++++ b/arch/um/os-Linux/skas/process.c
+@@ -442,7 +442,7 @@ void userspace(struct uml_pt_regs *regs)
+ 				unblock_signals();
+ 				break;
+ 			default:
+-			        printk(UM_KERN_ERR "userspace - child stopped "
++				printk(UM_KERN_ERR "userspace - child stopped "
+ 				       "with signal %d\n", sig);
+ 				fatal_sigsegv();
+ 			}
+diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
+index 997d019..b4b36e0 100644
+--- a/arch/um/os-Linux/start_up.c
++++ b/arch/um/os-Linux/start_up.c
+@@ -23,6 +23,7 @@
+ #include "mem_user.h"
+ #include "ptrace_user.h"
+ #include "registers.h"
++#include "skas.h"
+ #include "skas_ptrace.h"
+ 
+ static void ptrace_child(void)
+@@ -140,14 +141,27 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
+ }
+ 
+ /* Changed only during early boot */
+-int ptrace_faultinfo = 1;
+-int ptrace_ldt = 1;
+-int proc_mm = 1;
+-int skas_needs_stub = 0;
++int ptrace_faultinfo;
++static int disable_ptrace_faultinfo;
++
++int ptrace_ldt;
++static int disable_ptrace_ldt;
++
++int proc_mm;
++static int disable_proc_mm;
++
++int have_switch_mm;
++static int disable_switch_mm;
++
++int skas_needs_stub;
+ 
+ static int __init skas0_cmd_param(char *str, int* add)
+ {
+-	ptrace_faultinfo = proc_mm = 0;
++	disable_ptrace_faultinfo = 1;
++	disable_ptrace_ldt = 1;
++	disable_proc_mm = 1;
++	disable_switch_mm = 1;
++
+ 	return 0;
+ }
+ 
+@@ -157,15 +171,12 @@ static int __init mode_skas0_cmd_param(char *str, int* add)
+ 	__attribute__((alias("skas0_cmd_param")));
+ 
+ __uml_setup("skas0", skas0_cmd_param,
+-		"skas0\n"
+-		"    Disables SKAS3 usage, so that SKAS0 is used, unless \n"
+-	        "    you specify mode=tt.\n\n");
++"skas0\n"
++"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
+ 
+ __uml_setup("mode=skas0", mode_skas0_cmd_param,
+-		"mode=skas0\n"
+-		"    Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
+-		"    specify mode=tt. Note that this was recently added - on \n"
+-		"    older kernels you must use simply \"skas0\".\n\n");
++"mode=skas0\n"
++"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
+ 
+ /* Changed only during early boot */
+ static int force_sysemu_disabled = 0;
+@@ -360,7 +371,7 @@ void __init os_early_checks(void)
+ 
+ static int __init noprocmm_cmd_param(char *str, int* add)
+ {
+-	proc_mm = 0;
++	disable_proc_mm = 1;
+ 	return 0;
+ }
+ 
+@@ -372,7 +383,7 @@ __uml_setup("noprocmm", noprocmm_cmd_param,
+ 
+ static int __init noptracefaultinfo_cmd_param(char *str, int* add)
+ {
+-	ptrace_faultinfo = 0;
++	disable_ptrace_faultinfo = 1;
+ 	return 0;
+ }
+ 
+@@ -384,7 +395,7 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
+ 
+ static int __init noptraceldt_cmd_param(char *str, int* add)
+ {
+-	ptrace_ldt = 0;
++	disable_ptrace_ldt = 1;
+ 	return 0;
+ }
+ 
+@@ -404,17 +415,15 @@ static inline void check_skas3_ptrace_faultinfo(void)
+ 
+ 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
+ 	if (n < 0) {
+-		ptrace_faultinfo = 0;
+ 		if (errno == EIO)
+ 			non_fatal("not found\n");
+ 		else
+ 			perror("not found");
+-	}
++	} else if (disable_ptrace_faultinfo)
++		non_fatal("found but disabled on command line\n");
+ 	else {
+-		if (!ptrace_faultinfo)
+-			non_fatal("found but disabled on command line\n");
+-		else
+-			non_fatal("found\n");
++		ptrace_faultinfo = 1;
++		non_fatal("found\n");
+ 	}
+ 
+ 	stop_ptraced_child(pid, 1, 1);
+@@ -437,38 +446,30 @@ static inline void check_skas3_ptrace_ldt(void)
+ 	if (n < 0) {
+ 		if (errno == EIO)
+ 			non_fatal("not found\n");
+-		else {
++		else
+ 			perror("not found");
+-		}
+-		ptrace_ldt = 0;
+-	}
++	} else if (disable_ptrace_ldt)
++		non_fatal("found, but use is disabled\n");
+ 	else {
+-		if (ptrace_ldt)
+-			non_fatal("found\n");
+-		else
+-			non_fatal("found, but use is disabled\n");
++		ptrace_ldt = 1;
++		non_fatal("found\n");
+ 	}
+ 
+ 	stop_ptraced_child(pid, 1, 1);
+-#else
+-	/* PTRACE_LDT might be disabled via cmdline option.
+-	 * We want to override this, else we might use the stub
+-	 * without real need
+-	 */
+-	ptrace_ldt = 1;
+ #endif
+ }
+ 
+ static inline void check_skas3_proc_mm(void)
+ {
+ 	non_fatal("  - /proc/mm...");
+-	if (access("/proc/mm", W_OK) < 0) {
+-		proc_mm = 0;
++	if (access("/proc/mm", W_OK) < 0)
+ 		perror("not found");
+-	}
+-	else if (!proc_mm)
++	else if (disable_proc_mm)
+ 		non_fatal("found but disabled on command line\n");
+-	else non_fatal("found\n");
++	else {
++		proc_mm = 1;
++		non_fatal("found\n");
++	}
+ }
+ 
+ void can_do_skas(void)
+diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
+index b613473..c6183e7 100644
+--- a/arch/um/os-Linux/sys-i386/registers.c
++++ b/arch/um/os-Linux/sys-i386/registers.c
+@@ -5,6 +5,7 @@
+  */
+ 
+ #include <errno.h>
++#include <asm/user.h>
+ #include "kern_constants.h"
+ #include "longjmp.h"
+ #include "user.h"
+@@ -74,10 +75,10 @@ int put_fp_registers(int pid, unsigned long *regs)
+ 
+ void arch_init_registers(int pid)
+ {
+-	unsigned long fpx_regs[HOST_XFP_SIZE];
++	struct user_fxsr_struct fpx_regs;
+ 	int err;
+ 
+-	err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
++	err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
+ 	if (!err)
+ 		return;
+ 
+diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
+index e492805..bee98f4 100644
+--- a/arch/um/os-Linux/time.c
++++ b/arch/um/os-Linux/time.c
+@@ -9,7 +9,9 @@
+ #include <time.h>
+ #include <sys/time.h>
+ #include "kern_constants.h"
++#include "kern_util.h"
+ #include "os.h"
++#include "process.h"
+ #include "user.h"
+ 
+ int set_interval(void)
+@@ -58,12 +60,17 @@ static inline long long timeval_to_ns(const struct timeval *tv)
+ long long disable_timer(void)
+ {
+ 	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
++	int remain, max = UM_NSEC_PER_SEC / UM_HZ;
+ 
+ 	if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
+ 		printk(UM_KERN_ERR "disable_timer - setitimer failed, "
+ 		       "errno = %d\n", errno);
+ 
+-	return timeval_to_ns(&time.it_value);
++	remain = timeval_to_ns(&time.it_value);
++	if (remain > max)
++		remain = max;
++
++	return remain;
+ }
+ 
+ long long os_nsecs(void)
+@@ -79,7 +86,44 @@ static int after_sleep_interval(struct timespec *ts)
+ {
+ 	return 0;
+ }
++
++static void deliver_alarm(void)
++{
++	alarm_handler(SIGVTALRM, NULL);
++}
++
++static unsigned long long sleep_time(unsigned long long nsecs)
++{
++	return nsecs;
++}
++
+ #else
++unsigned long long last_tick;
++unsigned long long skew;
++
++static void deliver_alarm(void)
++{
++	unsigned long long this_tick = os_nsecs();
++	int one_tick = UM_NSEC_PER_SEC / UM_HZ;
++
++	if (last_tick == 0)
++		last_tick = this_tick - one_tick;
++
++	skew += this_tick - last_tick;
++
++	while (skew >= one_tick) {
++		alarm_handler(SIGVTALRM, NULL);
++		skew -= one_tick;
++	}
++
++	last_tick = this_tick;
++}
++
++static unsigned long long sleep_time(unsigned long long nsecs)
++{
++	return nsecs > skew ? nsecs - skew : 0;
++}
++
+ static inline long long timespec_to_us(const struct timespec *ts)
+ {
+ 	return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
+@@ -102,6 +146,8 @@ static int after_sleep_interval(struct timespec *ts)
+ 	 */
+ 	if (start_usecs > usec)
+ 		start_usecs = usec;
++
++	start_usecs -= skew / UM_NSEC_PER_USEC;
+ 	tv = ((struct timeval) { .tv_sec  = start_usecs / UM_USEC_PER_SEC,
+ 				 .tv_usec = start_usecs % UM_USEC_PER_SEC });
+ 	interval = ((struct itimerval) { { 0, usec }, tv });
+@@ -113,8 +159,6 @@ static int after_sleep_interval(struct timespec *ts)
+ }
+ #endif
+ 
+-extern void alarm_handler(int sig, struct sigcontext *sc);
+-
+ void idle_sleep(unsigned long long nsecs)
+ {
+ 	struct timespec ts;
+@@ -126,10 +170,12 @@ void idle_sleep(unsigned long long nsecs)
+ 	 */
+ 	if (nsecs == 0)
+ 		nsecs = UM_NSEC_PER_SEC / UM_HZ;
++
++	nsecs = sleep_time(nsecs);
+ 	ts = ((struct timespec) { .tv_sec	= nsecs / UM_NSEC_PER_SEC,
+ 				  .tv_nsec	= nsecs % UM_NSEC_PER_SEC });
+ 
+ 	if (nanosleep(&ts, &ts) == 0)
+-		alarm_handler(SIGVTALRM, NULL);
++		deliver_alarm();
+ 	after_sleep_interval(&ts);
+ }
+diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
+index 6b44999..c9b1765 100644
+--- a/arch/um/sys-i386/ptrace.c
++++ b/arch/um/sys-i386/ptrace.c
+@@ -148,14 +148,13 @@ int peek_user(struct task_struct *child, long addr, long data)
+ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+ {
+ 	int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
+-	long fpregs[HOST_FP_SIZE];
++	struct user_i387_struct fpregs;
+ 
+-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
+-	err = save_fp_registers(userspace_pid[cpu], fpregs);
++	err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
+ 	if (err)
+ 		return err;
+ 
+-	n = copy_to_user(buf, fpregs, sizeof(fpregs));
++	n = copy_to_user(buf, &fpregs, sizeof(fpregs));
+ 	if(n > 0)
+ 		return -EFAULT;
+ 
+@@ -165,27 +164,26 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+ {
+ 	int n, cpu = ((struct thread_info *) child->stack)->cpu;
+-	long fpregs[HOST_FP_SIZE];
++	struct user_i387_struct fpregs;
+ 
+-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
+-	n = copy_from_user(fpregs, buf, sizeof(fpregs));
++	n = copy_from_user(&fpregs, buf, sizeof(fpregs));
+ 	if (n > 0)
+ 		return -EFAULT;
+ 
+-	return restore_fp_registers(userspace_pid[cpu], fpregs);
++	return restore_fp_registers(userspace_pid[cpu],
++				    (unsigned long *) &fpregs);
+ }
+ 
+ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+ {
+ 	int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
+-	long fpregs[HOST_XFP_SIZE];
++	struct user_fxsr_struct fpregs;
+ 
+-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
+-	err = save_fpx_registers(userspace_pid[cpu], fpregs);
++	err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
+ 	if (err)
+ 		return err;
+ 
+-	n = copy_to_user(buf, fpregs, sizeof(fpregs));
++	n = copy_to_user(buf, &fpregs, sizeof(fpregs));
+ 	if(n > 0)
+ 		return -EFAULT;
+ 
+@@ -195,14 +193,14 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+ {
+ 	int n, cpu = ((struct thread_info *) child->stack)->cpu;
+-	long fpregs[HOST_XFP_SIZE];
++	struct user_fxsr_struct fpregs;
+ 
+-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
+-	n = copy_from_user(fpregs, buf, sizeof(fpregs));
++	n = copy_from_user(&fpregs, buf, sizeof(fpregs));
+ 	if (n > 0)
+ 		return -EFAULT;
+ 
+-	return restore_fpx_registers(userspace_pid[cpu], fpregs);
++	return restore_fpx_registers(userspace_pid[cpu],
++				     (unsigned long *) &fpregs);
+ }
+ 
+ long subarch_ptrace(struct task_struct *child, long request, long addr,
+diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
+index 39bd32b..5f883bf 100644
+--- a/arch/um/sys-i386/user-offsets.c
++++ b/arch/um/sys-i386/user-offsets.c
+@@ -22,7 +22,7 @@ void foo(void)
+ 	OFFSET(HOST_SC_CR2, sigcontext, cr2);
+ 
+ 	DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
+-	DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
++	DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct));
+ 
+ 	DEFINE(HOST_IP, EIP);
+ 	DEFINE(HOST_SP, UESP);
+diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
+index 2f3443c..9735854 100644
+--- a/arch/um/sys-x86_64/user-offsets.c
++++ b/arch/um/sys-x86_64/user-offsets.c
+@@ -24,7 +24,6 @@ void foo(void)
+ 	OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+ 
+ 	DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
+-	DEFINE(HOST_XFP_SIZE, 0);
+ 	DEFINE_LONGS(HOST_RBX, RBX);
+ 	DEFINE_LONGS(HOST_RCX, RCX);
+ 	DEFINE_LONGS(HOST_RDI, RDI);
+diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
+index 22fab6c..7da00b7 100644
+--- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S
++++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
+@@ -12,11 +12,6 @@ ENTRY(_start)
+ 
+ SECTIONS
+ {
+-	. = HEADER_OFFSET;
+-	.header : {
+-		 *(.header)
+-	}
+-
+ 	. = 0;
+ 	.text : {
+ 		 *(.text*)
+@@ -50,6 +45,11 @@ SECTIONS
+ 		__bss_end = .;
+ 	}
+ 
++	. = HEADER_OFFSET;
++	.header : {
++		*(.header)
++	}
++
+ 	. = ALIGN(16);
+ 	_end = .;
+ 
+diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
+index 0c37f16..c5ef1af 100644
+--- a/arch/x86/kernel/pci-dma.c
++++ b/arch/x86/kernel/pci-dma.c
+@@ -385,11 +385,13 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ 	if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
+ 		return memory;
+ 
+-	if (!dev)
++	if (!dev) {
+ 		dev = &fallback_dev;
++		gfp |= GFP_DMA;
++	}
+ 	dma_mask = dev->coherent_dma_mask;
+ 	if (dma_mask == 0)
+-		dma_mask = DMA_32BIT_MASK;
++		dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
+ 
+ 	/* Device not DMA able */
+ 	if (dev->dma_mask == NULL)
+@@ -403,7 +405,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ 	   larger than 16MB and in this case we have a chance of
+ 	   finding fitting memory in the next higher zone first. If
+ 	   not retry with true GFP_DMA. -AK */
+-	if (dma_mask <= DMA_32BIT_MASK)
++	if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
+ 		gfp |= GFP_DMA32;
+ #endif
+ 
+diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
+index fb03ef3..a7835f2 100644
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -1303,6 +1303,9 @@ static const struct user_regset_view user_x86_64_view = {
+ #define genregs32_get		genregs_get
+ #define genregs32_set		genregs_set
+ 
++#define user_i387_ia32_struct	user_i387_struct
++#define user32_fxsr_struct	user_fxsr_struct
++
+ #endif	/* CONFIG_X86_64 */
+ 
+ #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
+@@ -1315,13 +1318,13 @@ static const struct user_regset x86_32_regsets[] = {
+ 	},
+ 	[REGSET_FP] = {
+ 		.core_note_type = NT_PRFPREG,
+-		.n = sizeof(struct user_i387_struct) / sizeof(u32),
++		.n = sizeof(struct user_i387_ia32_struct) / sizeof(u32),
+ 		.size = sizeof(u32), .align = sizeof(u32),
+ 		.active = fpregs_active, .get = fpregs_get, .set = fpregs_set
+ 	},
+ 	[REGSET_XFP] = {
+ 		.core_note_type = NT_PRXFPREG,
+-		.n = sizeof(struct user_i387_struct) / sizeof(u32),
++		.n = sizeof(struct user32_fxsr_struct) / sizeof(u32),
+ 		.size = sizeof(u32), .align = sizeof(u32),
+ 		.active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
+ 	},
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index c0c68c1..6f80b85 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -12,6 +12,7 @@
+ #include <asm/mpspec.h>
+ #include <asm/apicdef.h>
+ 
++#ifdef CONFIG_X86_LOCAL_APIC
+ unsigned int num_processors;
+ unsigned disabled_cpus __cpuinitdata;
+ /* Processor that is doing the boot up */
+@@ -23,8 +24,9 @@ EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+ 
+ /* Bitmask of physically existing CPUs */
+ physid_mask_t phys_cpu_present_map;
++#endif
+ 
+-#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_SMP)
++#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP)
+ /*
+  * Copy data used in early init routines from the initial arrays to the
+  * per cpu data areas.  These arrays then become expendable and the
+diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
+index f2fc8fe..6dff128 100644
+--- a/arch/x86/kernel/setup_64.c
++++ b/arch/x86/kernel/setup_64.c
+@@ -951,7 +951,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
+ static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
+ {
+ 	if (c->x86 == 0x6 && c->x86_model >= 0xf)
+-		set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
++		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+ }
+ 
+ static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
+diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
+index 8f75893..0cb7aad 100644
+--- a/arch/x86/kernel/smp.c
++++ b/arch/x86/kernel/smp.c
+@@ -231,7 +231,8 @@ native_smp_call_function_mask(cpumask_t mask,
+ 	wmb();
+ 
+ 	/* Send a message to other CPUs */
+-	if (cpus_equal(mask, allbutself))
++	if (cpus_equal(mask, allbutself) &&
++	    cpus_equal(cpu_online_map, cpu_callout_map))
+ 		send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+ 	else
+ 		send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index 6b087ab..3898849 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -86,6 +86,7 @@ void *x86_bios_cpu_apicid_early_ptr;
+ 
+ #ifdef CONFIG_X86_32
+ u8 apicid_2_node[MAX_APICID];
++static int low_mappings;
+ #endif
+ 
+ /* State of each CPU */
+@@ -326,6 +327,12 @@ static void __cpuinit start_secondary(void *unused)
+ 		enable_8259A_irq(0);
+ 	}
+ 
++#ifdef CONFIG_X86_32
++	while (low_mappings)
++		cpu_relax();
++	__flush_tlb_all();
++#endif
++
+ 	/* This must be done before setting cpu_online_map */
+ 	set_cpu_sibling_map(raw_smp_processor_id());
+ 	wmb();
+@@ -1040,14 +1047,20 @@ int __cpuinit native_cpu_up(unsigned int cpu)
+ #ifdef CONFIG_X86_32
+ 	/* init low mem mapping */
+ 	clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+-			min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
++		min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+ 	flush_tlb_all();
+-#endif
++	low_mappings = 1;
+ 
+ 	err = do_boot_cpu(apicid, cpu);
+-	if (err < 0) {
++
++	zap_low_mappings();
++	low_mappings = 0;
++#else
++	err = do_boot_cpu(apicid, cpu);
++#endif
++	if (err) {
+ 		Dprintk("do_boot_cpu failed %d\n", err);
+-		return err;
++		return -EIO;
+ 	}
+ 
+ 	/*
+@@ -1259,9 +1272,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
+ 	setup_ioapic_dest();
+ #endif
+ 	check_nmi_watchdog();
+-#ifdef CONFIG_X86_32
+-	zap_low_mappings();
+-#endif
+ }
+ 
+ #ifdef CONFIG_HOTPLUG_CPU
+diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
+index 58882f9..f6c05d0 100644
+--- a/arch/x86/kernel/x8664_ksyms_64.c
++++ b/arch/x86/kernel/x8664_ksyms_64.c
+@@ -2,6 +2,7 @@
+    All C exports should go in the respective C files. */
+ 
+ #include <linux/module.h>
++#include <net/checksum.h>
+ #include <linux/smp.h>
+ 
+ #include <asm/processor.h>
+@@ -29,6 +30,8 @@ EXPORT_SYMBOL(__copy_from_user_inatomic);
+ EXPORT_SYMBOL(copy_page);
+ EXPORT_SYMBOL(clear_page);
+ 
++EXPORT_SYMBOL(csum_partial);
++
+ /*
+  * Export string functions. We normally rely on gcc builtin for most of these,
+  * but gcc sometimes decides not to inline them.
+diff --git a/arch/x86/lib/csum-partial_64.c b/arch/x86/lib/csum-partial_64.c
+index bc503f5..bf51144 100644
+--- a/arch/x86/lib/csum-partial_64.c
++++ b/arch/x86/lib/csum-partial_64.c
+@@ -136,8 +136,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
+ 						(__force u32)sum);
+ }
+ 
+-EXPORT_SYMBOL(csum_partial);
+-
+ /*
+  * this routine is used for miscellaneous IP-like checksums, mainly
+  * in icmp.c
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index de236e4..ec30d10 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -438,8 +438,6 @@ void zap_low_mappings(void)
+ {
+ 	int i;
+ 
+-	save_pg_dir();
+-
+ 	/*
+ 	 * Zap initial low-memory mappings.
+ 	 *
+@@ -663,16 +661,8 @@ void __init mem_init(void)
+ 		test_wp_bit();
+ 
+ 	cpa_init();
+-
+-	/*
+-	 * Subtle. SMP is doing it's boot stuff late (because it has to
+-	 * fork idle threads) - but it also needs low mappings for the
+-	 * protected-mode entry to work. We zap these entries only after
+-	 * the WP-bit has been tested.
+-	 */
+-#ifndef CONFIG_SMP
++	save_pg_dir();
+ 	zap_low_mappings();
+-#endif
+ }
+ 
+ #ifdef CONFIG_MEMORY_HOTPLUG
+diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+index 60adbe2..bcb1a8e 100644
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -555,7 +555,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
+ 		"%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
+ 			current->comm, current->pid,
+ 			cattr_name(flags),
+-			offset, offset + size);
++			offset, (unsigned long long)(offset + size));
+ 		return 0;
+ 	}
+ 
+@@ -576,7 +576,7 @@ void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
+ 		"%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
+ 			current->comm, current->pid,
+ 			cattr_name(want_flags),
+-			addr, addr + size,
++			addr, (unsigned long long)(addr + size),
+ 			cattr_name(flags));
+ 	}
+ }
+diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
+index 8af0f0b..10fb308 100644
+--- a/arch/x86/pci/i386.c
++++ b/arch/x86/pci/i386.c
+@@ -301,15 +301,13 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ 	prot = pgprot_val(vma->vm_page_prot);
+ 	if (pat_wc_enabled && write_combine)
+ 		prot |= _PAGE_CACHE_WC;
+-	else if (pat_wc_enabled)
++	else if (pat_wc_enabled || boot_cpu_data.x86 > 3)
+ 		/*
+ 		 * ioremap() and ioremap_nocache() defaults to UC MINUS for now.
+ 		 * To avoid attribute conflicts, request UC MINUS here
+ 		 * aswell.
+ 		 */
+ 		prot |= _PAGE_CACHE_UC_MINUS;
+-	else if (boot_cpu_data.x86 > 3)
+-		prot |= _PAGE_CACHE_UC;
+ 
+ 	vma->vm_page_prot = __pgprot(prot);
+ 
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 2987fe4..6a9cc0d 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -482,6 +482,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
+ 	kobject_init(&q->kobj, &blk_queue_ktype);
+ 
+ 	mutex_init(&q->sysfs_lock);
++	spin_lock_init(&q->__queue_lock);
+ 
+ 	return q;
+ }
+@@ -544,10 +545,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
+ 	 * if caller didn't supply a lock, they get per-queue locking with
+ 	 * our embedded lock
+ 	 */
+-	if (!lock) {
+-		spin_lock_init(&q->__queue_lock);
++	if (!lock)
+ 		lock = &q->__queue_lock;
+-	}
+ 
+ 	q->request_fn		= rfn;
+ 	q->prep_rq_fn		= NULL;
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index bb93d4c..8dd8641 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -286,8 +286,14 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
+ 	t->max_hw_segments = min(t->max_hw_segments, b->max_hw_segments);
+ 	t->max_segment_size = min(t->max_segment_size, b->max_segment_size);
+ 	t->hardsect_size = max(t->hardsect_size, b->hardsect_size);
+-	if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
++	if (!t->queue_lock)
++		WARN_ON_ONCE(1);
++	else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
++		unsigned long flags;
++		spin_lock_irqsave(t->queue_lock, flags);
+ 		queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
++		spin_unlock_irqrestore(t->queue_lock, flags);
++	}
+ }
+ EXPORT_SYMBOL(blk_queue_stack_limits);
+ 
+diff --git a/block/blktrace.c b/block/blktrace.c
+index 568588c..b2cbb4e 100644
+--- a/block/blktrace.c
++++ b/block/blktrace.c
+@@ -476,7 +476,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
+ 
+ 	switch (cmd) {
+ 	case BLKTRACESETUP:
+-		strcpy(b, bdevname(bdev, b));
++		bdevname(bdev, b);
+ 		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+ 		break;
+ 	case BLKTRACESTART:
+diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
+index c70d0b6..c23177e 100644
+--- a/block/compat_ioctl.c
++++ b/block/compat_ioctl.c
+@@ -555,7 +555,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
+ 	if (copy_from_user(&cbuts, arg, sizeof(cbuts)))
+ 		return -EFAULT;
+ 
+-	strcpy(b, bdevname(bdev, b));
++	bdevname(bdev, b);
+ 
+ 	buts = (struct blk_user_trace_setup) {
+ 		.act_mask = cbuts.act_mask,
+diff --git a/block/genhd.c b/block/genhd.c
+index fda9c7a..129ad93 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -653,7 +653,7 @@ void genhd_media_change_notify(struct gendisk *disk)
+ EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+ #endif  /*  0  */
+ 
+-dev_t blk_lookup_devt(const char *name)
++dev_t blk_lookup_devt(const char *name, int part)
+ {
+ 	struct device *dev;
+ 	dev_t devt = MKDEV(0, 0);
+@@ -661,7 +661,11 @@ dev_t blk_lookup_devt(const char *name)
+ 	mutex_lock(&block_class_lock);
+ 	list_for_each_entry(dev, &block_class.devices, node) {
+ 		if (strcmp(dev->bus_id, name) == 0) {
+-			devt = dev->devt;
++			struct gendisk *disk = dev_to_disk(dev);
++
++			if (part < disk->minors)
++				devt = MKDEV(MAJOR(dev->devt),
++					     MINOR(dev->devt) + part);
+ 			break;
+ 		}
+ 	}
+@@ -669,7 +673,6 @@ dev_t blk_lookup_devt(const char *name)
+ 
+ 	return devt;
+ }
+-
+ EXPORT_SYMBOL(blk_lookup_devt);
+ 
+ struct gendisk *alloc_disk(int minors)
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index 0ef00e8..e085af0 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -140,7 +140,6 @@ int class_register(struct class *cls)
+ 
+ 	pr_debug("device class '%s': registering\n", cls->name);
+ 
+-	INIT_LIST_HEAD(&cls->children);
+ 	INIT_LIST_HEAD(&cls->devices);
+ 	INIT_LIST_HEAD(&cls->interfaces);
+ 	kset_init(&cls->class_dirs);
+diff --git a/drivers/base/memory.c b/drivers/base/memory.c
+index 8ce6de5..937e825 100644
+--- a/drivers/base/memory.c
++++ b/drivers/base/memory.c
+@@ -53,11 +53,13 @@ int register_memory_notifier(struct notifier_block *nb)
+ {
+         return blocking_notifier_chain_register(&memory_chain, nb);
+ }
++EXPORT_SYMBOL(register_memory_notifier);
+ 
+ void unregister_memory_notifier(struct notifier_block *nb)
+ {
+         blocking_notifier_chain_unregister(&memory_chain, nb);
+ }
++EXPORT_SYMBOL(unregister_memory_notifier);
+ 
+ /*
+  * register_memory - Setup a sysfs device for a memory block
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index 5dce387..595a925 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -196,6 +196,7 @@ config ESPSERIAL
+ config MOXA_INTELLIO
+ 	tristate "Moxa Intellio support"
+ 	depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
++	select FW_LOADER
+ 	help
+ 	  Say Y here if you have a Moxa Intellio multiport serial card.
+ 
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 5a54555..1926883 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -2352,10 +2352,16 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
+ 
+ 	info->si_type		= (enum si_type) match->data;
+ 	info->addr_source	= "device-tree";
+-	info->io_setup		= mem_setup;
+ 	info->irq_setup		= std_irq_setup;
+ 
+-	info->io.addr_type	= IPMI_MEM_ADDR_SPACE;
++	if (resource.flags & IORESOURCE_IO) {
++		info->io_setup		= port_setup;
++		info->io.addr_type	= IPMI_IO_ADDR_SPACE;
++	} else {
++		info->io_setup		= mem_setup;
++		info->io.addr_type	= IPMI_MEM_ADDR_SPACE;
++	}
++
+ 	info->io.addr_data	= resource.start;
+ 
+ 	info->io.regsize	= regsize ? *regsize : DEFAULT_REGSIZE;
+diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
+index 2001b0e..55c1653 100644
+--- a/drivers/char/synclink_gt.c
++++ b/drivers/char/synclink_gt.c
+@@ -916,7 +916,7 @@ static int put_char(struct tty_struct *tty, unsigned char ch)
+ {
+ 	struct slgt_info *info = tty->driver_data;
+ 	unsigned long flags;
+-	int ret;
++	int ret = 0;
+ 
+ 	if (sanity_check(info, tty->name, "put_char"))
+ 		return 0;
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index 49c1a22..e94bee0 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1215,10 +1215,11 @@ int tty_check_change(struct tty_struct *tty)
+ 
+ 	if (!tty->pgrp) {
+ 		printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
+-		goto out;
++		goto out_unlock;
+ 	}
+ 	if (task_pgrp(current) == tty->pgrp)
+-		goto out;
++		goto out_unlock;
++	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ 	if (is_ignored(SIGTTOU))
+ 		goto out;
+ 	if (is_current_pgrp_orphaned()) {
+@@ -1229,6 +1230,8 @@ int tty_check_change(struct tty_struct *tty)
+ 	set_thread_flag(TIF_SIGPENDING);
+ 	ret = -ERESTARTSYS;
+ out:
++	return ret;
++out_unlock:
+ 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ 	return ret;
+ }
+diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
+index 491718f..cae9dc8 100644
+--- a/drivers/i2c/busses/i2c-au1550.c
++++ b/drivers/i2c/busses/i2c-au1550.c
+@@ -335,7 +335,7 @@ i2c_au1550_probe(struct platform_device *pdev)
+ 		goto out_mem;
+ 	}
+ 
+-	priv->psc_base = r->start;
++	priv->psc_base = CKSEG1ADDR(r->start);
+ 	priv->xfer_timeout = 200;
+ 	priv->ack_timeout = 200;
+ 
+diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
+index f702f91..b4f3aef 100644
+--- a/drivers/ide/Kconfig
++++ b/drivers/ide/Kconfig
+@@ -1,8 +1,6 @@
+ #
+ # IDE ATA ATAPI Block device driver configuration
+ #
+-# Andre Hedrick <andre at linux-ide.org>
+-#
+ 
+ # Select HAVE_IDE if IDE is supported
+ config HAVE_IDE
+@@ -335,7 +333,7 @@ config BLK_DEV_CMD640
+ 	  This driver will work automatically in PCI based systems (most new
+ 	  systems have PCI slots). But if your system uses VESA local bus
+ 	  (VLB) instead of PCI, you must also supply a kernel boot parameter
+-	  to enable the CMD640 bugfix/support: "ide0=cmd640_vlb". (Try "man
++	  to enable the CMD640 bugfix/support: "cmd640.probe_vlb". (Try "man
+ 	  bootparam" or see the documentation of your boot loader about how to
+ 	  pass options to the kernel.)
+ 
+@@ -457,27 +455,11 @@ config BLK_DEV_ALI15X3
+ 	  onboard chipsets.  It also tests for Simplex mode and enables
+ 	  normal dual channel support.
+ 
+-	  If you say Y here, you also need to say Y to "Use DMA by default
+-	  when available", above.  Please read the comments at the top of
++	  Please read the comments at the top of
+ 	  <file:drivers/ide/pci/alim15x3.c>.
+ 
+ 	  If unsure, say N.
+ 
+-config WDC_ALI15X3
+-	bool "ALI M15x3 WDC support (DANGEROUS)"
+-	depends on BLK_DEV_ALI15X3
+-	---help---
+-	  This allows for UltraDMA support for WDC drives that ignore CRC
+-	  checking. You are a fool for enabling this option, but there have
+-	  been requests. DO NOT COMPLAIN IF YOUR DRIVE HAS FS CORRUPTION, IF
+-	  YOU ENABLE THIS! No one will listen, just laugh for ignoring this
+-	  SERIOUS WARNING.
+-
+-	  Using this option can allow WDC drives to run at ATA-4/5 transfer
+-	  rates with only an ATA-2 support structure.
+-
+-	  SAY N!
+-
+ config BLK_DEV_AMD74XX
+ 	tristate "AMD and nVidia IDE support"
+ 	depends on !ARM
+@@ -520,9 +502,6 @@ config BLK_DEV_CY82C693
+ 	  This driver adds detection and support for the CY82C693 chipset
+ 	  used on Digital's PC-Alpha 164SX boards.
+ 
+-	  If you say Y here, you need to say Y to "Use DMA by default
+-	  when available" as well.
+-
+ config BLK_DEV_CS5520
+ 	tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
+@@ -613,13 +592,12 @@ config BLK_DEV_SC1200
+ 	  National SCx200 series of embedded x86 "Geode" systems.
+ 
+ config BLK_DEV_PIIX
+-	tristate "Intel PIIXn chipsets support"
++	tristate "Intel PIIX/ICH chipsets support"
+ 	select BLK_DEV_IDEDMA_PCI
+ 	help
+-	  This driver adds explicit support for Intel PIIX and ICH chips
+-	  and also for the Efar Victory66 (slc90e66) chip.  This allows
+-	  the kernel to change PIO, DMA and UDMA speeds and to configure
+-	  the chip to optimum performance.
++	  This driver adds explicit support for Intel PIIX and ICH chips.
++	  This allows the kernel to change PIO, DMA and UDMA speeds and to
++	  configure the chip to optimum performance.
+ 
+ config BLK_DEV_IT8213
+ 	tristate "IT8213 IDE support"
+@@ -657,11 +635,7 @@ config BLK_DEV_PDC202XX_OLD
+ 	  happen if the BIOS revisions of all installed cards (three-max) do
+ 	  not match, the driver attempts to do dynamic tuning of the chipset
+ 	  at boot-time for max-speed.  Ultra33 BIOS 1.25 or newer is required
+-	  for more than one card. This card may require that you say Y to
+-	  "Special UDMA Feature".
+-
+-	  If you say Y here, you need to say Y to "Use DMA by default when
+-	  available" as well.
++	  for more than one card.
+ 
+ 	  Please read the comments at the top of
+ 	  <file:drivers/ide/pci/pdc202xx_old.c>.
+@@ -710,9 +684,6 @@ config BLK_DEV_SIS5513
+ 	  ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740,
+ 	  SiS745, SiS750
+ 
+-	  If you say Y here, you need to say Y to "Use DMA by default when
+-	  available" as well.
+-
+ 	  Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
+ 
+ config BLK_DEV_SL82C105
+@@ -734,9 +705,6 @@ config BLK_DEV_SLC90E66
+ 	  and it will handle timing cycles.  Since this is an improved
+ 	  look-a-like to the PIIX4 it should be a nice addition.
+ 
+-	  If you say Y here, you need to say Y to "Use DMA by default when
+-	  available" as well.
+-
+ 	  Please read the comments at the top of
+ 	  <file:drivers/ide/pci/slc90e66.c>.
+ 
+@@ -888,17 +856,17 @@ config BLK_DEV_IDEDOUBLER
+ 	bool "Amiga IDE Doubler support (EXPERIMENTAL)"
+ 	depends on BLK_DEV_GAYLE && EXPERIMENTAL
+ 	---help---
+-	  This driver provides support for the so-called `IDE doublers' (made
++	  This feature provides support for the so-called `IDE doublers' (made
+ 	  by various manufacturers, e.g. Eyetech) that can be connected to
+ 	  the on-board IDE interface of some Amiga models. Using such an IDE
+ 	  doubler, you can connect up to four instead of two IDE devices to
+ 	  the Amiga's on-board IDE interface.
+ 
+ 	  Note that the normal Amiga Gayle IDE driver may not work correctly
+-	  if you have an IDE doubler and don't enable this driver!
++	  if you have an IDE doubler and don't enable this feature!
+ 
+-	  Say Y if you have an IDE doubler.  The driver is enabled at kernel
+-	  runtime using the "ide=doubler" kernel boot parameter.
++	  Say Y if you have an IDE doubler.  The feature is enabled at kernel
++	  runtime using the "gayle.doubler" kernel boot parameter.
+ 
+ config BLK_DEV_BUDDHA
+ 	tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
+diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
+index 57d9a9a..0daf923 100644
+--- a/drivers/ide/ide-iops.c
++++ b/drivers/ide/ide-iops.c
+@@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive)
+ 	hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
+ }
+ 
+-void SELECT_MASK (ide_drive_t *drive, int mask)
++static void SELECT_MASK(ide_drive_t *drive, int mask)
+ {
+ 	const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+ 
+diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
+index 712d17b..52fee3d 100644
+--- a/drivers/ide/mips/swarm.c
++++ b/drivers/ide/mips/swarm.c
+@@ -4,7 +4,7 @@
+  *	Author:	Manish Lachwani, mlachwani at mvista.com
+  * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
+  *	Author: Maciej W. Rozycki <macro at mips.com>
+- * Copyright (c) 2006  Maciej W. Rozycki
++ * Copyright (c) 2006, 2008  Maciej W. Rozycki
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -70,8 +70,9 @@ static int __devinit swarm_ide_probe(struct device *dev)
+ 	ide_hwif_t *hwif;
+ 	u8 __iomem *base;
+ 	phys_t offset, size;
++	hw_regs_t hw;
+ 	int i;
+-	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
++	u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
+ 
+ 	if (!SIBYTE_HAVE_IDE)
+ 		return -ENODEV;
+@@ -112,14 +113,15 @@ static int __devinit swarm_ide_probe(struct device *dev)
+ 	hwif->host_flags = IDE_HFLAG_MMIO;
+ 	default_hwif_mmiops(hwif);
+ 
+-	hwif->chipset = ide_generic;
+-
+ 	for (i = 0; i <= 7; i++)
+-		hwif->io_ports_array[i] =
++		hw.io_ports_array[i] =
+ 				(unsigned long)(base + ((0x1f0 + i) << 5));
+-	hwif->io_ports.ctl_addr =
++	hw.io_ports.ctl_addr =
+ 				(unsigned long)(base + (0x3f6 << 5));
+-	hwif->irq = K_INT_GB_IDE;
++	hw.irq = K_INT_GB_IDE;
++	hw.chipset = ide_generic;
++
++	ide_init_port_hw(hwif, &hw);
+ 
+ 	idx[0] = hwif->index;
+ 
+diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
+index c1922f9..f2129d5 100644
+--- a/drivers/ide/pci/alim15x3.c
++++ b/drivers/ide/pci/alim15x3.c
+@@ -39,6 +39,16 @@
+ #include <asm/io.h>
+ 
+ /*
++ * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking
++ * (this is DANGEROUS and could result in data corruption).
++ */
++static int wdc_udma;
++
++module_param(wdc_udma, bool, 0);
++MODULE_PARM_DESC(wdc_udma,
++		 "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)");
++
++/*
+  *	ALi devices are not plug in. Otherwise these static values would
+  *	need to go. They ought to go away anyway
+  */
+@@ -76,11 +86,6 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 		a_clc = 0;
+ 	c_time = ide_pio_timings[pio].cycle_time;
+ 
+-#if 0
+-	if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
+-		r_clc = 0;
+-#endif
+-
+ 	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
+ 		r_clc = 1;
+ 	} else {
+@@ -110,16 +115,6 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 	pci_write_config_byte(dev, port, s_clc);
+ 	pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
+ 	local_irq_restore(flags);
+-
+-	/*
+-	 * setup   active  rec
+-	 * { 70,   165,    365 },   PIO Mode 0
+-	 * { 50,   125,    208 },   PIO Mode 1
+-	 * { 30,   100,    110 },   PIO Mode 2
+-	 * { 30,   80,     70  },   PIO Mode 3 with IORDY
+-	 * { 25,   70,     25  },   PIO Mode 4 with IORDY  ns
+-	 * { 20,   50,     30  }    PIO Mode 5 with IORDY (nonstandard)
+-	 */
+ }
+ 
+ /**
+@@ -131,9 +126,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
+  *	The actual rules for the ALi are:
+  *		No UDMA on revisions <= 0x20
+  *		Disk only for revisions < 0xC2
+- *		Not WDC drives for revisions < 0xC2
+- *
+- *	FIXME: WDC ifdef needs to die
++ *		Not WDC drives on M1543C-E (?)
+  */
+ 
+ static u8 ali_udma_filter(ide_drive_t *drive)
+@@ -141,10 +134,9 @@ static u8 ali_udma_filter(ide_drive_t *drive)
+ 	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
+ 		if (drive->media != ide_disk)
+ 			return 0;
+-#ifndef CONFIG_WDC_ALI15X3
+-		if (chip_is_1543c_e && strstr(drive->id->model, "WDC "))
++		if (chip_is_1543c_e && strstr(drive->id->model, "WDC ") &&
++		    wdc_udma == 0)
+ 			return 0;
+-#endif
+ 	}
+ 
+ 	return drive->hwif->ultra_mask;
+@@ -537,17 +529,9 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = {
+  
+ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+ {
+-	static struct pci_device_id ati_rs100[] = {
+-		{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
+-		{ },
+-	};
+-
+ 	struct ide_port_info d = ali15x3_chipset;
+ 	u8 rev = dev->revision, idx = id->driver_data;
+ 
+-	if (pci_dev_present(ati_rs100))
+-		printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+-
+ 	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
+ 	if (rev <= 0xC4)
+ 		d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
+diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
+index 17669a4..992b1cf 100644
+--- a/drivers/ide/pci/cs5520.c
++++ b/drivers/ide/pci/cs5520.c
+@@ -119,6 +119,7 @@ static const struct ide_dma_ops cs5520_dma_ops = {
+ 	.dma_timeout		= ide_dma_timeout,
+ };
+ 
++/* FIXME: VDMA is disabled because it caused system hangs */
+ #define DECLARE_CS_DEV(name_str)				\
+ 	{							\
+ 		.name		= name_str,			\
+@@ -126,7 +127,6 @@ static const struct ide_dma_ops cs5520_dma_ops = {
+ 		.dma_ops	= &cs5520_dma_ops,		\
+ 		.host_flags	= IDE_HFLAG_ISA_PORTS |		\
+ 				  IDE_HFLAG_CS5520 |		\
+-				  IDE_HFLAG_VDMA |		\
+ 				  IDE_HFLAG_NO_ATAPI_DMA |	\
+ 				  IDE_HFLAG_ABUSE_SET_DMA_MODE, \
+ 		.pio_mask	= ATA_PIO4,			\
+diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
+index ebf9d30..3f441fc 100644
+--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
++++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
+@@ -405,11 +405,11 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
+ 	struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2);
+ 
+ 	ptr = wq->sq_rptr + count;
+-	sqp += count;
++	sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
+ 	while (ptr != wq->sq_wptr) {
+ 		insert_sq_cqe(wq, cq, sqp);
+-		sqp++;
+ 		ptr++;
++		sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
+ 		flushed++;
+ 	}
+ 	return flushed;
+diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
+index ce7b7c3..daad09a 100644
+--- a/drivers/infiniband/hw/ipath/ipath_driver.c
++++ b/drivers/infiniband/hw/ipath/ipath_driver.c
+@@ -1894,7 +1894,7 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
+ 	 */
+ 	if (dd->ipath_flags & IPATH_HAS_SEND_DMA) {
+ 		int skip_cancel;
+-		u64 *statp = &dd->ipath_sdma_status;
++		unsigned long *statp = &dd->ipath_sdma_status;
+ 
+ 		spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
+ 		skip_cancel =
+@@ -2616,7 +2616,7 @@ int ipath_reset_device(int unit)
+ 				ipath_dbg("unit %u port %d is in use "
+ 					  "(PID %u cmd %s), can't reset\n",
+ 					  unit, i,
+-					  dd->ipath_pd[i]->port_pid,
++					  pid_nr(dd->ipath_pd[i]->port_pid),
+ 					  dd->ipath_pd[i]->port_comm);
+ 				ret = -EBUSY;
+ 				goto bail;
+@@ -2654,19 +2654,21 @@ bail:
+ static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
+ {
+ 	int i, sub, any = 0;
+-	pid_t pid;
++	struct pid *pid;
+ 
+ 	if (!dd->ipath_pd)
+ 		return 0;
+ 	for (i = 1; i < dd->ipath_cfgports; i++) {
+-		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt ||
+-		    !dd->ipath_pd[i]->port_pid)
++		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt)
+ 			continue;
+ 		pid = dd->ipath_pd[i]->port_pid;
++		if (!pid)
++			continue;
++
+ 		dev_info(&dd->pcidev->dev, "context %d in use "
+ 			  "(PID %u), sending signal %d\n",
+-			  i, pid, sig);
+-		kill_proc(pid, sig, 1);
++			  i, pid_nr(pid), sig);
++		kill_pid(pid, sig, 1);
+ 		any++;
+ 		for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) {
+ 			pid = dd->ipath_pd[i]->port_subpid[sub];
+@@ -2674,8 +2676,8 @@ static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
+ 				continue;
+ 			dev_info(&dd->pcidev->dev, "sub-context "
+ 				"%d:%d in use (PID %u), sending "
+-				"signal %d\n", i, sub, pid, sig);
+-			kill_proc(pid, sig, 1);
++				"signal %d\n", i, sub, pid_nr(pid), sig);
++			kill_pid(pid, sig, 1);
+ 			any++;
+ 		}
+ 	}
+diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
+index 3295177..b472b15 100644
+--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
++++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
+@@ -555,7 +555,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
+ 			p = dd->ipath_pageshadow[porttid + tid];
+ 			dd->ipath_pageshadow[porttid + tid] = NULL;
+ 			ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
+-				   pd->port_pid, tid);
++				   pid_nr(pd->port_pid), tid);
+ 			dd->ipath_f_put_tid(dd, &tidbase[tid],
+ 					    RCVHQ_RCV_TYPE_EXPECTED,
+ 					    dd->ipath_tidinvalid);
+@@ -1609,7 +1609,7 @@ static int try_alloc_port(struct ipath_devdata *dd, int port,
+ 			   port);
+ 		pd->port_cnt = 1;
+ 		port_fp(fp) = pd;
+-		pd->port_pid = current->pid;
++		pd->port_pid = get_pid(task_pid(current));
+ 		strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
+ 		ipath_stats.sps_ports++;
+ 		ret = 0;
+@@ -1793,14 +1793,15 @@ static int find_shared_port(struct file *fp,
+ 			}
+ 			port_fp(fp) = pd;
+ 			subport_fp(fp) = pd->port_cnt++;
+-			pd->port_subpid[subport_fp(fp)] = current->pid;
++			pd->port_subpid[subport_fp(fp)] =
++				get_pid(task_pid(current));
+ 			tidcursor_fp(fp) = 0;
+ 			pd->active_slaves |= 1 << subport_fp(fp);
+ 			ipath_cdbg(PROC,
+ 				   "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
+ 				   current->comm, current->pid,
+ 				   subport_fp(fp),
+-				   pd->port_comm, pd->port_pid,
++				   pd->port_comm, pid_nr(pd->port_pid),
+ 				   dd->ipath_unit, pd->port_port);
+ 			ret = 1;
+ 			goto done;
+@@ -2066,7 +2067,8 @@ static int ipath_close(struct inode *in, struct file *fp)
+ 		 * the slave(s) don't wait for receive data forever.
+ 		 */
+ 		pd->active_slaves &= ~(1 << fd->subport);
+-		pd->port_subpid[fd->subport] = 0;
++		put_pid(pd->port_subpid[fd->subport]);
++		pd->port_subpid[fd->subport] = NULL;
+ 		mutex_unlock(&ipath_mutex);
+ 		goto bail;
+ 	}
+@@ -2074,7 +2076,7 @@ static int ipath_close(struct inode *in, struct file *fp)
+ 
+ 	if (pd->port_hdrqfull) {
+ 		ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors "
+-			   "during run\n", pd->port_comm, pd->port_pid,
++			   "during run\n", pd->port_comm, pid_nr(pd->port_pid),
+ 			   pd->port_hdrqfull);
+ 		pd->port_hdrqfull = 0;
+ 	}
+@@ -2134,11 +2136,12 @@ static int ipath_close(struct inode *in, struct file *fp)
+ 			unlock_expected_tids(pd);
+ 		ipath_stats.sps_ports--;
+ 		ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
+-			   pd->port_comm, pd->port_pid,
++			   pd->port_comm, pid_nr(pd->port_pid),
+ 			   dd->ipath_unit, port);
+ 	}
+ 
+-	pd->port_pid = 0;
++	put_pid(pd->port_pid);
++	pd->port_pid = NULL;
+ 	dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */
+ 	mutex_unlock(&ipath_mutex);
+ 	ipath_free_pddata(dd, pd); /* after releasing the mutex */
+diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
+index 02b24a3..59a8b25 100644
+--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
++++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
+@@ -159,8 +159,8 @@ struct ipath_portdata {
+ 	/* saved total number of polled urgent packets for poll edge trigger */
+ 	u32 port_urgent_poll;
+ 	/* pid of process using this port */
+-	pid_t port_pid;
+-	pid_t port_subpid[INFINIPATH_MAX_SUBPORT];
++	struct pid *port_pid;
++	struct pid *port_subpid[INFINIPATH_MAX_SUBPORT];
+ 	/* same size as task_struct .comm[] */
+ 	char port_comm[16];
+ 	/* pkeys set by this use of this port */
+@@ -483,7 +483,7 @@ struct ipath_devdata {
+ 
+ 	/* SendDMA related entries */
+ 	spinlock_t            ipath_sdma_lock;
+-	u64                   ipath_sdma_status;
++	unsigned long         ipath_sdma_status;
+ 	unsigned long         ipath_sdma_abort_jiffies;
+ 	unsigned long         ipath_sdma_abort_intr_timeout;
+ 	unsigned long         ipath_sdma_buf_jiffies;
+@@ -822,8 +822,8 @@ struct ipath_devdata {
+ #define IPATH_SDMA_DISARMED  1
+ #define IPATH_SDMA_DISABLED  2
+ #define IPATH_SDMA_LAYERBUF  3
+-#define IPATH_SDMA_RUNNING  62
+-#define IPATH_SDMA_SHUTDOWN 63
++#define IPATH_SDMA_RUNNING  30
++#define IPATH_SDMA_SHUTDOWN 31
+ 
+ /* bit combinations that correspond to abort states */
+ #define IPATH_SDMA_ABORT_NONE 0
+diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
+index dd5b6e9..4715911 100644
+--- a/drivers/infiniband/hw/ipath/ipath_qp.c
++++ b/drivers/infiniband/hw/ipath/ipath_qp.c
+@@ -242,7 +242,6 @@ static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp)
+ {
+ 	struct ipath_qp *q, **qpp;
+ 	unsigned long flags;
+-	int fnd = 0;
+ 
+ 	spin_lock_irqsave(&qpt->lock, flags);
+ 
+@@ -253,51 +252,40 @@ static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp)
+ 			*qpp = qp->next;
+ 			qp->next = NULL;
+ 			atomic_dec(&qp->refcount);
+-			fnd = 1;
+ 			break;
+ 		}
+ 	}
+ 
+ 	spin_unlock_irqrestore(&qpt->lock, flags);
+-
+-	if (!fnd)
+-		return;
+-
+-	free_qpn(qpt, qp->ibqp.qp_num);
+-
+-	wait_event(qp->wait, !atomic_read(&qp->refcount));
+ }
+ 
+ /**
+- * ipath_free_all_qps - remove all QPs from the table
++ * ipath_free_all_qps - check for QPs still in use
+  * @qpt: the QP table to empty
++ *
++ * There should not be any QPs still in use.
++ * Free memory for table.
+  */
+-void ipath_free_all_qps(struct ipath_qp_table *qpt)
++unsigned ipath_free_all_qps(struct ipath_qp_table *qpt)
+ {
+ 	unsigned long flags;
+-	struct ipath_qp *qp, *nqp;
+-	u32 n;
++	struct ipath_qp *qp;
++	u32 n, qp_inuse = 0;
+ 
++	spin_lock_irqsave(&qpt->lock, flags);
+ 	for (n = 0; n < qpt->max; n++) {
+-		spin_lock_irqsave(&qpt->lock, flags);
+ 		qp = qpt->table[n];
+ 		qpt->table[n] = NULL;
+-		spin_unlock_irqrestore(&qpt->lock, flags);
+-
+-		while (qp) {
+-			nqp = qp->next;
+-			free_qpn(qpt, qp->ibqp.qp_num);
+-			if (!atomic_dec_and_test(&qp->refcount) ||
+-			    !ipath_destroy_qp(&qp->ibqp))
+-				ipath_dbg("QP memory leak!\n");
+-			qp = nqp;
+-		}
++
++		for (; qp; qp = qp->next)
++			qp_inuse++;
+ 	}
++	spin_unlock_irqrestore(&qpt->lock, flags);
+ 
+-	for (n = 0; n < ARRAY_SIZE(qpt->map); n++) {
++	for (n = 0; n < ARRAY_SIZE(qpt->map); n++)
+ 		if (qpt->map[n].page)
+-			free_page((unsigned long)qpt->map[n].page);
+-	}
++			free_page((unsigned long) qpt->map[n].page);
++	return qp_inuse;
+ }
+ 
+ /**
+@@ -336,11 +324,12 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
+ 	qp->remote_qpn = 0;
+ 	qp->qkey = 0;
+ 	qp->qp_access_flags = 0;
+-	qp->s_busy = 0;
++	atomic_set(&qp->s_dma_busy, 0);
+ 	qp->s_flags &= IPATH_S_SIGNAL_REQ_WR;
+ 	qp->s_hdrwords = 0;
+ 	qp->s_wqe = NULL;
+ 	qp->s_pkt_delay = 0;
++	qp->s_draining = 0;
+ 	qp->s_psn = 0;
+ 	qp->r_psn = 0;
+ 	qp->r_msn = 0;
+@@ -353,7 +342,8 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
+ 	}
+ 	qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
+ 	qp->r_nak_state = 0;
+-	qp->r_wrid_valid = 0;
++	qp->r_aflags = 0;
++	qp->r_flags = 0;
+ 	qp->s_rnr_timeout = 0;
+ 	qp->s_head = 0;
+ 	qp->s_tail = 0;
+@@ -361,7 +351,6 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
+ 	qp->s_last = 0;
+ 	qp->s_ssn = 1;
+ 	qp->s_lsn = 0;
+-	qp->s_wait_credit = 0;
+ 	memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue));
+ 	qp->r_head_ack_queue = 0;
+ 	qp->s_tail_ack_queue = 0;
+@@ -370,17 +359,17 @@ static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
+ 		qp->r_rq.wq->head = 0;
+ 		qp->r_rq.wq->tail = 0;
+ 	}
+-	qp->r_reuse_sge = 0;
+ }
+ 
+ /**
+- * ipath_error_qp - put a QP into an error state
+- * @qp: the QP to put into an error state
++ * ipath_error_qp - put a QP into the error state
++ * @qp: the QP to put into the error state
+  * @err: the receive completion error to signal if a RWQE is active
+  *
+  * Flushes both send and receive work queues.
+  * Returns true if last WQE event should be generated.
+  * The QP s_lock should be held and interrupts disabled.
++ * If we are already in error state, just return.
+  */
+ 
+ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
+@@ -389,8 +378,10 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
+ 	struct ib_wc wc;
+ 	int ret = 0;
+ 
+-	ipath_dbg("QP%d/%d in error state (%d)\n",
+-		  qp->ibqp.qp_num, qp->remote_qpn, err);
++	if (qp->state == IB_QPS_ERR)
++		goto bail;
++
++	qp->state = IB_QPS_ERR;
+ 
+ 	spin_lock(&dev->pending_lock);
+ 	if (!list_empty(&qp->timerwait))
+@@ -399,39 +390,21 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
+ 		list_del_init(&qp->piowait);
+ 	spin_unlock(&dev->pending_lock);
+ 
+-	wc.vendor_err = 0;
+-	wc.byte_len = 0;
+-	wc.imm_data = 0;
++	/* Schedule the sending tasklet to drain the send work queue. */
++	if (qp->s_last != qp->s_head)
++		ipath_schedule_send(qp);
++
++	memset(&wc, 0, sizeof(wc));
+ 	wc.qp = &qp->ibqp;
+-	wc.src_qp = 0;
+-	wc.wc_flags = 0;
+-	wc.pkey_index = 0;
+-	wc.slid = 0;
+-	wc.sl = 0;
+-	wc.dlid_path_bits = 0;
+-	wc.port_num = 0;
+-	if (qp->r_wrid_valid) {
+-		qp->r_wrid_valid = 0;
++	wc.opcode = IB_WC_RECV;
++
++	if (test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) {
+ 		wc.wr_id = qp->r_wr_id;
+-		wc.opcode = IB_WC_RECV;
+ 		wc.status = err;
+ 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
+ 	}
+ 	wc.status = IB_WC_WR_FLUSH_ERR;
+ 
+-	while (qp->s_last != qp->s_head) {
+-		struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
+-
+-		wc.wr_id = wqe->wr.wr_id;
+-		wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-		if (++qp->s_last >= qp->s_size)
+-			qp->s_last = 0;
+-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+-	}
+-	qp->s_cur = qp->s_tail = qp->s_head;
+-	qp->s_hdrwords = 0;
+-	qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
+-
+ 	if (qp->r_rq.wq) {
+ 		struct ipath_rwq *wq;
+ 		u32 head;
+@@ -447,7 +420,6 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
+ 		tail = wq->tail;
+ 		if (tail >= qp->r_rq.size)
+ 			tail = 0;
+-		wc.opcode = IB_WC_RECV;
+ 		while (tail != head) {
+ 			wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id;
+ 			if (++tail >= qp->r_rq.size)
+@@ -460,6 +432,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
+ 	} else if (qp->ibqp.event_handler)
+ 		ret = 1;
+ 
++bail:
+ 	return ret;
+ }
+ 
+@@ -478,11 +451,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 	struct ipath_ibdev *dev = to_idev(ibqp->device);
+ 	struct ipath_qp *qp = to_iqp(ibqp);
+ 	enum ib_qp_state cur_state, new_state;
+-	unsigned long flags;
+ 	int lastwqe = 0;
+ 	int ret;
+ 
+-	spin_lock_irqsave(&qp->s_lock, flags);
++	spin_lock_irq(&qp->s_lock);
+ 
+ 	cur_state = attr_mask & IB_QP_CUR_STATE ?
+ 		attr->cur_qp_state : qp->state;
+@@ -535,16 +507,42 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 
+ 	switch (new_state) {
+ 	case IB_QPS_RESET:
++		if (qp->state != IB_QPS_RESET) {
++			qp->state = IB_QPS_RESET;
++			spin_lock(&dev->pending_lock);
++			if (!list_empty(&qp->timerwait))
++				list_del_init(&qp->timerwait);
++			if (!list_empty(&qp->piowait))
++				list_del_init(&qp->piowait);
++			spin_unlock(&dev->pending_lock);
++			qp->s_flags &= ~IPATH_S_ANY_WAIT;
++			spin_unlock_irq(&qp->s_lock);
++			/* Stop the sending tasklet */
++			tasklet_kill(&qp->s_task);
++			wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));
++			spin_lock_irq(&qp->s_lock);
++		}
+ 		ipath_reset_qp(qp, ibqp->qp_type);
+ 		break;
+ 
++	case IB_QPS_SQD:
++		qp->s_draining = qp->s_last != qp->s_cur;
++		qp->state = new_state;
++		break;
++
++	case IB_QPS_SQE:
++		if (qp->ibqp.qp_type == IB_QPT_RC)
++			goto inval;
++		qp->state = new_state;
++		break;
++
+ 	case IB_QPS_ERR:
+ 		lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
+ 		break;
+ 
+ 	default:
++		qp->state = new_state;
+ 		break;
+-
+ 	}
+ 
+ 	if (attr_mask & IB_QP_PKEY_INDEX)
+@@ -597,8 +595,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
+ 		qp->s_max_rd_atomic = attr->max_rd_atomic;
+ 
+-	qp->state = new_state;
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
++	spin_unlock_irq(&qp->s_lock);
+ 
+ 	if (lastwqe) {
+ 		struct ib_event ev;
+@@ -612,7 +609,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 	goto bail;
+ 
+ inval:
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
++	spin_unlock_irq(&qp->s_lock);
+ 	ret = -EINVAL;
+ 
+ bail:
+@@ -643,7 +640,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 	attr->pkey_index = qp->s_pkey_index;
+ 	attr->alt_pkey_index = 0;
+ 	attr->en_sqd_async_notify = 0;
+-	attr->sq_draining = 0;
++	attr->sq_draining = qp->s_draining;
+ 	attr->max_rd_atomic = qp->s_max_rd_atomic;
+ 	attr->max_dest_rd_atomic = qp->r_max_rd_atomic;
+ 	attr->min_rnr_timer = qp->r_min_rnr_timer;
+@@ -833,6 +830,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
+ 		spin_lock_init(&qp->r_rq.lock);
+ 		atomic_set(&qp->refcount, 0);
+ 		init_waitqueue_head(&qp->wait);
++		init_waitqueue_head(&qp->wait_dma);
+ 		tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp);
+ 		INIT_LIST_HEAD(&qp->piowait);
+ 		INIT_LIST_HEAD(&qp->timerwait);
+@@ -926,6 +924,7 @@ bail_ip:
+ 	else
+ 		vfree(qp->r_rq.wq);
+ 	ipath_free_qp(&dev->qp_table, qp);
++	free_qpn(&dev->qp_table, qp->ibqp.qp_num);
+ bail_qp:
+ 	kfree(qp);
+ bail_swq:
+@@ -947,41 +946,44 @@ int ipath_destroy_qp(struct ib_qp *ibqp)
+ {
+ 	struct ipath_qp *qp = to_iqp(ibqp);
+ 	struct ipath_ibdev *dev = to_idev(ibqp->device);
+-	unsigned long flags;
+ 
+-	spin_lock_irqsave(&qp->s_lock, flags);
+-	qp->state = IB_QPS_ERR;
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
+-	spin_lock(&dev->n_qps_lock);
+-	dev->n_qps_allocated--;
+-	spin_unlock(&dev->n_qps_lock);
++	/* Make sure HW and driver activity is stopped. */
++	spin_lock_irq(&qp->s_lock);
++	if (qp->state != IB_QPS_RESET) {
++		qp->state = IB_QPS_RESET;
++		spin_lock(&dev->pending_lock);
++		if (!list_empty(&qp->timerwait))
++			list_del_init(&qp->timerwait);
++		if (!list_empty(&qp->piowait))
++			list_del_init(&qp->piowait);
++		spin_unlock(&dev->pending_lock);
++		qp->s_flags &= ~IPATH_S_ANY_WAIT;
++		spin_unlock_irq(&qp->s_lock);
++		/* Stop the sending tasklet */
++		tasklet_kill(&qp->s_task);
++		wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));
++	} else
++		spin_unlock_irq(&qp->s_lock);
+ 
+-	/* Stop the sending tasklet. */
+-	tasklet_kill(&qp->s_task);
++	ipath_free_qp(&dev->qp_table, qp);
+ 
+ 	if (qp->s_tx) {
+ 		atomic_dec(&qp->refcount);
+ 		if (qp->s_tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF)
+ 			kfree(qp->s_tx->txreq.map_addr);
++		spin_lock_irq(&dev->pending_lock);
++		list_add(&qp->s_tx->txreq.list, &dev->txreq_free);
++		spin_unlock_irq(&dev->pending_lock);
++		qp->s_tx = NULL;
+ 	}
+ 
+-	/* Make sure the QP isn't on the timeout list. */
+-	spin_lock_irqsave(&dev->pending_lock, flags);
+-	if (!list_empty(&qp->timerwait))
+-		list_del_init(&qp->timerwait);
+-	if (!list_empty(&qp->piowait))
+-		list_del_init(&qp->piowait);
+-	if (qp->s_tx)
+-		list_add(&qp->s_tx->txreq.list, &dev->txreq_free);
+-	spin_unlock_irqrestore(&dev->pending_lock, flags);
++	wait_event(qp->wait, !atomic_read(&qp->refcount));
+ 
+-	/*
+-	 * Make sure that the QP is not in the QPN table so receive
+-	 * interrupts will discard packets for this QP.  XXX Also remove QP
+-	 * from multicast table.
+-	 */
+-	if (atomic_read(&qp->refcount) != 0)
+-		ipath_free_qp(&dev->qp_table, qp);
++	/* all user's cleaned up, mark it available */
++	free_qpn(&dev->qp_table, qp->ibqp.qp_num);
++	spin_lock(&dev->n_qps_lock);
++	dev->n_qps_allocated--;
++	spin_unlock(&dev->n_qps_lock);
+ 
+ 	if (qp->ip)
+ 		kref_put(&qp->ip->ref, ipath_release_mmap_info);
+@@ -1026,48 +1028,6 @@ bail:
+ }
+ 
+ /**
+- * ipath_sqerror_qp - put a QP's send queue into an error state
+- * @qp: QP who's send queue will be put into an error state
+- * @wc: the WC responsible for putting the QP in this state
+- *
+- * Flushes the send work queue.
+- * The QP s_lock should be held and interrupts disabled.
+- */
+-
+-void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
+-{
+-	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+-	struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
+-
+-	ipath_dbg("Send queue error on QP%d/%d: err: %d\n",
+-		  qp->ibqp.qp_num, qp->remote_qpn, wc->status);
+-
+-	spin_lock(&dev->pending_lock);
+-	if (!list_empty(&qp->timerwait))
+-		list_del_init(&qp->timerwait);
+-	if (!list_empty(&qp->piowait))
+-		list_del_init(&qp->piowait);
+-	spin_unlock(&dev->pending_lock);
+-
+-	ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
+-	if (++qp->s_last >= qp->s_size)
+-		qp->s_last = 0;
+-
+-	wc->status = IB_WC_WR_FLUSH_ERR;
+-
+-	while (qp->s_last != qp->s_head) {
+-		wqe = get_swqe_ptr(qp, qp->s_last);
+-		wc->wr_id = wqe->wr.wr_id;
+-		wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
+-		if (++qp->s_last >= qp->s_size)
+-			qp->s_last = 0;
+-	}
+-	qp->s_cur = qp->s_tail = qp->s_head;
+-	qp->state = IB_QPS_SQE;
+-}
+-
+-/**
+  * ipath_get_credit - flush the send work queue of a QP
+  * @qp: the qp who's send work queue to flush
+  * @aeth: the Acknowledge Extended Transport Header
+@@ -1093,9 +1053,10 @@ void ipath_get_credit(struct ipath_qp *qp, u32 aeth)
+ 	}
+ 
+ 	/* Restart sending if it was blocked due to lack of credits. */
+-	if (qp->s_cur != qp->s_head &&
++	if ((qp->s_flags & IPATH_S_WAIT_SSN_CREDIT) &&
++	    qp->s_cur != qp->s_head &&
+ 	    (qp->s_lsn == (u32) -1 ||
+ 	     ipath_cmp24(get_swqe_ptr(qp, qp->s_cur)->ssn,
+ 			 qp->s_lsn + 1) <= 0))
+-		tasklet_hi_schedule(&qp->s_task);
++		ipath_schedule_send(qp);
+ }
+diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
+index 08b11b5..108df66 100644
+--- a/drivers/infiniband/hw/ipath/ipath_rc.c
++++ b/drivers/infiniband/hw/ipath/ipath_rc.c
+@@ -92,6 +92,10 @@ static int ipath_make_rc_ack(struct ipath_ibdev *dev, struct ipath_qp *qp,
+ 	u32 bth0;
+ 	u32 bth2;
+ 
++	/* Don't send an ACK if we aren't supposed to. */
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
++		goto bail;
++
+ 	/* header size in 32-bit words LRH+BTH = (8+12)/4. */
+ 	hwords = 5;
+ 
+@@ -238,14 +242,25 @@ int ipath_make_rc_req(struct ipath_qp *qp)
+ 	    ipath_make_rc_ack(dev, qp, ohdr, pmtu))
+ 		goto done;
+ 
+-	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) ||
+-	    qp->s_rnr_timeout || qp->s_wait_credit)
+-		goto bail;
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) {
++		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
++			goto bail;
++		/* We are in the error state, flush the work request. */
++		if (qp->s_last == qp->s_head)
++			goto bail;
++		/* If DMAs are in progress, we can't flush immediately. */
++		if (atomic_read(&qp->s_dma_busy)) {
++			qp->s_flags |= IPATH_S_WAIT_DMA;
++			goto bail;
++		}
++		wqe = get_swqe_ptr(qp, qp->s_last);
++		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
++		goto done;
++	}
+ 
+-	/* Limit the number of packets sent without an ACK. */
+-	if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) {
+-		qp->s_wait_credit = 1;
+-		dev->n_rc_stalls++;
++	/* Leave BUSY set until RNR timeout. */
++	if (qp->s_rnr_timeout) {
++		qp->s_flags |= IPATH_S_WAITING;
+ 		goto bail;
+ 	}
+ 
+@@ -257,6 +272,9 @@ int ipath_make_rc_req(struct ipath_qp *qp)
+ 	wqe = get_swqe_ptr(qp, qp->s_cur);
+ 	switch (qp->s_state) {
+ 	default:
++		if (!(ib_ipath_state_ops[qp->state] &
++		    IPATH_PROCESS_NEXT_SEND_OK))
++			goto bail;
+ 		/*
+ 		 * Resend an old request or start a new one.
+ 		 *
+@@ -294,8 +312,10 @@ int ipath_make_rc_req(struct ipath_qp *qp)
+ 		case IB_WR_SEND_WITH_IMM:
+ 			/* If no credit, return. */
+ 			if (qp->s_lsn != (u32) -1 &&
+-			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0)
++			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) {
++				qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT;
+ 				goto bail;
++			}
+ 			wqe->lpsn = wqe->psn;
+ 			if (len > pmtu) {
+ 				wqe->lpsn += (len - 1) / pmtu;
+@@ -325,8 +345,10 @@ int ipath_make_rc_req(struct ipath_qp *qp)
+ 		case IB_WR_RDMA_WRITE_WITH_IMM:
+ 			/* If no credit, return. */
+ 			if (qp->s_lsn != (u32) -1 &&
+-			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0)
++			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) {
++				qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT;
+ 				goto bail;
++			}
+ 			ohdr->u.rc.reth.vaddr =
+ 				cpu_to_be64(wqe->wr.wr.rdma.remote_addr);
+ 			ohdr->u.rc.reth.rkey =
+@@ -570,7 +592,11 @@ int ipath_make_rc_req(struct ipath_qp *qp)
+ 	ipath_make_ruc_header(dev, qp, ohdr, bth0 | (qp->s_state << 24), bth2);
+ done:
+ 	ret = 1;
++	goto unlock;
++
+ bail:
++	qp->s_flags &= ~IPATH_S_BUSY;
++unlock:
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 	return ret;
+ }
+@@ -606,7 +632,11 @@ static void send_rc_ack(struct ipath_qp *qp)
+ 
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 
++	/* Don't try to send ACKs if the link isn't ACTIVE */
+ 	dd = dev->dd;
++	if (!(dd->ipath_flags & IPATH_LINKACTIVE))
++		goto done;
++
+ 	piobuf = ipath_getpiobuf(dd, 0, NULL);
+ 	if (!piobuf) {
+ 		/*
+@@ -668,15 +698,16 @@ static void send_rc_ack(struct ipath_qp *qp)
+ 	goto done;
+ 
+ queue_ack:
+-	dev->n_rc_qacks++;
+-	qp->s_flags |= IPATH_S_ACK_PENDING;
+-	qp->s_nak_state = qp->r_nak_state;
+-	qp->s_ack_psn = qp->r_ack_psn;
++	if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK) {
++		dev->n_rc_qacks++;
++		qp->s_flags |= IPATH_S_ACK_PENDING;
++		qp->s_nak_state = qp->r_nak_state;
++		qp->s_ack_psn = qp->r_ack_psn;
++
++		/* Schedule the send tasklet. */
++		ipath_schedule_send(qp);
++	}
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+-
+-	/* Call ipath_do_rc_send() in another thread. */
+-	tasklet_hi_schedule(&qp->s_task);
+-
+ done:
+ 	return;
+ }
+@@ -735,7 +766,7 @@ static void reset_psn(struct ipath_qp *qp, u32 psn)
+ 	/*
+ 	 * Set the state to restart in the middle of a request.
+ 	 * Don't change the s_sge, s_cur_sge, or s_cur_size.
+-	 * See ipath_do_rc_send().
++	 * See ipath_make_rc_req().
+ 	 */
+ 	switch (opcode) {
+ 	case IB_WR_SEND:
+@@ -771,27 +802,14 @@ done:
+  *
+  * The QP s_lock should be held and interrupts disabled.
+  */
+-void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
++void ipath_restart_rc(struct ipath_qp *qp, u32 psn)
+ {
+ 	struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
+ 	struct ipath_ibdev *dev;
+ 
+ 	if (qp->s_retry == 0) {
+-		wc->wr_id = wqe->wr.wr_id;
+-		wc->status = IB_WC_RETRY_EXC_ERR;
+-		wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-		wc->vendor_err = 0;
+-		wc->byte_len = 0;
+-		wc->qp = &qp->ibqp;
+-		wc->imm_data = 0;
+-		wc->src_qp = qp->remote_qpn;
+-		wc->wc_flags = 0;
+-		wc->pkey_index = 0;
+-		wc->slid = qp->remote_ah_attr.dlid;
+-		wc->sl = qp->remote_ah_attr.sl;
+-		wc->dlid_path_bits = 0;
+-		wc->port_num = 0;
+-		ipath_sqerror_qp(qp, wc);
++		ipath_send_complete(qp, wqe, IB_WC_RETRY_EXC_ERR);
++		ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
+ 		goto bail;
+ 	}
+ 	qp->s_retry--;
+@@ -804,6 +822,8 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
+ 	spin_lock(&dev->pending_lock);
+ 	if (!list_empty(&qp->timerwait))
+ 		list_del_init(&qp->timerwait);
++	if (!list_empty(&qp->piowait))
++		list_del_init(&qp->piowait);
+ 	spin_unlock(&dev->pending_lock);
+ 
+ 	if (wqe->wr.opcode == IB_WR_RDMA_READ)
+@@ -812,7 +832,7 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
+ 		dev->n_rc_resends += (qp->s_psn - psn) & IPATH_PSN_MASK;
+ 
+ 	reset_psn(qp, psn);
+-	tasklet_hi_schedule(&qp->s_task);
++	ipath_schedule_send(qp);
+ 
+ bail:
+ 	return;
+@@ -820,13 +840,7 @@ bail:
+ 
+ static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
+ {
+-	if (qp->s_last_psn != psn) {
+-		qp->s_last_psn = psn;
+-		if (qp->s_wait_credit) {
+-			qp->s_wait_credit = 0;
+-			tasklet_hi_schedule(&qp->s_task);
+-		}
+-	}
++	qp->s_last_psn = psn;
+ }
+ 
+ /**
+@@ -845,6 +859,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ {
+ 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+ 	struct ib_wc wc;
++	enum ib_wc_status status;
+ 	struct ipath_swqe *wqe;
+ 	int ret = 0;
+ 	u32 ack_psn;
+@@ -909,7 +924,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 			 */
+ 			update_last_psn(qp, wqe->psn - 1);
+ 			/* Retry this request. */
+-			ipath_restart_rc(qp, wqe->psn, &wc);
++			ipath_restart_rc(qp, wqe->psn);
+ 			/*
+ 			 * No need to process the ACK/NAK since we are
+ 			 * restarting an earlier request.
+@@ -925,32 +940,23 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 		     wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)) {
+ 			qp->s_num_rd_atomic--;
+ 			/* Restart sending task if fence is complete */
+-			if ((qp->s_flags & IPATH_S_FENCE_PENDING) &&
+-			    !qp->s_num_rd_atomic) {
+-				qp->s_flags &= ~IPATH_S_FENCE_PENDING;
+-				tasklet_hi_schedule(&qp->s_task);
+-			} else if (qp->s_flags & IPATH_S_RDMAR_PENDING) {
+-				qp->s_flags &= ~IPATH_S_RDMAR_PENDING;
+-				tasklet_hi_schedule(&qp->s_task);
+-			}
++			if (((qp->s_flags & IPATH_S_FENCE_PENDING) &&
++			     !qp->s_num_rd_atomic) ||
++			    qp->s_flags & IPATH_S_RDMAR_PENDING)
++				ipath_schedule_send(qp);
+ 		}
+ 		/* Post a send completion queue entry if requested. */
+ 		if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
+ 		    (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
++			memset(&wc, 0, sizeof wc);
+ 			wc.wr_id = wqe->wr.wr_id;
+ 			wc.status = IB_WC_SUCCESS;
+ 			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-			wc.vendor_err = 0;
+ 			wc.byte_len = wqe->length;
+-			wc.imm_data = 0;
+ 			wc.qp = &qp->ibqp;
+ 			wc.src_qp = qp->remote_qpn;
+-			wc.wc_flags = 0;
+-			wc.pkey_index = 0;
+ 			wc.slid = qp->remote_ah_attr.dlid;
+ 			wc.sl = qp->remote_ah_attr.sl;
+-			wc.dlid_path_bits = 0;
+-			wc.port_num = 0;
+ 			ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0);
+ 		}
+ 		qp->s_retry = qp->s_retry_cnt;
+@@ -971,6 +977,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 		} else {
+ 			if (++qp->s_last >= qp->s_size)
+ 				qp->s_last = 0;
++			if (qp->state == IB_QPS_SQD && qp->s_last == qp->s_cur)
++				qp->s_draining = 0;
+ 			if (qp->s_last == qp->s_tail)
+ 				break;
+ 			wqe = get_swqe_ptr(qp, qp->s_last);
+@@ -994,7 +1002,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 			 */
+ 			if (ipath_cmp24(qp->s_psn, psn) <= 0) {
+ 				reset_psn(qp, psn + 1);
+-				tasklet_hi_schedule(&qp->s_task);
++				ipath_schedule_send(qp);
+ 			}
+ 		} else if (ipath_cmp24(qp->s_psn, psn) <= 0) {
+ 			qp->s_state = OP(SEND_LAST);
+@@ -1012,7 +1020,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 		if (qp->s_last == qp->s_tail)
+ 			goto bail;
+ 		if (qp->s_rnr_retry == 0) {
+-			wc.status = IB_WC_RNR_RETRY_EXC_ERR;
++			status = IB_WC_RNR_RETRY_EXC_ERR;
+ 			goto class_b;
+ 		}
+ 		if (qp->s_rnr_retry_cnt < 7)
+@@ -1033,6 +1041,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 			ib_ipath_rnr_table[(aeth >> IPATH_AETH_CREDIT_SHIFT) &
+ 					   IPATH_AETH_CREDIT_MASK];
+ 		ipath_insert_rnr_queue(qp);
++		ipath_schedule_send(qp);
+ 		goto bail;
+ 
+ 	case 3:		/* NAK */
+@@ -1050,37 +1059,25 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
+ 			 * RDMA READ response which terminates the RDMA
+ 			 * READ.
+ 			 */
+-			ipath_restart_rc(qp, psn, &wc);
++			ipath_restart_rc(qp, psn);
+ 			break;
+ 
+ 		case 1:	/* Invalid Request */
+-			wc.status = IB_WC_REM_INV_REQ_ERR;
++			status = IB_WC_REM_INV_REQ_ERR;
+ 			dev->n_other_naks++;
+ 			goto class_b;
+ 
+ 		case 2:	/* Remote Access Error */
+-			wc.status = IB_WC_REM_ACCESS_ERR;
++			status = IB_WC_REM_ACCESS_ERR;
+ 			dev->n_other_naks++;
+ 			goto class_b;
+ 
+ 		case 3:	/* Remote Operation Error */
+-			wc.status = IB_WC_REM_OP_ERR;
++			status = IB_WC_REM_OP_ERR;
+ 			dev->n_other_naks++;
+ 		class_b:
+-			wc.wr_id = wqe->wr.wr_id;
+-			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-			wc.vendor_err = 0;
+-			wc.byte_len = 0;
+-			wc.qp = &qp->ibqp;
+-			wc.imm_data = 0;
+-			wc.src_qp = qp->remote_qpn;
+-			wc.wc_flags = 0;
+-			wc.pkey_index = 0;
+-			wc.slid = qp->remote_ah_attr.dlid;
+-			wc.sl = qp->remote_ah_attr.sl;
+-			wc.dlid_path_bits = 0;
+-			wc.port_num = 0;
+-			ipath_sqerror_qp(qp, &wc);
++			ipath_send_complete(qp, wqe, status);
++			ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
+ 			break;
+ 
+ 		default:
+@@ -1126,8 +1123,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 				     int header_in_data)
+ {
+ 	struct ipath_swqe *wqe;
++	enum ib_wc_status status;
+ 	unsigned long flags;
+-	struct ib_wc wc;
+ 	int diff;
+ 	u32 pad;
+ 	u32 aeth;
+@@ -1135,6 +1132,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 
+ 	spin_lock_irqsave(&qp->s_lock, flags);
+ 
++	/* Double check we can process this now that we hold the s_lock. */
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
++		goto ack_done;
++
+ 	/* Ignore invalid responses. */
+ 	if (ipath_cmp24(psn, qp->s_next_psn) >= 0)
+ 		goto ack_done;
+@@ -1159,6 +1160,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 	if (unlikely(qp->s_last == qp->s_tail))
+ 		goto ack_done;
+ 	wqe = get_swqe_ptr(qp, qp->s_last);
++	status = IB_WC_SUCCESS;
+ 
+ 	switch (opcode) {
+ 	case OP(ACKNOWLEDGE):
+@@ -1187,6 +1189,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 		wqe = get_swqe_ptr(qp, qp->s_last);
+ 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
+ 			goto ack_op_err;
++		qp->r_flags &= ~IPATH_R_RDMAR_SEQ;
+ 		/*
+ 		 * If this is a response to a resent RDMA read, we
+ 		 * have to be careful to copy the data to the right
+@@ -1200,7 +1203,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 		/* no AETH, no ACK */
+ 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
+ 			dev->n_rdma_seq++;
+-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
++			if (qp->r_flags & IPATH_R_RDMAR_SEQ)
++				goto ack_done;
++			qp->r_flags |= IPATH_R_RDMAR_SEQ;
++			ipath_restart_rc(qp, qp->s_last_psn + 1);
+ 			goto ack_done;
+ 		}
+ 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
+@@ -1261,7 +1267,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 		/* ACKs READ req. */
+ 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
+ 			dev->n_rdma_seq++;
+-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
++			if (qp->r_flags & IPATH_R_RDMAR_SEQ)
++				goto ack_done;
++			qp->r_flags |= IPATH_R_RDMAR_SEQ;
++			ipath_restart_rc(qp, qp->s_last_psn + 1);
+ 			goto ack_done;
+ 		}
+ 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
+@@ -1291,31 +1300,16 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
+ 		goto ack_done;
+ 	}
+ 
+-ack_done:
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
+-	goto bail;
+-
+ ack_op_err:
+-	wc.status = IB_WC_LOC_QP_OP_ERR;
++	status = IB_WC_LOC_QP_OP_ERR;
+ 	goto ack_err;
+ 
+ ack_len_err:
+-	wc.status = IB_WC_LOC_LEN_ERR;
++	status = IB_WC_LOC_LEN_ERR;
+ ack_err:
+-	wc.wr_id = wqe->wr.wr_id;
+-	wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-	wc.vendor_err = 0;
+-	wc.byte_len = 0;
+-	wc.imm_data = 0;
+-	wc.qp = &qp->ibqp;
+-	wc.src_qp = qp->remote_qpn;
+-	wc.wc_flags = 0;
+-	wc.pkey_index = 0;
+-	wc.slid = qp->remote_ah_attr.dlid;
+-	wc.sl = qp->remote_ah_attr.sl;
+-	wc.dlid_path_bits = 0;
+-	wc.port_num = 0;
+-	ipath_sqerror_qp(qp, &wc);
++	ipath_send_complete(qp, wqe, status);
++	ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
++ack_done:
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+ bail:
+ 	return;
+@@ -1384,7 +1378,12 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
+ 	psn &= IPATH_PSN_MASK;
+ 	e = NULL;
+ 	old_req = 1;
++
+ 	spin_lock_irqsave(&qp->s_lock, flags);
++	/* Double check we can process this now that we hold the s_lock. */
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
++		goto unlock_done;
++
+ 	for (i = qp->r_head_ack_queue; ; i = prev) {
+ 		if (i == qp->s_tail_ack_queue)
+ 			old_req = 0;
+@@ -1512,7 +1511,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
+ 		break;
+ 	}
+ 	qp->r_nak_state = 0;
+-	tasklet_hi_schedule(&qp->s_task);
++	ipath_schedule_send(qp);
+ 
+ unlock_done:
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+@@ -1523,13 +1522,12 @@ send_ack:
+ 	return 0;
+ }
+ 
+-static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
++void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
+ {
+ 	unsigned long flags;
+ 	int lastwqe;
+ 
+ 	spin_lock_irqsave(&qp->s_lock, flags);
+-	qp->state = IB_QPS_ERR;
+ 	lastwqe = ipath_error_qp(qp, err);
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 
+@@ -1545,18 +1543,15 @@ static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
+ 
+ static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n)
+ {
+-	unsigned long flags;
+ 	unsigned next;
+ 
+ 	next = n + 1;
+ 	if (next > IPATH_MAX_RDMA_ATOMIC)
+ 		next = 0;
+-	spin_lock_irqsave(&qp->s_lock, flags);
+ 	if (n == qp->s_tail_ack_queue) {
+ 		qp->s_tail_ack_queue = next;
+ 		qp->s_ack_state = OP(ACKNOWLEDGE);
+ 	}
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
+ }
+ 
+ /**
+@@ -1585,6 +1580,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	int diff;
+ 	struct ib_reth *reth;
+ 	int header_in_data;
++	unsigned long flags;
+ 
+ 	/* Validate the SLID. See Ch. 9.6.1.5 */
+ 	if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
+@@ -1643,11 +1639,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		    opcode == OP(SEND_LAST) ||
+ 		    opcode == OP(SEND_LAST_WITH_IMMEDIATE))
+ 			break;
+-	nack_inv:
+-		ipath_rc_error(qp, IB_WC_REM_INV_REQ_ERR);
+-		qp->r_nak_state = IB_NAK_INVALID_REQUEST;
+-		qp->r_ack_psn = qp->r_psn;
+-		goto send_ack;
++		goto nack_inv;
+ 
+ 	case OP(RDMA_WRITE_FIRST):
+ 	case OP(RDMA_WRITE_MIDDLE):
+@@ -1673,18 +1665,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		break;
+ 	}
+ 
+-	wc.imm_data = 0;
+-	wc.wc_flags = 0;
++	memset(&wc, 0, sizeof wc);
+ 
+ 	/* OK, process the packet. */
+ 	switch (opcode) {
+ 	case OP(SEND_FIRST):
+-		if (!ipath_get_rwqe(qp, 0)) {
+-		rnr_nak:
+-			qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer;
+-			qp->r_ack_psn = qp->r_psn;
+-			goto send_ack;
+-		}
++		if (!ipath_get_rwqe(qp, 0))
++			goto rnr_nak;
+ 		qp->r_rcv_len = 0;
+ 		/* FALLTHROUGH */
+ 	case OP(SEND_MIDDLE):
+@@ -1741,9 +1728,8 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 			goto nack_inv;
+ 		ipath_copy_sge(&qp->r_sge, data, tlen);
+ 		qp->r_msn++;
+-		if (!qp->r_wrid_valid)
++		if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
+ 			break;
+-		qp->r_wrid_valid = 0;
+ 		wc.wr_id = qp->r_wr_id;
+ 		wc.status = IB_WC_SUCCESS;
+ 		if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) ||
+@@ -1751,14 +1737,10 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 			wc.opcode = IB_WC_RECV_RDMA_WITH_IMM;
+ 		else
+ 			wc.opcode = IB_WC_RECV;
+-		wc.vendor_err = 0;
+ 		wc.qp = &qp->ibqp;
+ 		wc.src_qp = qp->remote_qpn;
+-		wc.pkey_index = 0;
+ 		wc.slid = qp->remote_ah_attr.dlid;
+ 		wc.sl = qp->remote_ah_attr.sl;
+-		wc.dlid_path_bits = 0;
+-		wc.port_num = 0;
+ 		/* Signal completion event if the solicited bit is set. */
+ 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
+ 			       (ohdr->bth[0] &
+@@ -1819,9 +1801,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		next = qp->r_head_ack_queue + 1;
+ 		if (next > IPATH_MAX_RDMA_ATOMIC)
+ 			next = 0;
++		spin_lock_irqsave(&qp->s_lock, flags);
++		/* Double check we can process this while holding the s_lock. */
++		if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
++			goto unlock;
+ 		if (unlikely(next == qp->s_tail_ack_queue)) {
+ 			if (!qp->s_ack_queue[next].sent)
+-				goto nack_inv;
++				goto nack_inv_unlck;
+ 			ipath_update_ack_queue(qp, next);
+ 		}
+ 		e = &qp->s_ack_queue[qp->r_head_ack_queue];
+@@ -1842,7 +1828,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 			ok = ipath_rkey_ok(qp, &e->rdma_sge, len, vaddr,
+ 					   rkey, IB_ACCESS_REMOTE_READ);
+ 			if (unlikely(!ok))
+-				goto nack_acc;
++				goto nack_acc_unlck;
+ 			/*
+ 			 * Update the next expected PSN.  We add 1 later
+ 			 * below, so only add the remainder here.
+@@ -1869,13 +1855,12 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		qp->r_psn++;
+ 		qp->r_state = opcode;
+ 		qp->r_nak_state = 0;
+-		barrier();
+ 		qp->r_head_ack_queue = next;
+ 
+-		/* Call ipath_do_rc_send() in another thread. */
+-		tasklet_hi_schedule(&qp->s_task);
++		/* Schedule the send tasklet. */
++		ipath_schedule_send(qp);
+ 
+-		goto done;
++		goto unlock;
+ 	}
+ 
+ 	case OP(COMPARE_SWAP):
+@@ -1894,9 +1879,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		next = qp->r_head_ack_queue + 1;
+ 		if (next > IPATH_MAX_RDMA_ATOMIC)
+ 			next = 0;
++		spin_lock_irqsave(&qp->s_lock, flags);
++		/* Double check we can process this while holding the s_lock. */
++		if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
++			goto unlock;
+ 		if (unlikely(next == qp->s_tail_ack_queue)) {
+ 			if (!qp->s_ack_queue[next].sent)
+-				goto nack_inv;
++				goto nack_inv_unlck;
+ 			ipath_update_ack_queue(qp, next);
+ 		}
+ 		if (!header_in_data)
+@@ -1906,13 +1895,13 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		vaddr = ((u64) be32_to_cpu(ateth->vaddr[0]) << 32) |
+ 			be32_to_cpu(ateth->vaddr[1]);
+ 		if (unlikely(vaddr & (sizeof(u64) - 1)))
+-			goto nack_inv;
++			goto nack_inv_unlck;
+ 		rkey = be32_to_cpu(ateth->rkey);
+ 		/* Check rkey & NAK */
+ 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
+ 					    sizeof(u64), vaddr, rkey,
+ 					    IB_ACCESS_REMOTE_ATOMIC)))
+-			goto nack_acc;
++			goto nack_acc_unlck;
+ 		/* Perform atomic OP and save result. */
+ 		maddr = (atomic64_t *) qp->r_sge.sge.vaddr;
+ 		sdata = be64_to_cpu(ateth->swap_data);
+@@ -1929,13 +1918,12 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		qp->r_psn++;
+ 		qp->r_state = opcode;
+ 		qp->r_nak_state = 0;
+-		barrier();
+ 		qp->r_head_ack_queue = next;
+ 
+-		/* Call ipath_do_rc_send() in another thread. */
+-		tasklet_hi_schedule(&qp->s_task);
++		/* Schedule the send tasklet. */
++		ipath_schedule_send(qp);
+ 
+-		goto done;
++		goto unlock;
+ 	}
+ 
+ 	default:
+@@ -1951,14 +1939,31 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		goto send_ack;
+ 	goto done;
+ 
++rnr_nak:
++	qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer;
++	qp->r_ack_psn = qp->r_psn;
++	goto send_ack;
++
++nack_inv_unlck:
++	spin_unlock_irqrestore(&qp->s_lock, flags);
++nack_inv:
++	ipath_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
++	qp->r_nak_state = IB_NAK_INVALID_REQUEST;
++	qp->r_ack_psn = qp->r_psn;
++	goto send_ack;
++
++nack_acc_unlck:
++	spin_unlock_irqrestore(&qp->s_lock, flags);
+ nack_acc:
+-	ipath_rc_error(qp, IB_WC_REM_ACCESS_ERR);
++	ipath_rc_error(qp, IB_WC_LOC_PROT_ERR);
+ 	qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
+ 	qp->r_ack_psn = qp->r_psn;
+-
+ send_ack:
+ 	send_rc_ack(qp);
++	goto done;
+ 
++unlock:
++	spin_unlock_irqrestore(&qp->s_lock, flags);
+ done:
+ 	return;
+ }
+diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
+index 9e3fe61..a4b5521 100644
+--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
++++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
++ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
+  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
+  *
+  * This software is available to you under a choice of one of two
+@@ -78,6 +78,7 @@ const u32 ib_ipath_rnr_table[32] = {
+  * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device
+  * @qp: the QP
+  *
++ * Called with the QP s_lock held and interrupts disabled.
+  * XXX Use a simple list for now.  We might need a priority
+  * queue if we have lots of QPs waiting for RNR timeouts
+  * but that should be rare.
+@@ -85,9 +86,9 @@ const u32 ib_ipath_rnr_table[32] = {
+ void ipath_insert_rnr_queue(struct ipath_qp *qp)
+ {
+ 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+-	unsigned long flags;
+ 
+-	spin_lock_irqsave(&dev->pending_lock, flags);
++	/* We already did a spin_lock_irqsave(), so just use spin_lock */
++	spin_lock(&dev->pending_lock);
+ 	if (list_empty(&dev->rnrwait))
+ 		list_add(&qp->timerwait, &dev->rnrwait);
+ 	else {
+@@ -109,7 +110,7 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
+ 			nqp->s_rnr_timeout -= qp->s_rnr_timeout;
+ 		list_add(&qp->timerwait, l);
+ 	}
+-	spin_unlock_irqrestore(&dev->pending_lock, flags);
++	spin_unlock(&dev->pending_lock);
+ }
+ 
+ /**
+@@ -140,20 +141,11 @@ int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
+ 	goto bail;
+ 
+ bad_lkey:
++	memset(&wc, 0, sizeof(wc));
+ 	wc.wr_id = wqe->wr_id;
+ 	wc.status = IB_WC_LOC_PROT_ERR;
+ 	wc.opcode = IB_WC_RECV;
+-	wc.vendor_err = 0;
+-	wc.byte_len = 0;
+-	wc.imm_data = 0;
+ 	wc.qp = &qp->ibqp;
+-	wc.src_qp = 0;
+-	wc.wc_flags = 0;
+-	wc.pkey_index = 0;
+-	wc.slid = 0;
+-	wc.sl = 0;
+-	wc.dlid_path_bits = 0;
+-	wc.port_num = 0;
+ 	/* Signal solicited completion event. */
+ 	ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
+ 	ret = 0;
+@@ -194,6 +186,11 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
+ 	}
+ 
+ 	spin_lock_irqsave(&rq->lock, flags);
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
++		ret = 0;
++		goto unlock;
++	}
++
+ 	wq = rq->wq;
+ 	tail = wq->tail;
+ 	/* Validate tail before using it since it is user writable. */
+@@ -201,9 +198,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
+ 		tail = 0;
+ 	do {
+ 		if (unlikely(tail == wq->head)) {
+-			spin_unlock_irqrestore(&rq->lock, flags);
+ 			ret = 0;
+-			goto bail;
++			goto unlock;
+ 		}
+ 		/* Make sure entry is read after head index is read. */
+ 		smp_rmb();
+@@ -216,7 +212,7 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
+ 	wq->tail = tail;
+ 
+ 	ret = 1;
+-	qp->r_wrid_valid = 1;
++	set_bit(IPATH_R_WRID_VALID, &qp->r_aflags);
+ 	if (handler) {
+ 		u32 n;
+ 
+@@ -243,8 +239,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)
+ 			goto bail;
+ 		}
+ 	}
++unlock:
+ 	spin_unlock_irqrestore(&rq->lock, flags);
+-
+ bail:
+ 	return ret;
+ }
+@@ -270,38 +266,63 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)
+ 	struct ib_wc wc;
+ 	u64 sdata;
+ 	atomic64_t *maddr;
++	enum ib_wc_status send_status;
+ 
++	/*
++	 * Note that we check the responder QP state after
++	 * checking the requester's state.
++	 */
+ 	qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn);
+-	if (!qp) {
+-		dev->n_pkt_drops++;
+-		return;
+-	}
+ 
+-again:
+ 	spin_lock_irqsave(&sqp->s_lock, flags);
+ 
+-	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) ||
+-	    sqp->s_rnr_timeout) {
+-		spin_unlock_irqrestore(&sqp->s_lock, flags);
+-		goto done;
+-	}
++	/* Return if we are already busy processing a work request. */
++	if ((sqp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) ||
++	    !(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_OR_FLUSH_SEND))
++		goto unlock;
+ 
+-	/* Get the next send request. */
+-	if (sqp->s_last == sqp->s_head) {
+-		/* Send work queue is empty. */
+-		spin_unlock_irqrestore(&sqp->s_lock, flags);
+-		goto done;
++	sqp->s_flags |= IPATH_S_BUSY;
++
++again:
++	if (sqp->s_last == sqp->s_head)
++		goto clr_busy;
++	wqe = get_swqe_ptr(sqp, sqp->s_last);
++
++	/* Return if it is not OK to start a new work reqeust. */
++	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_NEXT_SEND_OK)) {
++		if (!(ib_ipath_state_ops[sqp->state] & IPATH_FLUSH_SEND))
++			goto clr_busy;
++		/* We are in the error state, flush the work request. */
++		send_status = IB_WC_WR_FLUSH_ERR;
++		goto flush_send;
+ 	}
+ 
+ 	/*
+ 	 * We can rely on the entry not changing without the s_lock
+ 	 * being held until we update s_last.
++	 * We increment s_cur to indicate s_last is in progress.
+ 	 */
+-	wqe = get_swqe_ptr(sqp, sqp->s_last);
++	if (sqp->s_last == sqp->s_cur) {
++		if (++sqp->s_cur >= sqp->s_size)
++			sqp->s_cur = 0;
++	}
+ 	spin_unlock_irqrestore(&sqp->s_lock, flags);
+ 
+-	wc.wc_flags = 0;
+-	wc.imm_data = 0;
++	if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
++		dev->n_pkt_drops++;
++		/*
++		 * For RC, the requester would timeout and retry so
++		 * shortcut the timeouts and just signal too many retries.
++		 */
++		if (sqp->ibqp.qp_type == IB_QPT_RC)
++			send_status = IB_WC_RETRY_EXC_ERR;
++		else
++			send_status = IB_WC_SUCCESS;
++		goto serr;
++	}
++
++	memset(&wc, 0, sizeof wc);
++	send_status = IB_WC_SUCCESS;
+ 
+ 	sqp->s_sge.sge = wqe->sg_list[0];
+ 	sqp->s_sge.sg_list = wqe->sg_list + 1;
+@@ -313,75 +334,33 @@ again:
+ 		wc.imm_data = wqe->wr.ex.imm_data;
+ 		/* FALLTHROUGH */
+ 	case IB_WR_SEND:
+-		if (!ipath_get_rwqe(qp, 0)) {
+-		rnr_nak:
+-			/* Handle RNR NAK */
+-			if (qp->ibqp.qp_type == IB_QPT_UC)
+-				goto send_comp;
+-			if (sqp->s_rnr_retry == 0) {
+-				wc.status = IB_WC_RNR_RETRY_EXC_ERR;
+-				goto err;
+-			}
+-			if (sqp->s_rnr_retry_cnt < 7)
+-				sqp->s_rnr_retry--;
+-			dev->n_rnr_naks++;
+-			sqp->s_rnr_timeout =
+-				ib_ipath_rnr_table[qp->r_min_rnr_timer];
+-			ipath_insert_rnr_queue(sqp);
+-			goto done;
+-		}
++		if (!ipath_get_rwqe(qp, 0))
++			goto rnr_nak;
+ 		break;
+ 
+ 	case IB_WR_RDMA_WRITE_WITH_IMM:
+-		if (unlikely(!(qp->qp_access_flags &
+-			       IB_ACCESS_REMOTE_WRITE))) {
+-			wc.status = IB_WC_REM_INV_REQ_ERR;
+-			goto err;
+-		}
++		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))
++			goto inv_err;
+ 		wc.wc_flags = IB_WC_WITH_IMM;
+ 		wc.imm_data = wqe->wr.ex.imm_data;
+ 		if (!ipath_get_rwqe(qp, 1))
+ 			goto rnr_nak;
+ 		/* FALLTHROUGH */
+ 	case IB_WR_RDMA_WRITE:
+-		if (unlikely(!(qp->qp_access_flags &
+-			       IB_ACCESS_REMOTE_WRITE))) {
+-			wc.status = IB_WC_REM_INV_REQ_ERR;
+-			goto err;
+-		}
++		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))
++			goto inv_err;
+ 		if (wqe->length == 0)
+ 			break;
+ 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
+ 					    wqe->wr.wr.rdma.remote_addr,
+ 					    wqe->wr.wr.rdma.rkey,
+-					    IB_ACCESS_REMOTE_WRITE))) {
+-		acc_err:
+-			wc.status = IB_WC_REM_ACCESS_ERR;
+-		err:
+-			wc.wr_id = wqe->wr.wr_id;
+-			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-			wc.vendor_err = 0;
+-			wc.byte_len = 0;
+-			wc.qp = &sqp->ibqp;
+-			wc.src_qp = sqp->remote_qpn;
+-			wc.pkey_index = 0;
+-			wc.slid = sqp->remote_ah_attr.dlid;
+-			wc.sl = sqp->remote_ah_attr.sl;
+-			wc.dlid_path_bits = 0;
+-			wc.port_num = 0;
+-			spin_lock_irqsave(&sqp->s_lock, flags);
+-			ipath_sqerror_qp(sqp, &wc);
+-			spin_unlock_irqrestore(&sqp->s_lock, flags);
+-			goto done;
+-		}
++					    IB_ACCESS_REMOTE_WRITE)))
++			goto acc_err;
+ 		break;
+ 
+ 	case IB_WR_RDMA_READ:
+-		if (unlikely(!(qp->qp_access_flags &
+-			       IB_ACCESS_REMOTE_READ))) {
+-			wc.status = IB_WC_REM_INV_REQ_ERR;
+-			goto err;
+-		}
++		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ)))
++			goto inv_err;
+ 		if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
+ 					    wqe->wr.wr.rdma.remote_addr,
+ 					    wqe->wr.wr.rdma.rkey,
+@@ -394,11 +373,8 @@ again:
+ 
+ 	case IB_WR_ATOMIC_CMP_AND_SWP:
+ 	case IB_WR_ATOMIC_FETCH_AND_ADD:
+-		if (unlikely(!(qp->qp_access_flags &
+-			       IB_ACCESS_REMOTE_ATOMIC))) {
+-			wc.status = IB_WC_REM_INV_REQ_ERR;
+-			goto err;
+-		}
++		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC)))
++			goto inv_err;
+ 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
+ 					    wqe->wr.wr.atomic.remote_addr,
+ 					    wqe->wr.wr.atomic.rkey,
+@@ -415,7 +391,8 @@ again:
+ 		goto send_comp;
+ 
+ 	default:
+-		goto done;
++		send_status = IB_WC_LOC_QP_OP_ERR;
++		goto serr;
+ 	}
+ 
+ 	sge = &sqp->s_sge.sge;
+@@ -448,8 +425,7 @@ again:
+ 		sqp->s_len -= len;
+ 	}
+ 
+-	if (wqe->wr.opcode == IB_WR_RDMA_WRITE ||
+-	    wqe->wr.opcode == IB_WR_RDMA_READ)
++	if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
+ 		goto send_comp;
+ 
+ 	if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM)
+@@ -458,33 +434,89 @@ again:
+ 		wc.opcode = IB_WC_RECV;
+ 	wc.wr_id = qp->r_wr_id;
+ 	wc.status = IB_WC_SUCCESS;
+-	wc.vendor_err = 0;
+ 	wc.byte_len = wqe->length;
+ 	wc.qp = &qp->ibqp;
+ 	wc.src_qp = qp->remote_qpn;
+-	wc.pkey_index = 0;
+ 	wc.slid = qp->remote_ah_attr.dlid;
+ 	wc.sl = qp->remote_ah_attr.sl;
+-	wc.dlid_path_bits = 0;
+ 	wc.port_num = 1;
+ 	/* Signal completion event if the solicited bit is set. */
+ 	ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
+ 		       wqe->wr.send_flags & IB_SEND_SOLICITED);
+ 
+ send_comp:
++	spin_lock_irqsave(&sqp->s_lock, flags);
++flush_send:
+ 	sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
+-	ipath_send_complete(sqp, wqe, IB_WC_SUCCESS);
++	ipath_send_complete(sqp, wqe, send_status);
+ 	goto again;
+ 
++rnr_nak:
++	/* Handle RNR NAK */
++	if (qp->ibqp.qp_type == IB_QPT_UC)
++		goto send_comp;
++	/*
++	 * Note: we don't need the s_lock held since the BUSY flag
++	 * makes this single threaded.
++	 */
++	if (sqp->s_rnr_retry == 0) {
++		send_status = IB_WC_RNR_RETRY_EXC_ERR;
++		goto serr;
++	}
++	if (sqp->s_rnr_retry_cnt < 7)
++		sqp->s_rnr_retry--;
++	spin_lock_irqsave(&sqp->s_lock, flags);
++	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_RECV_OK))
++		goto clr_busy;
++	sqp->s_flags |= IPATH_S_WAITING;
++	dev->n_rnr_naks++;
++	sqp->s_rnr_timeout = ib_ipath_rnr_table[qp->r_min_rnr_timer];
++	ipath_insert_rnr_queue(sqp);
++	goto clr_busy;
++
++inv_err:
++	send_status = IB_WC_REM_INV_REQ_ERR;
++	wc.status = IB_WC_LOC_QP_OP_ERR;
++	goto err;
++
++acc_err:
++	send_status = IB_WC_REM_ACCESS_ERR;
++	wc.status = IB_WC_LOC_PROT_ERR;
++err:
++	/* responder goes to error state */
++	ipath_rc_error(qp, wc.status);
++
++serr:
++	spin_lock_irqsave(&sqp->s_lock, flags);
++	ipath_send_complete(sqp, wqe, send_status);
++	if (sqp->ibqp.qp_type == IB_QPT_RC) {
++		int lastwqe = ipath_error_qp(sqp, IB_WC_WR_FLUSH_ERR);
++
++		sqp->s_flags &= ~IPATH_S_BUSY;
++		spin_unlock_irqrestore(&sqp->s_lock, flags);
++		if (lastwqe) {
++			struct ib_event ev;
++
++			ev.device = sqp->ibqp.device;
++			ev.element.qp = &sqp->ibqp;
++			ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
++			sqp->ibqp.event_handler(&ev, sqp->ibqp.qp_context);
++		}
++		goto done;
++	}
++clr_busy:
++	sqp->s_flags &= ~IPATH_S_BUSY;
++unlock:
++	spin_unlock_irqrestore(&sqp->s_lock, flags);
+ done:
+-	if (atomic_dec_and_test(&qp->refcount))
++	if (qp && atomic_dec_and_test(&qp->refcount))
+ 		wake_up(&qp->wait);
+ }
+ 
+ static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp)
+ {
+ 	if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) ||
+-		qp->ibqp.qp_type == IB_QPT_SMI) {
++	    qp->ibqp.qp_type == IB_QPT_SMI) {
+ 		unsigned long flags;
+ 
+ 		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
+@@ -502,26 +534,36 @@ static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp)
+  * @dev: the device we ran out of buffers on
+  *
+  * Called when we run out of PIO buffers.
++ * If we are now in the error state, return zero to flush the
++ * send work request.
+  */
+-static void ipath_no_bufs_available(struct ipath_qp *qp,
++static int ipath_no_bufs_available(struct ipath_qp *qp,
+ 				    struct ipath_ibdev *dev)
+ {
+ 	unsigned long flags;
++	int ret = 1;
+ 
+ 	/*
+ 	 * Note that as soon as want_buffer() is called and
+ 	 * possibly before it returns, ipath_ib_piobufavail()
+-	 * could be called.  If we are still in the tasklet function,
+-	 * tasklet_hi_schedule() will not call us until the next time
+-	 * tasklet_hi_schedule() is called.
+-	 * We leave the busy flag set so that another post send doesn't
+-	 * try to put the same QP on the piowait list again.
++	 * could be called. Therefore, put QP on the piowait list before
++	 * enabling the PIO avail interrupt.
+ 	 */
+-	spin_lock_irqsave(&dev->pending_lock, flags);
+-	list_add_tail(&qp->piowait, &dev->piowait);
+-	spin_unlock_irqrestore(&dev->pending_lock, flags);
+-	want_buffer(dev->dd, qp);
+-	dev->n_piowait++;
++	spin_lock_irqsave(&qp->s_lock, flags);
++	if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) {
++		dev->n_piowait++;
++		qp->s_flags |= IPATH_S_WAITING;
++		qp->s_flags &= ~IPATH_S_BUSY;
++		spin_lock(&dev->pending_lock);
++		if (list_empty(&qp->piowait))
++			list_add_tail(&qp->piowait, &dev->piowait);
++		spin_unlock(&dev->pending_lock);
++	} else
++		ret = 0;
++	spin_unlock_irqrestore(&qp->s_lock, flags);
++	if (ret)
++		want_buffer(dev->dd, qp);
++	return ret;
+ }
+ 
+ /**
+@@ -597,15 +639,13 @@ void ipath_do_send(unsigned long data)
+ 	struct ipath_qp *qp = (struct ipath_qp *)data;
+ 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+ 	int (*make_req)(struct ipath_qp *qp);
+-
+-	if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy))
+-		goto bail;
++	unsigned long flags;
+ 
+ 	if ((qp->ibqp.qp_type == IB_QPT_RC ||
+ 	     qp->ibqp.qp_type == IB_QPT_UC) &&
+ 	    qp->remote_ah_attr.dlid == dev->dd->ipath_lid) {
+ 		ipath_ruc_loopback(qp);
+-		goto clear;
++		goto bail;
+ 	}
+ 
+ 	if (qp->ibqp.qp_type == IB_QPT_RC)
+@@ -615,6 +655,19 @@ void ipath_do_send(unsigned long data)
+ 	else
+ 	       make_req = ipath_make_ud_req;
+ 
++	spin_lock_irqsave(&qp->s_lock, flags);
++
++	/* Return if we are already busy processing a work request. */
++	if ((qp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) ||
++	    !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) {
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++		goto bail;
++	}
++
++	qp->s_flags |= IPATH_S_BUSY;
++
++	spin_unlock_irqrestore(&qp->s_lock, flags);
++
+ again:
+ 	/* Check for a constructed packet to be sent. */
+ 	if (qp->s_hdrwords != 0) {
+@@ -624,8 +677,8 @@ again:
+ 		 */
+ 		if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords,
+ 				     qp->s_cur_sge, qp->s_cur_size)) {
+-			ipath_no_bufs_available(qp, dev);
+-			goto bail;
++			if (ipath_no_bufs_available(qp, dev))
++				goto bail;
+ 		}
+ 		dev->n_unicast_xmit++;
+ 		/* Record that we sent the packet and s_hdr is empty. */
+@@ -634,16 +687,20 @@ again:
+ 
+ 	if (make_req(qp))
+ 		goto again;
+-clear:
+-	clear_bit(IPATH_S_BUSY, &qp->s_busy);
++
+ bail:;
+ }
+ 
++/*
++ * This should be called with s_lock held.
++ */
+ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe,
+ 			 enum ib_wc_status status)
+ {
+-	unsigned long flags;
+-	u32 last;
++	u32 old_last, last;
++
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND))
++		return;
+ 
+ 	/* See ch. 11.2.4.1 and 10.7.3.1 */
+ 	if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
+@@ -651,27 +708,25 @@ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe,
+ 	    status != IB_WC_SUCCESS) {
+ 		struct ib_wc wc;
+ 
++		memset(&wc, 0, sizeof wc);
+ 		wc.wr_id = wqe->wr.wr_id;
+ 		wc.status = status;
+ 		wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+-		wc.vendor_err = 0;
+-		wc.byte_len = wqe->length;
+-		wc.imm_data = 0;
+ 		wc.qp = &qp->ibqp;
+-		wc.src_qp = 0;
+-		wc.wc_flags = 0;
+-		wc.pkey_index = 0;
+-		wc.slid = 0;
+-		wc.sl = 0;
+-		wc.dlid_path_bits = 0;
+-		wc.port_num = 0;
+-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0);
++		if (status == IB_WC_SUCCESS)
++			wc.byte_len = wqe->length;
++		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc,
++			       status != IB_WC_SUCCESS);
+ 	}
+ 
+-	spin_lock_irqsave(&qp->s_lock, flags);
+-	last = qp->s_last;
++	old_last = last = qp->s_last;
+ 	if (++last >= qp->s_size)
+ 		last = 0;
+ 	qp->s_last = last;
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
++	if (qp->s_cur == old_last)
++		qp->s_cur = last;
++	if (qp->s_tail == old_last)
++		qp->s_tail = last;
++	if (qp->state == IB_QPS_SQD && last == qp->s_cur)
++		qp->s_draining = 0;
+ }
+diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
+index bfe8926..7fd18e8 100644
+--- a/drivers/infiniband/hw/ipath/ipath_uc.c
++++ b/drivers/infiniband/hw/ipath/ipath_uc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
++ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
+  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
+  *
+  * This software is available to you under a choice of one of two
+@@ -47,14 +47,30 @@ int ipath_make_uc_req(struct ipath_qp *qp)
+ {
+ 	struct ipath_other_headers *ohdr;
+ 	struct ipath_swqe *wqe;
++	unsigned long flags;
+ 	u32 hwords;
+ 	u32 bth0;
+ 	u32 len;
+ 	u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
+ 	int ret = 0;
+ 
+-	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))
++	spin_lock_irqsave(&qp->s_lock, flags);
++
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) {
++		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
++			goto bail;
++		/* We are in the error state, flush the work request. */
++		if (qp->s_last == qp->s_head)
++			goto bail;
++		/* If DMAs are in progress, we can't flush immediately. */
++		if (atomic_read(&qp->s_dma_busy)) {
++			qp->s_flags |= IPATH_S_WAIT_DMA;
++			goto bail;
++		}
++		wqe = get_swqe_ptr(qp, qp->s_last);
++		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+ 		goto done;
++	}
+ 
+ 	ohdr = &qp->s_hdr.u.oth;
+ 	if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
+@@ -69,9 +85,12 @@ int ipath_make_uc_req(struct ipath_qp *qp)
+ 	qp->s_wqe = NULL;
+ 	switch (qp->s_state) {
+ 	default:
++		if (!(ib_ipath_state_ops[qp->state] &
++		    IPATH_PROCESS_NEXT_SEND_OK))
++			goto bail;
+ 		/* Check if send work queue is empty. */
+ 		if (qp->s_cur == qp->s_head)
+-			goto done;
++			goto bail;
+ 		/*
+ 		 * Start a new request.
+ 		 */
+@@ -134,7 +153,7 @@ int ipath_make_uc_req(struct ipath_qp *qp)
+ 			break;
+ 
+ 		default:
+-			goto done;
++			goto bail;
+ 		}
+ 		break;
+ 
+@@ -194,9 +213,14 @@ int ipath_make_uc_req(struct ipath_qp *qp)
+ 	ipath_make_ruc_header(to_idev(qp->ibqp.device),
+ 			      qp, ohdr, bth0 | (qp->s_state << 24),
+ 			      qp->s_next_psn++ & IPATH_PSN_MASK);
++done:
+ 	ret = 1;
++	goto unlock;
+ 
+-done:
++bail:
++	qp->s_flags &= ~IPATH_S_BUSY;
++unlock:
++	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 	return ret;
+ }
+ 
+@@ -258,8 +282,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	 */
+ 	opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
+ 
+-	wc.imm_data = 0;
+-	wc.wc_flags = 0;
++	memset(&wc, 0, sizeof wc);
+ 
+ 	/* Compare the PSN verses the expected PSN. */
+ 	if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) {
+@@ -322,8 +345,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	case OP(SEND_ONLY):
+ 	case OP(SEND_ONLY_WITH_IMMEDIATE):
+ 	send_first:
+-		if (qp->r_reuse_sge) {
+-			qp->r_reuse_sge = 0;
++		if (qp->r_flags & IPATH_R_REUSE_SGE) {
++			qp->r_flags &= ~IPATH_R_REUSE_SGE;
+ 			qp->r_sge = qp->s_rdma_read_sge;
+ 		} else if (!ipath_get_rwqe(qp, 0)) {
+ 			dev->n_pkt_drops++;
+@@ -340,13 +363,13 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	case OP(SEND_MIDDLE):
+ 		/* Check for invalid length PMTU or posted rwqe len. */
+ 		if (unlikely(tlen != (hdrsize + pmtu + 4))) {
+-			qp->r_reuse_sge = 1;
++			qp->r_flags |= IPATH_R_REUSE_SGE;
+ 			dev->n_pkt_drops++;
+ 			goto done;
+ 		}
+ 		qp->r_rcv_len += pmtu;
+ 		if (unlikely(qp->r_rcv_len > qp->r_len)) {
+-			qp->r_reuse_sge = 1;
++			qp->r_flags |= IPATH_R_REUSE_SGE;
+ 			dev->n_pkt_drops++;
+ 			goto done;
+ 		}
+@@ -372,7 +395,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		/* Check for invalid length. */
+ 		/* XXX LAST len should be >= 1 */
+ 		if (unlikely(tlen < (hdrsize + pad + 4))) {
+-			qp->r_reuse_sge = 1;
++			qp->r_flags |= IPATH_R_REUSE_SGE;
+ 			dev->n_pkt_drops++;
+ 			goto done;
+ 		}
+@@ -380,7 +403,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		tlen -= (hdrsize + pad + 4);
+ 		wc.byte_len = tlen + qp->r_rcv_len;
+ 		if (unlikely(wc.byte_len > qp->r_len)) {
+-			qp->r_reuse_sge = 1;
++			qp->r_flags |= IPATH_R_REUSE_SGE;
+ 			dev->n_pkt_drops++;
+ 			goto done;
+ 		}
+@@ -390,14 +413,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		wc.wr_id = qp->r_wr_id;
+ 		wc.status = IB_WC_SUCCESS;
+ 		wc.opcode = IB_WC_RECV;
+-		wc.vendor_err = 0;
+ 		wc.qp = &qp->ibqp;
+ 		wc.src_qp = qp->remote_qpn;
+-		wc.pkey_index = 0;
+ 		wc.slid = qp->remote_ah_attr.dlid;
+ 		wc.sl = qp->remote_ah_attr.sl;
+-		wc.dlid_path_bits = 0;
+-		wc.port_num = 0;
+ 		/* Signal completion event if the solicited bit is set. */
+ 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
+ 			       (ohdr->bth[0] &
+@@ -488,8 +507,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 			dev->n_pkt_drops++;
+ 			goto done;
+ 		}
+-		if (qp->r_reuse_sge)
+-			qp->r_reuse_sge = 0;
++		if (qp->r_flags & IPATH_R_REUSE_SGE)
++			qp->r_flags &= ~IPATH_R_REUSE_SGE;
+ 		else if (!ipath_get_rwqe(qp, 1)) {
+ 			dev->n_pkt_drops++;
+ 			goto done;
+diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
+index 8b6a261..77ca8ca 100644
+--- a/drivers/infiniband/hw/ipath/ipath_ud.c
++++ b/drivers/infiniband/hw/ipath/ipath_ud.c
+@@ -65,9 +65,9 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
+ 	u32 length;
+ 
+ 	qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn);
+-	if (!qp) {
++	if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
+ 		dev->n_pkt_drops++;
+-		goto send_comp;
++		goto done;
+ 	}
+ 
+ 	rsge.sg_list = NULL;
+@@ -91,14 +91,12 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
+ 	 * present on the wire.
+ 	 */
+ 	length = swqe->length;
++	memset(&wc, 0, sizeof wc);
+ 	wc.byte_len = length + sizeof(struct ib_grh);
+ 
+ 	if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) {
+ 		wc.wc_flags = IB_WC_WITH_IMM;
+ 		wc.imm_data = swqe->wr.ex.imm_data;
+-	} else {
+-		wc.wc_flags = 0;
+-		wc.imm_data = 0;
+ 	}
+ 
+ 	/*
+@@ -229,7 +227,6 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
+ 	}
+ 	wc.status = IB_WC_SUCCESS;
+ 	wc.opcode = IB_WC_RECV;
+-	wc.vendor_err = 0;
+ 	wc.qp = &qp->ibqp;
+ 	wc.src_qp = sqp->ibqp.qp_num;
+ 	/* XXX do we know which pkey matched? Only needed for GSI. */
+@@ -248,8 +245,7 @@ drop:
+ 	kfree(rsge.sg_list);
+ 	if (atomic_dec_and_test(&qp->refcount))
+ 		wake_up(&qp->wait);
+-send_comp:
+-	ipath_send_complete(sqp, swqe, IB_WC_SUCCESS);
++done:;
+ }
+ 
+ /**
+@@ -264,6 +260,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
+ 	struct ipath_other_headers *ohdr;
+ 	struct ib_ah_attr *ah_attr;
+ 	struct ipath_swqe *wqe;
++	unsigned long flags;
+ 	u32 nwords;
+ 	u32 extra_bytes;
+ 	u32 bth0;
+@@ -271,13 +268,30 @@ int ipath_make_ud_req(struct ipath_qp *qp)
+ 	u16 lid;
+ 	int ret = 0;
+ 
+-	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)))
+-		goto bail;
++	spin_lock_irqsave(&qp->s_lock, flags);
++
++	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_NEXT_SEND_OK)) {
++		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
++			goto bail;
++		/* We are in the error state, flush the work request. */
++		if (qp->s_last == qp->s_head)
++			goto bail;
++		/* If DMAs are in progress, we can't flush immediately. */
++		if (atomic_read(&qp->s_dma_busy)) {
++			qp->s_flags |= IPATH_S_WAIT_DMA;
++			goto bail;
++		}
++		wqe = get_swqe_ptr(qp, qp->s_last);
++		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
++		goto done;
++	}
+ 
+ 	if (qp->s_cur == qp->s_head)
+ 		goto bail;
+ 
+ 	wqe = get_swqe_ptr(qp, qp->s_cur);
++	if (++qp->s_cur >= qp->s_size)
++		qp->s_cur = 0;
+ 
+ 	/* Construct the header. */
+ 	ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
+@@ -288,10 +302,23 @@ int ipath_make_ud_req(struct ipath_qp *qp)
+ 			dev->n_unicast_xmit++;
+ 	} else {
+ 		dev->n_unicast_xmit++;
+-		lid = ah_attr->dlid &
+-			~((1 << dev->dd->ipath_lmc) - 1);
++		lid = ah_attr->dlid & ~((1 << dev->dd->ipath_lmc) - 1);
+ 		if (unlikely(lid == dev->dd->ipath_lid)) {
++			/*
++			 * If DMAs are in progress, we can't generate
++			 * a completion for the loopback packet since
++			 * it would be out of order.
++			 * XXX Instead of waiting, we could queue a
++			 * zero length descriptor so we get a callback.
++			 */
++			if (atomic_read(&qp->s_dma_busy)) {
++				qp->s_flags |= IPATH_S_WAIT_DMA;
++				goto bail;
++			}
++			spin_unlock_irqrestore(&qp->s_lock, flags);
+ 			ipath_ud_loopback(qp, wqe);
++			spin_lock_irqsave(&qp->s_lock, flags);
++			ipath_send_complete(qp, wqe, IB_WC_SUCCESS);
+ 			goto done;
+ 		}
+ 	}
+@@ -368,11 +395,13 @@ int ipath_make_ud_req(struct ipath_qp *qp)
+ 	ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num);
+ 
+ done:
+-	if (++qp->s_cur >= qp->s_size)
+-		qp->s_cur = 0;
+ 	ret = 1;
++	goto unlock;
+ 
+ bail:
++	qp->s_flags &= ~IPATH_S_BUSY;
++unlock:
++	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 	return ret;
+ }
+ 
+@@ -506,8 +535,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	/*
+ 	 * Get the next work request entry to find where to put the data.
+ 	 */
+-	if (qp->r_reuse_sge)
+-		qp->r_reuse_sge = 0;
++	if (qp->r_flags & IPATH_R_REUSE_SGE)
++		qp->r_flags &= ~IPATH_R_REUSE_SGE;
+ 	else if (!ipath_get_rwqe(qp, 0)) {
+ 		/*
+ 		 * Count VL15 packets dropped due to no receive buffer.
+@@ -523,7 +552,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 	}
+ 	/* Silently drop packets which are too big. */
+ 	if (wc.byte_len > qp->r_len) {
+-		qp->r_reuse_sge = 1;
++		qp->r_flags |= IPATH_R_REUSE_SGE;
+ 		dev->n_pkt_drops++;
+ 		goto bail;
+ 	}
+@@ -535,7 +564,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh));
+ 	ipath_copy_sge(&qp->r_sge, data,
+ 		       wc.byte_len - sizeof(struct ib_grh));
+-	qp->r_wrid_valid = 0;
++	if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
++		goto bail;
+ 	wc.wr_id = qp->r_wr_id;
+ 	wc.status = IB_WC_SUCCESS;
+ 	wc.opcode = IB_WC_RECV;
+diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.h b/drivers/infiniband/hw/ipath/ipath_user_sdma.h
+index e70946c..fc76316 100644
+--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.h
++++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.h
+@@ -45,8 +45,6 @@ int ipath_user_sdma_writev(struct ipath_devdata *dd,
+ int ipath_user_sdma_make_progress(struct ipath_devdata *dd,
+ 				  struct ipath_user_sdma_queue *pq);
+ 
+-int ipath_user_sdma_pkt_sent(const struct ipath_user_sdma_queue *pq,
+-			     u32 counter);
+ void ipath_user_sdma_queue_drain(struct ipath_devdata *dd,
+ 				 struct ipath_user_sdma_queue *pq);
+ 
+diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
+index 5015cd2..e0ec540 100644
+--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
++++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
+@@ -111,16 +111,24 @@ static unsigned int ib_ipath_disable_sma;
+ module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO);
+ MODULE_PARM_DESC(disable_sma, "Disable the SMA");
+ 
++/*
++ * Note that it is OK to post send work requests in the SQE and ERR
++ * states; ipath_do_send() will process them and generate error
++ * completions as per IB 1.2 C10-96.
++ */
+ const int ib_ipath_state_ops[IB_QPS_ERR + 1] = {
+ 	[IB_QPS_RESET] = 0,
+ 	[IB_QPS_INIT] = IPATH_POST_RECV_OK,
+ 	[IB_QPS_RTR] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK,
+ 	[IB_QPS_RTS] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
+-	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK,
++	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK |
++	    IPATH_PROCESS_NEXT_SEND_OK,
+ 	[IB_QPS_SQD] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
+-	    IPATH_POST_SEND_OK,
+-	[IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK,
+-	[IB_QPS_ERR] = 0,
++	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK,
++	[IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
++	    IPATH_POST_SEND_OK | IPATH_FLUSH_SEND,
++	[IB_QPS_ERR] = IPATH_POST_RECV_OK | IPATH_FLUSH_RECV |
++	    IPATH_POST_SEND_OK | IPATH_FLUSH_SEND,
+ };
+ 
+ struct ipath_ucontext {
+@@ -230,18 +238,6 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
+ 	}
+ }
+ 
+-static void ipath_flush_wqe(struct ipath_qp *qp, struct ib_send_wr *wr)
+-{
+-	struct ib_wc wc;
+-
+-	memset(&wc, 0, sizeof(wc));
+-	wc.wr_id = wr->wr_id;
+-	wc.status = IB_WC_WR_FLUSH_ERR;
+-	wc.opcode = ib_ipath_wc_opcode[wr->opcode];
+-	wc.qp = &qp->ibqp;
+-	ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+-}
+-
+ /*
+  * Count the number of DMA descriptors needed to send length bytes of data.
+  * Don't modify the ipath_sge_state to get the count.
+@@ -347,14 +343,8 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr)
+ 	spin_lock_irqsave(&qp->s_lock, flags);
+ 
+ 	/* Check that state is OK to post send. */
+-	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK))) {
+-		if (qp->state != IB_QPS_SQE && qp->state != IB_QPS_ERR)
+-			goto bail_inval;
+-		/* C10-96 says generate a flushed completion entry. */
+-		ipath_flush_wqe(qp, wr);
+-		ret = 0;
+-		goto bail;
+-	}
++	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)))
++		goto bail_inval;
+ 
+ 	/* IB spec says that num_sge == 0 is OK. */
+ 	if (wr->num_sge > qp->s_max_sge)
+@@ -677,6 +667,7 @@ bail:;
+ static void ipath_ib_timer(struct ipath_ibdev *dev)
+ {
+ 	struct ipath_qp *resend = NULL;
++	struct ipath_qp *rnr = NULL;
+ 	struct list_head *last;
+ 	struct ipath_qp *qp;
+ 	unsigned long flags;
+@@ -703,7 +694,9 @@ static void ipath_ib_timer(struct ipath_ibdev *dev)
+ 		if (--qp->s_rnr_timeout == 0) {
+ 			do {
+ 				list_del_init(&qp->timerwait);
+-				tasklet_hi_schedule(&qp->s_task);
++				qp->timer_next = rnr;
++				rnr = qp;
++				atomic_inc(&qp->refcount);
+ 				if (list_empty(last))
+ 					break;
+ 				qp = list_entry(last->next, struct ipath_qp,
+@@ -743,13 +736,15 @@ static void ipath_ib_timer(struct ipath_ibdev *dev)
+ 	spin_unlock_irqrestore(&dev->pending_lock, flags);
+ 
+ 	/* XXX What if timer fires again while this is running? */
+-	for (qp = resend; qp != NULL; qp = qp->timer_next) {
+-		struct ib_wc wc;
++	while (resend != NULL) {
++		qp = resend;
++		resend = qp->timer_next;
+ 
+ 		spin_lock_irqsave(&qp->s_lock, flags);
+-		if (qp->s_last != qp->s_tail && qp->state == IB_QPS_RTS) {
++		if (qp->s_last != qp->s_tail &&
++		    ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) {
+ 			dev->n_timeouts++;
+-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
++			ipath_restart_rc(qp, qp->s_last_psn + 1);
+ 		}
+ 		spin_unlock_irqrestore(&qp->s_lock, flags);
+ 
+@@ -757,6 +752,19 @@ static void ipath_ib_timer(struct ipath_ibdev *dev)
+ 		if (atomic_dec_and_test(&qp->refcount))
+ 			wake_up(&qp->wait);
+ 	}
++	while (rnr != NULL) {
++		qp = rnr;
++		rnr = qp->timer_next;
++
++		spin_lock_irqsave(&qp->s_lock, flags);
++		if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)
++			ipath_schedule_send(qp);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++
++		/* Notify ipath_destroy_qp() if it is waiting. */
++		if (atomic_dec_and_test(&qp->refcount))
++			wake_up(&qp->wait);
++	}
+ }
+ 
+ static void update_sge(struct ipath_sge_state *ss, u32 length)
+@@ -1012,13 +1020,24 @@ static void sdma_complete(void *cookie, int status)
+ 	struct ipath_verbs_txreq *tx = cookie;
+ 	struct ipath_qp *qp = tx->qp;
+ 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
++	unsigned int flags;
++	enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ?
++		IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR;
+ 
+-	/* Generate a completion queue entry if needed */
+-	if (qp->ibqp.qp_type != IB_QPT_RC && tx->wqe) {
+-		enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ?
+-			IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR;
+-
++	if (atomic_dec_and_test(&qp->s_dma_busy)) {
++		spin_lock_irqsave(&qp->s_lock, flags);
++		if (tx->wqe)
++			ipath_send_complete(qp, tx->wqe, ibs);
++		if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND &&
++		     qp->s_last != qp->s_head) ||
++		    (qp->s_flags & IPATH_S_WAIT_DMA))
++			ipath_schedule_send(qp);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++		wake_up(&qp->wait_dma);
++	} else if (tx->wqe) {
++		spin_lock_irqsave(&qp->s_lock, flags);
+ 		ipath_send_complete(qp, tx->wqe, ibs);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
+ 	}
+ 
+ 	if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF)
+@@ -1029,6 +1048,21 @@ static void sdma_complete(void *cookie, int status)
+ 		wake_up(&qp->wait);
+ }
+ 
++static void decrement_dma_busy(struct ipath_qp *qp)
++{
++	unsigned int flags;
++
++	if (atomic_dec_and_test(&qp->s_dma_busy)) {
++		spin_lock_irqsave(&qp->s_lock, flags);
++		if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND &&
++		     qp->s_last != qp->s_head) ||
++		    (qp->s_flags & IPATH_S_WAIT_DMA))
++			ipath_schedule_send(qp);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++		wake_up(&qp->wait_dma);
++	}
++}
++
+ /*
+  * Compute the number of clock cycles of delay before sending the next packet.
+  * The multipliers reflect the number of clocks for the fastest rate so
+@@ -1067,9 +1101,12 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp,
+ 	if (tx) {
+ 		qp->s_tx = NULL;
+ 		/* resend previously constructed packet */
++		atomic_inc(&qp->s_dma_busy);
+ 		ret = ipath_sdma_verbs_send(dd, tx->ss, tx->len, tx);
+-		if (ret)
++		if (ret) {
+ 			qp->s_tx = tx;
++			decrement_dma_busy(qp);
++		}
+ 		goto bail;
+ 	}
+ 
+@@ -1120,12 +1157,14 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp,
+ 		tx->txreq.sg_count = ndesc;
+ 		tx->map_len = (hdrwords + 2) << 2;
+ 		tx->txreq.map_addr = &tx->hdr;
++		atomic_inc(&qp->s_dma_busy);
+ 		ret = ipath_sdma_verbs_send(dd, ss, dwords, tx);
+ 		if (ret) {
+ 			/* save ss and length in dwords */
+ 			tx->ss = ss;
+ 			tx->len = dwords;
+ 			qp->s_tx = tx;
++			decrement_dma_busy(qp);
+ 		}
+ 		goto bail;
+ 	}
+@@ -1146,6 +1185,7 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp,
+ 	memcpy(piobuf, hdr, hdrwords << 2);
+ 	ipath_copy_from_sge(piobuf + hdrwords, ss, len);
+ 
++	atomic_inc(&qp->s_dma_busy);
+ 	ret = ipath_sdma_verbs_send(dd, NULL, 0, tx);
+ 	/*
+ 	 * If we couldn't queue the DMA request, save the info
+@@ -1156,6 +1196,7 @@ static int ipath_verbs_send_dma(struct ipath_qp *qp,
+ 		tx->ss = NULL;
+ 		tx->len = 0;
+ 		qp->s_tx = tx;
++		decrement_dma_busy(qp);
+ 	}
+ 	dev->n_unaligned++;
+ 	goto bail;
+@@ -1179,6 +1220,7 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp,
+ 	unsigned flush_wc;
+ 	u32 control;
+ 	int ret;
++	unsigned int flags;
+ 
+ 	piobuf = ipath_getpiobuf(dd, plen, NULL);
+ 	if (unlikely(piobuf == NULL)) {
+@@ -1249,8 +1291,11 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp,
+ 	}
+ 	copy_io(piobuf, ss, len, flush_wc);
+ done:
+-	if (qp->s_wqe)
++	if (qp->s_wqe) {
++		spin_lock_irqsave(&qp->s_lock, flags);
+ 		ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++	}
+ 	ret = 0;
+ bail:
+ 	return ret;
+@@ -1283,19 +1328,12 @@ int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr,
+ 	 * can defer SDMA restart until link goes ACTIVE without
+ 	 * worrying about just how we got there.
+ 	 */
+-	if (qp->ibqp.qp_type == IB_QPT_SMI)
++	if (qp->ibqp.qp_type == IB_QPT_SMI ||
++	    !(dd->ipath_flags & IPATH_HAS_SEND_DMA))
+ 		ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len,
+ 					   plen, dwords);
+-	/* All non-VL15 packets are dropped if link is not ACTIVE */
+-	else if (!(dd->ipath_flags & IPATH_LINKACTIVE)) {
+-		if (qp->s_wqe)
+-			ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS);
+-		ret = 0;
+-	} else if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
+-		ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len,
+-					   plen, dwords);
+ 	else
+-		ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len,
++		ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len,
+ 					   plen, dwords);
+ 
+ 	return ret;
+@@ -1403,27 +1441,46 @@ bail:
+  * This is called from ipath_intr() at interrupt level when a PIO buffer is
+  * available after ipath_verbs_send() returned an error that no buffers were
+  * available.  Return 1 if we consumed all the PIO buffers and we still have
+- * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and
++ * QPs waiting for buffers (for now, just restart the send tasklet and
+  * return zero).
+  */
+ int ipath_ib_piobufavail(struct ipath_ibdev *dev)
+ {
++	struct list_head *list;
++	struct ipath_qp *qplist;
+ 	struct ipath_qp *qp;
+ 	unsigned long flags;
+ 
+ 	if (dev == NULL)
+ 		goto bail;
+ 
++	list = &dev->piowait;
++	qplist = NULL;
++
+ 	spin_lock_irqsave(&dev->pending_lock, flags);
+-	while (!list_empty(&dev->piowait)) {
+-		qp = list_entry(dev->piowait.next, struct ipath_qp,
+-				piowait);
++	while (!list_empty(list)) {
++		qp = list_entry(list->next, struct ipath_qp, piowait);
+ 		list_del_init(&qp->piowait);
+-		clear_bit(IPATH_S_BUSY, &qp->s_busy);
+-		tasklet_hi_schedule(&qp->s_task);
++		qp->pio_next = qplist;
++		qplist = qp;
++		atomic_inc(&qp->refcount);
+ 	}
+ 	spin_unlock_irqrestore(&dev->pending_lock, flags);
+ 
++	while (qplist != NULL) {
++		qp = qplist;
++		qplist = qp->pio_next;
++
++		spin_lock_irqsave(&qp->s_lock, flags);
++		if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)
++			ipath_schedule_send(qp);
++		spin_unlock_irqrestore(&qp->s_lock, flags);
++
++		/* Notify ipath_destroy_qp() if it is waiting. */
++		if (atomic_dec_and_test(&qp->refcount))
++			wake_up(&qp->wait);
++	}
++
+ bail:
+ 	return 0;
+ }
+@@ -2145,11 +2202,12 @@ bail:
+ void ipath_unregister_ib_device(struct ipath_ibdev *dev)
+ {
+ 	struct ib_device *ibdev = &dev->ibdev;
+-
+-	disable_timer(dev->dd);
++	u32 qps_inuse;
+ 
+ 	ib_unregister_device(ibdev);
+ 
++	disable_timer(dev->dd);
++
+ 	if (!list_empty(&dev->pending[0]) ||
+ 	    !list_empty(&dev->pending[1]) ||
+ 	    !list_empty(&dev->pending[2]))
+@@ -2164,7 +2222,10 @@ void ipath_unregister_ib_device(struct ipath_ibdev *dev)
+ 	 * Note that ipath_unregister_ib_device() can be called before all
+ 	 * the QPs are destroyed!
+ 	 */
+-	ipath_free_all_qps(&dev->qp_table);
++	qps_inuse = ipath_free_all_qps(&dev->qp_table);
++	if (qps_inuse)
++		ipath_dev_err(dev->dd, "QP memory leak! %u still in use\n",
++			qps_inuse);
+ 	kfree(dev->qp_table.table);
+ 	kfree(dev->lk_table.table);
+ 	kfree(dev->txreq_bufs);
+@@ -2215,17 +2276,14 @@ static ssize_t show_stats(struct device *device, struct device_attribute *attr,
+ 		      "RC OTH NAKs %d\n"
+ 		      "RC timeouts %d\n"
+ 		      "RC RDMA dup %d\n"
+-		      "RC stalls   %d\n"
+ 		      "piobuf wait %d\n"
+-		      "no piobuf   %d\n"
+ 		      "unaligned   %d\n"
+ 		      "PKT drops   %d\n"
+ 		      "WQE errs    %d\n",
+ 		      dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
+ 		      dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
+ 		      dev->n_other_naks, dev->n_timeouts,
+-		      dev->n_rdma_dup_busy, dev->n_rc_stalls, dev->n_piowait,
+-		      dev->n_no_piobuf, dev->n_unaligned,
++		      dev->n_rdma_dup_busy, dev->n_piowait, dev->n_unaligned,
+ 		      dev->n_pkt_drops, dev->n_wqe_errs);
+ 	for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
+ 		const struct ipath_opcode_stats *si = &dev->opstats[i];
+diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
+index 6514aa8..9d12ae8 100644
+--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
++++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
+@@ -74,6 +74,11 @@
+ #define IPATH_POST_RECV_OK		0x02
+ #define IPATH_PROCESS_RECV_OK		0x04
+ #define IPATH_PROCESS_SEND_OK		0x08
++#define IPATH_PROCESS_NEXT_SEND_OK	0x10
++#define IPATH_FLUSH_SEND		0x20
++#define IPATH_FLUSH_RECV		0x40
++#define IPATH_PROCESS_OR_FLUSH_SEND \
++	(IPATH_PROCESS_SEND_OK | IPATH_FLUSH_SEND)
+ 
+ /* IB Performance Manager status values */
+ #define IB_PMA_SAMPLE_STATUS_DONE	0x00
+@@ -353,12 +358,14 @@ struct ipath_qp {
+ 	struct ib_qp ibqp;
+ 	struct ipath_qp *next;		/* link list for QPN hash table */
+ 	struct ipath_qp *timer_next;	/* link list for ipath_ib_timer() */
++	struct ipath_qp *pio_next;	/* link for ipath_ib_piobufavail() */
+ 	struct list_head piowait;	/* link for wait PIO buf */
+ 	struct list_head timerwait;	/* link for waiting for timeouts */
+ 	struct ib_ah_attr remote_ah_attr;
+ 	struct ipath_ib_header s_hdr;	/* next packet header to send */
+ 	atomic_t refcount;
+ 	wait_queue_head_t wait;
++	wait_queue_head_t wait_dma;
+ 	struct tasklet_struct s_task;
+ 	struct ipath_mmap_info *ip;
+ 	struct ipath_sge_state *s_cur_sge;
+@@ -369,7 +376,7 @@ struct ipath_qp {
+ 	struct ipath_sge_state s_rdma_read_sge;
+ 	struct ipath_sge_state r_sge;	/* current receive data */
+ 	spinlock_t s_lock;
+-	unsigned long s_busy;
++	atomic_t s_dma_busy;
+ 	u16 s_pkt_delay;
+ 	u16 s_hdrwords;		/* size of s_hdr in 32 bit words */
+ 	u32 s_cur_size;		/* size of send packet in bytes */
+@@ -383,6 +390,7 @@ struct ipath_qp {
+ 	u32 s_rnr_timeout;	/* number of milliseconds for RNR timeout */
+ 	u32 r_ack_psn;		/* PSN for next ACK or atomic ACK */
+ 	u64 r_wr_id;		/* ID for current receive WQE */
++	unsigned long r_aflags;
+ 	u32 r_len;		/* total length of r_sge */
+ 	u32 r_rcv_len;		/* receive data len processed */
+ 	u32 r_psn;		/* expected rcv packet sequence number */
+@@ -394,8 +402,7 @@ struct ipath_qp {
+ 	u8 r_state;		/* opcode of last packet received */
+ 	u8 r_nak_state;		/* non-zero if NAK is pending */
+ 	u8 r_min_rnr_timer;	/* retry timeout value for RNR NAKs */
+-	u8 r_reuse_sge;		/* for UC receive errors */
+-	u8 r_wrid_valid;	/* r_wrid set but CQ entry not yet made */
++	u8 r_flags;
+ 	u8 r_max_rd_atomic;	/* max number of RDMA read/atomic to receive */
+ 	u8 r_head_ack_queue;	/* index into s_ack_queue[] */
+ 	u8 qp_access_flags;
+@@ -404,13 +411,13 @@ struct ipath_qp {
+ 	u8 s_rnr_retry_cnt;
+ 	u8 s_retry;		/* requester retry counter */
+ 	u8 s_rnr_retry;		/* requester RNR retry counter */
+-	u8 s_wait_credit;	/* limit number of unacked packets sent */
+ 	u8 s_pkey_index;	/* PKEY index to use */
+ 	u8 s_max_rd_atomic;	/* max number of RDMA read/atomic to send */
+ 	u8 s_num_rd_atomic;	/* number of RDMA read/atomic pending */
+ 	u8 s_tail_ack_queue;	/* index into s_ack_queue[] */
+ 	u8 s_flags;
+ 	u8 s_dmult;
++	u8 s_draining;
+ 	u8 timeout;		/* Timeout for this QP */
+ 	enum ib_mtu path_mtu;
+ 	u32 remote_qpn;
+@@ -428,16 +435,40 @@ struct ipath_qp {
+ 	struct ipath_sge r_sg_list[0];	/* verified SGEs */
+ };
+ 
+-/* Bit definition for s_busy. */
+-#define IPATH_S_BUSY		0
++/*
++ * Atomic bit definitions for r_aflags.
++ */
++#define IPATH_R_WRID_VALID	0
++
++/*
++ * Bit definitions for r_flags.
++ */
++#define IPATH_R_REUSE_SGE	0x01
++#define IPATH_R_RDMAR_SEQ	0x02
+ 
+ /*
+  * Bit definitions for s_flags.
++ *
++ * IPATH_S_FENCE_PENDING - waiting for all prior RDMA read or atomic SWQEs
++ *			   before processing the next SWQE
++ * IPATH_S_RDMAR_PENDING - waiting for any RDMA read or atomic SWQEs
++ *			   before processing the next SWQE
++ * IPATH_S_WAITING - waiting for RNR timeout or send buffer available.
++ * IPATH_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE
++ * IPATH_S_WAIT_DMA - waiting for send DMA queue to drain before generating
++ *		      next send completion entry not via send DMA.
+  */
+ #define IPATH_S_SIGNAL_REQ_WR	0x01
+ #define IPATH_S_FENCE_PENDING	0x02
+ #define IPATH_S_RDMAR_PENDING	0x04
+ #define IPATH_S_ACK_PENDING	0x08
++#define IPATH_S_BUSY		0x10
++#define IPATH_S_WAITING		0x20
++#define IPATH_S_WAIT_SSN_CREDIT	0x40
++#define IPATH_S_WAIT_DMA	0x80
++
++#define IPATH_S_ANY_WAIT (IPATH_S_FENCE_PENDING | IPATH_S_RDMAR_PENDING | \
++	IPATH_S_WAITING | IPATH_S_WAIT_SSN_CREDIT | IPATH_S_WAIT_DMA)
+ 
+ #define IPATH_PSN_CREDIT	512
+ 
+@@ -573,13 +604,11 @@ struct ipath_ibdev {
+ 	u32 n_rnr_naks;
+ 	u32 n_other_naks;
+ 	u32 n_timeouts;
+-	u32 n_rc_stalls;
+ 	u32 n_pkt_drops;
+ 	u32 n_vl15_dropped;
+ 	u32 n_wqe_errs;
+ 	u32 n_rdma_dup_busy;
+ 	u32 n_piowait;
+-	u32 n_no_piobuf;
+ 	u32 n_unaligned;
+ 	u32 port_cap_flags;
+ 	u32 pma_sample_start;
+@@ -657,6 +686,17 @@ static inline struct ipath_ibdev *to_idev(struct ib_device *ibdev)
+ 	return container_of(ibdev, struct ipath_ibdev, ibdev);
+ }
+ 
++/*
++ * This must be called with s_lock held.
++ */
++static inline void ipath_schedule_send(struct ipath_qp *qp)
++{
++	if (qp->s_flags & IPATH_S_ANY_WAIT)
++		qp->s_flags &= ~IPATH_S_ANY_WAIT;
++	if (!(qp->s_flags & IPATH_S_BUSY))
++		tasklet_hi_schedule(&qp->s_task);
++}
++
+ int ipath_process_mad(struct ib_device *ibdev,
+ 		      int mad_flags,
+ 		      u8 port_num,
+@@ -706,12 +746,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 		   int attr_mask, struct ib_qp_init_attr *init_attr);
+ 
+-void ipath_free_all_qps(struct ipath_qp_table *qpt);
++unsigned ipath_free_all_qps(struct ipath_qp_table *qpt);
+ 
+ int ipath_init_qp_table(struct ipath_ibdev *idev, int size);
+ 
+-void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
+-
+ void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
+ 
+ unsigned ipath_ib_rate_to_mult(enum ib_rate rate);
+@@ -729,7 +767,9 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
+ 		  int has_grh, void *data, u32 tlen, struct ipath_qp *qp);
+ 
+-void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc);
++void ipath_restart_rc(struct ipath_qp *qp, u32 psn);
++
++void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err);
+ 
+ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr);
+ 
+diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
+index 9f7364a..a4e9269 100644
+--- a/drivers/infiniband/hw/nes/nes.c
++++ b/drivers/infiniband/hw/nes/nes.c
+@@ -91,10 +91,6 @@ unsigned int nes_debug_level = 0;
+ module_param_named(debug_level, nes_debug_level, uint, 0644);
+ MODULE_PARM_DESC(debug_level, "Enable debug output level");
+ 
+-unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
+-module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR);
+-MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation");
+-
+ LIST_HEAD(nes_adapter_list);
+ static LIST_HEAD(nes_dev_list);
+ 
+diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
+index 1f9f7bf..61b46e9 100644
+--- a/drivers/infiniband/hw/nes/nes.h
++++ b/drivers/infiniband/hw/nes/nes.h
+@@ -173,7 +173,6 @@ extern int disable_mpa_crc;
+ extern unsigned int send_first;
+ extern unsigned int nes_drv_opt;
+ extern unsigned int nes_debug_level;
+-extern unsigned int nes_lro_max_aggr;
+ 
+ extern struct list_head nes_adapter_list;
+ 
+diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
+index 8dc70f9..d3278f1 100644
+--- a/drivers/infiniband/hw/nes/nes_hw.c
++++ b/drivers/infiniband/hw/nes/nes_hw.c
+@@ -42,6 +42,10 @@
+ 
+ #include "nes.h"
+ 
++static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
++module_param(nes_lro_max_aggr, uint, 0444);
++MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
++
+ static u32 crit_err_count;
+ u32 int_mod_timer_init;
+ u32 int_mod_cq_depth_256;
+@@ -1738,7 +1742,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
+ 			jumbomode = 1;
+ 		nes_nic_init_timer_defaults(nesdev, jumbomode);
+ 	}
+-	nesvnic->lro_mgr.max_aggr       = NES_LRO_MAX_AGGR;
++	nesvnic->lro_mgr.max_aggr       = nes_lro_max_aggr;
+ 	nesvnic->lro_mgr.max_desc       = NES_MAX_LRO_DESCRIPTORS;
+ 	nesvnic->lro_mgr.lro_arr        = nesvnic->lro_desc;
+ 	nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index 0b85117..1074824 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -250,6 +250,7 @@ static int linear_run (mddev_t *mddev)
+ {
+ 	linear_conf_t *conf;
+ 
++	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
+ 	conf = linear_conf(mddev, mddev->raid_disks);
+ 
+ 	if (!conf)
+diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
+index 42ee1a2..4f4d1f3 100644
+--- a/drivers/md/multipath.c
++++ b/drivers/md/multipath.c
+@@ -417,6 +417,7 @@ static int multipath_run (mddev_t *mddev)
+ 	 * bookkeeping area. [whatever we allocate in multipath_run(),
+ 	 * should be freed in multipath_stop()]
+ 	 */
++	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
+ 
+ 	conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL);
+ 	mddev->private = conf;
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 818b482..914c04d 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -280,6 +280,7 @@ static int raid0_run (mddev_t *mddev)
+ 	       (mddev->chunk_size>>1)-1);
+ 	blk_queue_max_sectors(mddev->queue, mddev->chunk_size >> 9);
+ 	blk_queue_segment_boundary(mddev->queue, (mddev->chunk_size>>1) - 1);
++	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
+ 
+ 	conf = kmalloc(sizeof (raid0_conf_t), GFP_KERNEL);
+ 	if (!conf)
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 6778b7c..ac409b7 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1935,6 +1935,9 @@ static int run(mddev_t *mddev)
+ 	if (!conf->r1bio_pool)
+ 		goto out_no_mem;
+ 
++	spin_lock_init(&conf->device_lock);
++	mddev->queue->queue_lock = &conf->device_lock;
++
+ 	rdev_for_each(rdev, tmp, mddev) {
+ 		disk_idx = rdev->raid_disk;
+ 		if (disk_idx >= mddev->raid_disks
+@@ -1958,7 +1961,6 @@ static int run(mddev_t *mddev)
+ 	}
+ 	conf->raid_disks = mddev->raid_disks;
+ 	conf->mddev = mddev;
+-	spin_lock_init(&conf->device_lock);
+ 	INIT_LIST_HEAD(&conf->retry_list);
+ 
+ 	spin_lock_init(&conf->resync_lock);
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index faf3d89..8536ede 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -2082,6 +2082,9 @@ static int run(mddev_t *mddev)
+ 		goto out_free_conf;
+ 	}
+ 
++	spin_lock_init(&conf->device_lock);
++	mddev->queue->queue_lock = &conf->device_lock;
++
+ 	rdev_for_each(rdev, tmp, mddev) {
+ 		disk_idx = rdev->raid_disk;
+ 		if (disk_idx >= mddev->raid_disks
+@@ -2103,7 +2106,6 @@ static int run(mddev_t *mddev)
+ 
+ 		disk->head_position = 0;
+ 	}
+-	spin_lock_init(&conf->device_lock);
+ 	INIT_LIST_HEAD(&conf->retry_list);
+ 
+ 	spin_lock_init(&conf->resync_lock);
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 087eee0..93fde48 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2369,8 +2369,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 
+ 	/* complete a check operation */
+ 	if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
+-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
+-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
++		clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
++		clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+ 		if (s->failed == 0) {
+ 			if (sh->ops.zero_sum_result == 0)
+ 				/* parity is correct (on disc,
+@@ -2400,16 +2400,6 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 			canceled_check = 1; /* STRIPE_INSYNC is not set */
+ 	}
+ 
+-	/* check if we can clear a parity disk reconstruct */
+-	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
+-		test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
+-
+-		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
+-	}
+-
+ 	/* start a new check operation if there are no failures, the stripe is
+ 	 * not insync, and a repair is not in flight
+ 	 */
+@@ -2424,6 +2414,17 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 		}
+ 	}
+ 
++	/* check if we can clear a parity disk reconstruct */
++	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
++	    test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
++
++		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
++	}
++
++
+ 	/* Wait for check parity and compute block operations to complete
+ 	 * before write-back.  If a failure occurred while the check operation
+ 	 * was in flight we need to cycle this stripe through handle_stripe
+@@ -4256,6 +4257,7 @@ static int run(mddev_t *mddev)
+ 			goto abort;
+ 	}
+ 	spin_lock_init(&conf->device_lock);
++	mddev->queue->queue_lock = &conf->device_lock;
+ 	init_waitqueue_head(&conf->wait_for_stripe);
+ 	init_waitqueue_head(&conf->wait_for_overlap);
+ 	INIT_LIST_HEAD(&conf->handle_list);
+diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
+index ddf57e1..7a7803b 100644
+--- a/drivers/media/Kconfig
++++ b/drivers/media/Kconfig
+@@ -89,8 +89,7 @@ config DVB_CORE
+ 
+ config VIDEO_MEDIA
+ 	tristate
+-	default DVB_CORE || VIDEO_DEV
+-	depends on DVB_CORE || VIDEO_DEV
++	default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
+ 
+ comment "Multimedia drivers"
+ 
+diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
+index 5be85ff..d620654 100644
+--- a/drivers/media/common/tuners/Kconfig
++++ b/drivers/media/common/tuners/Kconfig
+@@ -1,6 +1,6 @@
+ config MEDIA_ATTACH
+ 	bool "Load and attach frontend and tuner driver modules as needed"
+-	depends on DVB_CORE
++	depends on VIDEO_MEDIA
+ 	depends on MODULES
+ 	help
+ 	  Remove the static dependency of DVB card drivers on all
+@@ -19,10 +19,10 @@ config MEDIA_ATTACH
+ 
+ config MEDIA_TUNER
+ 	tristate
+-	default DVB_CORE || VIDEO_DEV
+-	depends on DVB_CORE || VIDEO_DEV
+-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
+-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
++	default VIDEO_MEDIA && I2C
++	depends on VIDEO_MEDIA && I2C
++	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
++	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+ 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
+ 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
+ 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
+@@ -46,7 +46,7 @@ if MEDIA_TUNER_CUSTOMIZE
+ 
+ config MEDIA_TUNER_SIMPLE
+ 	tristate "Simple tuner support"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	select MEDIA_TUNER_TDA9887
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+@@ -54,7 +54,7 @@ config MEDIA_TUNER_SIMPLE
+ 
+ config MEDIA_TUNER_TDA8290
+ 	tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	select MEDIA_TUNER_TDA827X
+ 	select MEDIA_TUNER_TDA18271
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+@@ -63,21 +63,21 @@ config MEDIA_TUNER_TDA8290
+ 
+ config MEDIA_TUNER_TDA827X
+ 	tristate "Philips TDA827X silicon tuner"
+-	depends on DVB_CORE && I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A DVB-T silicon tuner module. Say Y when you want to support this tuner.
+ 
+ config MEDIA_TUNER_TDA18271
+ 	tristate "NXP TDA18271 silicon tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A silicon tuner module. Say Y when you want to support this tuner.
+ 
+ config MEDIA_TUNER_TDA9887
+ 	tristate "TDA 9885/6/7 analog IF demodulator"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for Philips TDA9885/6/7
+@@ -85,67 +85,79 @@ config MEDIA_TUNER_TDA9887
+ 
+ config MEDIA_TUNER_TEA5761
+ 	tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
+-	depends on I2C && EXPERIMENTAL
++	depends on VIDEO_MEDIA && I2C
++	depends on EXPERIMENTAL
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for the Philips TEA5761 radio tuner.
+ 
+ config MEDIA_TUNER_TEA5767
+ 	tristate "TEA 5767 radio tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for the Philips TEA5767 radio tuner.
+ 
+ config MEDIA_TUNER_MT20XX
+ 	tristate "Microtune 2032 / 2050 tuners"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for the MT2032 / MT2050 tuner.
+ 
+ config MEDIA_TUNER_MT2060
+ 	tristate "Microtune MT2060 silicon IF tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A driver for the silicon IF tuner MT2060 from Microtune.
+ 
+ config MEDIA_TUNER_MT2266
+ 	tristate "Microtune MT2266 silicon tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A driver for the silicon baseband tuner MT2266 from Microtune.
+ 
+ config MEDIA_TUNER_MT2131
+ 	tristate "Microtune MT2131 silicon tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A driver for the silicon baseband tuner MT2131 from Microtune.
+ 
+ config MEDIA_TUNER_QT1010
+ 	tristate "Quantek QT1010 silicon tuner"
+-	depends on DVB_CORE && I2C
++	depends on VIDEO_MEDIA && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A driver for the silicon tuner QT1010 from Quantek.
+ 
+ config MEDIA_TUNER_XC2028
+ 	tristate "XCeive xc2028/xc3028 tuners"
+-	depends on I2C && FW_LOADER
++	depends on VIDEO_MEDIA && I2C
++	depends on HOTPLUG
++	select FW_LOADER
+ 	default m if MEDIA_TUNER_CUSTOMIZE
+ 	help
+ 	  Say Y here to include support for the xc2028/xc3028 tuners.
+ 
+ config MEDIA_TUNER_XC5000
+ 	tristate "Xceive XC5000 silicon tuner"
+-	depends on I2C
++	depends on VIDEO_MEDIA && I2C
++	depends on HOTPLUG
++	select FW_LOADER
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+ 	  A driver for the silicon tuner XC5000 from Xceive.
+ 	  This device is only used inside a SiP called togther with a
+ 	  demodulator for now.
+ 
++config MEDIA_TUNER_MXL5005S
++	tristate "MaxLinear MSL5005S silicon tuner"
++	depends on VIDEO_MEDIA && I2C
++	default m if DVB_FE_CUSTOMISE
++	help
++	  A driver for the silicon tuner MXL5005S from MaxLinear.
++
+ endif # MEDIA_TUNER_CUSTOMIZE
+diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
+index 236d993..55f7e67 100644
+--- a/drivers/media/common/tuners/Makefile
++++ b/drivers/media/common/tuners/Makefile
+@@ -20,6 +20,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
+ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
+ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
+ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
++obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
+ 
+ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+ EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
+new file mode 100644
+index 0000000..5d05b53
+--- /dev/null
++++ b/drivers/media/common/tuners/mxl5005s.c
+@@ -0,0 +1,4110 @@
++/*
++    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
++
++    Copyright (C) 2008 MaxLinear
++    Copyright (C) 2006 Steven Toth <stoth at hauppauge.com>
++      Functions:
++	mxl5005s_reset()
++	mxl5005s_writereg()
++	mxl5005s_writeregs()
++	mxl5005s_init()
++	mxl5005s_reconfigure()
++	mxl5005s_AssignTunerMode()
++	mxl5005s_set_params()
++	mxl5005s_get_frequency()
++	mxl5005s_get_bandwidth()
++	mxl5005s_release()
++	mxl5005s_attach()
++
++    Copyright (C) 2008 Realtek
++    Copyright (C) 2008 Jan Hoogenraad
++      Functions:
++	mxl5005s_SetRfFreqHz()
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++
++*/
++
++/*
++    History of this driver (Steven Toth):
++      I was given a public release of a linux driver that included
++      support for the MaxLinear MXL5005S silicon tuner. Analysis of
++      the tuner driver showed clearly three things.
++
++      1. The tuner driver didn't support the LinuxTV tuner API
++	 so the code Realtek added had to be removed.
++
++      2. A significant amount of the driver is reference driver code
++	 from MaxLinear, I felt it was important to identify and
++	 preserve this.
++
++      3. New code has to be added to interface correctly with the
++	 LinuxTV API, as a regular kernel module.
++
++      Other than the reference driver enum's, I've clearly marked
++      sections of the code and retained the copyright of the
++      respective owners.
++*/
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include "dvb_frontend.h"
++#include "mxl5005s.h"
++
++static int debug;
++
++#define dprintk(level, arg...) do {    \
++	if (level <= debug)            \
++		printk(arg);    \
++	} while (0)
++
++#define TUNER_REGS_NUM          104
++#define INITCTRL_NUM            40
++
++#ifdef _MXL_PRODUCTION
++#define CHCTRL_NUM              39
++#else
++#define CHCTRL_NUM              36
++#endif
++
++#define MXLCTRL_NUM             189
++#define MASTER_CONTROL_ADDR     9
++
++/* Enumeration of Master Control Register State */
++enum master_control_state {
++	MC_LOAD_START = 1,
++	MC_POWER_DOWN,
++	MC_SYNTH_RESET,
++	MC_SEQ_OFF
++};
++
++/* Enumeration of MXL5005 Tuner Modulation Type */
++enum {
++	MXL_DEFAULT_MODULATION = 0,
++	MXL_DVBT,
++	MXL_ATSC,
++	MXL_QAM,
++	MXL_ANALOG_CABLE,
++	MXL_ANALOG_OTA
++} tuner_modu_type;
++
++/* MXL5005 Tuner Register Struct */
++struct TunerReg {
++	u16 Reg_Num;	/* Tuner Register Address */
++	u16 Reg_Val;	/* Current sw programmed value waiting to be writen */
++};
++
++enum {
++	/* Initialization Control Names */
++	DN_IQTN_AMP_CUT = 1,       /* 1 */
++	BB_MODE,                   /* 2 */
++	BB_BUF,                    /* 3 */
++	BB_BUF_OA,                 /* 4 */
++	BB_ALPF_BANDSELECT,        /* 5 */
++	BB_IQSWAP,                 /* 6 */
++	BB_DLPF_BANDSEL,           /* 7 */
++	RFSYN_CHP_GAIN,            /* 8 */
++	RFSYN_EN_CHP_HIGAIN,       /* 9 */
++	AGC_IF,                    /* 10 */
++	AGC_RF,                    /* 11 */
++	IF_DIVVAL,                 /* 12 */
++	IF_VCO_BIAS,               /* 13 */
++	CHCAL_INT_MOD_IF,          /* 14 */
++	CHCAL_FRAC_MOD_IF,         /* 15 */
++	DRV_RES_SEL,               /* 16 */
++	I_DRIVER,                  /* 17 */
++	EN_AAF,                    /* 18 */
++	EN_3P,                     /* 19 */
++	EN_AUX_3P,                 /* 20 */
++	SEL_AAF_BAND,              /* 21 */
++	SEQ_ENCLK16_CLK_OUT,       /* 22 */
++	SEQ_SEL4_16B,              /* 23 */
++	XTAL_CAPSELECT,            /* 24 */
++	IF_SEL_DBL,                /* 25 */
++	RFSYN_R_DIV,               /* 26 */
++	SEQ_EXTSYNTHCALIF,         /* 27 */
++	SEQ_EXTDCCAL,              /* 28 */
++	AGC_EN_RSSI,               /* 29 */
++	RFA_ENCLKRFAGC,            /* 30 */
++	RFA_RSSI_REFH,             /* 31 */
++	RFA_RSSI_REF,              /* 32 */
++	RFA_RSSI_REFL,             /* 33 */
++	RFA_FLR,                   /* 34 */
++	RFA_CEIL,                  /* 35 */
++	SEQ_EXTIQFSMPULSE,         /* 36 */
++	OVERRIDE_1,                /* 37 */
++	BB_INITSTATE_DLPF_TUNE,    /* 38 */
++	TG_R_DIV,                  /* 39 */
++	EN_CHP_LIN_B,              /* 40 */
++
++	/* Channel Change Control Names */
++	DN_POLY = 51,              /* 51 */
++	DN_RFGAIN,                 /* 52 */
++	DN_CAP_RFLPF,              /* 53 */
++	DN_EN_VHFUHFBAR,           /* 54 */
++	DN_GAIN_ADJUST,            /* 55 */
++	DN_IQTNBUF_AMP,            /* 56 */
++	DN_IQTNGNBFBIAS_BST,       /* 57 */
++	RFSYN_EN_OUTMUX,           /* 58 */
++	RFSYN_SEL_VCO_OUT,         /* 59 */
++	RFSYN_SEL_VCO_HI,          /* 60 */
++	RFSYN_SEL_DIVM,            /* 61 */
++	RFSYN_RF_DIV_BIAS,         /* 62 */
++	DN_SEL_FREQ,               /* 63 */
++	RFSYN_VCO_BIAS,            /* 64 */
++	CHCAL_INT_MOD_RF,          /* 65 */
++	CHCAL_FRAC_MOD_RF,         /* 66 */
++	RFSYN_LPF_R,               /* 67 */
++	CHCAL_EN_INT_RF,           /* 68 */
++	TG_LO_DIVVAL,              /* 69 */
++	TG_LO_SELVAL,              /* 70 */
++	TG_DIV_VAL,                /* 71 */
++	TG_VCO_BIAS,               /* 72 */
++	SEQ_EXTPOWERUP,            /* 73 */
++	OVERRIDE_2,                /* 74 */
++	OVERRIDE_3,                /* 75 */
++	OVERRIDE_4,                /* 76 */
++	SEQ_FSM_PULSE,             /* 77 */
++	GPIO_4B,                   /* 78 */
++	GPIO_3B,                   /* 79 */
++	GPIO_4,                    /* 80 */
++	GPIO_3,                    /* 81 */
++	GPIO_1B,                   /* 82 */
++	DAC_A_ENABLE,              /* 83 */
++	DAC_B_ENABLE,              /* 84 */
++	DAC_DIN_A,                 /* 85 */
++	DAC_DIN_B,                 /* 86 */
++#ifdef _MXL_PRODUCTION
++	RFSYN_EN_DIV,              /* 87 */
++	RFSYN_DIVM,                /* 88 */
++	DN_BYPASS_AGC_I2C          /* 89 */
++#endif
++} MXL5005_ControlName;
++
++/*
++ * The following context is source code provided by MaxLinear.
++ * MaxLinear source code - Common_MXL.h (?)
++ */
++
++/* Constants */
++#define MXL5005S_REG_WRITING_TABLE_LEN_MAX	104
++#define MXL5005S_LATCH_BYTE			0xfe
++
++/* Register address, MSB, and LSB */
++#define MXL5005S_BB_IQSWAP_ADDR			59
++#define MXL5005S_BB_IQSWAP_MSB			0
++#define MXL5005S_BB_IQSWAP_LSB			0
++
++#define MXL5005S_BB_DLPF_BANDSEL_ADDR		53
++#define MXL5005S_BB_DLPF_BANDSEL_MSB		4
++#define MXL5005S_BB_DLPF_BANDSEL_LSB		3
++
++/* Standard modes */
++enum {
++	MXL5005S_STANDARD_DVBT,
++	MXL5005S_STANDARD_ATSC,
++};
++#define MXL5005S_STANDARD_MODE_NUM		2
++
++/* Bandwidth modes */
++enum {
++	MXL5005S_BANDWIDTH_6MHZ = 6000000,
++	MXL5005S_BANDWIDTH_7MHZ = 7000000,
++	MXL5005S_BANDWIDTH_8MHZ = 8000000,
++};
++#define MXL5005S_BANDWIDTH_MODE_NUM		3
++
++/* MXL5005 Tuner Control Struct */
++struct TunerControl {
++	u16 Ctrl_Num;	/* Control Number */
++	u16 size;	/* Number of bits to represent Value */
++	u16 addr[25];	/* Array of Tuner Register Address for each bit pos */
++	u16 bit[25];	/* Array of bit pos in Reg Addr for each bit pos */
++	u16 val[25];	/* Binary representation of Value */
++};
++
++/* MXL5005 Tuner Struct */
++struct mxl5005s_state {
++	u8	Mode;		/* 0: Analog Mode ; 1: Digital Mode */
++	u8	IF_Mode;	/* for Analog Mode, 0: zero IF; 1: low IF */
++	u32	Chan_Bandwidth;	/* filter  channel bandwidth (6, 7, 8) */
++	u32	IF_OUT;		/* Desired IF Out Frequency */
++	u16	IF_OUT_LOAD;	/* IF Out Load Resistor (200/300 Ohms) */
++	u32	RF_IN;		/* RF Input Frequency */
++	u32	Fxtal;		/* XTAL Frequency */
++	u8	AGC_Mode;	/* AGC Mode 0: Dual AGC; 1: Single AGC */
++	u16	TOP;		/* Value: take over point */
++	u8	CLOCK_OUT;	/* 0: turn off clk out; 1: turn on clock out */
++	u8	DIV_OUT;	/* 4MHz or 16MHz */
++	u8	CAPSELECT;	/* 0: disable On-Chip pulling cap; 1: enable */
++	u8	EN_RSSI;	/* 0: disable RSSI; 1: enable RSSI */
++
++	/* Modulation Type; */
++	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
++	u8	Mod_Type;
++
++	/* Tracking Filter Type */
++	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
++	u8	TF_Type;
++
++	/* Calculated Settings */
++	u32	RF_LO;		/* Synth RF LO Frequency */
++	u32	IF_LO;		/* Synth IF LO Frequency */
++	u32	TG_LO;		/* Synth TG_LO Frequency */
++
++	/* Pointers to ControlName Arrays */
++	u16	Init_Ctrl_Num;		/* Number of INIT Control Names */
++	struct TunerControl
++		Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */
++
++	u16	CH_Ctrl_Num;		/* Number of CH Control Names */
++	struct TunerControl
++		CH_Ctrl[CHCTRL_NUM];	/* CH Control Name Array Pointer */
++
++	u16	MXL_Ctrl_Num;		/* Number of MXL Control Names */
++	struct TunerControl
++		MXL_Ctrl[MXLCTRL_NUM];	/* MXL Control Name Array Pointer */
++
++	/* Pointer to Tuner Register Array */
++	u16	TunerRegs_Num;		/* Number of Tuner Registers */
++	struct TunerReg
++		TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
++
++	/* Linux driver framework specific */
++	struct mxl5005s_config *config;
++	struct dvb_frontend *frontend;
++	struct i2c_adapter *i2c;
++
++	/* Cache values */
++	u32 current_mode;
++
++};
++
++static u16 MXL_GetMasterControl(u8 *MasterReg, int state);
++static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
++static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
++static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
++	u8 bitVal);
++static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum,
++	u8 *RegVal, int *count);
++static u32 MXL_Ceiling(u32 value, u32 resolution);
++static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal);
++static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
++	u32 value, u16 controlGroup);
++static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val);
++static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
++	u8 *RegVal, int *count);
++static u32 MXL_GetXtalInt(u32 Xtal_Freq);
++static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
++static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
++static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
++static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
++	u8 *RegVal, int *count);
++static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
++	u8 *datatable, u8 len);
++static u16 MXL_IFSynthInit(struct dvb_frontend *fe);
++static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
++	u32 bandwidth);
++static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
++	u32 bandwidth);
++
++/* ----------------------------------------------------------------
++ * Begin: Custom code salvaged from the Realtek driver.
++ * Copyright (C) 2008 Realtek
++ * Copyright (C) 2008 Jan Hoogenraad
++ * This code is placed under the terms of the GNU General Public License
++ *
++ * Released by Realtek under GPLv2.
++ * Thanks to Realtek for a lot of support we received !
++ *
++ *  Revision: 080314 - original version
++ */
++
++static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
++	unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
++	int TableLen;
++
++	u32 IfDivval = 0;
++	unsigned char MasterControlByte;
++
++	dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz);
++
++	/* Set MxL5005S tuner RF frequency according to example code. */
++
++	/* Tuner RF frequency setting stage 0 */
++	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
++	AddrTable[0] = MASTER_CONTROL_ADDR;
++	ByteTable[0] |= state->config->AgcMasterByte;
++
++	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
++
++	/* Tuner RF frequency setting stage 1 */
++	MXL_TuneRF(fe, RfFreqHz);
++
++	MXL_ControlRead(fe, IF_DIVVAL, &IfDivval);
++
++	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0);
++	MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1);
++	MXL_ControlWrite(fe, IF_DIVVAL, 8);
++	MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen);
++
++	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
++	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
++	ByteTable[TableLen] = MasterControlByte |
++		state->config->AgcMasterByte;
++	TableLen += 1;
++
++	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
++
++	/* Wait 30 ms. */
++	msleep(150);
++
++	/* Tuner RF frequency setting stage 2 */
++	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1);
++	MXL_ControlWrite(fe, IF_DIVVAL, IfDivval);
++	MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen);
++
++	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
++	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
++	ByteTable[TableLen] = MasterControlByte |
++		state->config->AgcMasterByte ;
++	TableLen += 1;
++
++	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
++
++	msleep(100);
++
++	return 0;
++}
++/* End: Custom code taken from the Realtek driver */
++
++/* ----------------------------------------------------------------
++ * Begin: Reference driver code found in the Realtek driver.
++ * Copyright (C) 2008 MaxLinear
++ */
++static u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	state->TunerRegs_Num = TUNER_REGS_NUM ;
++
++	state->TunerRegs[0].Reg_Num = 9 ;
++	state->TunerRegs[0].Reg_Val = 0x40 ;
++
++	state->TunerRegs[1].Reg_Num = 11 ;
++	state->TunerRegs[1].Reg_Val = 0x19 ;
++
++	state->TunerRegs[2].Reg_Num = 12 ;
++	state->TunerRegs[2].Reg_Val = 0x60 ;
++
++	state->TunerRegs[3].Reg_Num = 13 ;
++	state->TunerRegs[3].Reg_Val = 0x00 ;
++
++	state->TunerRegs[4].Reg_Num = 14 ;
++	state->TunerRegs[4].Reg_Val = 0x00 ;
++
++	state->TunerRegs[5].Reg_Num = 15 ;
++	state->TunerRegs[5].Reg_Val = 0xC0 ;
++
++	state->TunerRegs[6].Reg_Num = 16 ;
++	state->TunerRegs[6].Reg_Val = 0x00 ;
++
++	state->TunerRegs[7].Reg_Num = 17 ;
++	state->TunerRegs[7].Reg_Val = 0x00 ;
++
++	state->TunerRegs[8].Reg_Num = 18 ;
++	state->TunerRegs[8].Reg_Val = 0x00 ;
++
++	state->TunerRegs[9].Reg_Num = 19 ;
++	state->TunerRegs[9].Reg_Val = 0x34 ;
++
++	state->TunerRegs[10].Reg_Num = 21 ;
++	state->TunerRegs[10].Reg_Val = 0x00 ;
++
++	state->TunerRegs[11].Reg_Num = 22 ;
++	state->TunerRegs[11].Reg_Val = 0x6B ;
++
++	state->TunerRegs[12].Reg_Num = 23 ;
++	state->TunerRegs[12].Reg_Val = 0x35 ;
++
++	state->TunerRegs[13].Reg_Num = 24 ;
++	state->TunerRegs[13].Reg_Val = 0x70 ;
++
++	state->TunerRegs[14].Reg_Num = 25 ;
++	state->TunerRegs[14].Reg_Val = 0x3E ;
++
++	state->TunerRegs[15].Reg_Num = 26 ;
++	state->TunerRegs[15].Reg_Val = 0x82 ;
++
++	state->TunerRegs[16].Reg_Num = 31 ;
++	state->TunerRegs[16].Reg_Val = 0x00 ;
++
++	state->TunerRegs[17].Reg_Num = 32 ;
++	state->TunerRegs[17].Reg_Val = 0x40 ;
++
++	state->TunerRegs[18].Reg_Num = 33 ;
++	state->TunerRegs[18].Reg_Val = 0x53 ;
++
++	state->TunerRegs[19].Reg_Num = 34 ;
++	state->TunerRegs[19].Reg_Val = 0x81 ;
++
++	state->TunerRegs[20].Reg_Num = 35 ;
++	state->TunerRegs[20].Reg_Val = 0xC9 ;
++
++	state->TunerRegs[21].Reg_Num = 36 ;
++	state->TunerRegs[21].Reg_Val = 0x01 ;
++
++	state->TunerRegs[22].Reg_Num = 37 ;
++	state->TunerRegs[22].Reg_Val = 0x00 ;
++
++	state->TunerRegs[23].Reg_Num = 41 ;
++	state->TunerRegs[23].Reg_Val = 0x00 ;
++
++	state->TunerRegs[24].Reg_Num = 42 ;
++	state->TunerRegs[24].Reg_Val = 0xF8 ;
++
++	state->TunerRegs[25].Reg_Num = 43 ;
++	state->TunerRegs[25].Reg_Val = 0x43 ;
++
++	state->TunerRegs[26].Reg_Num = 44 ;
++	state->TunerRegs[26].Reg_Val = 0x20 ;
++
++	state->TunerRegs[27].Reg_Num = 45 ;
++	state->TunerRegs[27].Reg_Val = 0x80 ;
++
++	state->TunerRegs[28].Reg_Num = 46 ;
++	state->TunerRegs[28].Reg_Val = 0x88 ;
++
++	state->TunerRegs[29].Reg_Num = 47 ;
++	state->TunerRegs[29].Reg_Val = 0x86 ;
++
++	state->TunerRegs[30].Reg_Num = 48 ;
++	state->TunerRegs[30].Reg_Val = 0x00 ;
++
++	state->TunerRegs[31].Reg_Num = 49 ;
++	state->TunerRegs[31].Reg_Val = 0x00 ;
++
++	state->TunerRegs[32].Reg_Num = 53 ;
++	state->TunerRegs[32].Reg_Val = 0x94 ;
++
++	state->TunerRegs[33].Reg_Num = 54 ;
++	state->TunerRegs[33].Reg_Val = 0xFA ;
++
++	state->TunerRegs[34].Reg_Num = 55 ;
++	state->TunerRegs[34].Reg_Val = 0x92 ;
++
++	state->TunerRegs[35].Reg_Num = 56 ;
++	state->TunerRegs[35].Reg_Val = 0x80 ;
++
++	state->TunerRegs[36].Reg_Num = 57 ;
++	state->TunerRegs[36].Reg_Val = 0x41 ;
++
++	state->TunerRegs[37].Reg_Num = 58 ;
++	state->TunerRegs[37].Reg_Val = 0xDB ;
++
++	state->TunerRegs[38].Reg_Num = 59 ;
++	state->TunerRegs[38].Reg_Val = 0x00 ;
++
++	state->TunerRegs[39].Reg_Num = 60 ;
++	state->TunerRegs[39].Reg_Val = 0x00 ;
++
++	state->TunerRegs[40].Reg_Num = 61 ;
++	state->TunerRegs[40].Reg_Val = 0x00 ;
++
++	state->TunerRegs[41].Reg_Num = 62 ;
++	state->TunerRegs[41].Reg_Val = 0x00 ;
++
++	state->TunerRegs[42].Reg_Num = 65 ;
++	state->TunerRegs[42].Reg_Val = 0xF8 ;
++
++	state->TunerRegs[43].Reg_Num = 66 ;
++	state->TunerRegs[43].Reg_Val = 0xE4 ;
++
++	state->TunerRegs[44].Reg_Num = 67 ;
++	state->TunerRegs[44].Reg_Val = 0x90 ;
++
++	state->TunerRegs[45].Reg_Num = 68 ;
++	state->TunerRegs[45].Reg_Val = 0xC0 ;
++
++	state->TunerRegs[46].Reg_Num = 69 ;
++	state->TunerRegs[46].Reg_Val = 0x01 ;
++
++	state->TunerRegs[47].Reg_Num = 70 ;
++	state->TunerRegs[47].Reg_Val = 0x50 ;
++
++	state->TunerRegs[48].Reg_Num = 71 ;
++	state->TunerRegs[48].Reg_Val = 0x06 ;
++
++	state->TunerRegs[49].Reg_Num = 72 ;
++	state->TunerRegs[49].Reg_Val = 0x00 ;
++
++	state->TunerRegs[50].Reg_Num = 73 ;
++	state->TunerRegs[50].Reg_Val = 0x20 ;
++
++	state->TunerRegs[51].Reg_Num = 76 ;
++	state->TunerRegs[51].Reg_Val = 0xBB ;
++
++	state->TunerRegs[52].Reg_Num = 77 ;
++	state->TunerRegs[52].Reg_Val = 0x13 ;
++
++	state->TunerRegs[53].Reg_Num = 81 ;
++	state->TunerRegs[53].Reg_Val = 0x04 ;
++
++	state->TunerRegs[54].Reg_Num = 82 ;
++	state->TunerRegs[54].Reg_Val = 0x75 ;
++
++	state->TunerRegs[55].Reg_Num = 83 ;
++	state->TunerRegs[55].Reg_Val = 0x00 ;
++
++	state->TunerRegs[56].Reg_Num = 84 ;
++	state->TunerRegs[56].Reg_Val = 0x00 ;
++
++	state->TunerRegs[57].Reg_Num = 85 ;
++	state->TunerRegs[57].Reg_Val = 0x00 ;
++
++	state->TunerRegs[58].Reg_Num = 91 ;
++	state->TunerRegs[58].Reg_Val = 0x70 ;
++
++	state->TunerRegs[59].Reg_Num = 92 ;
++	state->TunerRegs[59].Reg_Val = 0x00 ;
++
++	state->TunerRegs[60].Reg_Num = 93 ;
++	state->TunerRegs[60].Reg_Val = 0x00 ;
++
++	state->TunerRegs[61].Reg_Num = 94 ;
++	state->TunerRegs[61].Reg_Val = 0x00 ;
++
++	state->TunerRegs[62].Reg_Num = 95 ;
++	state->TunerRegs[62].Reg_Val = 0x0C ;
++
++	state->TunerRegs[63].Reg_Num = 96 ;
++	state->TunerRegs[63].Reg_Val = 0x00 ;
++
++	state->TunerRegs[64].Reg_Num = 97 ;
++	state->TunerRegs[64].Reg_Val = 0x00 ;
++
++	state->TunerRegs[65].Reg_Num = 98 ;
++	state->TunerRegs[65].Reg_Val = 0xE2 ;
++
++	state->TunerRegs[66].Reg_Num = 99 ;
++	state->TunerRegs[66].Reg_Val = 0x00 ;
++
++	state->TunerRegs[67].Reg_Num = 100 ;
++	state->TunerRegs[67].Reg_Val = 0x00 ;
++
++	state->TunerRegs[68].Reg_Num = 101 ;
++	state->TunerRegs[68].Reg_Val = 0x12 ;
++
++	state->TunerRegs[69].Reg_Num = 102 ;
++	state->TunerRegs[69].Reg_Val = 0x80 ;
++
++	state->TunerRegs[70].Reg_Num = 103 ;
++	state->TunerRegs[70].Reg_Val = 0x32 ;
++
++	state->TunerRegs[71].Reg_Num = 104 ;
++	state->TunerRegs[71].Reg_Val = 0xB4 ;
++
++	state->TunerRegs[72].Reg_Num = 105 ;
++	state->TunerRegs[72].Reg_Val = 0x60 ;
++
++	state->TunerRegs[73].Reg_Num = 106 ;
++	state->TunerRegs[73].Reg_Val = 0x83 ;
++
++	state->TunerRegs[74].Reg_Num = 107 ;
++	state->TunerRegs[74].Reg_Val = 0x84 ;
++
++	state->TunerRegs[75].Reg_Num = 108 ;
++	state->TunerRegs[75].Reg_Val = 0x9C ;
++
++	state->TunerRegs[76].Reg_Num = 109 ;
++	state->TunerRegs[76].Reg_Val = 0x02 ;
++
++	state->TunerRegs[77].Reg_Num = 110 ;
++	state->TunerRegs[77].Reg_Val = 0x81 ;
++
++	state->TunerRegs[78].Reg_Num = 111 ;
++	state->TunerRegs[78].Reg_Val = 0xC0 ;
++
++	state->TunerRegs[79].Reg_Num = 112 ;
++	state->TunerRegs[79].Reg_Val = 0x10 ;
++
++	state->TunerRegs[80].Reg_Num = 131 ;
++	state->TunerRegs[80].Reg_Val = 0x8A ;
++
++	state->TunerRegs[81].Reg_Num = 132 ;
++	state->TunerRegs[81].Reg_Val = 0x10 ;
++
++	state->TunerRegs[82].Reg_Num = 133 ;
++	state->TunerRegs[82].Reg_Val = 0x24 ;
++
++	state->TunerRegs[83].Reg_Num = 134 ;
++	state->TunerRegs[83].Reg_Val = 0x00 ;
++
++	state->TunerRegs[84].Reg_Num = 135 ;
++	state->TunerRegs[84].Reg_Val = 0x00 ;
++
++	state->TunerRegs[85].Reg_Num = 136 ;
++	state->TunerRegs[85].Reg_Val = 0x7E ;
++
++	state->TunerRegs[86].Reg_Num = 137 ;
++	state->TunerRegs[86].Reg_Val = 0x40 ;
++
++	state->TunerRegs[87].Reg_Num = 138 ;
++	state->TunerRegs[87].Reg_Val = 0x38 ;
++
++	state->TunerRegs[88].Reg_Num = 146 ;
++	state->TunerRegs[88].Reg_Val = 0xF6 ;
++
++	state->TunerRegs[89].Reg_Num = 147 ;
++	state->TunerRegs[89].Reg_Val = 0x1A ;
++
++	state->TunerRegs[90].Reg_Num = 148 ;
++	state->TunerRegs[90].Reg_Val = 0x62 ;
++
++	state->TunerRegs[91].Reg_Num = 149 ;
++	state->TunerRegs[91].Reg_Val = 0x33 ;
++
++	state->TunerRegs[92].Reg_Num = 150 ;
++	state->TunerRegs[92].Reg_Val = 0x80 ;
++
++	state->TunerRegs[93].Reg_Num = 156 ;
++	state->TunerRegs[93].Reg_Val = 0x56 ;
++
++	state->TunerRegs[94].Reg_Num = 157 ;
++	state->TunerRegs[94].Reg_Val = 0x17 ;
++
++	state->TunerRegs[95].Reg_Num = 158 ;
++	state->TunerRegs[95].Reg_Val = 0xA9 ;
++
++	state->TunerRegs[96].Reg_Num = 159 ;
++	state->TunerRegs[96].Reg_Val = 0x00 ;
++
++	state->TunerRegs[97].Reg_Num = 160 ;
++	state->TunerRegs[97].Reg_Val = 0x00 ;
++
++	state->TunerRegs[98].Reg_Num = 161 ;
++	state->TunerRegs[98].Reg_Val = 0x00 ;
++
++	state->TunerRegs[99].Reg_Num = 162 ;
++	state->TunerRegs[99].Reg_Val = 0x40 ;
++
++	state->TunerRegs[100].Reg_Num = 166 ;
++	state->TunerRegs[100].Reg_Val = 0xAE ;
++
++	state->TunerRegs[101].Reg_Num = 167 ;
++	state->TunerRegs[101].Reg_Val = 0x1B ;
++
++	state->TunerRegs[102].Reg_Num = 168 ;
++	state->TunerRegs[102].Reg_Val = 0xF2 ;
++
++	state->TunerRegs[103].Reg_Num = 195 ;
++	state->TunerRegs[103].Reg_Val = 0x00 ;
++
++	return 0 ;
++}
++
++static u16 MXL5005_ControlInit(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	state->Init_Ctrl_Num = INITCTRL_NUM;
++
++	state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ;
++	state->Init_Ctrl[0].size = 1 ;
++	state->Init_Ctrl[0].addr[0] = 73;
++	state->Init_Ctrl[0].bit[0] = 7;
++	state->Init_Ctrl[0].val[0] = 0;
++
++	state->Init_Ctrl[1].Ctrl_Num = BB_MODE ;
++	state->Init_Ctrl[1].size = 1 ;
++	state->Init_Ctrl[1].addr[0] = 53;
++	state->Init_Ctrl[1].bit[0] = 2;
++	state->Init_Ctrl[1].val[0] = 1;
++
++	state->Init_Ctrl[2].Ctrl_Num = BB_BUF ;
++	state->Init_Ctrl[2].size = 2 ;
++	state->Init_Ctrl[2].addr[0] = 53;
++	state->Init_Ctrl[2].bit[0] = 1;
++	state->Init_Ctrl[2].val[0] = 0;
++	state->Init_Ctrl[2].addr[1] = 57;
++	state->Init_Ctrl[2].bit[1] = 0;
++	state->Init_Ctrl[2].val[1] = 1;
++
++	state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ;
++	state->Init_Ctrl[3].size = 1 ;
++	state->Init_Ctrl[3].addr[0] = 53;
++	state->Init_Ctrl[3].bit[0] = 0;
++	state->Init_Ctrl[3].val[0] = 0;
++
++	state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ;
++	state->Init_Ctrl[4].size = 3 ;
++	state->Init_Ctrl[4].addr[0] = 53;
++	state->Init_Ctrl[4].bit[0] = 5;
++	state->Init_Ctrl[4].val[0] = 0;
++	state->Init_Ctrl[4].addr[1] = 53;
++	state->Init_Ctrl[4].bit[1] = 6;
++	state->Init_Ctrl[4].val[1] = 0;
++	state->Init_Ctrl[4].addr[2] = 53;
++	state->Init_Ctrl[4].bit[2] = 7;
++	state->Init_Ctrl[4].val[2] = 1;
++
++	state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ;
++	state->Init_Ctrl[5].size = 1 ;
++	state->Init_Ctrl[5].addr[0] = 59;
++	state->Init_Ctrl[5].bit[0] = 0;
++	state->Init_Ctrl[5].val[0] = 0;
++
++	state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ;
++	state->Init_Ctrl[6].size = 2 ;
++	state->Init_Ctrl[6].addr[0] = 53;
++	state->Init_Ctrl[6].bit[0] = 3;
++	state->Init_Ctrl[6].val[0] = 0;
++	state->Init_Ctrl[6].addr[1] = 53;
++	state->Init_Ctrl[6].bit[1] = 4;
++	state->Init_Ctrl[6].val[1] = 1;
++
++	state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ;
++	state->Init_Ctrl[7].size = 4 ;
++	state->Init_Ctrl[7].addr[0] = 22;
++	state->Init_Ctrl[7].bit[0] = 4;
++	state->Init_Ctrl[7].val[0] = 0;
++	state->Init_Ctrl[7].addr[1] = 22;
++	state->Init_Ctrl[7].bit[1] = 5;
++	state->Init_Ctrl[7].val[1] = 1;
++	state->Init_Ctrl[7].addr[2] = 22;
++	state->Init_Ctrl[7].bit[2] = 6;
++	state->Init_Ctrl[7].val[2] = 1;
++	state->Init_Ctrl[7].addr[3] = 22;
++	state->Init_Ctrl[7].bit[3] = 7;
++	state->Init_Ctrl[7].val[3] = 0;
++
++	state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ;
++	state->Init_Ctrl[8].size = 1 ;
++	state->Init_Ctrl[8].addr[0] = 22;
++	state->Init_Ctrl[8].bit[0] = 2;
++	state->Init_Ctrl[8].val[0] = 0;
++
++	state->Init_Ctrl[9].Ctrl_Num = AGC_IF ;
++	state->Init_Ctrl[9].size = 4 ;
++	state->Init_Ctrl[9].addr[0] = 76;
++	state->Init_Ctrl[9].bit[0] = 0;
++	state->Init_Ctrl[9].val[0] = 1;
++	state->Init_Ctrl[9].addr[1] = 76;
++	state->Init_Ctrl[9].bit[1] = 1;
++	state->Init_Ctrl[9].val[1] = 1;
++	state->Init_Ctrl[9].addr[2] = 76;
++	state->Init_Ctrl[9].bit[2] = 2;
++	state->Init_Ctrl[9].val[2] = 0;
++	state->Init_Ctrl[9].addr[3] = 76;
++	state->Init_Ctrl[9].bit[3] = 3;
++	state->Init_Ctrl[9].val[3] = 1;
++
++	state->Init_Ctrl[10].Ctrl_Num = AGC_RF ;
++	state->Init_Ctrl[10].size = 4 ;
++	state->Init_Ctrl[10].addr[0] = 76;
++	state->Init_Ctrl[10].bit[0] = 4;
++	state->Init_Ctrl[10].val[0] = 1;
++	state->Init_Ctrl[10].addr[1] = 76;
++	state->Init_Ctrl[10].bit[1] = 5;
++	state->Init_Ctrl[10].val[1] = 1;
++	state->Init_Ctrl[10].addr[2] = 76;
++	state->Init_Ctrl[10].bit[2] = 6;
++	state->Init_Ctrl[10].val[2] = 0;
++	state->Init_Ctrl[10].addr[3] = 76;
++	state->Init_Ctrl[10].bit[3] = 7;
++	state->Init_Ctrl[10].val[3] = 1;
++
++	state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ;
++	state->Init_Ctrl[11].size = 5 ;
++	state->Init_Ctrl[11].addr[0] = 43;
++	state->Init_Ctrl[11].bit[0] = 3;
++	state->Init_Ctrl[11].val[0] = 0;
++	state->Init_Ctrl[11].addr[1] = 43;
++	state->Init_Ctrl[11].bit[1] = 4;
++	state->Init_Ctrl[11].val[1] = 0;
++	state->Init_Ctrl[11].addr[2] = 43;
++	state->Init_Ctrl[11].bit[2] = 5;
++	state->Init_Ctrl[11].val[2] = 0;
++	state->Init_Ctrl[11].addr[3] = 43;
++	state->Init_Ctrl[11].bit[3] = 6;
++	state->Init_Ctrl[11].val[3] = 1;
++	state->Init_Ctrl[11].addr[4] = 43;
++	state->Init_Ctrl[11].bit[4] = 7;
++	state->Init_Ctrl[11].val[4] = 0;
++
++	state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ;
++	state->Init_Ctrl[12].size = 6 ;
++	state->Init_Ctrl[12].addr[0] = 44;
++	state->Init_Ctrl[12].bit[0] = 2;
++	state->Init_Ctrl[12].val[0] = 0;
++	state->Init_Ctrl[12].addr[1] = 44;
++	state->Init_Ctrl[12].bit[1] = 3;
++	state->Init_Ctrl[12].val[1] = 0;
++	state->Init_Ctrl[12].addr[2] = 44;
++	state->Init_Ctrl[12].bit[2] = 4;
++	state->Init_Ctrl[12].val[2] = 0;
++	state->Init_Ctrl[12].addr[3] = 44;
++	state->Init_Ctrl[12].bit[3] = 5;
++	state->Init_Ctrl[12].val[3] = 1;
++	state->Init_Ctrl[12].addr[4] = 44;
++	state->Init_Ctrl[12].bit[4] = 6;
++	state->Init_Ctrl[12].val[4] = 0;
++	state->Init_Ctrl[12].addr[5] = 44;
++	state->Init_Ctrl[12].bit[5] = 7;
++	state->Init_Ctrl[12].val[5] = 0;
++
++	state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ;
++	state->Init_Ctrl[13].size = 7 ;
++	state->Init_Ctrl[13].addr[0] = 11;
++	state->Init_Ctrl[13].bit[0] = 0;
++	state->Init_Ctrl[13].val[0] = 1;
++	state->Init_Ctrl[13].addr[1] = 11;
++	state->Init_Ctrl[13].bit[1] = 1;
++	state->Init_Ctrl[13].val[1] = 0;
++	state->Init_Ctrl[13].addr[2] = 11;
++	state->Init_Ctrl[13].bit[2] = 2;
++	state->Init_Ctrl[13].val[2] = 0;
++	state->Init_Ctrl[13].addr[3] = 11;
++	state->Init_Ctrl[13].bit[3] = 3;
++	state->Init_Ctrl[13].val[3] = 1;
++	state->Init_Ctrl[13].addr[4] = 11;
++	state->Init_Ctrl[13].bit[4] = 4;
++	state->Init_Ctrl[13].val[4] = 1;
++	state->Init_Ctrl[13].addr[5] = 11;
++	state->Init_Ctrl[13].bit[5] = 5;
++	state->Init_Ctrl[13].val[5] = 0;
++	state->Init_Ctrl[13].addr[6] = 11;
++	state->Init_Ctrl[13].bit[6] = 6;
++	state->Init_Ctrl[13].val[6] = 0;
++
++	state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ;
++	state->Init_Ctrl[14].size = 16 ;
++	state->Init_Ctrl[14].addr[0] = 13;
++	state->Init_Ctrl[14].bit[0] = 0;
++	state->Init_Ctrl[14].val[0] = 0;
++	state->Init_Ctrl[14].addr[1] = 13;
++	state->Init_Ctrl[14].bit[1] = 1;
++	state->Init_Ctrl[14].val[1] = 0;
++	state->Init_Ctrl[14].addr[2] = 13;
++	state->Init_Ctrl[14].bit[2] = 2;
++	state->Init_Ctrl[14].val[2] = 0;
++	state->Init_Ctrl[14].addr[3] = 13;
++	state->Init_Ctrl[14].bit[3] = 3;
++	state->Init_Ctrl[14].val[3] = 0;
++	state->Init_Ctrl[14].addr[4] = 13;
++	state->Init_Ctrl[14].bit[4] = 4;
++	state->Init_Ctrl[14].val[4] = 0;
++	state->Init_Ctrl[14].addr[5] = 13;
++	state->Init_Ctrl[14].bit[5] = 5;
++	state->Init_Ctrl[14].val[5] = 0;
++	state->Init_Ctrl[14].addr[6] = 13;
++	state->Init_Ctrl[14].bit[6] = 6;
++	state->Init_Ctrl[14].val[6] = 0;
++	state->Init_Ctrl[14].addr[7] = 13;
++	state->Init_Ctrl[14].bit[7] = 7;
++	state->Init_Ctrl[14].val[7] = 0;
++	state->Init_Ctrl[14].addr[8] = 12;
++	state->Init_Ctrl[14].bit[8] = 0;
++	state->Init_Ctrl[14].val[8] = 0;
++	state->Init_Ctrl[14].addr[9] = 12;
++	state->Init_Ctrl[14].bit[9] = 1;
++	state->Init_Ctrl[14].val[9] = 0;
++	state->Init_Ctrl[14].addr[10] = 12;
++	state->Init_Ctrl[14].bit[10] = 2;
++	state->Init_Ctrl[14].val[10] = 0;
++	state->Init_Ctrl[14].addr[11] = 12;
++	state->Init_Ctrl[14].bit[11] = 3;
++	state->Init_Ctrl[14].val[11] = 0;
++	state->Init_Ctrl[14].addr[12] = 12;
++	state->Init_Ctrl[14].bit[12] = 4;
++	state->Init_Ctrl[14].val[12] = 0;
++	state->Init_Ctrl[14].addr[13] = 12;
++	state->Init_Ctrl[14].bit[13] = 5;
++	state->Init_Ctrl[14].val[13] = 1;
++	state->Init_Ctrl[14].addr[14] = 12;
++	state->Init_Ctrl[14].bit[14] = 6;
++	state->Init_Ctrl[14].val[14] = 1;
++	state->Init_Ctrl[14].addr[15] = 12;
++	state->Init_Ctrl[14].bit[15] = 7;
++	state->Init_Ctrl[14].val[15] = 0;
++
++	state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ;
++	state->Init_Ctrl[15].size = 3 ;
++	state->Init_Ctrl[15].addr[0] = 147;
++	state->Init_Ctrl[15].bit[0] = 2;
++	state->Init_Ctrl[15].val[0] = 0;
++	state->Init_Ctrl[15].addr[1] = 147;
++	state->Init_Ctrl[15].bit[1] = 3;
++	state->Init_Ctrl[15].val[1] = 1;
++	state->Init_Ctrl[15].addr[2] = 147;
++	state->Init_Ctrl[15].bit[2] = 4;
++	state->Init_Ctrl[15].val[2] = 1;
++
++	state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ;
++	state->Init_Ctrl[16].size = 2 ;
++	state->Init_Ctrl[16].addr[0] = 147;
++	state->Init_Ctrl[16].bit[0] = 0;
++	state->Init_Ctrl[16].val[0] = 0;
++	state->Init_Ctrl[16].addr[1] = 147;
++	state->Init_Ctrl[16].bit[1] = 1;
++	state->Init_Ctrl[16].val[1] = 1;
++
++	state->Init_Ctrl[17].Ctrl_Num = EN_AAF ;
++	state->Init_Ctrl[17].size = 1 ;
++	state->Init_Ctrl[17].addr[0] = 147;
++	state->Init_Ctrl[17].bit[0] = 7;
++	state->Init_Ctrl[17].val[0] = 0;
++
++	state->Init_Ctrl[18].Ctrl_Num = EN_3P ;
++	state->Init_Ctrl[18].size = 1 ;
++	state->Init_Ctrl[18].addr[0] = 147;
++	state->Init_Ctrl[18].bit[0] = 6;
++	state->Init_Ctrl[18].val[0] = 0;
++
++	state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ;
++	state->Init_Ctrl[19].size = 1 ;
++	state->Init_Ctrl[19].addr[0] = 156;
++	state->Init_Ctrl[19].bit[0] = 0;
++	state->Init_Ctrl[19].val[0] = 0;
++
++	state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ;
++	state->Init_Ctrl[20].size = 1 ;
++	state->Init_Ctrl[20].addr[0] = 147;
++	state->Init_Ctrl[20].bit[0] = 5;
++	state->Init_Ctrl[20].val[0] = 0;
++
++	state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ;
++	state->Init_Ctrl[21].size = 1 ;
++	state->Init_Ctrl[21].addr[0] = 137;
++	state->Init_Ctrl[21].bit[0] = 4;
++	state->Init_Ctrl[21].val[0] = 0;
++
++	state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ;
++	state->Init_Ctrl[22].size = 1 ;
++	state->Init_Ctrl[22].addr[0] = 137;
++	state->Init_Ctrl[22].bit[0] = 7;
++	state->Init_Ctrl[22].val[0] = 0;
++
++	state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ;
++	state->Init_Ctrl[23].size = 1 ;
++	state->Init_Ctrl[23].addr[0] = 91;
++	state->Init_Ctrl[23].bit[0] = 5;
++	state->Init_Ctrl[23].val[0] = 1;
++
++	state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ;
++	state->Init_Ctrl[24].size = 1 ;
++	state->Init_Ctrl[24].addr[0] = 43;
++	state->Init_Ctrl[24].bit[0] = 0;
++	state->Init_Ctrl[24].val[0] = 1;
++
++	state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ;
++	state->Init_Ctrl[25].size = 2 ;
++	state->Init_Ctrl[25].addr[0] = 22;
++	state->Init_Ctrl[25].bit[0] = 0;
++	state->Init_Ctrl[25].val[0] = 1;
++	state->Init_Ctrl[25].addr[1] = 22;
++	state->Init_Ctrl[25].bit[1] = 1;
++	state->Init_Ctrl[25].val[1] = 1;
++
++	state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ;
++	state->Init_Ctrl[26].size = 1 ;
++	state->Init_Ctrl[26].addr[0] = 134;
++	state->Init_Ctrl[26].bit[0] = 2;
++	state->Init_Ctrl[26].val[0] = 0;
++
++	state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ;
++	state->Init_Ctrl[27].size = 1 ;
++	state->Init_Ctrl[27].addr[0] = 137;
++	state->Init_Ctrl[27].bit[0] = 3;
++	state->Init_Ctrl[27].val[0] = 0;
++
++	state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ;
++	state->Init_Ctrl[28].size = 1 ;
++	state->Init_Ctrl[28].addr[0] = 77;
++	state->Init_Ctrl[28].bit[0] = 7;
++	state->Init_Ctrl[28].val[0] = 0;
++
++	state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ;
++	state->Init_Ctrl[29].size = 1 ;
++	state->Init_Ctrl[29].addr[0] = 166;
++	state->Init_Ctrl[29].bit[0] = 7;
++	state->Init_Ctrl[29].val[0] = 1;
++
++	state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ;
++	state->Init_Ctrl[30].size = 3 ;
++	state->Init_Ctrl[30].addr[0] = 166;
++	state->Init_Ctrl[30].bit[0] = 0;
++	state->Init_Ctrl[30].val[0] = 0;
++	state->Init_Ctrl[30].addr[1] = 166;
++	state->Init_Ctrl[30].bit[1] = 1;
++	state->Init_Ctrl[30].val[1] = 1;
++	state->Init_Ctrl[30].addr[2] = 166;
++	state->Init_Ctrl[30].bit[2] = 2;
++	state->Init_Ctrl[30].val[2] = 1;
++
++	state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ;
++	state->Init_Ctrl[31].size = 3 ;
++	state->Init_Ctrl[31].addr[0] = 166;
++	state->Init_Ctrl[31].bit[0] = 3;
++	state->Init_Ctrl[31].val[0] = 1;
++	state->Init_Ctrl[31].addr[1] = 166;
++	state->Init_Ctrl[31].bit[1] = 4;
++	state->Init_Ctrl[31].val[1] = 0;
++	state->Init_Ctrl[31].addr[2] = 166;
++	state->Init_Ctrl[31].bit[2] = 5;
++	state->Init_Ctrl[31].val[2] = 1;
++
++	state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ;
++	state->Init_Ctrl[32].size = 3 ;
++	state->Init_Ctrl[32].addr[0] = 167;
++	state->Init_Ctrl[32].bit[0] = 0;
++	state->Init_Ctrl[32].val[0] = 1;
++	state->Init_Ctrl[32].addr[1] = 167;
++	state->Init_Ctrl[32].bit[1] = 1;
++	state->Init_Ctrl[32].val[1] = 1;
++	state->Init_Ctrl[32].addr[2] = 167;
++	state->Init_Ctrl[32].bit[2] = 2;
++	state->Init_Ctrl[32].val[2] = 0;
++
++	state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ;
++	state->Init_Ctrl[33].size = 4 ;
++	state->Init_Ctrl[33].addr[0] = 168;
++	state->Init_Ctrl[33].bit[0] = 0;
++	state->Init_Ctrl[33].val[0] = 0;
++	state->Init_Ctrl[33].addr[1] = 168;
++	state->Init_Ctrl[33].bit[1] = 1;
++	state->Init_Ctrl[33].val[1] = 1;
++	state->Init_Ctrl[33].addr[2] = 168;
++	state->Init_Ctrl[33].bit[2] = 2;
++	state->Init_Ctrl[33].val[2] = 0;
++	state->Init_Ctrl[33].addr[3] = 168;
++	state->Init_Ctrl[33].bit[3] = 3;
++	state->Init_Ctrl[33].val[3] = 0;
++
++	state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ;
++	state->Init_Ctrl[34].size = 4 ;
++	state->Init_Ctrl[34].addr[0] = 168;
++	state->Init_Ctrl[34].bit[0] = 4;
++	state->Init_Ctrl[34].val[0] = 1;
++	state->Init_Ctrl[34].addr[1] = 168;
++	state->Init_Ctrl[34].bit[1] = 5;
++	state->Init_Ctrl[34].val[1] = 1;
++	state->Init_Ctrl[34].addr[2] = 168;
++	state->Init_Ctrl[34].bit[2] = 6;
++	state->Init_Ctrl[34].val[2] = 1;
++	state->Init_Ctrl[34].addr[3] = 168;
++	state->Init_Ctrl[34].bit[3] = 7;
++	state->Init_Ctrl[34].val[3] = 1;
++
++	state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ;
++	state->Init_Ctrl[35].size = 1 ;
++	state->Init_Ctrl[35].addr[0] = 135;
++	state->Init_Ctrl[35].bit[0] = 0;
++	state->Init_Ctrl[35].val[0] = 0;
++
++	state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ;
++	state->Init_Ctrl[36].size = 1 ;
++	state->Init_Ctrl[36].addr[0] = 56;
++	state->Init_Ctrl[36].bit[0] = 3;
++	state->Init_Ctrl[36].val[0] = 0;
++
++	state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ;
++	state->Init_Ctrl[37].size = 7 ;
++	state->Init_Ctrl[37].addr[0] = 59;
++	state->Init_Ctrl[37].bit[0] = 1;
++	state->Init_Ctrl[37].val[0] = 0;
++	state->Init_Ctrl[37].addr[1] = 59;
++	state->Init_Ctrl[37].bit[1] = 2;
++	state->Init_Ctrl[37].val[1] = 0;
++	state->Init_Ctrl[37].addr[2] = 59;
++	state->Init_Ctrl[37].bit[2] = 3;
++	state->Init_Ctrl[37].val[2] = 0;
++	state->Init_Ctrl[37].addr[3] = 59;
++	state->Init_Ctrl[37].bit[3] = 4;
++	state->Init_Ctrl[37].val[3] = 0;
++	state->Init_Ctrl[37].addr[4] = 59;
++	state->Init_Ctrl[37].bit[4] = 5;
++	state->Init_Ctrl[37].val[4] = 0;
++	state->Init_Ctrl[37].addr[5] = 59;
++	state->Init_Ctrl[37].bit[5] = 6;
++	state->Init_Ctrl[37].val[5] = 0;
++	state->Init_Ctrl[37].addr[6] = 59;
++	state->Init_Ctrl[37].bit[6] = 7;
++	state->Init_Ctrl[37].val[6] = 0;
++
++	state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ;
++	state->Init_Ctrl[38].size = 6 ;
++	state->Init_Ctrl[38].addr[0] = 32;
++	state->Init_Ctrl[38].bit[0] = 2;
++	state->Init_Ctrl[38].val[0] = 0;
++	state->Init_Ctrl[38].addr[1] = 32;
++	state->Init_Ctrl[38].bit[1] = 3;
++	state->Init_Ctrl[38].val[1] = 0;
++	state->Init_Ctrl[38].addr[2] = 32;
++	state->Init_Ctrl[38].bit[2] = 4;
++	state->Init_Ctrl[38].val[2] = 0;
++	state->Init_Ctrl[38].addr[3] = 32;
++	state->Init_Ctrl[38].bit[3] = 5;
++	state->Init_Ctrl[38].val[3] = 0;
++	state->Init_Ctrl[38].addr[4] = 32;
++	state->Init_Ctrl[38].bit[4] = 6;
++	state->Init_Ctrl[38].val[4] = 1;
++	state->Init_Ctrl[38].addr[5] = 32;
++	state->Init_Ctrl[38].bit[5] = 7;
++	state->Init_Ctrl[38].val[5] = 0;
++
++	state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ;
++	state->Init_Ctrl[39].size = 1 ;
++	state->Init_Ctrl[39].addr[0] = 25;
++	state->Init_Ctrl[39].bit[0] = 3;
++	state->Init_Ctrl[39].val[0] = 1;
++
++
++	state->CH_Ctrl_Num = CHCTRL_NUM ;
++
++	state->CH_Ctrl[0].Ctrl_Num = DN_POLY ;
++	state->CH_Ctrl[0].size = 2 ;
++	state->CH_Ctrl[0].addr[0] = 68;
++	state->CH_Ctrl[0].bit[0] = 6;
++	state->CH_Ctrl[0].val[0] = 1;
++	state->CH_Ctrl[0].addr[1] = 68;
++	state->CH_Ctrl[0].bit[1] = 7;
++	state->CH_Ctrl[0].val[1] = 1;
++
++	state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ;
++	state->CH_Ctrl[1].size = 2 ;
++	state->CH_Ctrl[1].addr[0] = 70;
++	state->CH_Ctrl[1].bit[0] = 6;
++	state->CH_Ctrl[1].val[0] = 1;
++	state->CH_Ctrl[1].addr[1] = 70;
++	state->CH_Ctrl[1].bit[1] = 7;
++	state->CH_Ctrl[1].val[1] = 0;
++
++	state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ;
++	state->CH_Ctrl[2].size = 9 ;
++	state->CH_Ctrl[2].addr[0] = 69;
++	state->CH_Ctrl[2].bit[0] = 5;
++	state->CH_Ctrl[2].val[0] = 0;
++	state->CH_Ctrl[2].addr[1] = 69;
++	state->CH_Ctrl[2].bit[1] = 6;
++	state->CH_Ctrl[2].val[1] = 0;
++	state->CH_Ctrl[2].addr[2] = 69;
++	state->CH_Ctrl[2].bit[2] = 7;
++	state->CH_Ctrl[2].val[2] = 0;
++	state->CH_Ctrl[2].addr[3] = 68;
++	state->CH_Ctrl[2].bit[3] = 0;
++	state->CH_Ctrl[2].val[3] = 0;
++	state->CH_Ctrl[2].addr[4] = 68;
++	state->CH_Ctrl[2].bit[4] = 1;
++	state->CH_Ctrl[2].val[4] = 0;
++	state->CH_Ctrl[2].addr[5] = 68;
++	state->CH_Ctrl[2].bit[5] = 2;
++	state->CH_Ctrl[2].val[5] = 0;
++	state->CH_Ctrl[2].addr[6] = 68;
++	state->CH_Ctrl[2].bit[6] = 3;
++	state->CH_Ctrl[2].val[6] = 0;
++	state->CH_Ctrl[2].addr[7] = 68;
++	state->CH_Ctrl[2].bit[7] = 4;
++	state->CH_Ctrl[2].val[7] = 0;
++	state->CH_Ctrl[2].addr[8] = 68;
++	state->CH_Ctrl[2].bit[8] = 5;
++	state->CH_Ctrl[2].val[8] = 0;
++
++	state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ;
++	state->CH_Ctrl[3].size = 1 ;
++	state->CH_Ctrl[3].addr[0] = 70;
++	state->CH_Ctrl[3].bit[0] = 5;
++	state->CH_Ctrl[3].val[0] = 0;
++
++	state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ;
++	state->CH_Ctrl[4].size = 3 ;
++	state->CH_Ctrl[4].addr[0] = 73;
++	state->CH_Ctrl[4].bit[0] = 4;
++	state->CH_Ctrl[4].val[0] = 0;
++	state->CH_Ctrl[4].addr[1] = 73;
++	state->CH_Ctrl[4].bit[1] = 5;
++	state->CH_Ctrl[4].val[1] = 1;
++	state->CH_Ctrl[4].addr[2] = 73;
++	state->CH_Ctrl[4].bit[2] = 6;
++	state->CH_Ctrl[4].val[2] = 0;
++
++	state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ;
++	state->CH_Ctrl[5].size = 4 ;
++	state->CH_Ctrl[5].addr[0] = 70;
++	state->CH_Ctrl[5].bit[0] = 0;
++	state->CH_Ctrl[5].val[0] = 0;
++	state->CH_Ctrl[5].addr[1] = 70;
++	state->CH_Ctrl[5].bit[1] = 1;
++	state->CH_Ctrl[5].val[1] = 0;
++	state->CH_Ctrl[5].addr[2] = 70;
++	state->CH_Ctrl[5].bit[2] = 2;
++	state->CH_Ctrl[5].val[2] = 0;
++	state->CH_Ctrl[5].addr[3] = 70;
++	state->CH_Ctrl[5].bit[3] = 3;
++	state->CH_Ctrl[5].val[3] = 0;
++
++	state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ;
++	state->CH_Ctrl[6].size = 1 ;
++	state->CH_Ctrl[6].addr[0] = 70;
++	state->CH_Ctrl[6].bit[0] = 4;
++	state->CH_Ctrl[6].val[0] = 1;
++
++	state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ;
++	state->CH_Ctrl[7].size = 1 ;
++	state->CH_Ctrl[7].addr[0] = 111;
++	state->CH_Ctrl[7].bit[0] = 4;
++	state->CH_Ctrl[7].val[0] = 0;
++
++	state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ;
++	state->CH_Ctrl[8].size = 1 ;
++	state->CH_Ctrl[8].addr[0] = 111;
++	state->CH_Ctrl[8].bit[0] = 7;
++	state->CH_Ctrl[8].val[0] = 1;
++
++	state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ;
++	state->CH_Ctrl[9].size = 1 ;
++	state->CH_Ctrl[9].addr[0] = 111;
++	state->CH_Ctrl[9].bit[0] = 6;
++	state->CH_Ctrl[9].val[0] = 1;
++
++	state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ;
++	state->CH_Ctrl[10].size = 1 ;
++	state->CH_Ctrl[10].addr[0] = 111;
++	state->CH_Ctrl[10].bit[0] = 5;
++	state->CH_Ctrl[10].val[0] = 0;
++
++	state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ;
++	state->CH_Ctrl[11].size = 2 ;
++	state->CH_Ctrl[11].addr[0] = 110;
++	state->CH_Ctrl[11].bit[0] = 0;
++	state->CH_Ctrl[11].val[0] = 1;
++	state->CH_Ctrl[11].addr[1] = 110;
++	state->CH_Ctrl[11].bit[1] = 1;
++	state->CH_Ctrl[11].val[1] = 0;
++
++	state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ;
++	state->CH_Ctrl[12].size = 3 ;
++	state->CH_Ctrl[12].addr[0] = 69;
++	state->CH_Ctrl[12].bit[0] = 2;
++	state->CH_Ctrl[12].val[0] = 0;
++	state->CH_Ctrl[12].addr[1] = 69;
++	state->CH_Ctrl[12].bit[1] = 3;
++	state->CH_Ctrl[12].val[1] = 0;
++	state->CH_Ctrl[12].addr[2] = 69;
++	state->CH_Ctrl[12].bit[2] = 4;
++	state->CH_Ctrl[12].val[2] = 0;
++
++	state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ;
++	state->CH_Ctrl[13].size = 6 ;
++	state->CH_Ctrl[13].addr[0] = 110;
++	state->CH_Ctrl[13].bit[0] = 2;
++	state->CH_Ctrl[13].val[0] = 0;
++	state->CH_Ctrl[13].addr[1] = 110;
++	state->CH_Ctrl[13].bit[1] = 3;
++	state->CH_Ctrl[13].val[1] = 0;
++	state->CH_Ctrl[13].addr[2] = 110;
++	state->CH_Ctrl[13].bit[2] = 4;
++	state->CH_Ctrl[13].val[2] = 0;
++	state->CH_Ctrl[13].addr[3] = 110;
++	state->CH_Ctrl[13].bit[3] = 5;
++	state->CH_Ctrl[13].val[3] = 0;
++	state->CH_Ctrl[13].addr[4] = 110;
++	state->CH_Ctrl[13].bit[4] = 6;
++	state->CH_Ctrl[13].val[4] = 0;
++	state->CH_Ctrl[13].addr[5] = 110;
++	state->CH_Ctrl[13].bit[5] = 7;
++	state->CH_Ctrl[13].val[5] = 1;
++
++	state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ;
++	state->CH_Ctrl[14].size = 7 ;
++	state->CH_Ctrl[14].addr[0] = 14;
++	state->CH_Ctrl[14].bit[0] = 0;
++	state->CH_Ctrl[14].val[0] = 0;
++	state->CH_Ctrl[14].addr[1] = 14;
++	state->CH_Ctrl[14].bit[1] = 1;
++	state->CH_Ctrl[14].val[1] = 0;
++	state->CH_Ctrl[14].addr[2] = 14;
++	state->CH_Ctrl[14].bit[2] = 2;
++	state->CH_Ctrl[14].val[2] = 0;
++	state->CH_Ctrl[14].addr[3] = 14;
++	state->CH_Ctrl[14].bit[3] = 3;
++	state->CH_Ctrl[14].val[3] = 0;
++	state->CH_Ctrl[14].addr[4] = 14;
++	state->CH_Ctrl[14].bit[4] = 4;
++	state->CH_Ctrl[14].val[4] = 0;
++	state->CH_Ctrl[14].addr[5] = 14;
++	state->CH_Ctrl[14].bit[5] = 5;
++	state->CH_Ctrl[14].val[5] = 0;
++	state->CH_Ctrl[14].addr[6] = 14;
++	state->CH_Ctrl[14].bit[6] = 6;
++	state->CH_Ctrl[14].val[6] = 0;
++
++	state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ;
++	state->CH_Ctrl[15].size = 18 ;
++	state->CH_Ctrl[15].addr[0] = 17;
++	state->CH_Ctrl[15].bit[0] = 6;
++	state->CH_Ctrl[15].val[0] = 0;
++	state->CH_Ctrl[15].addr[1] = 17;
++	state->CH_Ctrl[15].bit[1] = 7;
++	state->CH_Ctrl[15].val[1] = 0;
++	state->CH_Ctrl[15].addr[2] = 16;
++	state->CH_Ctrl[15].bit[2] = 0;
++	state->CH_Ctrl[15].val[2] = 0;
++	state->CH_Ctrl[15].addr[3] = 16;
++	state->CH_Ctrl[15].bit[3] = 1;
++	state->CH_Ctrl[15].val[3] = 0;
++	state->CH_Ctrl[15].addr[4] = 16;
++	state->CH_Ctrl[15].bit[4] = 2;
++	state->CH_Ctrl[15].val[4] = 0;
++	state->CH_Ctrl[15].addr[5] = 16;
++	state->CH_Ctrl[15].bit[5] = 3;
++	state->CH_Ctrl[15].val[5] = 0;
++	state->CH_Ctrl[15].addr[6] = 16;
++	state->CH_Ctrl[15].bit[6] = 4;
++	state->CH_Ctrl[15].val[6] = 0;
++	state->CH_Ctrl[15].addr[7] = 16;
++	state->CH_Ctrl[15].bit[7] = 5;
++	state->CH_Ctrl[15].val[7] = 0;
++	state->CH_Ctrl[15].addr[8] = 16;
++	state->CH_Ctrl[15].bit[8] = 6;
++	state->CH_Ctrl[15].val[8] = 0;
++	state->CH_Ctrl[15].addr[9] = 16;
++	state->CH_Ctrl[15].bit[9] = 7;
++	state->CH_Ctrl[15].val[9] = 0;
++	state->CH_Ctrl[15].addr[10] = 15;
++	state->CH_Ctrl[15].bit[10] = 0;
++	state->CH_Ctrl[15].val[10] = 0;
++	state->CH_Ctrl[15].addr[11] = 15;
++	state->CH_Ctrl[15].bit[11] = 1;
++	state->CH_Ctrl[15].val[11] = 0;
++	state->CH_Ctrl[15].addr[12] = 15;
++	state->CH_Ctrl[15].bit[12] = 2;
++	state->CH_Ctrl[15].val[12] = 0;
++	state->CH_Ctrl[15].addr[13] = 15;
++	state->CH_Ctrl[15].bit[13] = 3;
++	state->CH_Ctrl[15].val[13] = 0;
++	state->CH_Ctrl[15].addr[14] = 15;
++	state->CH_Ctrl[15].bit[14] = 4;
++	state->CH_Ctrl[15].val[14] = 0;
++	state->CH_Ctrl[15].addr[15] = 15;
++	state->CH_Ctrl[15].bit[15] = 5;
++	state->CH_Ctrl[15].val[15] = 0;
++	state->CH_Ctrl[15].addr[16] = 15;
++	state->CH_Ctrl[15].bit[16] = 6;
++	state->CH_Ctrl[15].val[16] = 1;
++	state->CH_Ctrl[15].addr[17] = 15;
++	state->CH_Ctrl[15].bit[17] = 7;
++	state->CH_Ctrl[15].val[17] = 1;
++
++	state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ;
++	state->CH_Ctrl[16].size = 5 ;
++	state->CH_Ctrl[16].addr[0] = 112;
++	state->CH_Ctrl[16].bit[0] = 0;
++	state->CH_Ctrl[16].val[0] = 0;
++	state->CH_Ctrl[16].addr[1] = 112;
++	state->CH_Ctrl[16].bit[1] = 1;
++	state->CH_Ctrl[16].val[1] = 0;
++	state->CH_Ctrl[16].addr[2] = 112;
++	state->CH_Ctrl[16].bit[2] = 2;
++	state->CH_Ctrl[16].val[2] = 0;
++	state->CH_Ctrl[16].addr[3] = 112;
++	state->CH_Ctrl[16].bit[3] = 3;
++	state->CH_Ctrl[16].val[3] = 0;
++	state->CH_Ctrl[16].addr[4] = 112;
++	state->CH_Ctrl[16].bit[4] = 4;
++	state->CH_Ctrl[16].val[4] = 1;
++
++	state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ;
++	state->CH_Ctrl[17].size = 1 ;
++	state->CH_Ctrl[17].addr[0] = 14;
++	state->CH_Ctrl[17].bit[0] = 7;
++	state->CH_Ctrl[17].val[0] = 0;
++
++	state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ;
++	state->CH_Ctrl[18].size = 4 ;
++	state->CH_Ctrl[18].addr[0] = 107;
++	state->CH_Ctrl[18].bit[0] = 3;
++	state->CH_Ctrl[18].val[0] = 0;
++	state->CH_Ctrl[18].addr[1] = 107;
++	state->CH_Ctrl[18].bit[1] = 4;
++	state->CH_Ctrl[18].val[1] = 0;
++	state->CH_Ctrl[18].addr[2] = 107;
++	state->CH_Ctrl[18].bit[2] = 5;
++	state->CH_Ctrl[18].val[2] = 0;
++	state->CH_Ctrl[18].addr[3] = 107;
++	state->CH_Ctrl[18].bit[3] = 6;
++	state->CH_Ctrl[18].val[3] = 0;
++
++	state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ;
++	state->CH_Ctrl[19].size = 3 ;
++	state->CH_Ctrl[19].addr[0] = 107;
++	state->CH_Ctrl[19].bit[0] = 7;
++	state->CH_Ctrl[19].val[0] = 1;
++	state->CH_Ctrl[19].addr[1] = 106;
++	state->CH_Ctrl[19].bit[1] = 0;
++	state->CH_Ctrl[19].val[1] = 1;
++	state->CH_Ctrl[19].addr[2] = 106;
++	state->CH_Ctrl[19].bit[2] = 1;
++	state->CH_Ctrl[19].val[2] = 1;
++
++	state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ;
++	state->CH_Ctrl[20].size = 11 ;
++	state->CH_Ctrl[20].addr[0] = 109;
++	state->CH_Ctrl[20].bit[0] = 2;
++	state->CH_Ctrl[20].val[0] = 0;
++	state->CH_Ctrl[20].addr[1] = 109;
++	state->CH_Ctrl[20].bit[1] = 3;
++	state->CH_Ctrl[20].val[1] = 0;
++	state->CH_Ctrl[20].addr[2] = 109;
++	state->CH_Ctrl[20].bit[2] = 4;
++	state->CH_Ctrl[20].val[2] = 0;
++	state->CH_Ctrl[20].addr[3] = 109;
++	state->CH_Ctrl[20].bit[3] = 5;
++	state->CH_Ctrl[20].val[3] = 0;
++	state->CH_Ctrl[20].addr[4] = 109;
++	state->CH_Ctrl[20].bit[4] = 6;
++	state->CH_Ctrl[20].val[4] = 0;
++	state->CH_Ctrl[20].addr[5] = 109;
++	state->CH_Ctrl[20].bit[5] = 7;
++	state->CH_Ctrl[20].val[5] = 0;
++	state->CH_Ctrl[20].addr[6] = 108;
++	state->CH_Ctrl[20].bit[6] = 0;
++	state->CH_Ctrl[20].val[6] = 0;
++	state->CH_Ctrl[20].addr[7] = 108;
++	state->CH_Ctrl[20].bit[7] = 1;
++	state->CH_Ctrl[20].val[7] = 0;
++	state->CH_Ctrl[20].addr[8] = 108;
++	state->CH_Ctrl[20].bit[8] = 2;
++	state->CH_Ctrl[20].val[8] = 1;
++	state->CH_Ctrl[20].addr[9] = 108;
++	state->CH_Ctrl[20].bit[9] = 3;
++	state->CH_Ctrl[20].val[9] = 1;
++	state->CH_Ctrl[20].addr[10] = 108;
++	state->CH_Ctrl[20].bit[10] = 4;
++	state->CH_Ctrl[20].val[10] = 1;
++
++	state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ;
++	state->CH_Ctrl[21].size = 6 ;
++	state->CH_Ctrl[21].addr[0] = 106;
++	state->CH_Ctrl[21].bit[0] = 2;
++	state->CH_Ctrl[21].val[0] = 0;
++	state->CH_Ctrl[21].addr[1] = 106;
++	state->CH_Ctrl[21].bit[1] = 3;
++	state->CH_Ctrl[21].val[1] = 0;
++	state->CH_Ctrl[21].addr[2] = 106;
++	state->CH_Ctrl[21].bit[2] = 4;
++	state->CH_Ctrl[21].val[2] = 0;
++	state->CH_Ctrl[21].addr[3] = 106;
++	state->CH_Ctrl[21].bit[3] = 5;
++	state->CH_Ctrl[21].val[3] = 0;
++	state->CH_Ctrl[21].addr[4] = 106;
++	state->CH_Ctrl[21].bit[4] = 6;
++	state->CH_Ctrl[21].val[4] = 0;
++	state->CH_Ctrl[21].addr[5] = 106;
++	state->CH_Ctrl[21].bit[5] = 7;
++	state->CH_Ctrl[21].val[5] = 1;
++
++	state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ;
++	state->CH_Ctrl[22].size = 1 ;
++	state->CH_Ctrl[22].addr[0] = 138;
++	state->CH_Ctrl[22].bit[0] = 4;
++	state->CH_Ctrl[22].val[0] = 1;
++
++	state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ;
++	state->CH_Ctrl[23].size = 1 ;
++	state->CH_Ctrl[23].addr[0] = 17;
++	state->CH_Ctrl[23].bit[0] = 5;
++	state->CH_Ctrl[23].val[0] = 0;
++
++	state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ;
++	state->CH_Ctrl[24].size = 1 ;
++	state->CH_Ctrl[24].addr[0] = 111;
++	state->CH_Ctrl[24].bit[0] = 3;
++	state->CH_Ctrl[24].val[0] = 0;
++
++	state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ;
++	state->CH_Ctrl[25].size = 1 ;
++	state->CH_Ctrl[25].addr[0] = 112;
++	state->CH_Ctrl[25].bit[0] = 7;
++	state->CH_Ctrl[25].val[0] = 0;
++
++	state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ;
++	state->CH_Ctrl[26].size = 1 ;
++	state->CH_Ctrl[26].addr[0] = 136;
++	state->CH_Ctrl[26].bit[0] = 7;
++	state->CH_Ctrl[26].val[0] = 0;
++
++	state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ;
++	state->CH_Ctrl[27].size = 1 ;
++	state->CH_Ctrl[27].addr[0] = 149;
++	state->CH_Ctrl[27].bit[0] = 7;
++	state->CH_Ctrl[27].val[0] = 0;
++
++	state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ;
++	state->CH_Ctrl[28].size = 1 ;
++	state->CH_Ctrl[28].addr[0] = 149;
++	state->CH_Ctrl[28].bit[0] = 6;
++	state->CH_Ctrl[28].val[0] = 0;
++
++	state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ;
++	state->CH_Ctrl[29].size = 1 ;
++	state->CH_Ctrl[29].addr[0] = 149;
++	state->CH_Ctrl[29].bit[0] = 5;
++	state->CH_Ctrl[29].val[0] = 1;
++
++	state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ;
++	state->CH_Ctrl[30].size = 1 ;
++	state->CH_Ctrl[30].addr[0] = 149;
++	state->CH_Ctrl[30].bit[0] = 4;
++	state->CH_Ctrl[30].val[0] = 1;
++
++	state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ;
++	state->CH_Ctrl[31].size = 1 ;
++	state->CH_Ctrl[31].addr[0] = 149;
++	state->CH_Ctrl[31].bit[0] = 3;
++	state->CH_Ctrl[31].val[0] = 0;
++
++	state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ;
++	state->CH_Ctrl[32].size = 1 ;
++	state->CH_Ctrl[32].addr[0] = 93;
++	state->CH_Ctrl[32].bit[0] = 1;
++	state->CH_Ctrl[32].val[0] = 0;
++
++	state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ;
++	state->CH_Ctrl[33].size = 1 ;
++	state->CH_Ctrl[33].addr[0] = 93;
++	state->CH_Ctrl[33].bit[0] = 0;
++	state->CH_Ctrl[33].val[0] = 0;
++
++	state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ;
++	state->CH_Ctrl[34].size = 6 ;
++	state->CH_Ctrl[34].addr[0] = 92;
++	state->CH_Ctrl[34].bit[0] = 2;
++	state->CH_Ctrl[34].val[0] = 0;
++	state->CH_Ctrl[34].addr[1] = 92;
++	state->CH_Ctrl[34].bit[1] = 3;
++	state->CH_Ctrl[34].val[1] = 0;
++	state->CH_Ctrl[34].addr[2] = 92;
++	state->CH_Ctrl[34].bit[2] = 4;
++	state->CH_Ctrl[34].val[2] = 0;
++	state->CH_Ctrl[34].addr[3] = 92;
++	state->CH_Ctrl[34].bit[3] = 5;
++	state->CH_Ctrl[34].val[3] = 0;
++	state->CH_Ctrl[34].addr[4] = 92;
++	state->CH_Ctrl[34].bit[4] = 6;
++	state->CH_Ctrl[34].val[4] = 0;
++	state->CH_Ctrl[34].addr[5] = 92;
++	state->CH_Ctrl[34].bit[5] = 7;
++	state->CH_Ctrl[34].val[5] = 0;
++
++	state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ;
++	state->CH_Ctrl[35].size = 6 ;
++	state->CH_Ctrl[35].addr[0] = 93;
++	state->CH_Ctrl[35].bit[0] = 2;
++	state->CH_Ctrl[35].val[0] = 0;
++	state->CH_Ctrl[35].addr[1] = 93;
++	state->CH_Ctrl[35].bit[1] = 3;
++	state->CH_Ctrl[35].val[1] = 0;
++	state->CH_Ctrl[35].addr[2] = 93;
++	state->CH_Ctrl[35].bit[2] = 4;
++	state->CH_Ctrl[35].val[2] = 0;
++	state->CH_Ctrl[35].addr[3] = 93;
++	state->CH_Ctrl[35].bit[3] = 5;
++	state->CH_Ctrl[35].val[3] = 0;
++	state->CH_Ctrl[35].addr[4] = 93;
++	state->CH_Ctrl[35].bit[4] = 6;
++	state->CH_Ctrl[35].val[4] = 0;
++	state->CH_Ctrl[35].addr[5] = 93;
++	state->CH_Ctrl[35].bit[5] = 7;
++	state->CH_Ctrl[35].val[5] = 0;
++
++#ifdef _MXL_PRODUCTION
++	state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ;
++	state->CH_Ctrl[36].size = 1 ;
++	state->CH_Ctrl[36].addr[0] = 109;
++	state->CH_Ctrl[36].bit[0] = 1;
++	state->CH_Ctrl[36].val[0] = 1;
++
++	state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ;
++	state->CH_Ctrl[37].size = 2 ;
++	state->CH_Ctrl[37].addr[0] = 112;
++	state->CH_Ctrl[37].bit[0] = 5;
++	state->CH_Ctrl[37].val[0] = 0;
++	state->CH_Ctrl[37].addr[1] = 112;
++	state->CH_Ctrl[37].bit[1] = 6;
++	state->CH_Ctrl[37].val[1] = 0;
++
++	state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ;
++	state->CH_Ctrl[38].size = 1 ;
++	state->CH_Ctrl[38].addr[0] = 65;
++	state->CH_Ctrl[38].bit[0] = 1;
++	state->CH_Ctrl[38].val[0] = 0;
++#endif
++
++	return 0 ;
++}
++
++static void InitTunerControls(struct dvb_frontend *fe)
++{
++	MXL5005_RegisterInit(fe);
++	MXL5005_ControlInit(fe);
++#ifdef _MXL_INTERNAL
++	MXL5005_MXLControlInit(fe);
++#endif
++}
++
++static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
++	u8	Mode,		/* 0: Analog Mode ; 1: Digital Mode */
++	u8	IF_mode,	/* for Analog Mode, 0: zero IF; 1: low IF */
++	u32	Bandwidth,	/* filter  channel bandwidth (6, 7, 8) */
++	u32	IF_out,		/* Desired IF Out Frequency */
++	u32	Fxtal,		/* XTAL Frequency */
++	u8	AGC_Mode,	/* AGC Mode - Dual AGC: 0, Single AGC: 1 */
++	u16	TOP,		/* 0: Dual AGC; Value: take over point */
++	u16	IF_OUT_LOAD,	/* IF Out Load Resistor (200 / 300 Ohms) */
++	u8	CLOCK_OUT, 	/* 0: turn off clk out; 1: turn on clock out */
++	u8	DIV_OUT,	/* 0: Div-1; 1: Div-4 */
++	u8	CAPSELECT, 	/* 0: disable On-Chip pulling cap; 1: enable */
++	u8	EN_RSSI, 	/* 0: disable RSSI; 1: enable RSSI */
++
++	/* Modulation Type; */
++	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
++	u8	Mod_Type,
++
++	/* Tracking Filter */
++	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
++	u8	TF_Type
++	)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0;
++
++	state->Mode = Mode;
++	state->IF_Mode = IF_mode;
++	state->Chan_Bandwidth = Bandwidth;
++	state->IF_OUT = IF_out;
++	state->Fxtal = Fxtal;
++	state->AGC_Mode = AGC_Mode;
++	state->TOP = TOP;
++	state->IF_OUT_LOAD = IF_OUT_LOAD;
++	state->CLOCK_OUT = CLOCK_OUT;
++	state->DIV_OUT = DIV_OUT;
++	state->CAPSELECT = CAPSELECT;
++	state->EN_RSSI = EN_RSSI;
++	state->Mod_Type = Mod_Type;
++	state->TF_Type = TF_Type;
++
++	/* Initialize all the controls and registers */
++	InitTunerControls(fe);
++
++	/* Synthesizer LO frequency calculation */
++	MXL_SynthIFLO_Calc(fe);
++
++	return status;
++}
++
++static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	if (state->Mode == 1) /* Digital Mode */
++		state->IF_LO = state->IF_OUT;
++	else /* Analog Mode */ {
++		if (state->IF_Mode == 0) /* Analog Zero IF mode */
++			state->IF_LO = state->IF_OUT + 400000;
++		else /* Analog Low IF mode */
++			state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2;
++	}
++}
++
++static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++
++	if (state->Mode == 1) /* Digital Mode */ {
++			/* remove 20.48MHz setting for 2.6.10 */
++			state->RF_LO = state->RF_IN;
++			/* change for 2.6.6 */
++			state->TG_LO = state->RF_IN - 750000;
++	} else /* Analog Mode */ {
++		if (state->IF_Mode == 0) /* Analog Zero IF mode */ {
++			state->RF_LO = state->RF_IN - 400000;
++			state->TG_LO = state->RF_IN - 1750000;
++		} else /* Analog Low IF mode */ {
++			state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2;
++			state->TG_LO = state->RF_IN -
++				state->Chan_Bandwidth + 500000;
++		}
++	}
++}
++
++static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
++{
++	u16 status = 0;
++
++	status += MXL_ControlWrite(fe, OVERRIDE_1, 1);
++	status += MXL_ControlWrite(fe, OVERRIDE_2, 1);
++	status += MXL_ControlWrite(fe, OVERRIDE_3, 1);
++	status += MXL_ControlWrite(fe, OVERRIDE_4, 1);
++
++	return status;
++}
++
++static u16 MXL_BlockInit(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0;
++
++	status += MXL_OverwriteICDefault(fe);
++
++	/* Downconverter Control Dig Ana */
++	status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0);
++
++	/* Filter Control  Dig  Ana */
++	status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1);
++	status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2);
++	status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0);
++	status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1);
++	status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0);
++
++	/* Initialize Low-Pass Filter */
++	if (state->Mode) { /* Digital Mode */
++		switch (state->Chan_Bandwidth) {
++		case 8000000:
++			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0);
++			break;
++		case 7000000:
++			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
++			break;
++		case 6000000:
++			status += MXL_ControlWrite(fe,
++					BB_DLPF_BANDSEL, 3);
++			break;
++		}
++	} else { /* Analog Mode */
++		switch (state->Chan_Bandwidth) {
++		case 8000000:	/* Low Zero */
++			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
++					(state->IF_Mode ? 0 : 3));
++			break;
++		case 7000000:
++			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
++					(state->IF_Mode ? 1 : 4));
++			break;
++		case 6000000:
++			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
++					(state->IF_Mode ? 2 : 5));
++			break;
++		}
++	}
++
++	/* Charge Pump Control Dig  Ana */
++	status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8);
++	status += MXL_ControlWrite(fe,
++		RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1);
++	status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0);
++
++	/* AGC TOP Control */
++	if (state->AGC_Mode == 0) /* Dual AGC */ {
++		status += MXL_ControlWrite(fe, AGC_IF, 15);
++		status += MXL_ControlWrite(fe, AGC_RF, 15);
++	} else /*  Single AGC Mode Dig  Ana */
++		status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
++
++	if (state->TOP == 55) /* TOP == 5.5 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x0);
++
++	if (state->TOP == 72) /* TOP == 7.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x1);
++
++	if (state->TOP == 92) /* TOP == 9.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x2);
++
++	if (state->TOP == 110) /* TOP == 11.0 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x3);
++
++	if (state->TOP == 129) /* TOP == 12.9 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x4);
++
++	if (state->TOP == 147) /* TOP == 14.7 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x5);
++
++	if (state->TOP == 168) /* TOP == 16.8 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x6);
++
++	if (state->TOP == 194) /* TOP == 19.4 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x7);
++
++	if (state->TOP == 212) /* TOP == 21.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0x9);
++
++	if (state->TOP == 232) /* TOP == 23.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xA);
++
++	if (state->TOP == 252) /* TOP == 25.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xB);
++
++	if (state->TOP == 271) /* TOP == 27.1 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xC);
++
++	if (state->TOP == 292) /* TOP == 29.2 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xD);
++
++	if (state->TOP == 317) /* TOP == 31.7 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xE);
++
++	if (state->TOP == 349) /* TOP == 34.9 */
++		status += MXL_ControlWrite(fe, AGC_IF, 0xF);
++
++	/* IF Synthesizer Control */
++	status += MXL_IFSynthInit(fe);
++
++	/* IF UpConverter Control */
++	if (state->IF_OUT_LOAD == 200) {
++		status += MXL_ControlWrite(fe, DRV_RES_SEL, 6);
++		status += MXL_ControlWrite(fe, I_DRIVER, 2);
++	}
++	if (state->IF_OUT_LOAD == 300) {
++		status += MXL_ControlWrite(fe, DRV_RES_SEL, 4);
++		status += MXL_ControlWrite(fe, I_DRIVER, 1);
++	}
++
++	/* Anti-Alias Filtering Control
++	 * initialise Anti-Aliasing Filter
++	 */
++	if (state->Mode) { /* Digital Mode */
++		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) {
++			status += MXL_ControlWrite(fe, EN_AAF, 1);
++			status += MXL_ControlWrite(fe, EN_3P, 1);
++			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
++			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
++		}
++		if ((state->IF_OUT == 36125000UL) ||
++			(state->IF_OUT == 36150000UL)) {
++			status += MXL_ControlWrite(fe, EN_AAF, 1);
++			status += MXL_ControlWrite(fe, EN_3P, 1);
++			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
++			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
++		}
++		if (state->IF_OUT > 36150000UL) {
++			status += MXL_ControlWrite(fe, EN_AAF, 0);
++			status += MXL_ControlWrite(fe, EN_3P, 1);
++			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
++			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
++		}
++	} else { /* Analog Mode */
++		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) {
++			status += MXL_ControlWrite(fe, EN_AAF, 1);
++			status += MXL_ControlWrite(fe, EN_3P, 1);
++			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
++			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
++		}
++		if (state->IF_OUT > 5000000UL) {
++			status += MXL_ControlWrite(fe, EN_AAF, 0);
++			status += MXL_ControlWrite(fe, EN_3P, 0);
++			status += MXL_ControlWrite(fe, EN_AUX_3P, 0);
++			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
++		}
++	}
++
++	/* Demod Clock Out */
++	if (state->CLOCK_OUT)
++		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1);
++	else
++		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0);
++
++	if (state->DIV_OUT == 1)
++		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1);
++	if (state->DIV_OUT == 0)
++		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0);
++
++	/* Crystal Control */
++	if (state->CAPSELECT)
++		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1);
++	else
++		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0);
++
++	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
++		status += MXL_ControlWrite(fe, IF_SEL_DBL, 1);
++	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
++		status += MXL_ControlWrite(fe, IF_SEL_DBL, 0);
++
++	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
++		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3);
++	if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL)
++		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0);
++
++	/* Misc Controls */
++	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */
++		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0);
++	else
++		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1);
++
++	/* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */
++
++	/* Set TG_R_DIV */
++	status += MXL_ControlWrite(fe, TG_R_DIV,
++		MXL_Ceiling(state->Fxtal, 1000000));
++
++	/* Apply Default value to BB_INITSTATE_DLPF_TUNE */
++
++	/* RSSI Control */
++	if (state->EN_RSSI) {
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++		/* RSSI reference point */
++		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
++
++		/* TOP point */
++		status += MXL_ControlWrite(fe, RFA_FLR, 0);
++		status += MXL_ControlWrite(fe, RFA_CEIL, 12);
++	}
++
++	/* Modulation type bit settings
++	 * Override the control values preset
++	 */
++	if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ {
++		state->AGC_Mode = 1; /* Single AGC Mode */
++
++		/* Enable RSSI */
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++		/* RSSI reference point */
++		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
++
++		/* TOP point */
++		status += MXL_ControlWrite(fe, RFA_FLR, 2);
++		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
++		if (state->IF_OUT <= 6280000UL)	/* Low IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
++		else /* High IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
++
++	}
++	if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ {
++		state->AGC_Mode = 1;	/* Single AGC Mode */
++
++		/* Enable RSSI */
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++		/* RSSI reference point */
++		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
++
++		/* TOP point */
++		status += MXL_ControlWrite(fe, RFA_FLR, 2);
++		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
++		status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1);
++		/* Low Zero */
++		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
++
++		if (state->IF_OUT <= 6280000UL)	/* Low IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
++		else /* High IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
++	}
++	if (state->Mod_Type == MXL_QAM) /* QAM Mode */ {
++		state->Mode = MXL_DIGITAL_MODE;
++
++		/* state->AGC_Mode = 1; */ /* Single AGC Mode */
++
++		/* Disable RSSI */	/* change here for v2.6.5 */
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++		/* RSSI reference point */
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
++		/* change here for v2.6.5 */
++		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
++
++		if (state->IF_OUT <= 6280000UL)	/* Low IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
++		else /* High IF */
++			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
++		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
++
++	}
++	if (state->Mod_Type == MXL_ANALOG_CABLE) {
++		/* Analog Cable Mode */
++		/* state->Mode = MXL_DIGITAL_MODE; */
++
++		state->AGC_Mode = 1; /* Single AGC Mode */
++
++		/* Disable RSSI */
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++		/* change for 2.6.3 */
++		status += MXL_ControlWrite(fe, AGC_IF, 1);
++		status += MXL_ControlWrite(fe, AGC_RF, 15);
++		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
++	}
++
++	if (state->Mod_Type == MXL_ANALOG_OTA) {
++		/* Analog OTA Terrestrial mode add for 2.6.7 */
++		/* state->Mode = MXL_ANALOG_MODE; */
++
++		/* Enable RSSI */
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++		/* RSSI reference point */
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
++		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
++		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
++		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
++	}
++
++	/* RSSI disable */
++	if (state->EN_RSSI == 0) {
++		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
++		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++	}
++
++	return status;
++}
++
++static u16 MXL_IFSynthInit(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0 ;
++	u32	Fref = 0 ;
++	u32	Kdbl, intModVal ;
++	u32	fracModVal ;
++	Kdbl = 2 ;
++
++	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
++		Kdbl = 2 ;
++	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
++		Kdbl = 1 ;
++
++	/* IF Synthesizer Control */
++	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ {
++		if (state->IF_LO == 41000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 328000000UL ;
++		}
++		if (state->IF_LO == 47000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 376000000UL ;
++		}
++		if (state->IF_LO == 54000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 324000000UL ;
++		}
++		if (state->IF_LO == 60000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 39250000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 314000000UL ;
++		}
++		if (state->IF_LO == 39650000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 317200000UL ;
++		}
++		if (state->IF_LO == 40150000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 321200000UL ;
++		}
++		if (state->IF_LO == 40650000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 325200000UL ;
++		}
++	}
++
++	if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) {
++		if (state->IF_LO == 57000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 342000000UL ;
++		}
++		if (state->IF_LO == 44000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 352000000UL ;
++		}
++		if (state->IF_LO == 43750000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 350000000UL ;
++		}
++		if (state->IF_LO == 36650000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 366500000UL ;
++		}
++		if (state->IF_LO == 36150000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 361500000UL ;
++		}
++		if (state->IF_LO == 36000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 35250000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 352500000UL ;
++		}
++		if (state->IF_LO == 34750000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 347500000UL ;
++		}
++		if (state->IF_LO == 6280000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 376800000UL ;
++		}
++		if (state->IF_LO == 5000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 4500000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 4570000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 365600000UL ;
++		}
++		if (state->IF_LO == 4000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 57400000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 344400000UL ;
++		}
++		if (state->IF_LO == 44400000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 355200000UL ;
++		}
++		if (state->IF_LO == 44150000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 353200000UL ;
++		}
++		if (state->IF_LO == 37050000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 370500000UL ;
++		}
++		if (state->IF_LO == 36550000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 365500000UL ;
++		}
++		if (state->IF_LO == 36125000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 361250000UL ;
++		}
++		if (state->IF_LO == 6000000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 360000000UL ;
++		}
++		if (state->IF_LO == 5400000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 324000000UL ;
++		}
++		if (state->IF_LO == 5380000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
++			Fref = 322800000UL ;
++		}
++		if (state->IF_LO == 5200000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 374400000UL ;
++		}
++		if (state->IF_LO == 4900000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 352800000UL ;
++		}
++		if (state->IF_LO == 4400000UL) {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 352000000UL ;
++		}
++		if (state->IF_LO == 4063000UL)  /* add for 2.6.8 */ {
++			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
++			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
++			Fref = 365670000UL ;
++		}
++	}
++	/* CHCAL_INT_MOD_IF */
++	/* CHCAL_FRAC_MOD_IF */
++	intModVal = Fref / (state->Fxtal * Kdbl/2);
++	status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal);
++
++	fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) *
++		intModVal);
++
++	fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000);
++	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal);
++
++	return status ;
++}
++
++static u32 MXL_GetXtalInt(u32 Xtal_Freq)
++{
++	if ((Xtal_Freq % 1000000) == 0)
++		return (Xtal_Freq / 10000);
++	else
++		return (((Xtal_Freq / 1000000) + 1)*100);
++}
++
++static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0;
++	u32 divider_val, E3, E4, E5, E5A;
++	u32 Fmax, Fmin, FmaxBin, FminBin;
++	u32 Kdbl_RF = 2;
++	u32 tg_divval;
++	u32 tg_lo;
++	u32 Xtal_Int;
++
++	u32 Fref_TG;
++	u32 Fvco;
++
++	Xtal_Int = MXL_GetXtalInt(state->Fxtal);
++
++	state->RF_IN = RF_Freq;
++
++	MXL_SynthRFTGLO_Calc(fe);
++
++	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
++		Kdbl_RF = 2;
++	if (state->Fxtal > 22000000 && state->Fxtal <= 32000000)
++		Kdbl_RF = 1;
++
++	/* Downconverter Controls
++	 * Look-Up Table Implementation for:
++	 *	DN_POLY
++	 *	DN_RFGAIN
++	 *	DN_CAP_RFLPF
++	 *	DN_EN_VHFUHFBAR
++	 *	DN_GAIN_ADJUST
++	 *  Change the boundary reference from RF_IN to RF_LO
++	 */
++	if (state->RF_LO < 40000000UL)
++		return -1;
++
++	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              2);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         423);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
++	}
++	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         222);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
++	}
++	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         147);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
++	}
++	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         9);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
++	}
++	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
++	}
++	if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            1);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
++	}
++	if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) {
++		status += MXL_ControlWrite(fe, DN_POLY,              3);
++		status += MXL_ControlWrite(fe, DN_RFGAIN,            2);
++		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
++		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
++		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
++	}
++	if (state->RF_LO > 900000000UL)
++		return -1;
++
++	/*	DN_IQTNBUF_AMP */
++	/*	DN_IQTNGNBFBIAS_BST */
++	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
++	}
++	if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
++	}
++	if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) {
++		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
++		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
++	}
++
++	/*
++	 * Set RF Synth and LO Path Control
++	 *
++	 * Look-Up table implementation for:
++	 *	RFSYN_EN_OUTMUX
++	 *	RFSYN_SEL_VCO_OUT
++	 *	RFSYN_SEL_VCO_HI
++	 *  RFSYN_SEL_DIVM
++	 *	RFSYN_RF_DIV_BIAS
++	 *	DN_SEL_FREQ
++	 *
++	 * Set divider_val, Fmax, Fmix to use in Equations
++	 */
++	FminBin = 28000000UL ;
++	FmaxBin = 42500000UL ;
++	if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
++		divider_val = 64 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 42500000UL ;
++	FmaxBin = 56000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
++		divider_val = 64 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 56000000UL ;
++	FmaxBin = 85000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
++		divider_val = 32 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 85000000UL ;
++	FmaxBin = 112000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
++		divider_val = 32 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 112000000UL ;
++	FmaxBin = 170000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
++		divider_val = 16 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 170000000UL ;
++	FmaxBin = 225000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
++		divider_val = 16 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 225000000UL ;
++	FmaxBin = 300000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         4);
++		divider_val = 8 ;
++		Fmax = 340000000UL ;
++		Fmin = FminBin ;
++	}
++	FminBin = 300000000UL ;
++	FmaxBin = 340000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
++		divider_val = 8 ;
++		Fmax = FmaxBin ;
++		Fmin = 225000000UL ;
++	}
++	FminBin = 340000000UL ;
++	FmaxBin = 450000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   2);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
++		divider_val = 8 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 450000000UL ;
++	FmaxBin = 680000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
++		divider_val = 4 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 680000000UL ;
++	FmaxBin = 900000000UL ;
++	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
++		divider_val = 4 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++
++	/*	CHCAL_INT_MOD_RF
++	 *	CHCAL_FRAC_MOD_RF
++	 *	RFSYN_LPF_R
++	 *	CHCAL_EN_INT_RF
++	 */
++	/* Equation E3 RFSYN_VCO_BIAS */
++	E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ;
++	status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3);
++
++	/* Equation E4 CHCAL_INT_MOD_RF */
++	E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000);
++	MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4);
++
++	/* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */
++	E5 = ((2<<17)*(state->RF_LO/10000*divider_val -
++		(E4*(2*state->Fxtal*Kdbl_RF)/10000))) /
++		(2*state->Fxtal*Kdbl_RF/10000);
++
++	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
++
++	/* Equation E5A RFSYN_LPF_R */
++	E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ;
++	status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A);
++
++	/* Euqation E5B CHCAL_EN_INIT_RF */
++	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0));
++	/*if (E5 == 0)
++	 *	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1);
++	 *else
++	 *	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
++	 */
++
++	/*
++	 * Set TG Synth
++	 *
++	 * Look-Up table implementation for:
++	 *	TG_LO_DIVVAL
++	 *	TG_LO_SELVAL
++	 *
++	 * Set divider_val, Fmax, Fmix to use in Equations
++	 */
++	if (state->TG_LO < 33000000UL)
++		return -1;
++
++	FminBin = 33000000UL ;
++	FmaxBin = 50000000UL ;
++	if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x6);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
++		divider_val = 36 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 50000000UL ;
++	FmaxBin = 67000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x1);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
++		divider_val = 24 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 67000000UL ;
++	FmaxBin = 100000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0xC);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
++		divider_val = 18 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 100000000UL ;
++	FmaxBin = 150000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
++		divider_val = 12 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 150000000UL ;
++	FmaxBin = 200000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
++		divider_val = 8 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 200000000UL ;
++	FmaxBin = 300000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
++		divider_val = 6 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 300000000UL ;
++	FmaxBin = 400000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
++		divider_val = 4 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 400000000UL ;
++	FmaxBin = 600000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
++		divider_val = 3 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++	FminBin = 600000000UL ;
++	FmaxBin = 900000000UL ;
++	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
++		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
++		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
++		divider_val = 2 ;
++		Fmax = FmaxBin ;
++		Fmin = FminBin ;
++	}
++
++	/* TG_DIV_VAL */
++	tg_divval = (state->TG_LO*divider_val/100000) *
++		(MXL_Ceiling(state->Fxtal, 1000000) * 100) /
++		(state->Fxtal/1000);
++
++	status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval);
++
++	if (state->TG_LO > 600000000UL)
++		status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1);
++
++	Fmax = 1800000000UL ;
++	Fmin = 1200000000UL ;
++
++	/* prevent overflow of 32 bit unsigned integer, use
++	 * following equation. Edit for v2.6.4
++	 */
++	/* Fref_TF = Fref_TG * 1000 */
++	Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000);
++
++	/* Fvco = Fvco/10 */
++	Fvco = (state->TG_LO/10000) * divider_val * Fref_TG;
++
++	tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8;
++
++	/* below equation is same as above but much harder to debug.
++	 * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) -
++	 * ((state->TG_LO/10000)*divider_val *
++	 * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 *
++	 * Xtal_Int/100) + 8;
++	 */
++
++	status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo);
++
++	/* add for 2.6.5 Special setting for QAM */
++	if (state->Mod_Type == MXL_QAM) {
++		if (state->RF_IN < 680000000)
++			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
++		else
++			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
++	}
++
++	/* Off Chip Tracking Filter Control */
++	if (state->TF_Type == MXL_TF_OFF) {
++		/* Tracking Filter Off State; turn off all the banks */
++		status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++		status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */
++		status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */
++		status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */
++	}
++
++	if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ {
++		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++		}
++		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++		}
++		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++		}
++		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 0);
++		}
++		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 29);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 0);
++		}
++		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 0);
++		}
++		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 16);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++		}
++		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 7);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++		}
++		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_C_H) {
++
++		/* Tracking Filter type C-H for Hauppauge only */
++		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++		}
++		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++		}
++		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++		}
++		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++		}
++		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++		}
++		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++		}
++		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++		}
++		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++		}
++		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */
++
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_D_L) {
++
++		/* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */
++		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
++
++		/* if UHF and terrestrial => Turn off Tracking Filter */
++		if (state->RF_IN >= 471000000 &&
++			(state->RF_IN - 471000000)%6000000 != 0) {
++			/* Turn off all the banks */
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++			status += MXL_ControlWrite(fe, AGC_IF, 10);
++		} else {
++			/* if VHF or cable => Turn on Tracking Filter */
++			if (state->RF_IN >= 43000000 &&
++				state->RF_IN < 140000000) {
++
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++				status += MXL_SetGPIO(fe, 4, 1);
++				status += MXL_SetGPIO(fe, 1, 1);
++				status += MXL_SetGPIO(fe, 3, 0);
++			}
++			if (state->RF_IN >= 140000000 &&
++				state->RF_IN < 240000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++				status += MXL_SetGPIO(fe, 4, 1);
++				status += MXL_SetGPIO(fe, 1, 0);
++				status += MXL_SetGPIO(fe, 3, 0);
++			}
++			if (state->RF_IN >= 240000000 &&
++				state->RF_IN < 340000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++				status += MXL_SetGPIO(fe, 4, 0);
++				status += MXL_SetGPIO(fe, 1, 1);
++				status += MXL_SetGPIO(fe, 3, 0);
++			}
++			if (state->RF_IN >= 340000000 &&
++				state->RF_IN < 430000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++				status += MXL_SetGPIO(fe, 4, 0);
++				status += MXL_SetGPIO(fe, 1, 0);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++			if (state->RF_IN >= 430000000 &&
++				state->RF_IN < 470000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++				status += MXL_SetGPIO(fe, 4, 1);
++				status += MXL_SetGPIO(fe, 1, 0);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++			if (state->RF_IN >= 470000000 &&
++				state->RF_IN < 570000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++				status += MXL_SetGPIO(fe, 4, 0);
++				status += MXL_SetGPIO(fe, 1, 0);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++			if (state->RF_IN >= 570000000 &&
++				state->RF_IN < 620000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
++				status += MXL_SetGPIO(fe, 4, 0);
++				status += MXL_SetGPIO(fe, 1, 1);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++			if (state->RF_IN >= 620000000 &&
++				state->RF_IN < 760000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++				status += MXL_SetGPIO(fe, 4, 0);
++				status += MXL_SetGPIO(fe, 1, 1);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++			if (state->RF_IN >= 760000000 &&
++				state->RF_IN <= 900000000) {
++				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
++				status += MXL_SetGPIO(fe, 4, 1);
++				status += MXL_SetGPIO(fe, 1, 1);
++				status += MXL_SetGPIO(fe, 3, 1);
++			}
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ {
++
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_F) {
++
++		/* Tracking Filter type F */
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_E_2) {
++
++		/* Tracking Filter type E_2 */
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_G) {
++
++		/* Tracking Filter type G add for v2.6.8 */
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) {
++
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++	}
++
++	if (state->TF_Type == MXL_TF_E_NA) {
++
++		/* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */
++		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
++
++		/* if UHF and terrestrial=> Turn off Tracking Filter */
++		if (state->RF_IN >= 471000000 &&
++			(state->RF_IN - 471000000)%6000000 != 0) {
++
++			/* Turn off all the banks */
++			status += MXL_SetGPIO(fe, 3, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++
++			/* 2.6.12 Turn on RSSI */
++			status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
++			status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
++			status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
++			status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
++
++			/* RSSI reference point */
++			status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
++			status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
++			status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
++
++			/* following parameter is from analog OTA mode,
++			 * can be change to seek better performance */
++			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
++		} else {
++		/* if VHF or Cable =>  Turn on Tracking Filter */
++
++		/* 2.6.12 Turn off RSSI */
++		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
++
++		/* change back from above condition */
++		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
++
++
++		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
++
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 0);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 0);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 0);
++		}
++		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
++			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
++			status += MXL_SetGPIO(fe, 4, 1);
++			status += MXL_SetGPIO(fe, 1, 1);
++			status += MXL_SetGPIO(fe, 3, 1);
++		}
++		}
++	}
++	return status ;
++}
++
++static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
++{
++	u16 status = 0;
++
++	if (GPIO_Num == 1)
++		status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1);
++
++	/* GPIO2 is not available */
++
++	if (GPIO_Num == 3) {
++		if (GPIO_Val == 1) {
++			status += MXL_ControlWrite(fe, GPIO_3, 0);
++			status += MXL_ControlWrite(fe, GPIO_3B, 0);
++		}
++		if (GPIO_Val == 0) {
++			status += MXL_ControlWrite(fe, GPIO_3, 1);
++			status += MXL_ControlWrite(fe, GPIO_3B, 1);
++		}
++		if (GPIO_Val == 3) { /* tri-state */
++			status += MXL_ControlWrite(fe, GPIO_3, 0);
++			status += MXL_ControlWrite(fe, GPIO_3B, 1);
++		}
++	}
++	if (GPIO_Num == 4) {
++		if (GPIO_Val == 1) {
++			status += MXL_ControlWrite(fe, GPIO_4, 0);
++			status += MXL_ControlWrite(fe, GPIO_4B, 0);
++		}
++		if (GPIO_Val == 0) {
++			status += MXL_ControlWrite(fe, GPIO_4, 1);
++			status += MXL_ControlWrite(fe, GPIO_4B, 1);
++		}
++		if (GPIO_Val == 3) { /* tri-state */
++			status += MXL_ControlWrite(fe, GPIO_4, 0);
++			status += MXL_ControlWrite(fe, GPIO_4B, 1);
++		}
++	}
++
++	return status;
++}
++
++static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
++{
++	u16 status = 0;
++
++	/* Will write ALL Matching Control Name */
++	/* Write Matching INIT Control */
++	status += MXL_ControlWrite_Group(fe, ControlNum, value, 1);
++	/* Write Matching CH Control */
++	status += MXL_ControlWrite_Group(fe, ControlNum, value, 2);
++#ifdef _MXL_INTERNAL
++	/* Write Matching MXL Control */
++	status += MXL_ControlWrite_Group(fe, ControlNum, value, 3);
++#endif
++	return status;
++}
++
++static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
++	u32 value, u16 controlGroup)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 i, j, k;
++	u32 highLimit;
++	u32 ctrlVal;
++
++	if (controlGroup == 1) /* Initial Control */ {
++
++		for (i = 0; i < state->Init_Ctrl_Num; i++) {
++
++			if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
++
++				highLimit = 1 << state->Init_Ctrl[i].size;
++				if (value < highLimit) {
++					for (j = 0; j < state->Init_Ctrl[i].size; j++) {
++						state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
++						MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]),
++							(u8)(state->Init_Ctrl[i].bit[j]),
++							(u8)((value>>j) & 0x01));
++					}
++					ctrlVal = 0;
++					for (k = 0; k < state->Init_Ctrl[i].size; k++)
++						ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
++				} else
++					return -1;
++			}
++		}
++	}
++	if (controlGroup == 2) /* Chan change Control */ {
++
++		for (i = 0; i < state->CH_Ctrl_Num; i++) {
++
++			if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
++
++				highLimit = 1 << state->CH_Ctrl[i].size;
++				if (value < highLimit) {
++					for (j = 0; j < state->CH_Ctrl[i].size; j++) {
++						state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
++						MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]),
++							(u8)(state->CH_Ctrl[i].bit[j]),
++							(u8)((value>>j) & 0x01));
++					}
++					ctrlVal = 0;
++					for (k = 0; k < state->CH_Ctrl[i].size; k++)
++						ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
++				} else
++					return -1;
++			}
++		}
++	}
++#ifdef _MXL_INTERNAL
++	if (controlGroup == 3) /* Maxlinear Control */ {
++
++		for (i = 0; i < state->MXL_Ctrl_Num; i++) {
++
++			if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
++
++				highLimit = (1 << state->MXL_Ctrl[i].size);
++				if (value < highLimit) {
++					for (j = 0; j < state->MXL_Ctrl[i].size; j++) {
++						state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
++						MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]),
++							(u8)(state->MXL_Ctrl[i].bit[j]),
++							(u8)((value>>j) & 0x01));
++					}
++					ctrlVal = 0;
++					for (k = 0; k < state->MXL_Ctrl[i].size; k++)
++						ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
++				} else
++					return -1;
++			}
++		}
++	}
++#endif
++	return 0 ; /* successful return */
++}
++
++static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	int i ;
++
++	for (i = 0; i < 104; i++) {
++		if (RegNum == state->TunerRegs[i].Reg_Num) {
++			*RegVal = (u8)(state->TunerRegs[i].Reg_Val);
++			return 0;
++		}
++	}
++
++	return 1;
++}
++
++static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u32 ctrlVal ;
++	u16 i, k ;
++
++	for (i = 0; i < state->Init_Ctrl_Num ; i++) {
++
++		if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
++
++			ctrlVal = 0;
++			for (k = 0; k < state->Init_Ctrl[i].size; k++)
++				ctrlVal += state->Init_Ctrl[i].val[k] * (1<<k);
++			*value = ctrlVal;
++			return 0;
++		}
++	}
++
++	for (i = 0; i < state->CH_Ctrl_Num ; i++) {
++
++		if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
++
++			ctrlVal = 0;
++			for (k = 0; k < state->CH_Ctrl[i].size; k++)
++				ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
++			*value = ctrlVal;
++			return 0;
++
++		}
++	}
++
++#ifdef _MXL_INTERNAL
++	for (i = 0; i < state->MXL_Ctrl_Num ; i++) {
++
++		if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
++
++			ctrlVal = 0;
++			for (k = 0; k < state->MXL_Ctrl[i].size; k++)
++				ctrlVal += state->MXL_Ctrl[i].val[k] * (1<<k);
++			*value = ctrlVal;
++			return 0;
++
++		}
++	}
++#endif
++	return 1;
++}
++
++static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
++	u8 bitVal)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	int i ;
++
++	const u8 AND_MAP[8] = {
++		0xFE, 0xFD, 0xFB, 0xF7,
++		0xEF, 0xDF, 0xBF, 0x7F } ;
++
++	const u8 OR_MAP[8] = {
++		0x01, 0x02, 0x04, 0x08,
++		0x10, 0x20, 0x40, 0x80 } ;
++
++	for (i = 0; i < state->TunerRegs_Num; i++) {
++		if (state->TunerRegs[i].Reg_Num == address) {
++			if (bitVal)
++				state->TunerRegs[i].Reg_Val |= OR_MAP[bit];
++			else
++				state->TunerRegs[i].Reg_Val &= AND_MAP[bit];
++			break ;
++		}
++	}
++}
++
++static u32 MXL_Ceiling(u32 value, u32 resolution)
++{
++	return (value/resolution + (value % resolution > 0 ? 1 : 0));
++}
++
++/* Retrieve the Initialzation Registers */
++static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
++	u8 *RegVal, int *count)
++{
++	u16 status = 0;
++	int i ;
++
++	u8 RegAddr[] = {
++		11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
++		76, 77, 91, 134, 135, 137, 147,
++		156, 166, 167, 168, 25 };
++
++	*count = sizeof(RegAddr) / sizeof(u8);
++
++	status += MXL_BlockInit(fe);
++
++	for (i = 0 ; i < *count; i++) {
++		RegNum[i] = RegAddr[i];
++		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
++	}
++
++	return status;
++}
++
++static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
++	int *count)
++{
++	u16 status = 0;
++	int i ;
++
++/* add 77, 166, 167, 168 register for 2.6.12 */
++#ifdef _MXL_PRODUCTION
++	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
++	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
++#else
++	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
++	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
++	/*
++	u8 RegAddr[171];
++	for (i = 0; i <= 170; i++)
++		RegAddr[i] = i;
++	*/
++#endif
++
++	*count = sizeof(RegAddr) / sizeof(u8);
++
++	for (i = 0 ; i < *count; i++) {
++		RegNum[i] = RegAddr[i];
++		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
++	}
++
++	return status;
++}
++
++static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
++	u8 *RegVal, int *count)
++{
++	u16 status = 0;
++	int i;
++
++	u8 RegAddr[] = {43, 136};
++
++	*count = sizeof(RegAddr) / sizeof(u8);
++
++	for (i = 0; i < *count; i++) {
++		RegNum[i] = RegAddr[i];
++		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
++	}
++
++	return status;
++}
++
++static u16 MXL_GetMasterControl(u8 *MasterReg, int state)
++{
++	if (state == 1) /* Load_Start */
++		*MasterReg = 0xF3;
++	if (state == 2) /* Power_Down */
++		*MasterReg = 0x41;
++	if (state == 3) /* Synth_Reset */
++		*MasterReg = 0xB1;
++	if (state == 4) /* Seq_Off */
++		*MasterReg = 0xF1;
++
++	return 0;
++}
++
++#ifdef _MXL_PRODUCTION
++static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0 ;
++
++	if (VCO_Range == 1) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
++		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
++		if (state->Mode == 0 && state->IF_Mode == 1) {
++			/* Analog Low IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 180224);
++		}
++		if (state->Mode == 0 && state->IF_Mode == 0) {
++			/* Analog Zero IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 222822);
++		}
++		if (state->Mode == 1) /* Digital Mode */ {
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 229376);
++		}
++	}
++
++	if (VCO_Range == 2) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
++		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
++		if (state->Mode == 0 && state->IF_Mode == 1) {
++			/* Analog Low IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 206438);
++		}
++		if (state->Mode == 0 && state->IF_Mode == 0) {
++			/* Analog Zero IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 206438);
++		}
++		if (state->Mode == 1) /* Digital Mode */ {
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 16384);
++		}
++	}
++
++	if (VCO_Range == 3) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
++		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
++		if (state->Mode == 0 && state->IF_Mode == 1) {
++			/* Analog Low IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 173670);
++		}
++		if (state->Mode == 0 && state->IF_Mode == 0) {
++			/* Analog Zero IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 173670);
++		}
++		if (state->Mode == 1) /* Digital Mode */ {
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 245760);
++		}
++	}
++
++	if (VCO_Range == 4) {
++		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
++		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
++		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
++		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
++		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
++		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
++		if (state->Mode == 0 && state->IF_Mode == 1) {
++			/* Analog Low IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 206438);
++		}
++		if (state->Mode == 0 && state->IF_Mode == 0) {
++			/* Analog Zero IF Mode */
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 206438);
++		}
++		if (state->Mode == 1) /* Digital Mode */ {
++			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
++			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
++			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
++			status += MXL_ControlWrite(fe,
++				CHCAL_FRAC_MOD_RF, 212992);
++		}
++	}
++
++	return status;
++}
++
++static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u16 status = 0;
++
++	if (Hystersis == 1)
++		status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1);
++
++	return status;
++}
++#endif
++/* End: Reference driver code found in the Realtek driver that
++ * is copyright MaxLinear */
++
++/* ----------------------------------------------------------------
++ * Begin: Everything after here is new code to adapt the
++ * proprietary Realtek driver into a Linux API tuner.
++ * Copyright (C) 2008 Steven Toth <stoth at hauppauge.com>
++ */
++static int mxl5005s_reset(struct dvb_frontend *fe)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	int ret = 0;
++
++	u8 buf[2] = { 0xff, 0x00 };
++	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
++			       .buf = buf, .len = 2 };
++
++	dprintk(2, "%s()\n", __func__);
++
++	if (fe->ops.i2c_gate_ctrl)
++		fe->ops.i2c_gate_ctrl(fe, 1);
++
++	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
++		printk(KERN_WARNING "mxl5005s I2C reset failed\n");
++		ret = -EREMOTEIO;
++	}
++
++	if (fe->ops.i2c_gate_ctrl)
++		fe->ops.i2c_gate_ctrl(fe, 0);
++
++	return ret;
++}
++
++/* Write a single byte to a single reg, latch the value if required by
++ * following the transaction with the latch byte.
++ */
++static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
++	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
++			       .buf = buf, .len = 3 };
++
++	if (latch == 0)
++		msg.len = 2;
++
++	dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr);
++
++	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
++		printk(KERN_WARNING "mxl5005s I2C write failed\n");
++		return -EREMOTEIO;
++	}
++	return 0;
++}
++
++static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
++	u8 *datatable, u8 len)
++{
++	int ret = 0, i;
++
++	if (fe->ops.i2c_gate_ctrl)
++		fe->ops.i2c_gate_ctrl(fe, 1);
++
++	for (i = 0 ; i < len-1; i++) {
++		ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
++		if (ret < 0)
++			break;
++	}
++
++	ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
++
++	if (fe->ops.i2c_gate_ctrl)
++		fe->ops.i2c_gate_ctrl(fe, 0);
++
++	return ret;
++}
++
++static int mxl5005s_init(struct dvb_frontend *fe)
++{
++	dprintk(1, "%s()\n", __func__);
++	return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
++}
++
++static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
++	u32 bandwidth)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++
++	u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
++	u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
++	int TableLen;
++
++	dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
++
++	mxl5005s_reset(fe);
++
++	/* Tuner initialization stage 0 */
++	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
++	AddrTable[0] = MASTER_CONTROL_ADDR;
++	ByteTable[0] |= state->config->AgcMasterByte;
++
++	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
++
++	mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
++
++	/* Tuner initialization stage 1 */
++	MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
++
++	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
++
++	return 0;
++}
++
++static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
++	u32 bandwidth)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	struct mxl5005s_config *c = state->config;
++
++	InitTunerControls(fe);
++
++	/* Set MxL5005S parameters. */
++	MXL5005_TunerConfig(
++		fe,
++		c->mod_mode,
++		c->if_mode,
++		bandwidth,
++		c->if_freq,
++		c->xtal_freq,
++		c->agc_mode,
++		c->top,
++		c->output_load,
++		c->clock_out,
++		c->div_out,
++		c->cap_select,
++		c->rssi_enable,
++		mod_type,
++		c->tracking_filter);
++
++	return 0;
++}
++
++static int mxl5005s_set_params(struct dvb_frontend *fe,
++			       struct dvb_frontend_parameters *params)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	u32 req_mode, req_bw = 0;
++	int ret;
++
++	dprintk(1, "%s()\n", __func__);
++
++	if (fe->ops.info.type == FE_ATSC) {
++		switch (params->u.vsb.modulation) {
++		case VSB_8:
++			req_mode = MXL_ATSC; break;
++		default:
++		case QAM_64:
++		case QAM_256:
++		case QAM_AUTO:
++			req_mode = MXL_QAM; break;
++		}
++	} else
++		req_mode = MXL_DVBT;
++
++	/* Change tuner for new modulation type if reqd */
++	if (req_mode != state->current_mode) {
++		switch (req_mode) {
++		case VSB_8:
++		case QAM_64:
++		case QAM_256:
++		case QAM_AUTO:
++			req_bw  = MXL5005S_BANDWIDTH_6MHZ;
++			break;
++		default:
++			/* Assume DVB-T */
++			switch (params->u.ofdm.bandwidth) {
++			case BANDWIDTH_6_MHZ:
++				req_bw  = MXL5005S_BANDWIDTH_6MHZ;
++				break;
++			case BANDWIDTH_7_MHZ:
++				req_bw  = MXL5005S_BANDWIDTH_7MHZ;
++				break;
++			case BANDWIDTH_AUTO:
++			case BANDWIDTH_8_MHZ:
++				req_bw  = MXL5005S_BANDWIDTH_8MHZ;
++				break;
++			}
++		}
++
++		state->current_mode = req_mode;
++		ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
++
++	} else
++		ret = 0;
++
++	if (ret == 0) {
++		dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
++		ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
++	}
++
++	return ret;
++}
++
++static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	dprintk(1, "%s()\n", __func__);
++
++	*frequency = state->RF_IN;
++
++	return 0;
++}
++
++static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
++{
++	struct mxl5005s_state *state = fe->tuner_priv;
++	dprintk(1, "%s()\n", __func__);
++
++	*bandwidth = state->Chan_Bandwidth;
++
++	return 0;
++}
++
++static int mxl5005s_release(struct dvb_frontend *fe)
++{
++	dprintk(1, "%s()\n", __func__);
++	kfree(fe->tuner_priv);
++	fe->tuner_priv = NULL;
++	return 0;
++}
++
++static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
++	.info = {
++		.name           = "MaxLinear MXL5005S",
++		.frequency_min  =  48000000,
++		.frequency_max  = 860000000,
++		.frequency_step =     50000,
++	},
++
++	.release       = mxl5005s_release,
++	.init          = mxl5005s_init,
++
++	.set_params    = mxl5005s_set_params,
++	.get_frequency = mxl5005s_get_frequency,
++	.get_bandwidth = mxl5005s_get_bandwidth,
++};
++
++struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
++				     struct i2c_adapter *i2c,
++				     struct mxl5005s_config *config)
++{
++	struct mxl5005s_state *state = NULL;
++	dprintk(1, "%s()\n", __func__);
++
++	state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL);
++	if (state == NULL)
++		return NULL;
++
++	state->frontend = fe;
++	state->config = config;
++	state->i2c = i2c;
++	state->current_mode = MXL_QAM;
++
++	printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
++		config->i2c_address);
++
++	memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops,
++		sizeof(struct dvb_tuner_ops));
++
++	fe->tuner_priv = state;
++	return fe;
++}
++EXPORT_SYMBOL(mxl5005s_attach);
++
++MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
++MODULE_AUTHOR("Steven Toth");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
+new file mode 100644
+index 0000000..396db15
+--- /dev/null
++++ b/drivers/media/common/tuners/mxl5005s.h
+@@ -0,0 +1,131 @@
++/*
++    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
++
++    Copyright (C) 2008 MaxLinear
++    Copyright (C) 2008 Steven Toth <stoth at hauppauge.com>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++
++*/
++
++#ifndef __MXL5005S_H
++#define __MXL5005S_H
++
++#include <linux/i2c.h>
++#include "dvb_frontend.h"
++
++struct mxl5005s_config {
++
++	/* 7 bit i2c address */
++	u8 i2c_address;
++
++#define IF_FREQ_4570000HZ    4570000
++#define IF_FREQ_4571429HZ    4571429
++#define IF_FREQ_5380000HZ    5380000
++#define IF_FREQ_36000000HZ  36000000
++#define IF_FREQ_36125000HZ  36125000
++#define IF_FREQ_36166667HZ  36166667
++#define IF_FREQ_44000000HZ  44000000
++	u32 if_freq;
++
++#define CRYSTAL_FREQ_4000000HZ    4000000
++#define CRYSTAL_FREQ_16000000HZ  16000000
++#define CRYSTAL_FREQ_25000000HZ  25000000
++#define CRYSTAL_FREQ_28800000HZ  28800000
++	u32 xtal_freq;
++
++#define MXL_DUAL_AGC   0
++#define MXL_SINGLE_AGC 1
++	u8 agc_mode;
++
++#define MXL_TF_DEFAULT	0
++#define MXL_TF_OFF	1
++#define MXL_TF_C	2
++#define MXL_TF_C_H	3
++#define MXL_TF_D	4
++#define MXL_TF_D_L	5
++#define MXL_TF_E	6
++#define MXL_TF_F	7
++#define MXL_TF_E_2	8
++#define MXL_TF_E_NA	9
++#define MXL_TF_G	10
++	u8 tracking_filter;
++
++#define MXL_RSSI_DISABLE	0
++#define MXL_RSSI_ENABLE		1
++	u8 rssi_enable;
++
++#define MXL_CAP_SEL_DISABLE	0
++#define MXL_CAP_SEL_ENABLE	1
++	u8 cap_select;
++
++#define MXL_DIV_OUT_1	0
++#define MXL_DIV_OUT_4	1
++	u8 div_out;
++
++#define MXL_CLOCK_OUT_DISABLE	0
++#define MXL_CLOCK_OUT_ENABLE	1
++	u8 clock_out;
++
++#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
++#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
++	u32 output_load;
++
++#define MXL5005S_TOP_5P5   55
++#define MXL5005S_TOP_7P2   72
++#define MXL5005S_TOP_9P2   92
++#define MXL5005S_TOP_11P0 110
++#define MXL5005S_TOP_12P9 129
++#define MXL5005S_TOP_14P7 147
++#define MXL5005S_TOP_16P8 168
++#define MXL5005S_TOP_19P4 194
++#define MXL5005S_TOP_21P2 212
++#define MXL5005S_TOP_23P2 232
++#define MXL5005S_TOP_25P2 252
++#define MXL5005S_TOP_27P1 271
++#define MXL5005S_TOP_29P2 292
++#define MXL5005S_TOP_31P7 317
++#define MXL5005S_TOP_34P9 349
++	u32 top;
++
++#define MXL_ANALOG_MODE  0
++#define MXL_DIGITAL_MODE 1
++	u8 mod_mode;
++
++#define MXL_ZERO_IF 0
++#define MXL_LOW_IF  1
++	u8 if_mode;
++
++	/* Stuff I don't know what to do with */
++	u8 AgcMasterByte;
++};
++
++#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
++	(defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
++extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
++					    struct i2c_adapter *i2c,
++					    struct mxl5005s_config *config);
++#else
++static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
++					    struct i2c_adapter *i2c,
++					    struct mxl5005s_config *config)
++{
++	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
++	return NULL;
++}
++#endif /* CONFIG_DVB_TUNER_MXL5005S */
++
++#endif /* __MXL5005S_H */
++
+diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
+index e27a762..42b5f5d 100644
+--- a/drivers/media/common/tuners/tda18271-common.c
++++ b/drivers/media/common/tuners/tda18271-common.c
+@@ -227,9 +227,8 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe,
+ 
+ 	regs[r_cp] &= ~0x20;
+ 	regs[r_cp] |= ((force & 1) << 5);
+-	tda18271_write_regs(fe, r_cp, 1);
+ 
+-	return 0;
++	return tda18271_write_regs(fe, r_cp, 1);
+ }
+ 
+ int tda18271_init_regs(struct dvb_frontend *fe)
+@@ -487,16 +486,15 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe,
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
+ 
+-	tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
++	if (tda18271_debug & DBG_ADV)
++		tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
+ 
+ 	regs[R_EP3]  &= ~0xe0; /* clear sm, sm_lt, sm_xt */
+ 	regs[R_EP3]  |= sm    ? (1 << 7) : 0 |
+ 			sm_lt ? (1 << 6) : 0 |
+ 			sm_xt ? (1 << 5) : 0;
+ 
+-	tda18271_write_regs(fe, R_EP3, 1);
+-
+-	return 0;
++	return tda18271_write_regs(fe, R_EP3, 1);
+ }
+ 
+ /*---------------------------------------------------------------------*/
+@@ -510,7 +508,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
+ 	u32 div;
+ 
+ 	int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_MPD]   = (0x77 & pd);
+@@ -542,7 +540,7 @@ int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
+ 	u32 div;
+ 
+ 	int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_CPD]   = pd;
+@@ -566,7 +564,7 @@ int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
+ 	u8 val;
+ 
+ 	int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
+@@ -583,7 +581,7 @@ int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
+ 	u8 val;
+ 
+ 	int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_EB13] &= ~0x7c; /* clear k & m bits */
+@@ -600,7 +598,7 @@ int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
+ 	u8 val;
+ 
+ 	int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
+@@ -617,7 +615,7 @@ int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
+ 	u8 val;
+ 
+ 	int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
+@@ -634,7 +632,7 @@ int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
+ 	u8 val;
+ 
+ 	int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	regs[R_EP5] &= ~0x07;
+diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
+index b262100..89c01fb 100644
+--- a/drivers/media/common/tuners/tda18271-fe.c
++++ b/drivers/media/common/tuners/tda18271-fe.c
+@@ -51,6 +51,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 	u32 N;
+ 
+ 	/* update TV broadcast parameters */
+@@ -85,7 +86,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
+ 	/* update rf top / if top */
+ 	regs[R_EB22]  = 0x00;
+ 	regs[R_EB22] |= map->rfagc_top;
+-	tda18271_write_regs(fe, R_EB22, 1);
++	ret = tda18271_write_regs(fe, R_EB22, 1);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* --------------------------------------------------------------- */
+ 
+@@ -121,7 +124,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
+ 	/* agc1 has priority on agc2 */
+ 	regs[R_EB1]  &= ~0x01;
+ 
+-	tda18271_write_regs(fe, R_EB1, 1);
++	ret = tda18271_write_regs(fe, R_EB1, 1);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* --------------------------------------------------------------- */
+ 
+@@ -141,7 +146,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
+ 		break;
+ 	}
+ 
+-	tda18271_write_regs(fe, R_TM, 7);
++	ret = tda18271_write_regs(fe, R_TM, 7);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* force charge pump source */
+ 	charge_pump_source(fe, 1);
+@@ -158,9 +165,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
+ 		regs[R_EP3] &= ~0x04;
+ 	else
+ 		regs[R_EP3] |= 0x04;
+-	tda18271_write_regs(fe, R_EP3, 1);
+-
+-	return 0;
++	ret = tda18271_write_regs(fe, R_EP3, 1);
++fail:
++	return ret;
+ }
+ 
+ static int tda18271_read_thermometer(struct dvb_frontend *fe)
+@@ -213,11 +220,13 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
+ 	unsigned char *regs = priv->tda18271_regs;
+-	int tm_current, rfcal_comp, approx, i;
++	int tm_current, rfcal_comp, approx, i, ret;
+ 	u8 dc_over_dt, rf_tab;
+ 
+ 	/* power up */
+-	tda18271_set_standby_mode(fe, 0, 0, 0);
++	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* read die current temperature */
+ 	tm_current = tda18271_read_thermometer(fe);
+@@ -228,8 +237,8 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
+ 	rf_tab = regs[R_EB14];
+ 
+ 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
+-	if (i < 0)
+-		return -EINVAL;
++	if (tda_fail(i))
++		return i;
+ 
+ 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
+ 		approx = map[i].rf_a1 *
+@@ -250,35 +259,42 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
+ 	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
+ 
+ 	regs[R_EB14] = approx + rfcal_comp;
+-	tda18271_write_regs(fe, R_EB14, 1);
+-
+-	return 0;
++	ret = tda18271_write_regs(fe, R_EB14, 1);
++fail:
++	return ret;
+ }
+ 
+ static int tda18271_por(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 
+ 	/* power up detector 1 */
+ 	regs[R_EB12] &= ~0x20;
+-	tda18271_write_regs(fe, R_EB12, 1);
++	ret = tda18271_write_regs(fe, R_EB12, 1);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
+ 	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
+-	tda18271_write_regs(fe, R_EB18, 1);
++	ret = tda18271_write_regs(fe, R_EB18, 1);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
+ 
+ 	/* POR mode */
+-	tda18271_set_standby_mode(fe, 1, 0, 0);
++	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* disable 1.5 MHz low pass filter */
+ 	regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
+ 	regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
+-	tda18271_write_regs(fe, R_EB21, 3);
+-
+-	return 0;
++	ret = tda18271_write_regs(fe, R_EB21, 3);
++fail:
++	return ret;
+ }
+ 
+ static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
+@@ -389,7 +405,7 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
+-	int sgn, bcal, count, wait;
++	int sgn, bcal, count, wait, ret;
+ 	u8 cid_target;
+ 	u16 count_limit;
+ 	u32 freq;
+@@ -421,7 +437,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
+ 	tda18271_write_regs(fe, R_EP2, 1);
+ 
+ 	/* read power detection info, stored in EB10 */
+-	tda18271_read_extended(fe);
++	ret = tda18271_read_extended(fe);
++	if (tda_fail(ret))
++		return ret;
+ 
+ 	/* algorithm initialization */
+ 	sgn = 1;
+@@ -447,7 +465,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
+ 		tda18271_write_regs(fe, R_EP2, 1);
+ 
+ 		/* read power detection info, stored in EB10 */
+-		tda18271_read_extended(fe);
++		ret = tda18271_read_extended(fe);
++		if (tda_fail(ret))
++			return ret;
+ 
+ 		count += 200;
+ 
+@@ -478,6 +498,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 
+ 	/* set standard to digital */
+ 	regs[R_EP3]  &= ~0x1f; /* clear std bits */
+@@ -489,10 +510,14 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
+ 	/* update IF output level & IF notch frequency */
+ 	regs[R_EP4]  &= ~0x1c; /* clear if level bits */
+ 
+-	tda18271_write_regs(fe, R_EP3, 2);
++	ret = tda18271_write_regs(fe, R_EP3, 2);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
+-	tda18271_write_regs(fe, R_EB18, 1);
++	ret = tda18271_write_regs(fe, R_EB18, 1);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
+ 
+@@ -500,9 +525,9 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
+ 	regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
+ 	regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
+ 
+-	tda18271_write_regs(fe, R_EB21, 3);
+-
+-	return 0;
++	ret = tda18271_write_regs(fe, R_EB21, 3);
++fail:
++	return ret;
+ }
+ 
+ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
+@@ -521,7 +546,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
+ 
+ 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
+ 
+-	if (i < 0)
++	if (tda_fail(i))
+ 		return i;
+ 
+ 	rf_default[RF1] = 1000 * map[i].rf1_def;
+@@ -535,6 +560,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
+ 
+ 		/* look for optimized calibration frequency */
+ 		bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
++		if (tda_fail(bcal))
++			return bcal;
+ 
+ 		tda18271_calc_rf_cal(fe, &rf_freq[rf]);
+ 		prog_tab[rf] = regs[R_EB14];
+@@ -575,22 +602,29 @@ static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned int i;
++	int ret;
+ 
+ 	tda_info("tda18271: performing RF tracking filter calibration\n");
+ 
+ 	/* wait for die temperature stabilization */
+ 	msleep(200);
+ 
+-	tda18271_powerscan_init(fe);
++	ret = tda18271_powerscan_init(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* rf band calibration */
+-	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++)
++	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
++		ret =
+ 		tda18271_rf_tracking_filters_init(fe, 1000 *
+ 						  priv->rf_cal_state[i].rfmax);
++		if (tda_fail(ret))
++			goto fail;
++	}
+ 
+ 	priv->tm_rfcal = tda18271_read_thermometer(fe);
+-
+-	return 0;
++fail:
++	return ret;
+ }
+ 
+ /* ------------------------------------------------------------------ */
+@@ -599,6 +633,7 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 
+ 	/* test RF_CAL_OK to see if we need init */
+ 	if ((regs[R_EP1] & 0x10) == 0)
+@@ -607,15 +642,22 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
+ 	if (priv->cal_initialized)
+ 		return 0;
+ 
+-	tda18271_calc_rf_filter_curve(fe);
++	ret = tda18271_calc_rf_filter_curve(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+-	tda18271_por(fe);
++	ret = tda18271_por(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	tda_info("tda18271: RF tracking filter calibration complete\n");
+ 
+ 	priv->cal_initialized = true;
+-
+-	return 0;
++	goto end;
++fail:
++	tda_info("tda18271: RF tracking filter calibration failed!\n");
++end:
++	return ret;
+ }
+ 
+ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
+@@ -623,6 +665,7 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 	u32 N = 0;
+ 
+ 	/* calculate bp filter */
+@@ -671,7 +714,10 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
+ 
+ 	tda18271_calc_main_pll(fe, N);
+ 
+-	tda18271_write_regs(fe, R_EP3, 11);
++	ret = tda18271_write_regs(fe, R_EP3, 11);
++	if (tda_fail(ret))
++		return ret;
++
+ 	msleep(5); /* RF tracking filter calibration initialization */
+ 
+ 	/* search for K,M,CO for RF calibration */
+@@ -719,45 +765,56 @@ static int tda18271_ir_cal_init(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
+ 	unsigned char *regs = priv->tda18271_regs;
++	int ret;
+ 
+-	tda18271_read_regs(fe);
++	ret = tda18271_read_regs(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* test IR_CAL_OK to see if we need init */
+ 	if ((regs[R_EP1] & 0x08) == 0)
+-		tda18271_init_regs(fe);
+-
+-	return 0;
++		ret = tda18271_init_regs(fe);
++fail:
++	return ret;
+ }
+ 
+ static int tda18271_init(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
++	int ret;
+ 
+ 	mutex_lock(&priv->lock);
+ 
+ 	/* power up */
+-	tda18271_set_standby_mode(fe, 0, 0, 0);
++	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	/* initialization */
+-	tda18271_ir_cal_init(fe);
++	ret = tda18271_ir_cal_init(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	if (priv->id == TDA18271HDC2)
+ 		tda18271c2_rf_cal_init(fe);
+-
++fail:
+ 	mutex_unlock(&priv->lock);
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int tda18271_tune(struct dvb_frontend *fe,
+ 			 struct tda18271_std_map_item *map, u32 freq, u32 bw)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
++	int ret;
+ 
+ 	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
+ 		freq, map->if_freq, bw, map->agc_mode, map->std);
+ 
+-	tda18271_init(fe);
++	ret = tda18271_init(fe);
++	if (tda_fail(ret))
++		goto fail;
+ 
+ 	mutex_lock(&priv->lock);
+ 
+@@ -769,11 +826,11 @@ static int tda18271_tune(struct dvb_frontend *fe,
+ 		tda18271c2_rf_tracking_filters_correction(fe, freq);
+ 		break;
+ 	}
+-	tda18271_channel_configuration(fe, map, freq, bw);
++	ret = tda18271_channel_configuration(fe, map, freq, bw);
+ 
+ 	mutex_unlock(&priv->lock);
+-
+-	return 0;
++fail:
++	return ret;
+ }
+ 
+ /* ------------------------------------------------------------------ */
+@@ -837,7 +894,7 @@ static int tda18271_set_params(struct dvb_frontend *fe,
+ 
+ 	ret = tda18271_tune(fe, map, freq, bw);
+ 
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	priv->frequency = freq;
+@@ -893,7 +950,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe,
+ 
+ 	ret = tda18271_tune(fe, map, freq, 0);
+ 
+-	if (ret < 0)
++	if (tda_fail(ret))
+ 		goto fail;
+ 
+ 	priv->frequency = freq;
+@@ -905,16 +962,17 @@ fail:
+ static int tda18271_sleep(struct dvb_frontend *fe)
+ {
+ 	struct tda18271_priv *priv = fe->tuner_priv;
++	int ret;
+ 
+ 	mutex_lock(&priv->lock);
+ 
+ 	/* standby mode w/ slave tuner output
+ 	 * & loop thru & xtal oscillator on */
+-	tda18271_set_standby_mode(fe, 1, 0, 0);
++	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
+ 
+ 	mutex_unlock(&priv->lock);
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int tda18271_release(struct dvb_frontend *fe)
+@@ -1095,10 +1153,10 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
+ 		if (cfg)
+ 			priv->small_i2c = cfg->small_i2c;
+ 
+-		if (tda18271_get_id(fe) < 0)
++		if (tda_fail(tda18271_get_id(fe)))
+ 			goto fail;
+ 
+-		if (tda18271_assign_map_layout(fe) < 0)
++		if (tda_fail(tda18271_assign_map_layout(fe)))
+ 			goto fail;
+ 
+ 		mutex_lock(&priv->lock);
+diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
+index 2bc5eb3..81a7393 100644
+--- a/drivers/media/common/tuners/tda18271-priv.h
++++ b/drivers/media/common/tuners/tda18271-priv.h
+@@ -153,6 +153,15 @@ extern int tda18271_debug;
+ #define tda_reg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_REG,  fmt, ##arg)
+ #define tda_cal(fmt, arg...)  dprintk(KERN_DEBUG, DBG_CAL,  fmt, ##arg)
+ 
++#define tda_fail(ret)							     \
++({									     \
++	int __ret;							     \
++	__ret = (ret < 0);						     \
++	if (__ret)							     \
++		tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
++	__ret;								     \
++})
++
+ /*---------------------------------------------------------------------*/
+ 
+ enum tda18271_map_type {
+diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
+index f6e7d7a..1f56463 100644
+--- a/drivers/media/common/tuners/tea5767.c
++++ b/drivers/media/common/tuners/tea5767.c
+@@ -373,14 +373,14 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
+ 
+ 	if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
+ 		printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
+-		return EINVAL;
++		return -EINVAL;
+ 	}
+ 
+ 	/* If all bytes are the same then it's a TV tuner and not a tea5767 */
+ 	if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
+ 	    buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
+ 		printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
+-		return EINVAL;
++		return -EINVAL;
+ 	}
+ 
+ 	/*  Status bytes:
+@@ -390,7 +390,7 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
+ 	 */
+ 	if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
+ 		printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
+-		return EINVAL;
++		return -EINVAL;
+ 	}
+ 
+ 
+diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
+index 43d35bd..ceae6db 100644
+--- a/drivers/media/common/tuners/xc5000.c
++++ b/drivers/media/common/tuners/xc5000.c
+@@ -212,7 +212,7 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
+ 	dprintk(1, "%s()\n", __func__);
+ 
+ 	if (priv->cfg->tuner_callback) {
+-		ret = priv->cfg->tuner_callback(priv->cfg->priv,
++		ret = priv->cfg->tuner_callback(priv->devptr,
+ 						XC5000_TUNER_RESET, 0);
+ 		if (ret)
+ 			printk(KERN_ERR "xc5000: reset failed\n");
+@@ -900,9 +900,9 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
+ 	.get_status	   = xc5000_get_status
+ };
+ 
+-struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
+-	struct i2c_adapter *i2c,
+-	struct xc5000_config *cfg)
++struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
++				   struct i2c_adapter *i2c,
++				   struct xc5000_config *cfg, void *devptr)
+ {
+ 	struct xc5000_priv *priv = NULL;
+ 	u16 id = 0;
+@@ -916,6 +916,7 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
+ 	priv->cfg = cfg;
+ 	priv->bandwidth = BANDWIDTH_6_MHZ;
+ 	priv->i2c = i2c;
++	priv->devptr = devptr;
+ 
+ 	/* Check if firmware has been loaded. It is possible that another
+ 	   instance of the driver has loaded the firmware.
+diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
+index 0ee80f9..c910715 100644
+--- a/drivers/media/common/tuners/xc5000.h
++++ b/drivers/media/common/tuners/xc5000.h
+@@ -31,29 +31,31 @@ struct xc5000_config {
+ 	u8   i2c_address;
+ 	u32  if_khz;
+ 
+-	/* For each bridge framework, when it attaches either analog or digital,
+-	 * it has to store a reference back to its _core equivalent structure,
+-	 * so that it can service the hardware by steering gpio's etc.
+-	 * Each bridge implementation is different so cast priv accordingly.
+-	 * The xc5000 driver cares not for this value, other than ensuring
+-	 * it's passed back to a bridge during tuner_callback().
+-	 */
+-	void *priv;
+ 	int  (*tuner_callback) (void *priv, int command, int arg);
+ };
+ 
+ /* xc5000 callback command */
+ #define XC5000_TUNER_RESET		0
+ 
++/* For each bridge framework, when it attaches either analog or digital,
++ * it has to store a reference back to its _core equivalent structure,
++ * so that it can service the hardware by steering gpio's etc.
++ * Each bridge implementation is different so cast devptr accordingly.
++ * The xc5000 driver cares not for this value, other than ensuring
++ * it's passed back to a bridge during tuner_callback().
++ */
++
+ #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
+     (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
+ extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+ 					  struct i2c_adapter *i2c,
+-					  struct xc5000_config *cfg);
++					  struct xc5000_config *cfg,
++					  void *devptr);
+ #else
+ static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+ 						 struct i2c_adapter *i2c,
+-						 struct xc5000_config *cfg)
++						 struct xc5000_config *cfg,
++						 void *devptr)
+ {
+ 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ 	return NULL;
+diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
+index 13b2d19..ecebfe4 100644
+--- a/drivers/media/common/tuners/xc5000_priv.h
++++ b/drivers/media/common/tuners/xc5000_priv.h
+@@ -31,6 +31,8 @@ struct xc5000_priv {
+ 	u8  video_standard;
+ 	u8  rf_mode;
+ 	u8  fwloaded;
++
++	void *devptr;
+ };
+ 
+ #endif
+diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+index 7b0ea3b..f9d0876 100644
+--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
++++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+@@ -634,7 +634,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
+ 	}
+ 
+ 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
+-	fc->fe = dvb_attach(vp310_mt312_attach,
++	fc->fe = dvb_attach(mt312_attach,
+ 		&skystar23_samsung_tbdu18132_config, i2c);
+ 	if (fc->fe != NULL) {
+ 		ops = &fc->fe->ops;
+diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
+index d1239b8..7588db1 100644
+--- a/drivers/media/dvb/bt8xx/Kconfig
++++ b/drivers/media/dvb/bt8xx/Kconfig
+@@ -1,6 +1,7 @@
+ config DVB_BT8XX
+ 	tristate "BT8xx based PCI cards"
+ 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select DVB_MT352 if !DVB_FE_CUSTOMISE
+ 	select DVB_SP887X if !DVB_FE_CUSTOMISE
+ 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
+diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
+index 3d778c5..c03513b 100644
+--- a/drivers/media/dvb/cinergyT2/Kconfig
++++ b/drivers/media/dvb/cinergyT2/Kconfig
+@@ -1,6 +1,6 @@
+ config DVB_CINERGYT2
+ 	tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
+-	depends on DVB_CORE && USB
++	depends on DVB_CORE && USB && INPUT
+ 	help
+ 	  Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
+ 
+diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+index 8cbdb0e..588fbe1 100644
+--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
++++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+@@ -910,15 +910,21 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
+ 	int curdelay = 100000000;
+ 	int slot;
+ 
++	/* Beware of too high polling frequency, because one polling
++	 * call might take several hundred milliseconds until timeout!
++	 */
+ 	for (slot = 0; slot < ca->slot_count; slot++) {
+ 		switch (ca->slot_info[slot].slot_state) {
+ 		default:
+ 		case DVB_CA_SLOTSTATE_NONE:
++			delay = HZ * 60;  /* 60s */
++			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
++				delay = HZ * 5;  /* 5s */
++			break;
+ 		case DVB_CA_SLOTSTATE_INVALID:
+-			delay = HZ * 60;
+-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
+-				delay = HZ / 10;
+-			}
++			delay = HZ * 60;  /* 60s */
++			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
++				delay = HZ / 10;  /* 100ms */
+ 			break;
+ 
+ 		case DVB_CA_SLOTSTATE_UNINITIALISED:
+@@ -926,19 +932,17 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
+ 		case DVB_CA_SLOTSTATE_VALIDATE:
+ 		case DVB_CA_SLOTSTATE_WAITFR:
+ 		case DVB_CA_SLOTSTATE_LINKINIT:
+-			delay = HZ / 10;
++			delay = HZ / 10;  /* 100ms */
+ 			break;
+ 
+ 		case DVB_CA_SLOTSTATE_RUNNING:
+-			delay = HZ * 60;
+-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
+-				delay = HZ / 10;
+-			}
++			delay = HZ * 60;  /* 60s */
++			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
++				delay = HZ / 10;  /* 100ms */
+ 			if (ca->open) {
+ 				if ((!ca->slot_info[slot].da_irq_supported) ||
+-				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
+-					delay = HZ / 10;
+-				}
++				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
++					delay = HZ / 10;  /* 100ms */
+ 			}
+ 			break;
+ 		}
+diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
+index 4c1cff9..cf4584e 100644
+--- a/drivers/media/dvb/dvb-usb/Kconfig
++++ b/drivers/media/dvb/dvb-usb/Kconfig
+@@ -1,6 +1,7 @@
+ config DVB_USB
+ 	tristate "Support for various USB DVB devices"
+ 	depends on DVB_CORE && USB && I2C
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select FW_LOADER
+ 	help
+ 	  By enabling this you will be able to choose the various supported
+diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
+index 6d23846..c20553c 100644
+--- a/drivers/media/dvb/frontends/Kconfig
++++ b/drivers/media/dvb/frontends/Kconfig
+@@ -30,7 +30,7 @@ config DVB_CX24123
+ 	  A DVB-S tuner module. Say Y when you want to support this frontend.
+ 
+ config DVB_MT312
+-	tristate "Zarlink VP310/MT312 based"
++	tristate "Zarlink VP310/MT312/ZL10313 based"
+ 	depends on DVB_CORE && I2C
+ 	default m if DVB_FE_CUSTOMISE
+ 	help
+@@ -97,7 +97,7 @@ comment "DVB-T (terrestrial) frontends"
+ 
+ config DVB_SP8870
+ 	tristate "Spase sp8870 based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -110,7 +110,7 @@ config DVB_SP8870
+ 
+ config DVB_SP887X
+ 	tristate "Spase sp887x based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -144,7 +144,7 @@ config DVB_L64781
+ 
+ config DVB_TDA1004X
+ 	tristate "Philips TDA10045H/TDA10046H based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -211,7 +211,7 @@ config DVB_DIB7000P
+ 
+ config DVB_TDA10048
+ 	tristate "Philips TDA10048HN based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -253,7 +253,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
+ 
+ config DVB_NXT200X
+ 	tristate "NxtWave Communications NXT2002/NXT2004 based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -268,7 +268,7 @@ config DVB_NXT200X
+ 
+ config DVB_OR51211
+ 	tristate "Oren OR51211 based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -281,7 +281,7 @@ config DVB_OR51211
+ 
+ config DVB_OR51132
+ 	tristate "Oren OR51132 based"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+@@ -297,7 +297,7 @@ config DVB_OR51132
+ 
+ config DVB_BCM3510
+ 	tristate "Broadcom BCM3510"
+-	depends on DVB_CORE && I2C
++	depends on DVB_CORE && I2C && HOTPLUG
+ 	default m if DVB_FE_CUSTOMISE
+ 	select FW_LOADER
+ 	help
+diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
+index 04c562c..600dad6 100644
+--- a/drivers/media/dvb/frontends/itd1000.c
++++ b/drivers/media/dvb/frontends/itd1000.c
+@@ -195,7 +195,7 @@ static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
+ 	}
+ }
+ 
+-struct {
++static const struct {
+ 	u32 freq;
+ 	u8 values[10]; /* RFTR, RFST1 - RFST9 */
+ } itd1000_fre_values[] = {
+diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
+index 081ca33..5ac9b15 100644
+--- a/drivers/media/dvb/frontends/mt312.c
++++ b/drivers/media/dvb/frontends/mt312.c
+@@ -737,7 +737,7 @@ static void mt312_release(struct dvb_frontend *fe)
+ }
+ 
+ #define MT312_SYS_CLK		90000000UL	/* 90 MHz */
+-static struct dvb_frontend_ops vp310_mt312_ops = {
++static struct dvb_frontend_ops mt312_ops = {
+ 
+ 	.info = {
+ 		.name = "Zarlink ???? DVB-S",
+@@ -776,7 +776,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
+ 	.set_voltage = mt312_set_voltage,
+ };
+ 
+-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
++struct dvb_frontend *mt312_attach(const struct mt312_config *config,
+ 					struct i2c_adapter *i2c)
+ {
+ 	struct mt312_state *state = NULL;
+@@ -795,7 +795,7 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+ 		goto error;
+ 
+ 	/* create dvb_frontend */
+-	memcpy(&state->frontend.ops, &vp310_mt312_ops,
++	memcpy(&state->frontend.ops, &mt312_ops,
+ 		sizeof(struct dvb_frontend_ops));
+ 	state->frontend.demodulator_priv = state;
+ 
+@@ -827,12 +827,13 @@ error:
+ 	kfree(state);
+ 	return NULL;
+ }
+-EXPORT_SYMBOL(vp310_mt312_attach);
++EXPORT_SYMBOL(mt312_attach);
+ 
+ module_param(debug, int, 0644);
+ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+ 
+ MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
+ MODULE_AUTHOR("Andreas Oberritter <obi at linuxtv.org>");
++MODULE_AUTHOR("Matthias Schwarzott <zzam at gentoo.org>");
+ MODULE_LICENSE("GPL");
+ 
+diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
+index de796ea..29e3bb5 100644
+--- a/drivers/media/dvb/frontends/mt312.h
++++ b/drivers/media/dvb/frontends/mt312.h
+@@ -37,10 +37,10 @@ struct mt312_config {
+ };
+ 
+ #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
+-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
++struct dvb_frontend *mt312_attach(const struct mt312_config *config,
+ 					struct i2c_adapter *i2c);
+ #else
+-static inline struct dvb_frontend *vp310_mt312_attach(
++static inline struct dvb_frontend *mt312_attach(
+ 	const struct mt312_config *config, struct i2c_adapter *i2c)
+ {
+ 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
+index ae88243..d4339b1 100644
+--- a/drivers/media/dvb/ttpci/Kconfig
++++ b/drivers/media/dvb/ttpci/Kconfig
+@@ -5,6 +5,7 @@ config TTPCI_EEPROM
+ config DVB_AV7110
+ 	tristate "AV7110 cards"
+ 	depends on DVB_CORE && PCI && I2C
++	depends on HOTPLUG
+ 	select FW_LOADER if !DVB_AV7110_FIRMWARE
+ 	select TTPCI_EEPROM
+ 	select VIDEO_SAA7146_VV
+@@ -123,6 +124,7 @@ config DVB_BUDGET_AV
+ 	depends on DVB_BUDGET_CORE && I2C
+ 	select VIDEO_SAA7146_VV
+ 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
++	depends on HOTPLUG	# dependency of FW_LOADER
+ 	select DVB_PLL if !DVB_FE_CUSTOMISE
+ 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
+index 8361101..0712899 100644
+--- a/drivers/media/dvb/ttusb-dec/Kconfig
++++ b/drivers/media/dvb/ttusb-dec/Kconfig
+@@ -1,6 +1,7 @@
+ config DVB_TTUSB_DEC
+ 	tristate "Technotrend/Hauppauge USB DEC devices"
+ 	depends on DVB_CORE && USB
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select FW_LOADER
+ 	select CRC32
+ 	help
+diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
+index fe743aa..89d8d37 100644
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -44,6 +44,10 @@ config VIDEO_TVEEPROM
+ 	tristate
+ 	depends on I2C
+ 
++config VIDEO_TUNER
++	tristate
++	depends on MEDIA_TUNER
++
+ #
+ # Multimedia Video device configuration
+ #
+@@ -690,7 +694,7 @@ config VIDEO_MXB
+ 	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
+ 	depends on PCI && VIDEO_V4L1 && I2C
+ 	select VIDEO_SAA7146_VV
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+ 	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
+ 	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
+@@ -906,7 +910,7 @@ config SOC_CAMERA
+ 
+ config SOC_CAMERA_MT9M001
+ 	tristate "mt9m001 support"
+-	depends on SOC_CAMERA
++	depends on SOC_CAMERA && I2C
+ 	select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
+ 	help
+ 	  This driver supports MT9M001 cameras from Micron, monochrome
+@@ -921,7 +925,7 @@ config MT9M001_PCA9536_SWITCH
+ 
+ config SOC_CAMERA_MT9V022
+ 	tristate "mt9v022 support"
+-	depends on SOC_CAMERA
++	depends on SOC_CAMERA && I2C
+ 	select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
+ 	help
+ 	  This driver supports MT9V022 cameras from Micron
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index a352c6e..dff0d6a 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -84,7 +84,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
+ obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
+ obj-$(CONFIG_TUNER_3036) += tuner-3036.o
+ 
+-obj-$(CONFIG_MEDIA_TUNER) += tuner.o
++obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+ 
+ obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
+ obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
+index cab277f..def10d0 100644
+--- a/drivers/media/video/au0828/Kconfig
++++ b/drivers/media/video/au0828/Kconfig
+@@ -1,8 +1,9 @@
+ 
+ config VIDEO_AU0828
+ 	tristate "Auvitek AU0828 support"
+-       depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
++	depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB
+ 	select I2C_ALGOBIT
++	select VIDEO_TVEEPROM
+ 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
+ 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+ 	---help---
+diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
+index 1371b4e..c86a5f1 100644
+--- a/drivers/media/video/au0828/au0828-dvb.c
++++ b/drivers/media/video/au0828/au0828-dvb.c
+@@ -337,12 +337,10 @@ int au0828_dvb_register(struct au0828_dev *dev)
+ 		dvb->frontend = dvb_attach(au8522_attach,
+ 				&hauppauge_hvr950q_config,
+ 				&dev->i2c_adap);
+-		if (dvb->frontend != NULL) {
+-			hauppauge_hvr950q_tunerconfig.priv = dev;
++		if (dvb->frontend != NULL)
+ 			dvb_attach(xc5000_attach, dvb->frontend,
+ 				&dev->i2c_adap,
+-				&hauppauge_hvr950q_tunerconfig);
+-		}
++				&hauppauge_hvr950q_tunerconfig, dev);
+ 		break;
+ 	default:
+ 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
+diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
+index 7431ef6..24a34fc 100644
+--- a/drivers/media/video/bt8xx/Kconfig
++++ b/drivers/media/video/bt8xx/Kconfig
+@@ -1,12 +1,13 @@
+ config VIDEO_BT848
+ 	tristate "BT848 Video For Linux"
+ 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select I2C_ALGOBIT
+ 	select FW_LOADER
+ 	select VIDEO_BTCX
+ 	select VIDEOBUF_DMA_SG
+ 	select VIDEO_IR
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
+ 	select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
+diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
+index acc4b47..5f94269 100644
+--- a/drivers/media/video/cx18/Kconfig
++++ b/drivers/media/video/cx18/Kconfig
+@@ -1,14 +1,17 @@
+ config VIDEO_CX18
+ 	tristate "Conexant cx23418 MPEG encoder support"
+ 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
++	depends on INPUT	# due to VIDEO_IR
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select I2C_ALGOBIT
+ 	select FW_LOADER
+ 	select VIDEO_IR
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_CX2341X
+ 	select VIDEO_CS5345
+ 	select DVB_S5H1409
++	select MEDIA_TUNER_MXL5005S
+ 	---help---
+ 	  This is a video4linux driver for Conexant cx23418 based
+ 	  PCI combo video recorder devices.
+diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
+index f5e3ba1..553adbf 100644
+--- a/drivers/media/video/cx18/cx18-cards.c
++++ b/drivers/media/video/cx18/cx18-cards.c
+@@ -47,11 +47,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
+ static const struct cx18_card cx18_card_hvr1600_esmt = {
+ 	.type = CX18_CARD_HVR_1600_ESMT,
+ 	.name = "Hauppauge HVR-1600",
+-	.comment = "DVB & VBI are not yet supported\n",
++	.comment = "VBI is not yet supported\n",
+ 	.v4l2_capabilities = CX18_CAP_ENCODER,
+ 	.hw_audio_ctrl = CX18_HW_CX23418,
+ 	.hw_muxer = CX18_HW_CS5345,
+-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
++	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
++		  CX18_HW_CS5345 | CX18_HW_DVB,
+ 	.video_inputs = {
+ 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
+ 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
+@@ -86,11 +87,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
+ static const struct cx18_card cx18_card_hvr1600_samsung = {
+ 	.type = CX18_CARD_HVR_1600_SAMSUNG,
+ 	.name = "Hauppauge HVR-1600 (Preproduction)",
+-	.comment = "DVB & VBI are not yet supported\n",
++	.comment = "VBI is not yet supported\n",
+ 	.v4l2_capabilities = CX18_CAP_ENCODER,
+ 	.hw_audio_ctrl = CX18_HW_CX23418,
+ 	.hw_muxer = CX18_HW_CS5345,
+-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
++	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
++		  CX18_HW_CS5345 | CX18_HW_DVB,
+ 	.video_inputs = {
+ 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
+ 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
+@@ -134,14 +136,15 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
+ static const struct cx18_card cx18_card_h900 = {
+ 	.type = CX18_CARD_COMPRO_H900,
+ 	.name = "Compro VideoMate H900",
+-	.comment = "Not yet supported!\n",
+-	.v4l2_capabilities = 0,
++	.comment = "DVB & VBI are not yet supported\n",
++	.v4l2_capabilities = CX18_CAP_ENCODER,
+ 	.hw_audio_ctrl = CX18_HW_CX23418,
+ 	.hw_all = CX18_HW_TUNER,
+ 	.video_inputs = {
+-		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
+-		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
+-		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
++		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE2 },
++		{ CX18_CARD_INPUT_SVIDEO1,    1,
++			CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
++		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
+ 	},
+ 	.audio_inputs = {
+ 		{ CX18_CARD_INPUT_AUD_TUNER,
+@@ -163,6 +166,7 @@ static const struct cx18_card cx18_card_h900 = {
+ 		.tune_lane = 0,
+ 		.initial_emrs = 0,
+ 	},
++	.xceive_pin = 15,
+ 	.pci_list = cx18_pci_h900,
+ 	.i2c = &cx18_i2c_std,
+ };
+@@ -200,8 +204,6 @@ static const struct cx18_card cx18_card_mpc718 = {
+ 		/* XC3028 tuner */
+ 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+ 	},
+-	/* tuner reset */
+-	.gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
+ 	.ddr = {
+ 		/* Probably Samsung K4D263238G-VC33 memory */
+ 		.chip_config = 0x003,
+@@ -211,6 +213,7 @@ static const struct cx18_card cx18_card_mpc718 = {
+ 		.tune_lane = 0,
+ 		.initial_emrs = 2,
+ 	},
++	.xceive_pin = 15,
+ 	.pci_list = cx18_pci_mpc718,
+ 	.i2c = &cx18_i2c_std,
+ };
+diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
+index bca249b..bccb67f 100644
+--- a/drivers/media/video/cx18/cx18-cards.h
++++ b/drivers/media/video/cx18/cx18-cards.h
+@@ -114,8 +114,8 @@ struct cx18_card_pci_info {
+ /* The mask is the set of bits used by the operation */
+ 
+ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
+-	u16 direction; 	/* DIR setting. Leave to 0 if no init is needed */
+-	u16 initial_value;
++	u32 direction; 	/* DIR setting. Leave to 0 if no init is needed */
++	u32 initial_value;
+ };
+ 
+ struct cx18_card_tuner {
+@@ -153,6 +153,7 @@ struct cx18_card {
+ 	struct cx18_card_audio_input radio_input;
+ 
+ 	/* GPIO card-specific settings */
++	u8 xceive_pin; 		/* XCeive tuner GPIO reset pin */
+ 	struct cx18_gpio_init 		gpio_init;
+ 
+ 	struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
+diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
+index 3f55d47..0dd4e05 100644
+--- a/drivers/media/video/cx18/cx18-driver.c
++++ b/drivers/media/video/cx18/cx18-driver.c
+@@ -164,16 +164,6 @@ MODULE_LICENSE("GPL");
+ 
+ MODULE_VERSION(CX18_VERSION);
+ 
+-int cx18_waitq(wait_queue_head_t *waitq)
+-{
+-	DEFINE_WAIT(wait);
+-
+-	prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
+-	schedule();
+-	finish_wait(waitq, &wait);
+-	return signal_pending(current) ? -EINTR : 0;
+-}
+-
+ /* Generic utility functions */
+ int cx18_msleep_timeout(unsigned int msecs, int intr)
+ {
+@@ -220,13 +210,13 @@ static void cx18_process_eeprom(struct cx18 *cx)
+ 
+ 	/* Many thanks to Steven Toth from Hauppauge for providing the
+ 	   model numbers */
++	/* Note: the Samsung memory models cannot be reliably determined
++	   from the model number. Use the cardtype module option if you
++	   have one of these preproduction models. */
+ 	switch (tv.model) {
+-	case 74000 ... 74099:
++	case 74000 ... 74999:
+ 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
+ 		break;
+-	case 74700 ... 74799:
+-		cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
+-		break;
+ 	case 0:
+ 		CX18_ERR("Invalid EEPROM\n");
+ 		return;
+@@ -548,6 +538,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
+ 	return 0;
+ }
+ 
++#ifdef MODULE
+ static u32 cx18_request_module(struct cx18 *cx, u32 hw,
+ 		const char *name, u32 id)
+ {
+@@ -560,12 +551,14 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw,
+ 	CX18_DEBUG_INFO("Loaded module %s\n", name);
+ 	return hw;
+ }
++#endif
+ 
+ static void cx18_load_and_init_modules(struct cx18 *cx)
+ {
+ 	u32 hw = cx->card->hw_all;
+ 	int i;
+ 
++#ifdef MODULE
+ 	/* load modules */
+ #ifndef CONFIG_MEDIA_TUNER
+ 	hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
+@@ -573,6 +566,7 @@ static void cx18_load_and_init_modules(struct cx18 *cx)
+ #ifndef CONFIG_VIDEO_CS5345
+ 	hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
+ #endif
++#endif
+ 
+ 	/* check which i2c devices are actually found */
+ 	for (i = 0; i < 32; i++) {
+@@ -801,7 +795,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
+ 	return 0;
+ 
+ free_streams:
+-	cx18_streams_cleanup(cx);
++	cx18_streams_cleanup(cx, 1);
+ free_irq:
+ 	free_irq(cx->dev->irq, (void *)cx);
+ free_i2c:
+@@ -904,14 +898,13 @@ static void cx18_remove(struct pci_dev *pci_dev)
+ 
+ 	cx18_halt_firmware(cx);
+ 
+-	cx18_streams_cleanup(cx);
++	cx18_streams_cleanup(cx, 1);
+ 
+ 	exit_cx18_i2c(cx);
+ 
+ 	free_irq(cx->dev->irq, (void *)cx);
+ 
+-	if (cx->dev)
+-		cx18_iounmap(cx);
++	cx18_iounmap(cx);
+ 
+ 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
+ 
+diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
+index 2ee9391..a2a6c58 100644
+--- a/drivers/media/video/cx18/cx18-driver.h
++++ b/drivers/media/video/cx18/cx18-driver.h
+@@ -444,9 +444,6 @@ extern spinlock_t cx18_cards_lock;
+ /* Return non-zero if a signal is pending */
+ int cx18_msleep_timeout(unsigned int msecs, int intr);
+ 
+-/* Wait on queue, returns -EINTR if interrupted */
+-int cx18_waitq(wait_queue_head_t *waitq);
+-
+ /* Read Hauppauge eeprom */
+ struct tveeprom; /* forward reference */
+ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
+diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
+index 65efe69..c974417 100644
+--- a/drivers/media/video/cx18/cx18-dvb.c
++++ b/drivers/media/video/cx18/cx18-dvb.c
+@@ -24,25 +24,27 @@
+ #include "cx18-streams.h"
+ #include "cx18-cards.h"
+ #include "s5h1409.h"
+-
+-/* Wait until the MXL500X driver is merged */
+-#ifdef HAVE_MXL500X
+-#include "mxl500x.h"
+-#endif
++#include "mxl5005s.h"
+ 
+ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+ 
+ #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
+ 
+-#ifdef HAVE_MXL500X
+-static struct mxl500x_config hauppauge_hvr1600_tuner = {
+-	.delsys    = MXL500x_MODE_ATSC,
+-	.octf      = MXL500x_OCTF_CH,
+-	.xtal_freq = 16000000,
+-	.iflo_freq = 5380000,
+-	.ref_freq  = 322800000,
+-	.rssi_ena  = MXL_RSSI_ENABLE,
+-	.addr      = 0xC6 >> 1,
++static struct mxl5005s_config hauppauge_hvr1600_tuner = {
++	.i2c_address     = 0xC6 >> 1,
++	.if_freq         = IF_FREQ_5380000HZ,
++	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
++	.agc_mode        = MXL_SINGLE_AGC,
++	.tracking_filter = MXL_TF_C_H,
++	.rssi_enable     = MXL_RSSI_ENABLE,
++	.cap_select      = MXL_CAP_SEL_ENABLE,
++	.div_out         = MXL_DIV_OUT_4,
++	.clock_out       = MXL_CLOCK_OUT_DISABLE,
++	.output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
++	.top		 = MXL5005S_TOP_25P2,
++	.mod_mode        = MXL_DIGITAL_MODE,
++	.if_mode         = MXL_ZERO_IF,
++	.AgcMasterByte   = 0x00,
+ };
+ 
+ static struct s5h1409_config hauppauge_hvr1600_config = {
+@@ -55,7 +57,6 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
+ 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+ 
+ };
+-#endif
+ 
+ static int dvb_register(struct cx18_stream *stream);
+ 
+@@ -252,21 +253,18 @@ static int dvb_register(struct cx18_stream *stream)
+ 	int ret = 0;
+ 
+ 	switch (cx->card->type) {
+-/* Wait until the MXL500X driver is merged */
+-#ifdef HAVE_MXL500X
+ 	case CX18_CARD_HVR_1600_ESMT:
+ 	case CX18_CARD_HVR_1600_SAMSUNG:
+ 		dvb->fe = dvb_attach(s5h1409_attach,
+ 			&hauppauge_hvr1600_config,
+ 			&cx->i2c_adap[0]);
+ 		if (dvb->fe != NULL) {
+-			dvb_attach(mxl500x_attach, dvb->fe,
+-				&hauppauge_hvr1600_tuner,
+-				&cx->i2c_adap[0]);
++			dvb_attach(mxl5005s_attach, dvb->fe,
++				&cx->i2c_adap[0],
++				&hauppauge_hvr1600_tuner);
+ 			ret = 0;
+ 		}
+ 		break;
+-#endif
+ 	default:
+ 		/* No Digital Tv Support */
+ 		break;
+diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
+index 6930306..0b3141d 100644
+--- a/drivers/media/video/cx18/cx18-fileops.c
++++ b/drivers/media/video/cx18/cx18-fileops.c
+@@ -39,7 +39,7 @@
+    associated VBI streams are also automatically claimed.
+    Possible error returns: -EBUSY if someone else has claimed
+    the stream or 0 on success. */
+-int cx18_claim_stream(struct cx18_open_id *id, int type)
++static int cx18_claim_stream(struct cx18_open_id *id, int type)
+ {
+ 	struct cx18 *cx = id->cx;
+ 	struct cx18_stream *s = &cx->streams[type];
+@@ -87,7 +87,7 @@ int cx18_claim_stream(struct cx18_open_id *id, int type)
+ 
+ /* This function releases a previously claimed stream. It will take into
+    account associated VBI streams. */
+-void cx18_release_stream(struct cx18_stream *s)
++static void cx18_release_stream(struct cx18_stream *s)
+ {
+ 	struct cx18 *cx = s->cx;
+ 	struct cx18_stream *s_vbi;
+@@ -662,6 +662,8 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)
+ 	for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
+ 		/* find out which stream this open was on */
+ 		for (y = 0; y < CX18_MAX_STREAMS; y++) {
++			if (cx18_cards[x] == NULL)
++				continue;
+ 			s = &cx18_cards[x]->streams[y];
+ 			if (s->v4l2dev && s->v4l2dev->minor == minor) {
+ 				cx = cx18_cards[x];
+diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
+index 16cdafb..46da028 100644
+--- a/drivers/media/video/cx18/cx18-fileops.h
++++ b/drivers/media/video/cx18/cx18-fileops.h
+@@ -34,12 +34,3 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
+ void cx18_mute(struct cx18 *cx);
+ void cx18_unmute(struct cx18 *cx);
+ 
+-/* Utilities */
+-
+-/* Try to claim a stream for the filehandle. Return 0 on success,
+-   -EBUSY if stream already claimed. Once a stream is claimed, it
+-   remains claimed until the associated filehandle is closed. */
+-int cx18_claim_stream(struct cx18_open_id *id, int type);
+-
+-/* Release a previously claimed stream. */
+-void cx18_release_stream(struct cx18_stream *s);
+diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
+index 19253e6..bb8bc86 100644
+--- a/drivers/media/video/cx18/cx18-gpio.c
++++ b/drivers/media/video/cx18/cx18-gpio.c
+@@ -35,6 +35,9 @@
+ #define CX18_REG_GPIO_OUT2   0xc78104
+ #define CX18_REG_GPIO_DIR2   0xc7810c
+ 
++static u32 gpio_dir;
++static u32 gpio_val;
++
+ /*
+  * HVR-1600 GPIO pins, courtesy of Hauppauge:
+  *
+@@ -44,31 +47,53 @@
+  * gpio13: cs5345 reset pin
+ */
+ 
++static void gpio_write(struct cx18 *cx)
++{
++	write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
++	write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff),
++			CX18_REG_GPIO_OUT1);
++	write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2);
++	write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16),
++			CX18_REG_GPIO_OUT2);
++}
++
+ void cx18_gpio_init(struct cx18 *cx)
+ {
+-	if (cx->card->gpio_init.direction == 0)
++	gpio_dir = cx->card->gpio_init.direction;
++	gpio_val = cx->card->gpio_init.initial_value;
++
++	if (gpio_dir == 0)
+ 		return;
+ 
+-	CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
+-		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
++	gpio_dir |= 1 << cx->card->xceive_pin;
++	gpio_val |= 1 << cx->card->xceive_pin;
+ 
+-	/* init output data then direction */
+-	write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
+-	write_reg(0, CX18_REG_GPIO_DIR2);
+-	write_reg((cx->card->gpio_init.direction << 16) |
+-			cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
+-	write_reg(0, CX18_REG_GPIO_OUT2);
++	CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
++		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
++		   read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
++
++	gpio_write(cx);
+ }
+ 
+ /* Xceive tuner reset function */
+ int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
+ {
+ 	struct i2c_algo_bit_data *algo = dev;
+-	struct cx18 *cx = algo->data;
+-/*	int curdir, curout;*/
++	struct cx18_i2c_algo_callback_data *cb_data = algo->data;
++	struct cx18 *cx = cb_data->cx;
+ 
+ 	if (cmd != XC2028_TUNER_RESET)
+ 		return 0;
+ 	CX18_DEBUG_INFO("Resetting tuner\n");
++
++	gpio_dir |= 1 << cx->card->xceive_pin;
++	gpio_val &= ~(1 << cx->card->xceive_pin);
++
++	gpio_write(cx);
++	schedule_timeout_interruptible(msecs_to_jiffies(1));
++
++	gpio_val |= 1 << cx->card->xceive_pin;
++	gpio_write(cx);
++	schedule_timeout_interruptible(msecs_to_jiffies(1));
+ 	return 0;
+ }
+diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
+index 18c88d1..4f08a40 100644
+--- a/drivers/media/video/cx18/cx18-i2c.c
++++ b/drivers/media/video/cx18/cx18-i2c.c
+@@ -25,6 +25,7 @@
+ #include "cx18-cards.h"
+ #include "cx18-gpio.h"
+ #include "cx18-av-core.h"
++#include "cx18-i2c.h"
+ 
+ #include <media/ir-kbd-i2c.h>
+ 
+diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
+index 65af1bb..6990b77 100644
+--- a/drivers/media/video/cx18/cx18-queue.c
++++ b/drivers/media/video/cx18/cx18-queue.c
+@@ -26,17 +26,6 @@
+ #include "cx18-queue.h"
+ #include "cx18-scb.h"
+ 
+-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
+-		const char __user *src, int copybytes)
+-{
+-	if (s->buf_size - buf->bytesused < copybytes)
+-		copybytes = s->buf_size - buf->bytesused;
+-	if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
+-		return -EFAULT;
+-	buf->bytesused += copybytes;
+-	return copybytes;
+-}
+-
+ void cx18_buf_swap(struct cx18_buffer *buf)
+ {
+ 	int i;
+@@ -159,8 +148,9 @@ static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
+    -ENOMEM is returned if the buffers could not be obtained, 0 if all
+    buffers where obtained from the 'from' list and if non-zero then
+    the number of stolen buffers is returned. */
+-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
+-	struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
++static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
++			   struct cx18_queue *steal, struct cx18_queue *to,
++			   int needed_bytes)
+ {
+ 	unsigned long flags;
+ 	int rc = 0;
+@@ -239,12 +229,12 @@ int cx18_stream_alloc(struct cx18_stream *s)
+ 
+ 	/* allocate stream buffers. Initially all buffers are in q_free. */
+ 	for (i = 0; i < s->buffers; i++) {
+-		struct cx18_buffer *buf =
+-			kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
++		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
++						GFP_KERNEL|__GFP_NOWARN);
+ 
+ 		if (buf == NULL)
+ 			break;
+-		buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
++		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
+ 		if (buf->buf == NULL) {
+ 			kfree(buf);
+ 			break;
+diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
+index f86c8a6..91423b9 100644
+--- a/drivers/media/video/cx18/cx18-queue.h
++++ b/drivers/media/video/cx18/cx18-queue.h
+@@ -39,8 +39,6 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
+ 				s->buf_size, s->dma);
+ }
+ 
+-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
+-	const char __user *src, int copybytes);
+ void cx18_buf_swap(struct cx18_buffer *buf);
+ 
+ /* cx18_queue utility functions */
+@@ -48,8 +46,6 @@ void cx18_queue_init(struct cx18_queue *q);
+ void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
+ 	struct cx18_queue *q);
+ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
+-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
+-       struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
+ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
+ 	u32 bytesused);
+ void cx18_flush_queues(struct cx18_stream *s);
+diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
+index afb141b..4ca9d84 100644
+--- a/drivers/media/video/cx18/cx18-streams.c
++++ b/drivers/media/video/cx18/cx18-streams.c
+@@ -218,7 +218,7 @@ int cx18_streams_setup(struct cx18 *cx)
+ 		return 0;
+ 
+ 	/* One or more streams could not be initialized. Clean 'em all up. */
+-	cx18_streams_cleanup(cx);
++	cx18_streams_cleanup(cx, 0);
+ 	return -ENOMEM;
+ }
+ 
+@@ -296,12 +296,12 @@ int cx18_streams_register(struct cx18 *cx)
+ 		return 0;
+ 
+ 	/* One or more streams could not be initialized. Clean 'em all up. */
+-	cx18_streams_cleanup(cx);
++	cx18_streams_cleanup(cx, 1);
+ 	return -ENOMEM;
+ }
+ 
+ /* Unregister v4l2 devices */
+-void cx18_streams_cleanup(struct cx18 *cx)
++void cx18_streams_cleanup(struct cx18 *cx, int unregister)
+ {
+ 	struct video_device *vdev;
+ 	int type;
+@@ -319,8 +319,11 @@ void cx18_streams_cleanup(struct cx18 *cx)
+ 
+ 		cx18_stream_free(&cx->streams[type]);
+ 
+-		/* Unregister device */
+-		video_unregister_device(vdev);
++		/* Unregister or release device */
++		if (unregister)
++			video_unregister_device(vdev);
++		else
++			video_device_release(vdev);
+ 	}
+ }
+ 
+diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
+index 8c7ba7d..f327e94 100644
+--- a/drivers/media/video/cx18/cx18-streams.h
++++ b/drivers/media/video/cx18/cx18-streams.h
+@@ -24,7 +24,7 @@
+ u32 cx18_find_handle(struct cx18 *cx);
+ int cx18_streams_setup(struct cx18 *cx);
+ int cx18_streams_register(struct cx18 *cx);
+-void cx18_streams_cleanup(struct cx18 *cx);
++void cx18_streams_cleanup(struct cx18 *cx, int unregister);
+ 
+ /* Capture related */
+ int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
+diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
+index cadf936..7bf14c9 100644
+--- a/drivers/media/video/cx23885/Kconfig
++++ b/drivers/media/video/cx23885/Kconfig
+@@ -1,18 +1,20 @@
+ config VIDEO_CX23885
+ 	tristate "Conexant cx23885 (2388x successor) support"
+ 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select I2C_ALGOBIT
+ 	select FW_LOADER
+ 	select VIDEO_BTCX
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_IR
+ 	select VIDEOBUF_DVB
+ 	select VIDEO_CX25840
++	select VIDEO_CX2341X
++	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ 	select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
+ 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+ 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+-	select DVB_PLL if !DVB_FE_CUSTOMISE
+ 	select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
+ 	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
+ 	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
+diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
+index 6ebf587..20e05f2 100644
+--- a/drivers/media/video/cx23885/cx23885-cards.c
++++ b/drivers/media/video/cx23885/cx23885-cards.c
+@@ -200,6 +200,10 @@ struct cx23885_subid cx23885_subids[] = {
+ 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
+ 	}, {
+ 		.subvendor = 0x0070,
++		.subdevice = 0x71d3,
++		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
++	}, {
++		.subvendor = 0x0070,
+ 		.subdevice = 0x8101,
+ 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1700,
+ 	}, {
+@@ -245,6 +249,33 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
+ 	/* Make sure we support the board model */
+ 	switch (tv.model)
+ 	{
++	case 71009:
++		/* WinTV-HVR1200 (PCIe, Retail, full height)
++		 * DVB-T and basic analog */
++	case 71359:
++		/* WinTV-HVR1200 (PCIe, OEM, half height)
++		 * DVB-T and basic analog */
++	case 71439:
++		/* WinTV-HVR1200 (PCIe, OEM, half height)
++		 * DVB-T and basic analog */
++	case 71449:
++		/* WinTV-HVR1200 (PCIe, OEM, full height)
++		 * DVB-T and basic analog */
++	case 71939:
++		/* WinTV-HVR1200 (PCIe, OEM, half height)
++		 * DVB-T and basic analog */
++	case 71949:
++		/* WinTV-HVR1200 (PCIe, OEM, full height)
++		 * DVB-T and basic analog */
++	case 71959:
++		/* WinTV-HVR1200 (PCIe, OEM, full height)
++		 * DVB-T and basic analog */
++	case 71979:
++		/* WinTV-HVR1200 (PCIe, OEM, half height)
++		 * DVB-T and basic analog */
++	case 71999:
++		/* WinTV-HVR1200 (PCIe, OEM, full height)
++		 * DVB-T and basic analog */
+ 	case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
+ 	case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
+ 	case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
+@@ -263,8 +294,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
+ 	case 80019:
+ 		/* WinTV-HVR1400 (Express Card, Retail, IR,
+ 		 * DVB-T and Basic analog */
++	case 81509:
++		/* WinTV-HVR1700 (PCIe, OEM, No IR, half height)
++		 * DVB-T and MPEG2 HW Encoder */
+ 	case 81519:
+-		/* WinTV-HVR1700 (PCIe, Retail, No IR, half height,
++		/* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
+ 		 * DVB-T and MPEG2 HW Encoder */
+ 		break;
+ 	default:
+diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
+index f056497..022aa39 100644
+--- a/drivers/media/video/cx23885/cx23885-dvb.c
++++ b/drivers/media/video/cx23885/cx23885-dvb.c
+@@ -37,7 +37,6 @@
+ #include "lgdt330x.h"
+ #include "xc5000.h"
+ #include "tda10048.h"
+-#include "dvb-pll.h"
+ #include "tuner-xc2028.h"
+ #include "tuner-simple.h"
+ #include "dib7000p.h"
+@@ -385,12 +384,10 @@ static int dvb_register(struct cx23885_tsport *port)
+ 		port->dvb.frontend = dvb_attach(s5h1409_attach,
+ 						&hauppauge_hvr1500q_config,
+ 						&dev->i2c_bus[0].i2c_adap);
+-		if (port->dvb.frontend != NULL) {
+-			hauppauge_hvr1500q_tunerconfig.priv = i2c_bus;
++		if (port->dvb.frontend != NULL)
+ 			dvb_attach(xc5000_attach, port->dvb.frontend,
+ 				&i2c_bus->i2c_adap,
+-				&hauppauge_hvr1500q_tunerconfig);
+-		}
++				&hauppauge_hvr1500q_tunerconfig, i2c_bus);
+ 		break;
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
+ 		i2c_bus = &dev->i2c_bus[1];
+diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
+index 7cf29a0..448f4cd 100644
+--- a/drivers/media/video/cx25840/Kconfig
++++ b/drivers/media/video/cx25840/Kconfig
+@@ -1,6 +1,7 @@
+ config VIDEO_CX25840
+ 	tristate "Conexant CX2584x audio/video decoders"
+ 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
++	depends on HOTPLUG # due to FW_LOADER
+ 	select FW_LOADER
+ 	---help---
+ 	  Support for the Conexant CX2584x audio/video decoders.
+diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
+index b0d7d6a..10e20d8 100644
+--- a/drivers/media/video/cx88/Kconfig
++++ b/drivers/media/video/cx88/Kconfig
+@@ -2,10 +2,9 @@ config VIDEO_CX88
+ 	tristate "Conexant 2388x (bt878 successor) support"
+ 	depends on VIDEO_DEV && PCI && I2C && INPUT
+ 	select I2C_ALGOBIT
+-	select FW_LOADER
+ 	select VIDEO_BTCX
+ 	select VIDEOBUF_DMA_SG
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_IR
+ 	select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
+@@ -34,8 +33,9 @@ config VIDEO_CX88_ALSA
+ 
+ config VIDEO_CX88_BLACKBIRD
+ 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
+-	depends on VIDEO_CX88
++	depends on VIDEO_CX88 && HOTPLUG
+ 	select VIDEO_CX2341X
++	select FW_LOADER
+ 	---help---
+ 	  This adds support for MPEG encoder cards based on the
+ 	  Blackbird reference design, using the Conexant 2388x
+diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
+index 1c7fe68..d96173f 100644
+--- a/drivers/media/video/cx88/cx88-dvb.c
++++ b/drivers/media/video/cx88/cx88-dvb.c
+@@ -509,9 +509,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
+ 	if (!fe) {
+ 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
+ 		       dev->core->name);
+-		dvb_frontend_detach(dev->dvb.frontend);
+-		dvb_unregister_frontend(dev->dvb.frontend);
+-		dev->dvb.frontend = NULL;
+ 		return -EINVAL;
+ 	}
+ 
+@@ -523,20 +520,23 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
+ 
+ static int dvb_register(struct cx8802_dev *dev)
+ {
++	struct cx88_core *core = dev->core;
++
+ 	/* init struct videobuf_dvb */
+-	dev->dvb.name = dev->core->name;
++	dev->dvb.name = core->name;
+ 	dev->ts_gen_cntrl = 0x0c;
+ 
+ 	/* init frontend */
+-	switch (dev->core->boardnr) {
++	switch (core->boardnr) {
+ 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
+ 		dev->dvb.frontend = dvb_attach(cx22702_attach,
+ 					       &connexant_refboard_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+-				   &dev->core->i2c_adap,
+-				   DVB_PLL_THOMSON_DTT759X);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x61, &core->i2c_adap,
++					DVB_PLL_THOMSON_DTT759X))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
+@@ -545,11 +545,12 @@ static int dvb_register(struct cx8802_dev *dev)
+ 	case CX88_BOARD_WINFAST_DTV1000:
+ 		dev->dvb.frontend = dvb_attach(cx22702_attach,
+ 					       &connexant_refboard_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+-				   &dev->core->i2c_adap,
+-				   DVB_PLL_THOMSON_DTT7579);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x60, &core->i2c_adap,
++					DVB_PLL_THOMSON_DTT7579))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_WINFAST_DTV2000H:
+@@ -559,29 +560,32 @@ static int dvb_register(struct cx8802_dev *dev)
+ 	case CX88_BOARD_HAUPPAUGE_HVR3000:
+ 		dev->dvb.frontend = dvb_attach(cx22702_attach,
+ 					       &hauppauge_hvr_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_PHILIPS_FMD1216ME_MK3);
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++				   &core->i2c_adap, 0x61,
++				   TUNER_PHILIPS_FMD1216ME_MK3))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
+ 		dev->dvb.frontend = dvb_attach(mt352_attach,
+ 					       &dvico_fusionhdtv,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+-				   NULL, DVB_PLL_THOMSON_DTT7579);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
++				goto frontend_detach;
+ 			break;
+ 		}
+ 		/* ZL10353 replaces MT352 on later cards */
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &dvico_fusionhdtv_plus_v1_1,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+-				   NULL, DVB_PLL_THOMSON_DTT7579);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
+@@ -589,28 +593,31 @@ static int dvb_register(struct cx8802_dev *dev)
+ 		 * compatible, with a slightly different MT352 AGC gain. */
+ 		dev->dvb.frontend = dvb_attach(mt352_attach,
+ 					       &dvico_fusionhdtv_dual,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+-				   NULL, DVB_PLL_THOMSON_DTT7579);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
++				goto frontend_detach;
+ 			break;
+ 		}
+ 		/* ZL10353 replaces MT352 on later cards */
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &dvico_fusionhdtv_plus_v1_1,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+-				   NULL, DVB_PLL_THOMSON_DTT7579);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
+ 		dev->dvb.frontend = dvb_attach(mt352_attach,
+ 					       &dvico_fusionhdtv,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+-				   NULL, DVB_PLL_LG_Z201);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x61, NULL, DVB_PLL_LG_Z201))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_KWORLD_DVB_T:
+@@ -618,10 +625,11 @@ static int dvb_register(struct cx8802_dev *dev)
+ 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
+ 		dev->dvb.frontend = dvb_attach(mt352_attach,
+ 					       &dntv_live_dvbt_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+-				   NULL, DVB_PLL_UNKNOWN_1);
++			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
++					0x61, NULL, DVB_PLL_UNKNOWN_1))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+@@ -630,32 +638,35 @@ static int dvb_register(struct cx8802_dev *dev)
+ 		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
+ 					       &dev->vp3054->adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_PHILIPS_FMD1216ME_MK3);
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_PHILIPS_FMD1216ME_MK3))
++				goto frontend_detach;
+ 		}
+ #else
+-		printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name);
++		printk(KERN_ERR "%s/2: built without vp3054 support\n",
++				core->name);
+ #endif
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &dvico_fusionhdtv_hybrid,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_THOMSON_FE6600);
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++				   &core->i2c_adap, 0x61,
++				   TUNER_THOMSON_FE6600))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &dvico_fusionhdtv_xc3028,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend == NULL)
+ 			dev->dvb.frontend = dvb_attach(mt352_attach,
+ 						&dvico_fusionhdtv_mt352_xc3028,
+-						&dev->core->i2c_adap);
++						&core->i2c_adap);
+ 		/*
+ 		 * On this board, the demod provides the I2C bus pullup.
+ 		 * We must not permit gate_ctrl to be performed, or
+@@ -668,19 +679,18 @@ static int dvb_register(struct cx8802_dev *dev)
+ 		break;
+ 	case CX88_BOARD_PCHDTV_HD3000:
+ 		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_THOMSON_DTT761X);
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_THOMSON_DTT761X))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
+ 		dev->ts_gen_cntrl = 0x08;
+-		{
+-		/* Do a hardware reset of chip before using it. */
+-		struct cx88_core *core = dev->core;
+ 
++		/* Do a hardware reset of chip before using it. */
+ 		cx_clear(MO_GP0_IO, 1);
+ 		mdelay(100);
+ 		cx_set(MO_GP0_IO, 1);
+@@ -690,139 +700,137 @@ static int dvb_register(struct cx8802_dev *dev)
+ 		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
+ 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ 					       &fusionhdtv_3_gold,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_MICROTUNE_4042FI5);
+-		}
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_MICROTUNE_4042FI5))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
+ 		dev->ts_gen_cntrl = 0x08;
+-		{
+-		/* Do a hardware reset of chip before using it. */
+-		struct cx88_core *core = dev->core;
+ 
++		/* Do a hardware reset of chip before using it. */
+ 		cx_clear(MO_GP0_IO, 1);
+ 		mdelay(100);
+ 		cx_set(MO_GP0_IO, 9);
+ 		mdelay(200);
+ 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ 					       &fusionhdtv_3_gold,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_THOMSON_DTT761X);
+-		}
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_THOMSON_DTT761X))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
+ 		dev->ts_gen_cntrl = 0x08;
+-		{
+-		/* Do a hardware reset of chip before using it. */
+-		struct cx88_core *core = dev->core;
+ 
++		/* Do a hardware reset of chip before using it. */
+ 		cx_clear(MO_GP0_IO, 1);
+ 		mdelay(100);
+ 		cx_set(MO_GP0_IO, 1);
+ 		mdelay(200);
+ 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ 					       &fusionhdtv_5_gold,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_LG_TDVS_H06XF);
+-			dvb_attach(tda9887_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x43);
+-		}
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_LG_TDVS_H06XF))
++				goto frontend_detach;
++			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
++				   &core->i2c_adap, 0x43))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_PCHDTV_HD5500:
+ 		dev->ts_gen_cntrl = 0x08;
+-		{
+-		/* Do a hardware reset of chip before using it. */
+-		struct cx88_core *core = dev->core;
+ 
++		/* Do a hardware reset of chip before using it. */
+ 		cx_clear(MO_GP0_IO, 1);
+ 		mdelay(100);
+ 		cx_set(MO_GP0_IO, 1);
+ 		mdelay(200);
+ 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ 					       &pchdtv_hd5500,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_LG_TDVS_H06XF);
+-			dvb_attach(tda9887_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x43);
+-		}
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_LG_TDVS_H06XF))
++				goto frontend_detach;
++			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
++				   &core->i2c_adap, 0x43))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_ATI_HDTVWONDER:
+ 		dev->dvb.frontend = dvb_attach(nxt200x_attach,
+ 					       &ati_hdtvwonder,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x61,
+-				   TUNER_PHILIPS_TUV1236D);
++			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x61,
++					TUNER_PHILIPS_TUV1236D))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+ 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
+ 		dev->dvb.frontend = dvb_attach(cx24123_attach,
+ 					       &hauppauge_novas_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend) {
+-			dvb_attach(isl6421_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap, 0x08, 0x00, 0x00);
++			if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
++					&core->i2c_adap, 0x08, 0x00, 0x00))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_KWORLD_DVBS_100:
+ 		dev->dvb.frontend = dvb_attach(cx24123_attach,
+ 					       &kworld_dvbs_100_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend) {
+-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
++			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+ 			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
+ 		}
+ 		break;
+ 	case CX88_BOARD_GENIATECH_DVBS:
+ 		dev->dvb.frontend = dvb_attach(cx24123_attach,
+ 					       &geniatech_dvbs_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend) {
+-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
++			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+ 			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
+ 		}
+ 		break;
+ 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
+ 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ 					       &pinnacle_pctv_hd_800i_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+ 			/* tuner_config.video_dev must point to
+ 			 * i2c_adap.algo_data
+ 			 */
+-			pinnacle_pctv_hd_800i_tuner_config.priv =
+-						dev->core->i2c_adap.algo_data;
+-			dvb_attach(xc5000_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap,
+-				   &pinnacle_pctv_hd_800i_tuner_config);
++			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
++					&core->i2c_adap,
++					&pinnacle_pctv_hd_800i_tuner_config,
++					core->i2c_adap.algo_data))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
+ 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ 						&dvico_hdtv5_pci_nano_config,
+-						&dev->core->i2c_adap);
++						&core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+ 			struct dvb_frontend *fe;
+ 			struct xc2028_config cfg = {
+-				.i2c_adap  = &dev->core->i2c_adap,
++				.i2c_adap  = &core->i2c_adap,
+ 				.i2c_addr  = 0x61,
+ 				.callback  = cx88_pci_nano_callback,
+ 			};
+@@ -841,50 +849,50 @@ static int dvb_register(struct cx8802_dev *dev)
+ 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &cx88_geniatech_x8000_mt,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (attach_xc3028(0x61, dev) < 0)
+-			return -EINVAL;
++			goto frontend_detach;
+ 		break;
+ 	 case CX88_BOARD_GENIATECH_X8000_MT:
+ 		dev->ts_gen_cntrl = 0x00;
+ 
+ 		dev->dvb.frontend = dvb_attach(zl10353_attach,
+ 					       &cx88_geniatech_x8000_mt,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (attach_xc3028(0x61, dev) < 0)
+-			return -EINVAL;
++			goto frontend_detach;
+ 		break;
+ 	 case CX88_BOARD_KWORLD_ATSC_120:
+ 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ 					       &kworld_atsc_120_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (attach_xc3028(0x61, dev) < 0)
+-			return -EINVAL;
++			goto frontend_detach;
+ 		break;
+ 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
+ 		dev->dvb.frontend = dvb_attach(s5h1411_attach,
+ 					       &dvico_fusionhdtv7_config,
+-					       &dev->core->i2c_adap);
++					       &core->i2c_adap);
+ 		if (dev->dvb.frontend != NULL) {
+ 			/* tuner_config.video_dev must point to
+ 			 * i2c_adap.algo_data
+ 			 */
+-			dvico_fusionhdtv7_tuner_config.priv =
+-						dev->core->i2c_adap.algo_data;
+-			dvb_attach(xc5000_attach, dev->dvb.frontend,
+-				   &dev->core->i2c_adap,
+-				   &dvico_fusionhdtv7_tuner_config);
++			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
++					&core->i2c_adap,
++					&dvico_fusionhdtv7_tuner_config,
++					core->i2c_adap.algo_data))
++				goto frontend_detach;
+ 		}
+ 		break;
+ 	default:
+ 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
+-		       dev->core->name);
++		       core->name);
+ 		break;
+ 	}
+ 	if (NULL == dev->dvb.frontend) {
+ 		printk(KERN_ERR
+ 		       "%s/2: frontend initialization failed\n",
+-		       dev->core->name);
++		       core->name);
+ 		return -EINVAL;
+ 	}
+ 
+@@ -892,11 +900,18 @@ static int dvb_register(struct cx8802_dev *dev)
+ 	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ 
+ 	/* Put the analog decoder in standby to keep it quiet */
+-	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
++	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
+ 
+ 	/* register everything */
+ 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
+ 				     &dev->pci->dev, adapter_nr);
++
++frontend_detach:
++	if (dev->dvb.frontend) {
++		dvb_frontend_detach(dev->dvb.frontend);
++		dev->dvb.frontend = NULL;
++	}
++	return -EINVAL;
+ }
+ 
+ /* ----------------------------------------------------------- */
+diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
+index c7c2896..16a5af3 100644
+--- a/drivers/media/video/em28xx/Kconfig
++++ b/drivers/media/video/em28xx/Kconfig
+@@ -1,7 +1,7 @@
+ config VIDEO_EM28XX
+ 	tristate "Empia EM28xx USB video capture support"
+ 	depends on VIDEO_DEV && I2C && INPUT
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_IR
+ 	select VIDEOBUF_VMALLOC
+@@ -35,7 +35,6 @@ config VIDEO_EM28XX_DVB
+ 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+ 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ 	select VIDEOBUF_DVB
+-	select FW_LOADER
+ 	---help---
+ 	  This adds support for DVB cards based on the
+ 	  Empiatech em28xx chips.
+diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
+index 50ccf37..3e4f3c7 100644
+--- a/drivers/media/video/em28xx/em28xx-cards.c
++++ b/drivers/media/video/em28xx/em28xx-cards.c
+@@ -420,7 +420,13 @@ struct usb_device_id em28xx_id_table [] = {
+ 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+ 	{ USB_DEVICE(0x2040, 0x6502),
+ 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+-	{ USB_DEVICE(0x2040, 0x6513),
++	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
++			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
++	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
++			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
++	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
++			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
++	{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
+ 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ 	{ USB_DEVICE(0x0ccd, 0x0042),
+ 			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
+index 7df8157..8cf4983 100644
+--- a/drivers/media/video/em28xx/em28xx-dvb.c
++++ b/drivers/media/video/em28xx/em28xx-dvb.c
+@@ -251,7 +251,6 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
+ 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
+ 		       dev->name);
+ 		dvb_frontend_detach(dev->dvb->frontend);
+-		dvb_unregister_frontend(dev->dvb->frontend);
+ 		dev->dvb->frontend = NULL;
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
+index eec115b..5d7ee8f 100644
+--- a/drivers/media/video/ivtv/Kconfig
++++ b/drivers/media/video/ivtv/Kconfig
+@@ -1,10 +1,12 @@
+ config VIDEO_IVTV
+ 	tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
+ 	depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
++	depends on INPUT   # due to VIDEO_IR
++	depends on HOTPLUG # due to FW_LOADER
+ 	select I2C_ALGOBIT
+ 	select FW_LOADER
+ 	select VIDEO_IR
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_CX2341X
+ 	select VIDEO_CX25840
+diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
+index 8c02fa6..c7e449f 100644
+--- a/drivers/media/video/ivtv/ivtv-controls.c
++++ b/drivers/media/video/ivtv/ivtv-controls.c
+@@ -181,12 +181,12 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
+ 		return 0;
+ 	}
+ 	/* Need sliced data for mpeg insertion */
+-	if (get_service_set(itv->vbi.sliced_in) == 0) {
++	if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
+ 		if (itv->is_60hz)
+ 			itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
+ 		else
+ 			itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
+-		expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
++		ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
+ 	}
+ 	return 0;
+ }
+diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
+index ed020f7..797e636 100644
+--- a/drivers/media/video/ivtv/ivtv-driver.c
++++ b/drivers/media/video/ivtv/ivtv-driver.c
+@@ -853,6 +853,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
+ 	return 0;
+ }
+ 
++#ifdef MODULE
+ static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
+ 		const char *name, u32 id)
+ {
+@@ -865,12 +866,14 @@ static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
+ 	IVTV_DEBUG_INFO("Loaded module %s\n", name);
+ 	return hw;
+ }
++#endif
+ 
+ static void ivtv_load_and_init_modules(struct ivtv *itv)
+ {
+ 	u32 hw = itv->card->hw_all;
+ 	unsigned i;
+ 
++#ifdef MODULE
+ 	/* load modules */
+ #ifndef CONFIG_MEDIA_TUNER
+ 	hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
+@@ -911,6 +914,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
+ #ifndef CONFIG_VIDEO_M52790
+ 	hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
+ #endif
++#endif
+ 
+ 	/* check which i2c devices are actually found */
+ 	for (i = 0; i < 32; i++) {
+@@ -1228,7 +1232,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
+ 	return 0;
+ 
+ free_streams:
+-	ivtv_streams_cleanup(itv);
++	ivtv_streams_cleanup(itv, 1);
+ free_irq:
+ 	free_irq(itv->dev->irq, (void *)itv);
+ free_i2c:
+@@ -1373,7 +1377,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
+ 	flush_workqueue(itv->irq_work_queues);
+ 	destroy_workqueue(itv->irq_work_queues);
+ 
+-	ivtv_streams_cleanup(itv);
++	ivtv_streams_cleanup(itv, 1);
+ 	ivtv_udma_free(itv);
+ 
+ 	exit_ivtv_i2c(itv);
+diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
+index 2b74b0a..f2fa434 100644
+--- a/drivers/media/video/ivtv/ivtv-fileops.c
++++ b/drivers/media/video/ivtv/ivtv-fileops.c
+@@ -987,6 +987,8 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
+ 	/* Find which card this open was on */
+ 	spin_lock(&ivtv_cards_lock);
+ 	for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
++		if (ivtv_cards[x] == NULL)
++			continue;
+ 		/* find out which stream this open was on */
+ 		for (y = 0; y < IVTV_MAX_STREAMS; y++) {
+ 			s = &ivtv_cards[x]->streams[y];
+diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
+index d508b5d..26cc0f6 100644
+--- a/drivers/media/video/ivtv/ivtv-ioctl.c
++++ b/drivers/media/video/ivtv/ivtv-ioctl.c
+@@ -38,7 +38,7 @@
+ #include <linux/dvb/audio.h>
+ #include <linux/i2c-id.h>
+ 
+-u16 service2vbi(int type)
++u16 ivtv_service2vbi(int type)
+ {
+ 	switch (type) {
+ 		case V4L2_SLICED_TELETEXT_B:
+@@ -88,7 +88,7 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
+ 	return 0;
+ }
+ 
+-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
++void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+ {
+ 	u16 set = fmt->service_set;
+ 	int f, l;
+@@ -115,7 +115,7 @@ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+ 	return set != 0;
+ }
+ 
+-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
++u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
+ {
+ 	int f, l;
+ 	u16 set = 0;
+@@ -466,7 +466,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
+ 			vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
+ 			vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
+ 		}
+-		vbifmt->service_set = get_service_set(vbifmt);
++		vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ 		break;
+ 	}
+ 
+@@ -481,12 +481,12 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
+ 		if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
+ 			vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
+ 						 V4L2_SLICED_VBI_525;
+-			expand_service_set(vbifmt, itv->is_50hz);
++			ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ 			break;
+ 		}
+ 
+ 		itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
+-		vbifmt->service_set = get_service_set(vbifmt);
++		vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ 		break;
+ 	}
+ 	case V4L2_BUF_TYPE_VBI_OUTPUT:
+@@ -640,9 +640,9 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
+ 	memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
+ 
+ 	if (vbifmt->service_set)
+-		expand_service_set(vbifmt, itv->is_50hz);
++		ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ 	set = check_service_set(vbifmt, itv->is_50hz);
+-	vbifmt->service_set = get_service_set(vbifmt);
++	vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ 
+ 	if (!set_fmt)
+ 		return 0;
+diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
+index a03351b..4e67f0e 100644
+--- a/drivers/media/video/ivtv/ivtv-ioctl.h
++++ b/drivers/media/video/ivtv/ivtv-ioctl.h
+@@ -21,9 +21,9 @@
+ #ifndef IVTV_IOCTL_H
+ #define IVTV_IOCTL_H
+ 
+-u16 service2vbi(int type);
+-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
+-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
++u16 ivtv_service2vbi(int type);
++void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
++u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
+ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ 		    unsigned long arg);
+ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
+diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
+index 3e1deec..fc8b1ea 100644
+--- a/drivers/media/video/ivtv/ivtv-queue.c
++++ b/drivers/media/video/ivtv/ivtv-queue.c
+@@ -203,14 +203,14 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
+ 		s->dma != PCI_DMA_NONE ? "DMA " : "",
+ 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
+ 
+-	s->sg_pending = kzalloc(SGsize, GFP_KERNEL);
++	s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
+ 	if (s->sg_pending == NULL) {
+ 		IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
+ 		return -ENOMEM;
+ 	}
+ 	s->sg_pending_size = 0;
+ 
+-	s->sg_processing = kzalloc(SGsize, GFP_KERNEL);
++	s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
+ 	if (s->sg_processing == NULL) {
+ 		IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
+ 		kfree(s->sg_pending);
+@@ -219,7 +219,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
+ 	}
+ 	s->sg_processing_size = 0;
+ 
+-	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL);
++	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
++					GFP_KERNEL|__GFP_NOWARN);
+ 	if (s->sg_dma == NULL) {
+ 		IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
+ 		kfree(s->sg_pending);
+@@ -235,11 +236,12 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
+ 
+ 	/* allocate stream buffers. Initially all buffers are in q_free. */
+ 	for (i = 0; i < s->buffers; i++) {
+-		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL);
++		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
++						GFP_KERNEL|__GFP_NOWARN);
+ 
+ 		if (buf == NULL)
+ 			break;
+-		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL);
++		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
+ 		if (buf->buf == NULL) {
+ 			kfree(buf);
+ 			break;
+diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
+index 4ab8d36..c47c2b9 100644
+--- a/drivers/media/video/ivtv/ivtv-streams.c
++++ b/drivers/media/video/ivtv/ivtv-streams.c
+@@ -244,7 +244,7 @@ int ivtv_streams_setup(struct ivtv *itv)
+ 		return 0;
+ 
+ 	/* One or more streams could not be initialized. Clean 'em all up. */
+-	ivtv_streams_cleanup(itv);
++	ivtv_streams_cleanup(itv, 0);
+ 	return -ENOMEM;
+ }
+ 
+@@ -304,12 +304,12 @@ int ivtv_streams_register(struct ivtv *itv)
+ 		return 0;
+ 
+ 	/* One or more streams could not be initialized. Clean 'em all up. */
+-	ivtv_streams_cleanup(itv);
++	ivtv_streams_cleanup(itv, 1);
+ 	return -ENOMEM;
+ }
+ 
+ /* Unregister v4l2 devices */
+-void ivtv_streams_cleanup(struct ivtv *itv)
++void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
+ {
+ 	int type;
+ 
+@@ -322,8 +322,11 @@ void ivtv_streams_cleanup(struct ivtv *itv)
+ 			continue;
+ 
+ 		ivtv_stream_free(&itv->streams[type]);
+-		/* Unregister device */
+-		video_unregister_device(vdev);
++		/* Unregister or release device */
++		if (unregister)
++			video_unregister_device(vdev);
++		else
++			video_device_release(vdev);
+ 	}
+ }
+ 
+diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
+index 3d76a41..a653a51 100644
+--- a/drivers/media/video/ivtv/ivtv-streams.h
++++ b/drivers/media/video/ivtv/ivtv-streams.h
+@@ -23,7 +23,7 @@
+ 
+ int ivtv_streams_setup(struct ivtv *itv);
+ int ivtv_streams_register(struct ivtv *itv);
+-void ivtv_streams_cleanup(struct ivtv *itv);
++void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
+ 
+ /* Capture related */
+ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
+diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
+index c151bcf..71798f0 100644
+--- a/drivers/media/video/ivtv/ivtv-vbi.c
++++ b/drivers/media/video/ivtv/ivtv-vbi.c
+@@ -169,7 +169,8 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
+ 			linemask[0] |= (1 << l);
+ 		else
+ 			linemask[1] |= (1 << (l - 32));
+-		dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
++		dst[sd + 12 + line * 43] =
++			ivtv_service2vbi(itv->vbi.sliced_data[i].id);
+ 		memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
+ 		line++;
+ 	}
+diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
+index 62f70bd..a9417f6 100644
+--- a/drivers/media/video/ivtv/ivtv-yuv.c
++++ b/drivers/media/video/ivtv/ivtv-yuv.c
+@@ -908,7 +908,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
+ 	}
+ 
+ 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
+-	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL);
++	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
+ 	if (yi->blanking_ptr) {
+ 		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
+ 	} else {
+diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
+index df789f6..73be154 100644
+--- a/drivers/media/video/ivtv/ivtvfb.c
++++ b/drivers/media/video/ivtv/ivtvfb.c
+@@ -948,7 +948,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
+ 	}
+ 
+ 	/* Allocate the pseudo palette */
+-	oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
++	oi->ivtvfb_info.pseudo_palette =
++		kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
+ 
+ 	if (!oi->ivtvfb_info.pseudo_palette) {
+ 		IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
+@@ -1056,7 +1057,8 @@ static int ivtvfb_init_card(struct ivtv *itv)
+ 		return -EBUSY;
+ 	}
+ 
+-	itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC);
++	itv->osd_info = kzalloc(sizeof(struct osd_info),
++					GFP_ATOMIC|__GFP_NOWARN);
+ 	if (itv->osd_info == NULL) {
+ 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
+ 		return -ENOMEM;
+diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
+index 179e470..ee43499 100644
+--- a/drivers/media/video/mt9m001.c
++++ b/drivers/media/video/mt9m001.c
+@@ -12,15 +12,12 @@
+ #include <linux/slab.h>
+ #include <linux/i2c.h>
+ #include <linux/log2.h>
++#include <linux/gpio.h>
+ 
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-chip-ident.h>
+ #include <media/soc_camera.h>
+ 
+-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
+-#include <asm/gpio.h>
+-#endif
+-
+ /* mt9m001 i2c address 0x5d
+  * The platform has to define i2c_board_info
+  * and call i2c_register_board_info() */
+diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
+index d1391ac..1658fe5 100644
+--- a/drivers/media/video/mt9v022.c
++++ b/drivers/media/video/mt9v022.c
+@@ -13,15 +13,12 @@
+ #include <linux/i2c.h>
+ #include <linux/delay.h>
+ #include <linux/log2.h>
++#include <linux/gpio.h>
+ 
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-chip-ident.h>
+ #include <media/soc_camera.h>
+ 
+-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
+-#include <asm/gpio.h>
+-#endif
+-
+ /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
+  * The platform has to define i2c_board_info
+  * and call i2c_register_board_info() */
+@@ -91,7 +88,7 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
+ struct mt9v022 {
+ 	struct i2c_client *client;
+ 	struct soc_camera_device icd;
+-	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
++	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
+ 	int switch_gpio;
+ 	u16 chip_control;
+ 	unsigned char datawidth;
+diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
+index 9620c67..4482b2c 100644
+--- a/drivers/media/video/pvrusb2/Kconfig
++++ b/drivers/media/video/pvrusb2/Kconfig
+@@ -1,8 +1,10 @@
+ config VIDEO_PVRUSB2
+ 	tristate "Hauppauge WinTV-PVR USB2 support"
+ 	depends on VIDEO_V4L2 && I2C
++	depends on VIDEO_MEDIA	# Avoids pvrusb = Y / DVB = M
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select FW_LOADER
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select VIDEO_CX2341X
+ 	select VIDEO_SAA711X
+diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
+index 40e4c3b..83f076a 100644
+--- a/drivers/media/video/saa7134/Kconfig
++++ b/drivers/media/video/saa7134/Kconfig
+@@ -3,7 +3,7 @@ config VIDEO_SAA7134
+ 	depends on VIDEO_DEV && PCI && I2C && INPUT
+ 	select VIDEOBUF_DMA_SG
+ 	select VIDEO_IR
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_TVEEPROM
+ 	select CRC32
+ 	---help---
+@@ -27,6 +27,7 @@ config VIDEO_SAA7134_ALSA
+ config VIDEO_SAA7134_DVB
+ 	tristate "DVB/ATSC Support for saa7134 based TV cards"
+ 	depends on VIDEO_SAA7134 && DVB_CORE
++	depends on HOTPLUG	# due to FW_LOADER
+ 	select VIDEOBUF_DVB
+ 	select FW_LOADER
+ 	select DVB_PLL if !DVB_FE_CUSTOMISE
+diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
+index eec1278..2c19cd0 100644
+--- a/drivers/media/video/saa7134/saa7134-core.c
++++ b/drivers/media/video/saa7134/saa7134-core.c
+@@ -864,7 +864,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
+ 	struct saa7134_dev *dev;
+ 	struct saa7134_mpeg_ops *mops;
+ 	int err;
+-	int mask;
+ 
+ 	if (saa7134_devcount == SAA7134_MAXBOARDS)
+ 		return -ENOMEM;
+@@ -1065,11 +1064,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
+ 	if (TUNER_ABSENT != dev->tuner_type)
+ 		saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ 
+-	if (card(dev).gpiomask != 0) {
+-		mask = card(dev).gpiomask;
+-		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
+-		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0);
+-	}
+ 	return 0;
+ 
+  fail4:
+diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
+index 2d16be2..469f93a 100644
+--- a/drivers/media/video/saa7134/saa7134-dvb.c
++++ b/drivers/media/video/saa7134/saa7134-dvb.c
+@@ -538,19 +538,23 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
+ 	return 0;
+ }
+ 
+-static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf,
+-							  struct tda827x_config *tuner_conf)
++static int configure_tda827x_fe(struct saa7134_dev *dev,
++				struct tda1004x_config *cdec_conf,
++				struct tda827x_config *tuner_conf)
+ {
+ 	dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
+ 	if (dev->dvb.frontend) {
+ 		if (cdec_conf->i2c_gate)
+ 			dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
+-		if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address,
+-							&dev->i2c_adap, tuner_conf) == NULL) {
+-			wprintk("no tda827x tuner found at addr: %02x\n",
++		if (dvb_attach(tda827x_attach, dev->dvb.frontend,
++			       cdec_conf->tuner_address,
++			       &dev->i2c_adap, tuner_conf))
++			return 0;
++
++		wprintk("no tda827x tuner found at addr: %02x\n",
+ 				cdec_conf->tuner_address);
+-		}
+ 	}
++	return -EINVAL;
+ }
+ 
+ /* ------------------------------------------------------------------ */
+@@ -997,7 +1001,9 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		break;
+ 	case SAA7134_BOARD_FLYDVBTDUO:
+ 	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
+-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_PHILIPS_EUROPA:
+ 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
+@@ -1022,36 +1028,52 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		}
+ 		break;
+ 	case SAA7134_BOARD_KWORLD_DVBT_210:
+-		configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2);
++		if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
++					 &tda827x_cfg_2) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_PHILIPS_TIGER:
+-		configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &philips_tiger_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
+-		configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1);
++		if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
++					 &tda827x_cfg_1) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
+-		configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1);
++		if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
++					 &tda827x_cfg_1) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+-		configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_FLYDVBT_LR301:
+-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_FLYDVB_TRIO:
+-		if(! use_frontend) {	/* terrestrial */
+-			configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0);
++		if (!use_frontend) {	/* terrestrial */
++			if (configure_tda827x_fe(dev, &lifeview_trio_config,
++						 &tda827x_cfg_0) < 0)
++				goto dettach_frontend;
+ 		} else {  		/* satellite */
+ 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+ 			if (dev->dvb.frontend) {
+ 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+ 									&dev->i2c_adap, 0) == NULL) {
+ 					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
++					goto dettach_frontend;
+ 				}
+ 				if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
+ 										0x08, 0, 0) == NULL) {
+ 					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
++					goto dettach_frontend;
+ 				}
+ 			}
+ 		}
+@@ -1067,15 +1089,20 @@ static int dvb_init(struct saa7134_dev *dev)
+ 								&ads_duo_cfg) == NULL) {
+ 				wprintk("no tda827x tuner found at addr: %02x\n",
+ 					ads_tech_duo_config.tuner_address);
++				goto dettach_frontend;
+ 			}
+ 		}
+ 		break;
+ 	case SAA7134_BOARD_TEVION_DVBT_220RF:
+-		configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
+ 		if (!use_frontend) {     /* terrestrial */
+-			configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
++			if (configure_tda827x_fe(dev, &md8800_dvbt_config,
++						 &tda827x_cfg_0) < 0)
++				goto dettach_frontend;
+ 		} else {        /* satellite */
+ 			dev->dvb.frontend = dvb_attach(tda10086_attach,
+ 							&flydvbs, &dev->i2c_adap);
+@@ -1086,16 +1113,20 @@ static int dvb_init(struct saa7134_dev *dev)
+ 				struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
+ 
+ 				if (dvb_attach(tda826x_attach, dev->dvb.frontend,
+-						0x60, &dev->i2c_adap, 0) == NULL)
++						0x60, &dev->i2c_adap, 0) == NULL) {
+ 					wprintk("%s: Medion Quadro, no tda826x "
+ 						"found !\n", __func__);
++					goto dettach_frontend;
++				}
+ 				if (dev_id != 0x08) {
+ 					/* we need to open the i2c gate (we know it exists) */
+ 					fe->ops.i2c_gate_ctrl(fe, 1);
+ 					if (dvb_attach(isl6405_attach, fe,
+-							&dev->i2c_adap, 0x08, 0, 0) == NULL)
++							&dev->i2c_adap, 0x08, 0, 0) == NULL) {
+ 						wprintk("%s: Medion Quadro, no ISL6405 "
+ 							"found !\n", __func__);
++						goto dettach_frontend;
++					}
+ 					if (dev_id == 0x07) {
+ 						/* fire up the 2nd section of the LNB supply since
+ 						   we can't do this from the other section */
+@@ -1117,19 +1148,17 @@ static int dvb_init(struct saa7134_dev *dev)
+ 	case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
+ 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+ 					       &dev->i2c_adap);
+-		if (dev->dvb.frontend) {
++		if (dev->dvb.frontend)
+ 			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ 				   NULL, DVB_PLL_TDHU2);
+-		}
+ 		break;
+ 	case SAA7134_BOARD_KWORLD_ATSC110:
+ 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+ 					       &dev->i2c_adap);
+-		if (dev->dvb.frontend) {
++		if (dev->dvb.frontend)
+ 			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ 				   &dev->i2c_adap, 0x61,
+ 				   TUNER_PHILIPS_TUV1236D);
+-		}
+ 		break;
+ 	case SAA7134_BOARD_FLYDVBS_LR300:
+ 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+@@ -1138,10 +1167,12 @@ static int dvb_init(struct saa7134_dev *dev)
+ 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ 				       &dev->i2c_adap, 0) == NULL) {
+ 				wprintk("%s: No tda826x found!\n", __func__);
++				goto dettach_frontend;
+ 			}
+ 			if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+ 				       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
+ 				wprintk("%s: No ISL6421 found!\n", __func__);
++				goto dettach_frontend;
+ 			}
+ 		}
+ 		break;
+@@ -1168,43 +1199,65 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		}
+ 		break;
+ 	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
+-		configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &cinergy_ht_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_CINERGY_HT_PCI:
+-		configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_PHILIPS_TIGER_S:
+-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
++		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
++					 &tda827x_cfg_2) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_ASUS_P7131_4871:
+-		configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2);
++		if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
++					 &tda827x_cfg_2) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
+-		configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2);
++		if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
++					 &tda827x_cfg_2) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+-		configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &avermedia_super_007_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
+-		configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42);
++		if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
++					 &tda827x_cfg_2_sw42) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_PHILIPS_SNAKE:
+ 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ 						&dev->i2c_adap);
+ 		if (dev->dvb.frontend) {
+ 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+-					&dev->i2c_adap, 0) == NULL)
++					&dev->i2c_adap, 0) == NULL) {
+ 				wprintk("%s: No tda826x found!\n", __func__);
++				goto dettach_frontend;
++			}
+ 			if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+-					&dev->i2c_adap, 0, 0) == NULL)
++					&dev->i2c_adap, 0, 0) == NULL) {
+ 				wprintk("%s: No lnbp21 found!\n", __func__);
++				goto dettach_frontend;
++			}
+ 		}
+ 		break;
+ 	case SAA7134_BOARD_CREATIX_CTX953:
+-		configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
++		if (configure_tda827x_fe(dev, &md8800_dvbt_config,
++					 &tda827x_cfg_0) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
+-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
++		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
++					 &tda827x_cfg_2) < 0)
++			goto dettach_frontend;
+ 		break;
+ 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ 		dev->dvb.frontend = dvb_attach(mt352_attach,
+@@ -1218,16 +1271,20 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		if (dev->dvb.frontend) {
+ 			struct dvb_frontend *fe;
+ 			if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+-				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL)
++				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
+ 				wprintk("%s: MD7134 DVB-S, no SD1878 "
+ 					"found !\n", __func__);
++				goto dettach_frontend;
++			}
+ 			/* we need to open the i2c gate (we know it exists) */
+ 			fe = dev->dvb.frontend;
+ 			fe->ops.i2c_gate_ctrl(fe, 1);
+ 			if (dvb_attach(isl6405_attach, fe,
+-					&dev->i2c_adap, 0x08, 0, 0) == NULL)
++					&dev->i2c_adap, 0x08, 0, 0) == NULL) {
+ 				wprintk("%s: MD7134 DVB-S, no ISL6405 "
+ 					"found !\n", __func__);
++				goto dettach_frontend;
++			}
+ 			fe->ops.i2c_gate_ctrl(fe, 0);
+ 			dev->original_set_voltage = fe->ops.set_voltage;
+ 			fe->ops.set_voltage = md8800_set_voltage;
+@@ -1254,10 +1311,7 @@ static int dvb_init(struct saa7134_dev *dev)
+ 		if (!fe) {
+ 			printk(KERN_ERR "%s/2: xc3028 attach failed\n",
+ 			       dev->name);
+-			dvb_frontend_detach(dev->dvb.frontend);
+-			dvb_unregister_frontend(dev->dvb.frontend);
+-			dev->dvb.frontend = NULL;
+-			return -1;
++			goto dettach_frontend;
+ 		}
+ 	}
+ 
+@@ -1282,6 +1336,12 @@ static int dvb_init(struct saa7134_dev *dev)
+ 			dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
+ 	}
+ 	return ret;
++
++dettach_frontend:
++	dvb_frontend_detach(dev->dvb.frontend);
++	dev->dvb.frontend = NULL;
++
++	return -1;
+ }
+ 
+ static int dvb_fini(struct saa7134_dev *dev)
+diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
+index 9276ed9..b12c60c 100644
+--- a/drivers/media/video/stk-webcam.c
++++ b/drivers/media/video/stk-webcam.c
+@@ -30,6 +30,7 @@
+ #include <linux/kref.h>
+ 
+ #include <linux/usb.h>
++#include <linux/mm.h>
+ #include <linux/vmalloc.h>
+ #include <linux/videodev2.h>
+ #include <media/v4l2-common.h>
+@@ -245,6 +246,8 @@ static int stk_initialise(struct stk_camera *dev)
+ 		return -1;
+ }
+ 
++#ifdef CONFIG_VIDEO_V4L1_COMPAT
++
+ /* sysfs functions */
+ /*FIXME cleanup this */
+ 
+@@ -350,6 +353,10 @@ static void stk_remove_sysfs_files(struct video_device *vdev)
+ 	video_device_remove_file(vdev, &dev_attr_vflip);
+ }
+ 
++#else
++#define stk_create_sysfs_files(a)
++#define stk_remove_sysfs_files(a)
++#endif
+ 
+ /* *********************************************** */
+ /*
+diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
+index 6bf104e..5a75788 100644
+--- a/drivers/media/video/tuner-core.c
++++ b/drivers/media/video/tuner-core.c
+@@ -40,11 +40,11 @@
+ 	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
+ 	if (__a) { \
+ 		__r = (int) __a(ARGS); \
++		symbol_put(FUNCTION); \
+ 	} else { \
+ 		printk(KERN_ERR "TUNER: Unable to find " \
+ 				"symbol "#FUNCTION"()\n"); \
+ 	} \
+-	symbol_put(FUNCTION); \
+ 	__r; \
+ })
+ 
+@@ -340,16 +340,6 @@ static void tuner_i2c_address_check(struct tuner *t)
+ 	tuner_warn("====================== WARNING! ======================\n");
+ }
+ 
+-static void attach_tda829x(struct tuner *t)
+-{
+-	struct tda829x_config cfg = {
+-		.lna_cfg        = t->config,
+-		.tuner_callback = t->tuner_callback,
+-	};
+-	dvb_attach(tda829x_attach,
+-		   &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
+-}
+-
+ static struct xc5000_config xc5000_cfg;
+ 
+ static void set_type(struct i2c_client *c, unsigned int type,
+@@ -385,12 +375,19 @@ static void set_type(struct i2c_client *c, unsigned int type,
+ 
+ 	switch (t->type) {
+ 	case TUNER_MT2032:
+-		dvb_attach(microtune_attach,
+-			   &t->fe, t->i2c->adapter, t->i2c->addr);
++		if (!dvb_attach(microtune_attach,
++			   &t->fe, t->i2c->adapter, t->i2c->addr))
++			goto attach_failed;
+ 		break;
+ 	case TUNER_PHILIPS_TDA8290:
+ 	{
+-		attach_tda829x(t);
++		struct tda829x_config cfg = {
++			.lna_cfg        = t->config,
++			.tuner_callback = t->tuner_callback,
++		};
++		if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
++				t->i2c->addr, &cfg))
++			goto attach_failed;
+ 		break;
+ 	}
+ 	case TUNER_TEA5767:
+@@ -441,8 +438,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
+ 		break;
+ 	}
+ 	case TUNER_TDA9887:
+-		dvb_attach(tda9887_attach,
+-			   &t->fe, t->i2c->adapter, t->i2c->addr);
++		if (!dvb_attach(tda9887_attach,
++			   &t->fe, t->i2c->adapter, t->i2c->addr))
++			goto attach_failed;
+ 		break;
+ 	case TUNER_XC5000:
+ 	{
+@@ -450,10 +448,10 @@ static void set_type(struct i2c_client *c, unsigned int type,
+ 
+ 		xc5000_cfg.i2c_address	  = t->i2c->addr;
+ 		xc5000_cfg.if_khz	  = 5380;
+-		xc5000_cfg.priv           = c->adapter->algo_data;
+ 		xc5000_cfg.tuner_callback = t->tuner_callback;
+ 		if (!dvb_attach(xc5000_attach,
+-				&t->fe, t->i2c->adapter, &xc5000_cfg))
++				&t->fe, t->i2c->adapter, &xc5000_cfg,
++				c->adapter->algo_data))
+ 			goto attach_failed;
+ 
+ 		xc_tuner_ops = &t->fe.ops.tuner_ops;
+@@ -1167,7 +1165,7 @@ static int tuner_probe(struct i2c_client *client,
+ 			/* If chip is not tda8290, don't register.
+ 			   since it can be tda9887*/
+ 			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
+-					       t->i2c->addr) == 0) {
++					       t->i2c->addr) >= 0) {
+ 				tuner_dbg("tda829x detected\n");
+ 			} else {
+ 				/* Default is being tda9887 */
+@@ -1181,7 +1179,7 @@ static int tuner_probe(struct i2c_client *client,
+ 		case 0x60:
+ 			if (tuner_symbol_probe(tea5767_autodetection,
+ 					       t->i2c->adapter, t->i2c->addr)
+-					!= EINVAL) {
++					>= 0) {
+ 				t->type = TUNER_TEA5767;
+ 				t->mode_mask = T_RADIO;
+ 				t->mode = T_STANDBY;
+diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
+index 3cf8a8e..9da0e18 100644
+--- a/drivers/media/video/tveeprom.c
++++ b/drivers/media/video/tveeprom.c
+@@ -319,10 +319,12 @@ audioIC[] =
+ 	{AUDIO_CHIP_INTERNAL, "CX25843"},
+ 	{AUDIO_CHIP_INTERNAL, "CX23418"},
+ 	{AUDIO_CHIP_INTERNAL, "CX23885"},
+-	/* 40-42 */
++	/* 40-44 */
+ 	{AUDIO_CHIP_INTERNAL, "CX23888"},
+ 	{AUDIO_CHIP_INTERNAL, "SAA7131"},
+ 	{AUDIO_CHIP_INTERNAL, "CX23887"},
++	{AUDIO_CHIP_INTERNAL, "SAA7164"},
++	{AUDIO_CHIP_INTERNAL, "AU8522"},
+ };
+ 
+ /* This list is supplied by Hauppauge. Thanks! */
+@@ -341,8 +343,10 @@ static const char *decoderIC[] = {
+ 	"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
+ 	/* 30-34 */
+ 	"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
+-	/* 35-37 */
+-	"SAA7131", "CX25837", "CX23887"
++	/* 35-39 */
++	"SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
++	/* 40-42 */
++	"SAA7164", "CX23885B", "AU8522"
+ };
+ 
+ static int hasRadioTuner(int tunerType)
+diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
+index 74e1d30..fc24ef0 100644
+--- a/drivers/media/video/usbvision/Kconfig
++++ b/drivers/media/video/usbvision/Kconfig
+@@ -1,7 +1,7 @@
+ config VIDEO_USBVISION
+ 	tristate "USB video devices based on Nogatech NT1003/1004/1005"
+ 	depends on I2C && VIDEO_V4L2
+-	select MEDIA_TUNER
++	select VIDEO_TUNER
+ 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
+ 	---help---
+ 	  There are more than 50 different USB video devices based on
+diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
+index 5515234..03a87a3 100644
+--- a/drivers/misc/sgi-xp/xp.h
++++ b/drivers/misc/sgi-xp/xp.h
+@@ -157,215 +157,136 @@ struct xpc_msg {
+ /*
+  * Define the return values and values passed to user's callout functions.
+  * (It is important to add new value codes at the end just preceding
+- * xpcUnknownReason, which must have the highest numerical value.)
++ * xpUnknownReason, which must have the highest numerical value.)
+  */
+-enum xpc_retval {
+-	xpcSuccess = 0,
++enum xp_retval {
++	xpSuccess = 0,
+ 
+-	xpcNotConnected,	/*  1: channel is not connected */
+-	xpcConnected,		/*  2: channel connected (opened) */
+-	xpcRETIRED1,		/*  3: (formerly xpcDisconnected) */
++	xpNotConnected,		/*  1: channel is not connected */
++	xpConnected,		/*  2: channel connected (opened) */
++	xpRETIRED1,		/*  3: (formerly xpDisconnected) */
+ 
+-	xpcMsgReceived,		/*  4: message received */
+-	xpcMsgDelivered,	/*  5: message delivered and acknowledged */
++	xpMsgReceived,		/*  4: message received */
++	xpMsgDelivered,		/*  5: message delivered and acknowledged */
+ 
+-	xpcRETIRED2,		/*  6: (formerly xpcTransferFailed) */
++	xpRETIRED2,		/*  6: (formerly xpTransferFailed) */
+ 
+-	xpcNoWait,		/*  7: operation would require wait */
+-	xpcRetry,		/*  8: retry operation */
+-	xpcTimeout,		/*  9: timeout in xpc_allocate_msg_wait() */
+-	xpcInterrupted,		/* 10: interrupted wait */
++	xpNoWait,		/*  7: operation would require wait */
++	xpRetry,		/*  8: retry operation */
++	xpTimeout,		/*  9: timeout in xpc_allocate_msg_wait() */
++	xpInterrupted,		/* 10: interrupted wait */
+ 
+-	xpcUnequalMsgSizes,	/* 11: message size disparity between sides */
+-	xpcInvalidAddress,	/* 12: invalid address */
++	xpUnequalMsgSizes,	/* 11: message size disparity between sides */
++	xpInvalidAddress,	/* 12: invalid address */
+ 
+-	xpcNoMemory,		/* 13: no memory available for XPC structures */
+-	xpcLackOfResources,	/* 14: insufficient resources for operation */
+-	xpcUnregistered,	/* 15: channel is not registered */
+-	xpcAlreadyRegistered,	/* 16: channel is already registered */
++	xpNoMemory,		/* 13: no memory available for XPC structures */
++	xpLackOfResources,	/* 14: insufficient resources for operation */
++	xpUnregistered,		/* 15: channel is not registered */
++	xpAlreadyRegistered,	/* 16: channel is already registered */
+ 
+-	xpcPartitionDown,	/* 17: remote partition is down */
+-	xpcNotLoaded,		/* 18: XPC module is not loaded */
+-	xpcUnloading,		/* 19: this side is unloading XPC module */
++	xpPartitionDown,	/* 17: remote partition is down */
++	xpNotLoaded,		/* 18: XPC module is not loaded */
++	xpUnloading,		/* 19: this side is unloading XPC module */
+ 
+-	xpcBadMagic,		/* 20: XPC MAGIC string not found */
++	xpBadMagic,		/* 20: XPC MAGIC string not found */
+ 
+-	xpcReactivating,	/* 21: remote partition was reactivated */
++	xpReactivating,		/* 21: remote partition was reactivated */
+ 
+-	xpcUnregistering,	/* 22: this side is unregistering channel */
+-	xpcOtherUnregistering,	/* 23: other side is unregistering channel */
++	xpUnregistering,	/* 22: this side is unregistering channel */
++	xpOtherUnregistering,	/* 23: other side is unregistering channel */
+ 
+-	xpcCloneKThread,	/* 24: cloning kernel thread */
+-	xpcCloneKThreadFailed,	/* 25: cloning kernel thread failed */
++	xpCloneKThread,		/* 24: cloning kernel thread */
++	xpCloneKThreadFailed,	/* 25: cloning kernel thread failed */
+ 
+-	xpcNoHeartbeat,		/* 26: remote partition has no heartbeat */
++	xpNoHeartbeat,		/* 26: remote partition has no heartbeat */
+ 
+-	xpcPioReadError,	/* 27: PIO read error */
+-	xpcPhysAddrRegFailed,	/* 28: registration of phys addr range failed */
++	xpPioReadError,		/* 27: PIO read error */
++	xpPhysAddrRegFailed,	/* 28: registration of phys addr range failed */
+ 
+-	xpcBteDirectoryError,	/* 29: maps to BTEFAIL_DIR */
+-	xpcBtePoisonError,	/* 30: maps to BTEFAIL_POISON */
+-	xpcBteWriteError,	/* 31: maps to BTEFAIL_WERR */
+-	xpcBteAccessError,	/* 32: maps to BTEFAIL_ACCESS */
+-	xpcBtePWriteError,	/* 33: maps to BTEFAIL_PWERR */
+-	xpcBtePReadError,	/* 34: maps to BTEFAIL_PRERR */
+-	xpcBteTimeOutError,	/* 35: maps to BTEFAIL_TOUT */
+-	xpcBteXtalkError,	/* 36: maps to BTEFAIL_XTERR */
+-	xpcBteNotAvailable,	/* 37: maps to BTEFAIL_NOTAVAIL */
+-	xpcBteUnmappedError,	/* 38: unmapped BTEFAIL_ error */
++	xpRETIRED3,		/* 29: (formerly xpBteDirectoryError) */
++	xpRETIRED4,		/* 30: (formerly xpBtePoisonError) */
++	xpRETIRED5,		/* 31: (formerly xpBteWriteError) */
++	xpRETIRED6,		/* 32: (formerly xpBteAccessError) */
++	xpRETIRED7,		/* 33: (formerly xpBtePWriteError) */
++	xpRETIRED8,		/* 34: (formerly xpBtePReadError) */
++	xpRETIRED9,		/* 35: (formerly xpBteTimeOutError) */
++	xpRETIRED10,		/* 36: (formerly xpBteXtalkError) */
++	xpRETIRED11,		/* 37: (formerly xpBteNotAvailable) */
++	xpRETIRED12,		/* 38: (formerly xpBteUnmappedError) */
+ 
+-	xpcBadVersion,		/* 39: bad version number */
+-	xpcVarsNotSet,		/* 40: the XPC variables are not set up */
+-	xpcNoRsvdPageAddr,	/* 41: unable to get rsvd page's phys addr */
+-	xpcInvalidPartid,	/* 42: invalid partition ID */
+-	xpcLocalPartid,		/* 43: local partition ID */
++	xpBadVersion,		/* 39: bad version number */
++	xpVarsNotSet,		/* 40: the XPC variables are not set up */
++	xpNoRsvdPageAddr,	/* 41: unable to get rsvd page's phys addr */
++	xpInvalidPartid,	/* 42: invalid partition ID */
++	xpLocalPartid,		/* 43: local partition ID */
+ 
+-	xpcOtherGoingDown,	/* 44: other side going down, reason unknown */
+-	xpcSystemGoingDown,	/* 45: system is going down, reason unknown */
+-	xpcSystemHalt,		/* 46: system is being halted */
+-	xpcSystemReboot,	/* 47: system is being rebooted */
+-	xpcSystemPoweroff,	/* 48: system is being powered off */
++	xpOtherGoingDown,	/* 44: other side going down, reason unknown */
++	xpSystemGoingDown,	/* 45: system is going down, reason unknown */
++	xpSystemHalt,		/* 46: system is being halted */
++	xpSystemReboot,		/* 47: system is being rebooted */
++	xpSystemPoweroff,	/* 48: system is being powered off */
+ 
+-	xpcDisconnecting,	/* 49: channel disconnecting (closing) */
++	xpDisconnecting,	/* 49: channel disconnecting (closing) */
+ 
+-	xpcOpenCloseError,	/* 50: channel open/close protocol error */
++	xpOpenCloseError,	/* 50: channel open/close protocol error */
+ 
+-	xpcDisconnected,	/* 51: channel disconnected (closed) */
++	xpDisconnected,		/* 51: channel disconnected (closed) */
+ 
+-	xpcBteSh2Start,		/* 52: BTE CRB timeout */
++	xpBteCopyError,		/* 52: bte_copy() returned error */
+ 
+-				/* 53: 0x1 BTE Error Response Short */
+-	xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT,
+-
+-				/* 54: 0x2 BTE Error Response Long */
+-	xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG,
+-
+-				/* 56: 0x4 BTE Error Response DSB */
+-	xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP,
+-
+-				/* 60: 0x8 BTE Error Response Access */
+-	xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS,
+-
+-				/* 68: 0x10 BTE Error CRB timeout */
+-	xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO,
+-
+-				/* 84: 0x20 BTE Error NACK limit */
+-	xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT,
+-
+-				/* 115: BTE end */
+-	xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL,
+-
+-	xpcUnknownReason	/* 116: unknown reason - must be last in enum */
++	xpUnknownReason		/* 53: unknown reason - must be last in enum */
+ };
+ 
+ /*
+- * Define the callout function types used by XPC to update the user on
+- * connection activity and state changes (via the user function registered by
+- * xpc_connect()) and to notify them of messages received and delivered (via
+- * the user function registered by xpc_send_notify()).
+- *
+- * The two function types are xpc_channel_func and xpc_notify_func and
+- * both share the following arguments, with the exception of "data", which
+- * only xpc_channel_func has.
++ * Define the callout function type used by XPC to update the user on
++ * connection activity and state changes via the user function registered
++ * by xpc_connect().
+  *
+  * Arguments:
+  *
+- *	reason - reason code. (See following table.)
++ *	reason - reason code.
+  *	partid - partition ID associated with condition.
+  *	ch_number - channel # associated with condition.
+- *	data - pointer to optional data. (See following table.)
++ *	data - pointer to optional data.
+  *	key - pointer to optional user-defined value provided as the "key"
+- *	      argument to xpc_connect() or xpc_send_notify().
++ *	      argument to xpc_connect().
+  *
+- * In the following table the "Optional Data" column applies to callouts made
+- * to functions registered by xpc_connect(). A "NA" in that column indicates
+- * that this reason code can be passed to functions registered by
+- * xpc_send_notify() (i.e. they don't have data arguments).
++ * A reason code of xpConnected indicates that a connection has been
++ * established to the specified partition on the specified channel. The data
++ * argument indicates the max number of entries allowed in the message queue.
+  *
+- * Also, the first three reason codes in the following table indicate
+- * success, whereas the others indicate failure. When a failure reason code
+- * is received, one can assume that the channel is not connected.
++ * A reason code of xpMsgReceived indicates that a XPC message arrived from
++ * the specified partition on the specified channel. The data argument
++ * specifies the address of the message's payload. The user must call
++ * xpc_received() when finished with the payload.
+  *
+- *
+- * Reason Code          | Cause                          | Optional Data
+- * =====================+================================+=====================
+- * xpcConnected         | connection has been established| max #of entries
+- *                      | to the specified partition on  | allowed in message
+- *                      | the specified channel          | queue
+- * ---------------------+--------------------------------+---------------------
+- * xpcMsgReceived       | an XPC message arrived from    | address of payload
+- *                      | the specified partition on the |
+- *                      | specified channel              | [the user must call
+- *                      |                                | xpc_received() when
+- *                      |                                | finished with the
+- *                      |                                | payload]
+- * ---------------------+--------------------------------+---------------------
+- * xpcMsgDelivered      | notification that the message  | NA
+- *                      | was delivered to the intended  |
+- *                      | recipient and that they have   |
+- *                      | acknowledged its receipt by    |
+- *                      | calling xpc_received()         |
+- * =====================+================================+=====================
+- * xpcUnequalMsgSizes   | can't connect to the specified | NULL
+- *                      | partition on the specified     |
+- *                      | channel because of mismatched  |
+- *                      | message sizes                  |
+- * ---------------------+--------------------------------+---------------------
+- * xpcNoMemory          | insufficient memory avaiable   | NULL
+- *                      | to allocate message queue      |
+- * ---------------------+--------------------------------+---------------------
+- * xpcLackOfResources   | lack of resources to create    | NULL
+- *                      | the necessary kthreads to      |
+- *                      | support the channel            |
+- * ---------------------+--------------------------------+---------------------
+- * xpcUnregistering     | this side's user has           | NULL or NA
+- *                      | unregistered by calling        |
+- *                      | xpc_disconnect()               |
+- * ---------------------+--------------------------------+---------------------
+- * xpcOtherUnregistering| the other side's user has      | NULL or NA
+- *                      | unregistered by calling        |
+- *                      | xpc_disconnect()               |
+- * ---------------------+--------------------------------+---------------------
+- * xpcNoHeartbeat       | the other side's XPC is no     | NULL or NA
+- *                      | longer heartbeating            |
+- *                      |                                |
+- * ---------------------+--------------------------------+---------------------
+- * xpcUnloading         | this side's XPC module is      | NULL or NA
+- *                      | being unloaded                 |
+- *                      |                                |
+- * ---------------------+--------------------------------+---------------------
+- * xpcOtherUnloading    | the other side's XPC module is | NULL or NA
+- *                      | is being unloaded              |
+- *                      |                                |
+- * ---------------------+--------------------------------+---------------------
+- * xpcPioReadError      | xp_nofault_PIOR() returned an  | NULL or NA
+- *                      | error while sending an IPI     |
+- *                      |                                |
+- * ---------------------+--------------------------------+---------------------
+- * xpcInvalidAddress    | the address either received or | NULL or NA
+- *                      | sent by the specified partition|
+- *                      | is invalid                     |
+- * ---------------------+--------------------------------+---------------------
+- * xpcBteNotAvailable   | attempt to pull data from the  | NULL or NA
+- * xpcBtePoisonError    | specified partition over the   |
+- * xpcBteWriteError     | specified channel via a        |
+- * xpcBteAccessError    | bte_copy() failed              |
+- * xpcBteTimeOutError   |                                |
+- * xpcBteXtalkError     |                                |
+- * xpcBteDirectoryError |                                |
+- * xpcBteGenericError   |                                |
+- * xpcBteUnmappedError  |                                |
+- * ---------------------+--------------------------------+---------------------
+- * xpcUnknownReason     | the specified channel to the   | NULL or NA
+- *                      | specified partition was        |
+- *                      | unavailable for unknown reasons|
+- * =====================+================================+=====================
++ * All other reason codes indicate failure. The data argmument is NULL.
++ * When a failure reason code is received, one can assume that the channel
++ * is not connected.
+  */
+-
+-typedef void (*xpc_channel_func) (enum xpc_retval reason, partid_t partid,
++typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
+ 				  int ch_number, void *data, void *key);
+ 
+-typedef void (*xpc_notify_func) (enum xpc_retval reason, partid_t partid,
++/*
++ * Define the callout function type used by XPC to notify the user of
++ * messages received and delivered via the user function registered by
++ * xpc_send_notify().
++ *
++ * Arguments:
++ *
++ *	reason - reason code.
++ *	partid - partition ID associated with condition.
++ *	ch_number - channel # associated with condition.
++ *	key - pointer to optional user-defined value provided as the "key"
++ *	      argument to xpc_send_notify().
++ *
++ * A reason code of xpMsgDelivered indicates that the message was delivered
++ * to the intended recipient and that they have acknowledged its receipt by
++ * calling xpc_received().
++ *
++ * All other reason codes indicate failure.
++ */
++typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
+ 				 int ch_number, void *key);
+ 
+ /*
+@@ -401,57 +322,57 @@ struct xpc_registration {
+ struct xpc_interface {
+ 	void (*connect) (int);
+ 	void (*disconnect) (int);
+-	enum xpc_retval (*allocate) (partid_t, int, u32, void **);
+-	enum xpc_retval (*send) (partid_t, int, void *);
+-	enum xpc_retval (*send_notify) (partid_t, int, void *,
++	enum xp_retval (*allocate) (short, int, u32, void **);
++	enum xp_retval (*send) (short, int, void *);
++	enum xp_retval (*send_notify) (short, int, void *,
+ 					xpc_notify_func, void *);
+-	void (*received) (partid_t, int, void *);
+-	enum xpc_retval (*partid_to_nasids) (partid_t, void *);
++	void (*received) (short, int, void *);
++	enum xp_retval (*partid_to_nasids) (short, void *);
+ };
+ 
+ extern struct xpc_interface xpc_interface;
+ 
+ extern void xpc_set_interface(void (*)(int),
+ 			      void (*)(int),
+-			      enum xpc_retval (*)(partid_t, int, u32, void **),
+-			      enum xpc_retval (*)(partid_t, int, void *),
+-			      enum xpc_retval (*)(partid_t, int, void *,
++			      enum xp_retval (*)(short, int, u32, void **),
++			      enum xp_retval (*)(short, int, void *),
++			      enum xp_retval (*)(short, int, void *,
+ 						  xpc_notify_func, void *),
+-			      void (*)(partid_t, int, void *),
+-			      enum xpc_retval (*)(partid_t, void *));
++			      void (*)(short, int, void *),
++			      enum xp_retval (*)(short, void *));
+ extern void xpc_clear_interface(void);
+ 
+-extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
++extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
+ 				   u16, u32, u32);
+ extern void xpc_disconnect(int);
+ 
+-static inline enum xpc_retval
+-xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
++static inline enum xp_retval
++xpc_allocate(short partid, int ch_number, u32 flags, void **payload)
+ {
+ 	return xpc_interface.allocate(partid, ch_number, flags, payload);
+ }
+ 
+-static inline enum xpc_retval
+-xpc_send(partid_t partid, int ch_number, void *payload)
++static inline enum xp_retval
++xpc_send(short partid, int ch_number, void *payload)
+ {
+ 	return xpc_interface.send(partid, ch_number, payload);
+ }
+ 
+-static inline enum xpc_retval
+-xpc_send_notify(partid_t partid, int ch_number, void *payload,
++static inline enum xp_retval
++xpc_send_notify(short partid, int ch_number, void *payload,
+ 		xpc_notify_func func, void *key)
+ {
+ 	return xpc_interface.send_notify(partid, ch_number, payload, func, key);
+ }
+ 
+ static inline void
+-xpc_received(partid_t partid, int ch_number, void *payload)
++xpc_received(short partid, int ch_number, void *payload)
+ {
+ 	return xpc_interface.received(partid, ch_number, payload);
+ }
+ 
+-static inline enum xpc_retval
+-xpc_partid_to_nasids(partid_t partid, void *nasids)
++static inline enum xp_retval
++xpc_partid_to_nasids(short partid, void *nasids)
+ {
+ 	return xpc_interface.partid_to_nasids(partid, nasids);
+ }
+diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
+index 1fbf99b..196480b 100644
+--- a/drivers/misc/sgi-xp/xp_main.c
++++ b/drivers/misc/sgi-xp/xp_main.c
+@@ -42,21 +42,21 @@ EXPORT_SYMBOL_GPL(xpc_registrations);
+ /*
+  * Initialize the XPC interface to indicate that XPC isn't loaded.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_notloaded(void)
+ {
+-	return xpcNotLoaded;
++	return xpNotLoaded;
+ }
+ 
+ struct xpc_interface xpc_interface = {
+ 	(void (*)(int))xpc_notloaded,
+ 	(void (*)(int))xpc_notloaded,
+-	(enum xpc_retval(*)(partid_t, int, u32, void **))xpc_notloaded,
+-	(enum xpc_retval(*)(partid_t, int, void *))xpc_notloaded,
+-	(enum xpc_retval(*)(partid_t, int, void *, xpc_notify_func, void *))
++	(enum xp_retval(*)(short, int, u32, void **))xpc_notloaded,
++	(enum xp_retval(*)(short, int, void *))xpc_notloaded,
++	(enum xp_retval(*)(short, int, void *, xpc_notify_func, void *))
+ 	    xpc_notloaded,
+-	(void (*)(partid_t, int, void *))xpc_notloaded,
+-	(enum xpc_retval(*)(partid_t, void *))xpc_notloaded
++	(void (*)(short, int, void *))xpc_notloaded,
++	(enum xp_retval(*)(short, void *))xpc_notloaded
+ };
+ EXPORT_SYMBOL_GPL(xpc_interface);
+ 
+@@ -66,12 +66,12 @@ EXPORT_SYMBOL_GPL(xpc_interface);
+ void
+ xpc_set_interface(void (*connect) (int),
+ 		  void (*disconnect) (int),
+-		  enum xpc_retval (*allocate) (partid_t, int, u32, void **),
+-		  enum xpc_retval (*send) (partid_t, int, void *),
+-		  enum xpc_retval (*send_notify) (partid_t, int, void *,
++		  enum xp_retval (*allocate) (short, int, u32, void **),
++		  enum xp_retval (*send) (short, int, void *),
++		  enum xp_retval (*send_notify) (short, int, void *,
+ 						  xpc_notify_func, void *),
+-		  void (*received) (partid_t, int, void *),
+-		  enum xpc_retval (*partid_to_nasids) (partid_t, void *))
++		  void (*received) (short, int, void *),
++		  enum xp_retval (*partid_to_nasids) (short, void *))
+ {
+ 	xpc_interface.connect = connect;
+ 	xpc_interface.disconnect = disconnect;
+@@ -91,16 +91,16 @@ xpc_clear_interface(void)
+ {
+ 	xpc_interface.connect = (void (*)(int))xpc_notloaded;
+ 	xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
+-	xpc_interface.allocate = (enum xpc_retval(*)(partid_t, int, u32,
++	xpc_interface.allocate = (enum xp_retval(*)(short, int, u32,
+ 						     void **))xpc_notloaded;
+-	xpc_interface.send = (enum xpc_retval(*)(partid_t, int, void *))
++	xpc_interface.send = (enum xp_retval(*)(short, int, void *))
+ 	    xpc_notloaded;
+-	xpc_interface.send_notify = (enum xpc_retval(*)(partid_t, int, void *,
++	xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *,
+ 							xpc_notify_func,
+ 							void *))xpc_notloaded;
+-	xpc_interface.received = (void (*)(partid_t, int, void *))
++	xpc_interface.received = (void (*)(short, int, void *))
+ 	    xpc_notloaded;
+-	xpc_interface.partid_to_nasids = (enum xpc_retval(*)(partid_t, void *))
++	xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
+ 	    xpc_notloaded;
+ }
+ EXPORT_SYMBOL_GPL(xpc_clear_interface);
+@@ -123,13 +123,13 @@ EXPORT_SYMBOL_GPL(xpc_clear_interface);
+  *	nentries - max #of XPC message entries a message queue can contain.
+  *		   The actual number, which is determined when a connection
+  * 		   is established and may be less then requested, will be
+- *		   passed to the user via the xpcConnected callout.
++ *		   passed to the user via the xpConnected callout.
+  *	assigned_limit - max number of kthreads allowed to be processing
+  * 			 messages (per connection) at any given instant.
+  *	idle_limit - max number of kthreads allowed to be idle at any given
+  * 		     instant.
+  */
+-enum xpc_retval
++enum xp_retval
+ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
+ 	    u16 nentries, u32 assigned_limit, u32 idle_limit)
+ {
+@@ -143,12 +143,12 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
+ 	registration = &xpc_registrations[ch_number];
+ 
+ 	if (mutex_lock_interruptible(&registration->mutex) != 0)
+-		return xpcInterrupted;
++		return xpInterrupted;
+ 
+ 	/* if XPC_CHANNEL_REGISTERED(ch_number) */
+ 	if (registration->func != NULL) {
+ 		mutex_unlock(&registration->mutex);
+-		return xpcAlreadyRegistered;
++		return xpAlreadyRegistered;
+ 	}
+ 
+ 	/* register the channel for connection */
+@@ -163,7 +163,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
+ 
+ 	xpc_interface.connect(ch_number);
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ EXPORT_SYMBOL_GPL(xpc_connect);
+ 
+diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
+index 9eb6d4a..11ac267 100644
+--- a/drivers/misc/sgi-xp/xpc.h
++++ b/drivers/misc/sgi-xp/xpc.h
+@@ -172,13 +172,13 @@ struct xpc_vars {
+ 			(_version >= _XPC_VERSION(3, 1))
+ 
+ static inline int
+-xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
++xpc_hb_allowed(short partid, struct xpc_vars *vars)
+ {
+ 	return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
+ }
+ 
+ static inline void
+-xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
++xpc_allow_hb(short partid, struct xpc_vars *vars)
+ {
+ 	u64 old_mask, new_mask;
+ 
+@@ -190,7 +190,7 @@ xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
+ }
+ 
+ static inline void
+-xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
++xpc_disallow_hb(short partid, struct xpc_vars *vars)
+ {
+ 	u64 old_mask, new_mask;
+ 
+@@ -408,11 +408,11 @@ struct xpc_notify {
+  *	messages.
+  */
+ struct xpc_channel {
+-	partid_t partid;	/* ID of remote partition connected */
++	short partid;		/* ID of remote partition connected */
+ 	spinlock_t lock;	/* lock for updating this structure */
+ 	u32 flags;		/* general flags */
+ 
+-	enum xpc_retval reason;	/* reason why channel is disconnect'g */
++	enum xp_retval reason;	/* reason why channel is disconnect'g */
+ 	int reason_line;	/* line# disconnect initiated from */
+ 
+ 	u16 number;		/* channel # */
+@@ -522,7 +522,7 @@ struct xpc_partition {
+ 	spinlock_t act_lock;	/* protect updating of act_state */
+ 	u8 act_state;		/* from XPC HB viewpoint */
+ 	u8 remote_vars_version;	/* version# of partition's vars */
+-	enum xpc_retval reason;	/* reason partition is deactivating */
++	enum xp_retval reason;	/* reason partition is deactivating */
+ 	int reason_line;	/* line# deactivation initiated from */
+ 	int reactivate_nasid;	/* nasid in partition to reactivate */
+ 
+@@ -615,7 +615,7 @@ struct xpc_partition {
+ /* interval in seconds to print 'waiting disengagement' messages */
+ #define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
+ 
+-#define XPC_PARTID(_p)	((partid_t) ((_p) - &xpc_partitions[0]))
++#define XPC_PARTID(_p)	((short)((_p) - &xpc_partitions[0]))
+ 
+ /* found in xp_main.c */
+ extern struct xpc_registration xpc_registrations[];
+@@ -646,31 +646,31 @@ extern void xpc_allow_IPI_ops(void);
+ extern void xpc_restrict_IPI_ops(void);
+ extern int xpc_identify_act_IRQ_sender(void);
+ extern int xpc_partition_disengaged(struct xpc_partition *);
+-extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
++extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
+ extern void xpc_mark_partition_inactive(struct xpc_partition *);
+ extern void xpc_discovery(void);
+ extern void xpc_check_remote_hb(void);
+ extern void xpc_deactivate_partition(const int, struct xpc_partition *,
+-				     enum xpc_retval);
+-extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
++				     enum xp_retval);
++extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
+ 
+ /* found in xpc_channel.c */
+ extern void xpc_initiate_connect(int);
+ extern void xpc_initiate_disconnect(int);
+-extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
+-extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
+-extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
+-						xpc_notify_func, void *);
+-extern void xpc_initiate_received(partid_t, int, void *);
+-extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
+-extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
++extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
++extern enum xp_retval xpc_initiate_send(short, int, void *);
++extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
++					       xpc_notify_func, void *);
++extern void xpc_initiate_received(short, int, void *);
++extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
++extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
+ extern void xpc_process_channel_activity(struct xpc_partition *);
+ extern void xpc_connected_callout(struct xpc_channel *);
+ extern void xpc_deliver_msg(struct xpc_channel *);
+ extern void xpc_disconnect_channel(const int, struct xpc_channel *,
+-				   enum xpc_retval, unsigned long *);
+-extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
+-extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
++				   enum xp_retval, unsigned long *);
++extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
++extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
+ extern void xpc_teardown_infrastructure(struct xpc_partition *);
+ 
+ static inline void
+@@ -901,7 +901,7 @@ xpc_IPI_receive(AMO_t *amo)
+ 	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
+ }
+ 
+-static inline enum xpc_retval
++static inline enum xp_retval
+ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
+ {
+ 	int ret = 0;
+@@ -923,7 +923,7 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
+ 
+ 	local_irq_restore(irq_flags);
+ 
+-	return ((ret == 0) ? xpcSuccess : xpcPioReadError);
++	return ((ret == 0) ? xpSuccess : xpPioReadError);
+ }
+ 
+ /*
+@@ -992,7 +992,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
+ 		    unsigned long *irq_flags)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[ch->partid];
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
+ 		ret = xpc_IPI_send(part->remote_IPI_amo_va,
+@@ -1001,7 +1001,7 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
+ 				   part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
+ 		dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
+ 			ipi_flag_string, ch->partid, ch->number, ret);
+-		if (unlikely(ret != xpcSuccess)) {
++		if (unlikely(ret != xpSuccess)) {
+ 			if (irq_flags != NULL)
+ 				spin_unlock_irqrestore(&ch->lock, *irq_flags);
+ 			XPC_DEACTIVATE_PARTITION(part, ret);
+@@ -1123,41 +1123,10 @@ xpc_IPI_init(int index)
+ 	return amo;
+ }
+ 
+-static inline enum xpc_retval
++static inline enum xp_retval
+ xpc_map_bte_errors(bte_result_t error)
+ {
+-	if (error == BTE_SUCCESS)
+-		return xpcSuccess;
+-
+-	if (is_shub2()) {
+-		if (BTE_VALID_SH2_ERROR(error))
+-			return xpcBteSh2Start + error;
+-		return xpcBteUnmappedError;
+-	}
+-	switch (error) {
+-	case BTE_SUCCESS:
+-		return xpcSuccess;
+-	case BTEFAIL_DIR:
+-		return xpcBteDirectoryError;
+-	case BTEFAIL_POISON:
+-		return xpcBtePoisonError;
+-	case BTEFAIL_WERR:
+-		return xpcBteWriteError;
+-	case BTEFAIL_ACCESS:
+-		return xpcBteAccessError;
+-	case BTEFAIL_PWERR:
+-		return xpcBtePWriteError;
+-	case BTEFAIL_PRERR:
+-		return xpcBtePReadError;
+-	case BTEFAIL_TOUT:
+-		return xpcBteTimeOutError;
+-	case BTEFAIL_XTERR:
+-		return xpcBteXtalkError;
+-	case BTEFAIL_NOTAVAIL:
+-		return xpcBteNotAvailable;
+-	default:
+-		return xpcBteUnmappedError;
+-	}
++	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
+ }
+ 
+ /*
+diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
+index bfcb9ea..9c90c2d 100644
+--- a/drivers/misc/sgi-xp/xpc_channel.c
++++ b/drivers/misc/sgi-xp/xpc_channel.c
+@@ -53,7 +53,7 @@ xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
+  * Set up the initial values for the XPartition Communication channels.
+  */
+ static void
+-xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
++xpc_initialize_channels(struct xpc_partition *part, short partid)
+ {
+ 	int ch_number;
+ 	struct xpc_channel *ch;
+@@ -90,12 +90,12 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
+  * Setup the infrastructure necessary to support XPartition Communication
+  * between the specified remote partition and the local one.
+  */
+-enum xpc_retval
++enum xp_retval
+ xpc_setup_infrastructure(struct xpc_partition *part)
+ {
+ 	int ret, cpuid;
+ 	struct timer_list *timer;
+-	partid_t partid = XPC_PARTID(part);
++	short partid = XPC_PARTID(part);
+ 
+ 	/*
+ 	 * Zero out MOST of the entry for this partition. Only the fields
+@@ -114,7 +114,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 				 GFP_KERNEL);
+ 	if (part->channels == NULL) {
+ 		dev_err(xpc_chan, "can't get memory for channels\n");
+-		return xpcNoMemory;
++		return xpNoMemory;
+ 	}
+ 
+ 	part->nchannels = XPC_NCHANNELS;
+@@ -129,7 +129,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 		part->channels = NULL;
+ 		dev_err(xpc_chan, "can't get memory for local get/put "
+ 			"values\n");
+-		return xpcNoMemory;
++		return xpNoMemory;
+ 	}
+ 
+ 	part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
+@@ -143,7 +143,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 		part->local_GPs = NULL;
+ 		kfree(part->channels);
+ 		part->channels = NULL;
+-		return xpcNoMemory;
++		return xpNoMemory;
+ 	}
+ 
+ 	/* allocate all the required open and close args */
+@@ -159,7 +159,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 		part->local_GPs = NULL;
+ 		kfree(part->channels);
+ 		part->channels = NULL;
+-		return xpcNoMemory;
++		return xpNoMemory;
+ 	}
+ 
+ 	part->remote_openclose_args =
+@@ -175,7 +175,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 		part->local_GPs = NULL;
+ 		kfree(part->channels);
+ 		part->channels = NULL;
+-		return xpcNoMemory;
++		return xpNoMemory;
+ 	}
+ 
+ 	xpc_initialize_channels(part, partid);
+@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 		part->local_GPs = NULL;
+ 		kfree(part->channels);
+ 		part->channels = NULL;
+-		return xpcLackOfResources;
++		return xpLackOfResources;
+ 	}
+ 
+ 	/* Setup a timer to check for dropped IPIs */
+@@ -243,7 +243,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+ 	xpc_vars_part[partid].nchannels = part->nchannels;
+ 	xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -254,7 +254,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
+  * dst must be a cacheline aligned virtual address on this partition.
+  * cnt must be an cacheline sized
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
+ 			   const void *src, size_t cnt)
+ {
+@@ -270,7 +270,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
+ 	bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt,
+ 			      (BTE_NORMAL | BTE_WACQUIRE), NULL);
+ 	if (bte_ret == BTE_SUCCESS)
+-		return xpcSuccess;
++		return xpSuccess;
+ 
+ 	dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
+ 		XPC_PARTID(part), bte_ret);
+@@ -282,7 +282,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
+  * Pull the remote per partition specific variables from the specified
+  * partition.
+  */
+-enum xpc_retval
++enum xp_retval
+ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ {
+ 	u8 buffer[L1_CACHE_BYTES * 2];
+@@ -290,8 +290,8 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ 	    (struct xpc_vars_part *)L1_CACHE_ALIGN((u64)buffer);
+ 	struct xpc_vars_part *pulled_entry;
+ 	u64 remote_entry_cacheline_pa, remote_entry_pa;
+-	partid_t partid = XPC_PARTID(part);
+-	enum xpc_retval ret;
++	short partid = XPC_PARTID(part);
++	enum xp_retval ret;
+ 
+ 	/* pull the cacheline that contains the variables we're interested in */
+ 
+@@ -311,7 +311,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ 	ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline,
+ 					 (void *)remote_entry_cacheline_pa,
+ 					 L1_CACHE_BYTES);
+-	if (ret != xpcSuccess) {
++	if (ret != xpSuccess) {
+ 		dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
+ 			"partition %d, ret=%d\n", partid, ret);
+ 		return ret;
+@@ -326,11 +326,11 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ 			dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
+ 				"partition %d has bad magic value (=0x%lx)\n",
+ 				partid, sn_partition_id, pulled_entry->magic);
+-			return xpcBadMagic;
++			return xpBadMagic;
+ 		}
+ 
+ 		/* they've not been initialized yet */
+-		return xpcRetry;
++		return xpRetry;
+ 	}
+ 
+ 	if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
+@@ -344,7 +344,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ 			dev_err(xpc_chan, "partition %d's XPC vars_part for "
+ 				"partition %d are not valid\n", partid,
+ 				sn_partition_id);
+-			return xpcInvalidAddress;
++			return xpInvalidAddress;
+ 		}
+ 
+ 		/* the variables we imported look to be valid */
+@@ -366,9 +366,9 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
+ 	}
+ 
+ 	if (pulled_entry->magic == XPC_VP_MAGIC1)
+-		return xpcRetry;
++		return xpRetry;
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -379,7 +379,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
+ {
+ 	unsigned long irq_flags;
+ 	u64 IPI_amo;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	/*
+ 	 * See if there are any IPI flags to be handled.
+@@ -398,7 +398,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
+ 						 (void *)part->
+ 						 remote_openclose_args_pa,
+ 						 XPC_OPENCLOSE_ARGS_SIZE);
+-		if (ret != xpcSuccess) {
++		if (ret != xpSuccess) {
+ 			XPC_DEACTIVATE_PARTITION(part, ret);
+ 
+ 			dev_dbg(xpc_chan, "failed to pull openclose args from "
+@@ -414,7 +414,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
+ 		ret = xpc_pull_remote_cachelines(part, part->remote_GPs,
+ 						 (void *)part->remote_GPs_pa,
+ 						 XPC_GP_SIZE);
+-		if (ret != xpcSuccess) {
++		if (ret != xpSuccess) {
+ 			XPC_DEACTIVATE_PARTITION(part, ret);
+ 
+ 			dev_dbg(xpc_chan, "failed to pull GPs from partition "
+@@ -431,7 +431,7 @@ xpc_get_IPI_flags(struct xpc_partition *part)
+ /*
+  * Allocate the local message queue and the notify queue.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
+ {
+ 	unsigned long irq_flags;
+@@ -464,18 +464,18 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
+ 			ch->local_nentries = nentries;
+ 		}
+ 		spin_unlock_irqrestore(&ch->lock, irq_flags);
+-		return xpcSuccess;
++		return xpSuccess;
+ 	}
+ 
+ 	dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
+ 		"queue, partid=%d, channel=%d\n", ch->partid, ch->number);
+-	return xpcNoMemory;
++	return xpNoMemory;
+ }
+ 
+ /*
+  * Allocate the cached remote message queue.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
+ {
+ 	unsigned long irq_flags;
+@@ -502,12 +502,12 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
+ 			ch->remote_nentries = nentries;
+ 		}
+ 		spin_unlock_irqrestore(&ch->lock, irq_flags);
+-		return xpcSuccess;
++		return xpSuccess;
+ 	}
+ 
+ 	dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
+ 		"partid=%d, channel=%d\n", ch->partid, ch->number);
+-	return xpcNoMemory;
++	return xpNoMemory;
+ }
+ 
+ /*
+@@ -515,20 +515,20 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
+  *
+  * Note: Assumes all of the channel sizes are filled in.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_allocate_msgqueues(struct xpc_channel *ch)
+ {
+ 	unsigned long irq_flags;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	DBUG_ON(ch->flags & XPC_C_SETUP);
+ 
+ 	ret = xpc_allocate_local_msgqueue(ch);
+-	if (ret != xpcSuccess)
++	if (ret != xpSuccess)
+ 		return ret;
+ 
+ 	ret = xpc_allocate_remote_msgqueue(ch);
+-	if (ret != xpcSuccess) {
++	if (ret != xpSuccess) {
+ 		kfree(ch->local_msgqueue_base);
+ 		ch->local_msgqueue = NULL;
+ 		kfree(ch->notify_queue);
+@@ -540,7 +540,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
+ 	ch->flags |= XPC_C_SETUP;
+ 	spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -552,7 +552,7 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
+ static void
+ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
+ {
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	DBUG_ON(!spin_is_locked(&ch->lock));
+ 
+@@ -568,7 +568,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
+ 		ret = xpc_allocate_msgqueues(ch);
+ 		spin_lock_irqsave(&ch->lock, *irq_flags);
+ 
+-		if (ret != xpcSuccess)
++		if (ret != xpSuccess)
+ 			XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
+ 
+ 		if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
+@@ -603,7 +603,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
+  * Notify those who wanted to be notified upon delivery of their message.
+  */
+ static void
+-xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
++xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
+ {
+ 	struct xpc_notify *notify;
+ 	u8 notify_type;
+@@ -748,7 +748,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
+ 
+ 	if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
+ 		spin_unlock_irqrestore(&ch->lock, *irq_flags);
+-		xpc_disconnect_callout(ch, xpcDisconnected);
++		xpc_disconnect_callout(ch, xpDisconnected);
+ 		spin_lock_irqsave(&ch->lock, *irq_flags);
+ 	}
+ 
+@@ -791,7 +791,7 @@ xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number,
+ 	struct xpc_openclose_args *args =
+ 	    &part->remote_openclose_args[ch_number];
+ 	struct xpc_channel *ch = &part->channels[ch_number];
+-	enum xpc_retval reason;
++	enum xp_retval reason;
+ 
+ 	spin_lock_irqsave(&ch->lock, irq_flags);
+ 
+@@ -871,10 +871,10 @@ again:
+ 
+ 		if (!(ch->flags & XPC_C_DISCONNECTING)) {
+ 			reason = args->reason;
+-			if (reason <= xpcSuccess || reason > xpcUnknownReason)
+-				reason = xpcUnknownReason;
+-			else if (reason == xpcUnregistering)
+-				reason = xpcOtherUnregistering;
++			if (reason <= xpSuccess || reason > xpUnknownReason)
++				reason = xpUnknownReason;
++			else if (reason == xpUnregistering)
++				reason = xpOtherUnregistering;
+ 
+ 			XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
+ 
+@@ -961,7 +961,7 @@ again:
+ 
+ 		if (ch->flags & XPC_C_OPENREQUEST) {
+ 			if (args->msg_size != ch->msg_size) {
+-				XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
++				XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
+ 						       &irq_flags);
+ 				spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 				return;
+@@ -991,7 +991,7 @@ again:
+ 			return;
+ 		}
+ 		if (!(ch->flags & XPC_C_OPENREQUEST)) {
+-			XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError,
++			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
+ 					       &irq_flags);
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 			return;
+@@ -1042,18 +1042,18 @@ again:
+ /*
+  * Attempt to establish a channel connection to a remote partition.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_connect_channel(struct xpc_channel *ch)
+ {
+ 	unsigned long irq_flags;
+ 	struct xpc_registration *registration = &xpc_registrations[ch->number];
+ 
+ 	if (mutex_trylock(&registration->mutex) == 0)
+-		return xpcRetry;
++		return xpRetry;
+ 
+ 	if (!XPC_CHANNEL_REGISTERED(ch->number)) {
+ 		mutex_unlock(&registration->mutex);
+-		return xpcUnregistered;
++		return xpUnregistered;
+ 	}
+ 
+ 	spin_lock_irqsave(&ch->lock, irq_flags);
+@@ -1095,10 +1095,10 @@ xpc_connect_channel(struct xpc_channel *ch)
+ 			 * the channel lock as needed.
+ 			 */
+ 			mutex_unlock(&registration->mutex);
+-			XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
++			XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
+ 					       &irq_flags);
+ 			spin_unlock_irqrestore(&ch->lock, irq_flags);
+-			return xpcUnequalMsgSizes;
++			return xpUnequalMsgSizes;
+ 		}
+ 	} else {
+ 		ch->msg_size = registration->msg_size;
+@@ -1120,7 +1120,7 @@ xpc_connect_channel(struct xpc_channel *ch)
+ 
+ 	spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -1203,7 +1203,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
+ 			 * Notify senders that messages sent have been
+ 			 * received and delivered by the other side.
+ 			 */
+-			xpc_notify_senders(ch, xpcMsgDelivered,
++			xpc_notify_senders(ch, xpMsgDelivered,
+ 					   ch->remote_GP.get);
+ 		}
+ 
+@@ -1335,7 +1335,7 @@ xpc_process_channel_activity(struct xpc_partition *part)
+  * at the same time.
+  */
+ void
+-xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
++xpc_partition_going_down(struct xpc_partition *part, enum xp_retval reason)
+ {
+ 	unsigned long irq_flags;
+ 	int ch_number;
+@@ -1375,7 +1375,7 @@ xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
+ void
+ xpc_teardown_infrastructure(struct xpc_partition *part)
+ {
+-	partid_t partid = XPC_PARTID(part);
++	short partid = XPC_PARTID(part);
+ 
+ 	/*
+ 	 * We start off by making this partition inaccessible to local
+@@ -1428,7 +1428,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part)
+ void
+ xpc_initiate_connect(int ch_number)
+ {
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+ 	struct xpc_channel *ch;
+ 
+@@ -1456,13 +1456,13 @@ xpc_connected_callout(struct xpc_channel *ch)
+ 	/* let the registerer know that a connection has been established */
+ 
+ 	if (ch->func != NULL) {
+-		dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, "
++		dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, "
+ 			"partid=%d, channel=%d\n", ch->partid, ch->number);
+ 
+-		ch->func(xpcConnected, ch->partid, ch->number,
++		ch->func(xpConnected, ch->partid, ch->number,
+ 			 (void *)(u64)ch->local_nentries, ch->key);
+ 
+-		dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
++		dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, "
+ 			"partid=%d, channel=%d\n", ch->partid, ch->number);
+ 	}
+ }
+@@ -1484,7 +1484,7 @@ void
+ xpc_initiate_disconnect(int ch_number)
+ {
+ 	unsigned long irq_flags;
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+ 	struct xpc_channel *ch;
+ 
+@@ -1503,7 +1503,7 @@ xpc_initiate_disconnect(int ch_number)
+ 			if (!(ch->flags & XPC_C_DISCONNECTED)) {
+ 				ch->flags |= XPC_C_WDISCONNECT;
+ 
+-				XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
++				XPC_DISCONNECT_CHANNEL(ch, xpUnregistering,
+ 						       &irq_flags);
+ 			}
+ 
+@@ -1528,7 +1528,7 @@ xpc_initiate_disconnect(int ch_number)
+  */
+ void
+ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
+-		       enum xpc_retval reason, unsigned long *irq_flags)
++		       enum xp_retval reason, unsigned long *irq_flags)
+ {
+ 	u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
+ 
+@@ -1563,7 +1563,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
+ 
+ 	} else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
+ 		   !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
+-		/* start a kthread that will do the xpcDisconnecting callout */
++		/* start a kthread that will do the xpDisconnecting callout */
+ 		xpc_create_kthreads(ch, 1, 1);
+ 	}
+ 
+@@ -1575,7 +1575,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
+ }
+ 
+ void
+-xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
++xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason)
+ {
+ 	/*
+ 	 * Let the channel's registerer know that the channel is being
+@@ -1598,13 +1598,13 @@ xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
+  * Wait for a message entry to become available for the specified channel,
+  * but don't wait any longer than 1 jiffy.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_allocate_msg_wait(struct xpc_channel *ch)
+ {
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	if (ch->flags & XPC_C_DISCONNECTING) {
+-		DBUG_ON(ch->reason == xpcInterrupted);
++		DBUG_ON(ch->reason == xpInterrupted);
+ 		return ch->reason;
+ 	}
+ 
+@@ -1614,11 +1614,11 @@ xpc_allocate_msg_wait(struct xpc_channel *ch)
+ 
+ 	if (ch->flags & XPC_C_DISCONNECTING) {
+ 		ret = ch->reason;
+-		DBUG_ON(ch->reason == xpcInterrupted);
++		DBUG_ON(ch->reason == xpInterrupted);
+ 	} else if (ret == 0) {
+-		ret = xpcTimeout;
++		ret = xpTimeout;
+ 	} else {
+-		ret = xpcInterrupted;
++		ret = xpInterrupted;
+ 	}
+ 
+ 	return ret;
+@@ -1628,12 +1628,12 @@ xpc_allocate_msg_wait(struct xpc_channel *ch)
+  * Allocate an entry for a message from the message queue associated with the
+  * specified channel.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+ 		 struct xpc_msg **address_of_msg)
+ {
+ 	struct xpc_msg *msg;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 	s64 put;
+ 
+ 	/* this reference will be dropped in xpc_send_msg() */
+@@ -1645,7 +1645,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+ 	}
+ 	if (!(ch->flags & XPC_C_CONNECTED)) {
+ 		xpc_msgqueue_deref(ch);
+-		return xpcNotConnected;
++		return xpNotConnected;
+ 	}
+ 
+ 	/*
+@@ -1653,7 +1653,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+ 	 * If none are available, we'll make sure that we grab the latest
+ 	 * GP values.
+ 	 */
+-	ret = xpcTimeout;
++	ret = xpTimeout;
+ 
+ 	while (1) {
+ 
+@@ -1683,16 +1683,16 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+ 		 * that will cause the IPI handler to fetch the latest
+ 		 * GP values as if an IPI was sent by the other side.
+ 		 */
+-		if (ret == xpcTimeout)
++		if (ret == xpTimeout)
+ 			xpc_IPI_send_local_msgrequest(ch);
+ 
+ 		if (flags & XPC_NOWAIT) {
+ 			xpc_msgqueue_deref(ch);
+-			return xpcNoWait;
++			return xpNoWait;
+ 		}
+ 
+ 		ret = xpc_allocate_msg_wait(ch);
+-		if (ret != xpcInterrupted && ret != xpcTimeout) {
++		if (ret != xpInterrupted && ret != xpTimeout) {
+ 			xpc_msgqueue_deref(ch);
+ 			return ret;
+ 		}
+@@ -1711,7 +1711,7 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+ 
+ 	*address_of_msg = msg;
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -1727,11 +1727,11 @@ xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
+  *	payload - address of the allocated payload area pointer (filled in on
+  * 	          return) in which the user-defined message is constructed.
+  */
+-enum xpc_retval
+-xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
++enum xp_retval
++xpc_initiate_allocate(short partid, int ch_number, u32 flags, void **payload)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+-	enum xpc_retval ret = xpcUnknownReason;
++	enum xp_retval ret = xpUnknownReason;
+ 	struct xpc_msg *msg = NULL;
+ 
+ 	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+@@ -1814,11 +1814,11 @@ xpc_send_msgs(struct xpc_channel *ch, s64 initial_put)
+  * local message queue's Put value and sends an IPI to the partition the
+  * message is being sent to.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
+ 	     xpc_notify_func func, void *key)
+ {
+-	enum xpc_retval ret = xpcSuccess;
++	enum xp_retval ret = xpSuccess;
+ 	struct xpc_notify *notify = notify;
+ 	s64 put, msg_number = msg->number;
+ 
+@@ -1908,12 +1908,12 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
+  *	payload - pointer to the payload area allocated via
+  *			xpc_initiate_allocate().
+  */
+-enum xpc_retval
+-xpc_initiate_send(partid_t partid, int ch_number, void *payload)
++enum xp_retval
++xpc_initiate_send(short partid, int ch_number, void *payload)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
+ 		partid, ch_number);
+@@ -1957,13 +1957,13 @@ xpc_initiate_send(partid_t partid, int ch_number, void *payload)
+  *		  receipt. THIS FUNCTION MUST BE NON-BLOCKING.
+  *	key - user-defined key to be passed to the function when it's called.
+  */
+-enum xpc_retval
+-xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload,
++enum xp_retval
++xpc_initiate_send_notify(short partid, int ch_number, void *payload,
+ 			 xpc_notify_func func, void *key)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
+ 		partid, ch_number);
+@@ -1985,7 +1985,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
+ 	struct xpc_msg *remote_msg, *msg;
+ 	u32 msg_index, nmsgs;
+ 	u64 msg_offset;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
+ 		/* we were interrupted by a signal */
+@@ -2012,7 +2012,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
+ 
+ 		ret = xpc_pull_remote_cachelines(part, msg, remote_msg,
+ 						 nmsgs * ch->msg_size);
+-		if (ret != xpcSuccess) {
++		if (ret != xpSuccess) {
+ 
+ 			dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
+ 				" msg %ld from partition %d, channel=%d, "
+@@ -2112,7 +2112,7 @@ xpc_deliver_msg(struct xpc_channel *ch)
+ 				ch->number);
+ 
+ 			/* deliver the message to its intended recipient */
+-			ch->func(xpcMsgReceived, ch->partid, ch->number,
++			ch->func(xpMsgReceived, ch->partid, ch->number,
+ 				 &msg->payload, ch->key);
+ 
+ 			dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
+@@ -2203,7 +2203,7 @@ xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
+  *			xpc_initiate_allocate().
+  */
+ void
+-xpc_initiate_received(partid_t partid, int ch_number, void *payload)
++xpc_initiate_received(short partid, int ch_number, void *payload)
+ {
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	struct xpc_channel *ch;
+diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
+index f673ba9..08256ed 100644
+--- a/drivers/misc/sgi-xp/xpc_main.c
++++ b/drivers/misc/sgi-xp/xpc_main.c
+@@ -315,13 +315,13 @@ xpc_initiate_discovery(void *ignore)
+  * the XPC per partition variables from the remote partition and waiting for
+  * the remote partition to pull ours.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_make_first_contact(struct xpc_partition *part)
+ {
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+-	while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) {
+-		if (ret != xpcRetry) {
++	while ((ret = xpc_pull_remote_vars_part(part)) != xpSuccess) {
++		if (ret != xpRetry) {
+ 			XPC_DEACTIVATE_PARTITION(part, ret);
+ 			return ret;
+ 		}
+@@ -406,7 +406,7 @@ xpc_partition_up(struct xpc_partition *part)
+ 
+ 	dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part));
+ 
+-	if (xpc_setup_infrastructure(part) != xpcSuccess)
++	if (xpc_setup_infrastructure(part) != xpSuccess)
+ 		return;
+ 
+ 	/*
+@@ -418,7 +418,7 @@ xpc_partition_up(struct xpc_partition *part)
+ 
+ 	(void)xpc_part_ref(part);	/* this will always succeed */
+ 
+-	if (xpc_make_first_contact(part) == xpcSuccess)
++	if (xpc_make_first_contact(part) == xpSuccess)
+ 		xpc_channel_mgr(part);
+ 
+ 	xpc_part_deref(part);
+@@ -429,7 +429,7 @@ xpc_partition_up(struct xpc_partition *part)
+ static int
+ xpc_activating(void *__partid)
+ {
+-	partid_t partid = (u64)__partid;
++	short partid = (u64)__partid;
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	unsigned long irq_flags;
+ 
+@@ -470,7 +470,7 @@ xpc_activating(void *__partid)
+ 
+ 		spin_lock_irqsave(&part->act_lock, irq_flags);
+ 		part->act_state = XPC_P_INACTIVE;
+-		XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__);
++		XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__);
+ 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
+ 		part->remote_rp_pa = 0;
+ 		return 0;
+@@ -488,7 +488,7 @@ xpc_activating(void *__partid)
+ 	xpc_disallow_hb(partid, xpc_vars);
+ 	xpc_mark_partition_inactive(part);
+ 
+-	if (part->reason == xpcReactivating) {
++	if (part->reason == xpReactivating) {
+ 		/* interrupting ourselves results in activating partition */
+ 		xpc_IPI_send_reactivate(part);
+ 	}
+@@ -499,7 +499,7 @@ xpc_activating(void *__partid)
+ void
+ xpc_activate_partition(struct xpc_partition *part)
+ {
+-	partid_t partid = XPC_PARTID(part);
++	short partid = XPC_PARTID(part);
+ 	unsigned long irq_flags;
+ 	struct task_struct *kthread;
+ 
+@@ -508,7 +508,7 @@ xpc_activate_partition(struct xpc_partition *part)
+ 	DBUG_ON(part->act_state != XPC_P_INACTIVE);
+ 
+ 	part->act_state = XPC_P_ACTIVATION_REQ;
+-	XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
++	XPC_SET_REASON(part, xpCloneKThread, __LINE__);
+ 
+ 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
+ 
+@@ -517,7 +517,7 @@ xpc_activate_partition(struct xpc_partition *part)
+ 	if (IS_ERR(kthread)) {
+ 		spin_lock_irqsave(&part->act_lock, irq_flags);
+ 		part->act_state = XPC_P_INACTIVE;
+-		XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
++		XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__);
+ 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
+ 	}
+ }
+@@ -541,7 +541,7 @@ xpc_activate_partition(struct xpc_partition *part)
+ irqreturn_t
+ xpc_notify_IRQ_handler(int irq, void *dev_id)
+ {
+-	partid_t partid = (partid_t) (u64)dev_id;
++	short partid = (short)(u64)dev_id;
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 
+ 	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
+@@ -643,7 +643,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
+ static int
+ xpc_kthread_start(void *args)
+ {
+-	partid_t partid = XPC_UNPACK_ARG1(args);
++	short partid = XPC_UNPACK_ARG1(args);
+ 	u16 ch_number = XPC_UNPACK_ARG2(args);
+ 	struct xpc_partition *part = &xpc_partitions[partid];
+ 	struct xpc_channel *ch;
+@@ -696,7 +696,7 @@ xpc_kthread_start(void *args)
+ 		ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
+ 		spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 
+-		xpc_disconnect_callout(ch, xpcDisconnecting);
++		xpc_disconnect_callout(ch, xpDisconnecting);
+ 
+ 		spin_lock_irqsave(&ch->lock, irq_flags);
+ 		ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
+@@ -776,7 +776,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
+ 			 * then we'll deadlock if all other kthreads assigned
+ 			 * to this channel are blocked in the channel's
+ 			 * registerer, because the only thing that will unblock
+-			 * them is the xpcDisconnecting callout that this
++			 * them is the xpDisconnecting callout that this
+ 			 * failed kthread_run() would have made.
+ 			 */
+ 
+@@ -796,7 +796,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
+ 				 * to function.
+ 				 */
+ 				spin_lock_irqsave(&ch->lock, irq_flags);
+-				XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
++				XPC_DISCONNECT_CHANNEL(ch, xpLackOfResources,
+ 						       &irq_flags);
+ 				spin_unlock_irqrestore(&ch->lock, irq_flags);
+ 			}
+@@ -809,7 +809,7 @@ void
+ xpc_disconnect_wait(int ch_number)
+ {
+ 	unsigned long irq_flags;
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+ 	struct xpc_channel *ch;
+ 	int wakeup_channel_mgr;
+@@ -857,9 +857,9 @@ xpc_disconnect_wait(int ch_number)
+ }
+ 
+ static void
+-xpc_do_exit(enum xpc_retval reason)
++xpc_do_exit(enum xp_retval reason)
+ {
+-	partid_t partid;
++	short partid;
+ 	int active_part_count, printed_waiting_msg = 0;
+ 	struct xpc_partition *part;
+ 	unsigned long printmsg_time, disengage_request_timeout = 0;
+@@ -955,7 +955,7 @@ xpc_do_exit(enum xpc_retval reason)
+ 	del_timer_sync(&xpc_hb_timer);
+ 	DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
+ 
+-	if (reason == xpcUnloading) {
++	if (reason == xpUnloading) {
+ 		/* take ourselves off of the reboot_notifier_list */
+ 		(void)unregister_reboot_notifier(&xpc_reboot_notifier);
+ 
+@@ -981,20 +981,20 @@ xpc_do_exit(enum xpc_retval reason)
+ static int
+ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
+ {
+-	enum xpc_retval reason;
++	enum xp_retval reason;
+ 
+ 	switch (event) {
+ 	case SYS_RESTART:
+-		reason = xpcSystemReboot;
++		reason = xpSystemReboot;
+ 		break;
+ 	case SYS_HALT:
+-		reason = xpcSystemHalt;
++		reason = xpSystemHalt;
+ 		break;
+ 	case SYS_POWER_OFF:
+-		reason = xpcSystemPoweroff;
++		reason = xpSystemPoweroff;
+ 		break;
+ 	default:
+-		reason = xpcSystemGoingDown;
++		reason = xpSystemGoingDown;
+ 	}
+ 
+ 	xpc_do_exit(reason);
+@@ -1008,7 +1008,7 @@ static void
+ xpc_die_disengage(void)
+ {
+ 	struct xpc_partition *part;
+-	partid_t partid;
++	short partid;
+ 	unsigned long engaged;
+ 	long time, printmsg_time, disengage_request_timeout;
+ 
+@@ -1124,7 +1124,7 @@ int __init
+ xpc_init(void)
+ {
+ 	int ret;
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+ 	struct task_struct *kthread;
+ 	size_t buf_size;
+@@ -1279,7 +1279,7 @@ xpc_init(void)
+ 		/* mark this new thread as a non-starter */
+ 		complete(&xpc_discovery_exited);
+ 
+-		xpc_do_exit(xpcUnloading);
++		xpc_do_exit(xpUnloading);
+ 		return -EBUSY;
+ 	}
+ 
+@@ -1297,7 +1297,7 @@ module_init(xpc_init);
+ void __exit
+ xpc_exit(void)
+ {
+-	xpc_do_exit(xpcUnloading);
++	xpc_do_exit(xpUnloading);
+ }
+ 
+ module_exit(xpc_exit);
+diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
+index acd3fd4..7dd4b58 100644
+--- a/drivers/misc/sgi-xp/xpc_partition.c
++++ b/drivers/misc/sgi-xp/xpc_partition.c
+@@ -403,7 +403,7 @@ xpc_check_remote_hb(void)
+ {
+ 	struct xpc_vars *remote_vars;
+ 	struct xpc_partition *part;
+-	partid_t partid;
++	short partid;
+ 	bte_result_t bres;
+ 
+ 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
+@@ -444,7 +444,7 @@ xpc_check_remote_hb(void)
+ 		     (remote_vars->heartbeat_offline == 0)) ||
+ 		    !xpc_hb_allowed(sn_partition_id, remote_vars)) {
+ 
+-			XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
++			XPC_DEACTIVATE_PARTITION(part, xpNoHeartbeat);
+ 			continue;
+ 		}
+ 
+@@ -459,7 +459,7 @@ xpc_check_remote_hb(void)
+  * is large enough to contain a copy of their reserved page header and
+  * part_nasids mask.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+ 		  struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
+ {
+@@ -469,7 +469,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+ 
+ 	*remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
+ 	if (*remote_rp_pa == 0)
+-		return xpcNoRsvdPageAddr;
++		return xpNoRsvdPageAddr;
+ 
+ 	/* pull over the reserved page header and part_nasids mask */
+ 	bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp,
+@@ -489,18 +489,18 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+ 
+ 	if (remote_rp->partid < 1 ||
+ 	    remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
+-		return xpcInvalidPartid;
++		return xpInvalidPartid;
+ 	}
+ 
+ 	if (remote_rp->partid == sn_partition_id)
+-		return xpcLocalPartid;
++		return xpLocalPartid;
+ 
+ 	if (XPC_VERSION_MAJOR(remote_rp->version) !=
+ 	    XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
+-		return xpcBadVersion;
++		return xpBadVersion;
+ 	}
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -509,13 +509,13 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
+  * remote_vars points to a buffer that is cacheline aligned for BTE copies and
+  * assumed to be of size XPC_RP_VARS_SIZE.
+  */
+-static enum xpc_retval
++static enum xp_retval
+ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
+ {
+ 	int bres;
+ 
+ 	if (remote_vars_pa == 0)
+-		return xpcVarsNotSet;
++		return xpVarsNotSet;
+ 
+ 	/* pull over the cross partition variables */
+ 	bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE,
+@@ -525,10 +525,10 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
+ 
+ 	if (XPC_VERSION_MAJOR(remote_vars->version) !=
+ 	    XPC_VERSION_MAJOR(XPC_V_VERSION)) {
+-		return xpcBadVersion;
++		return xpBadVersion;
+ 	}
+ 
+-	return xpcSuccess;
++	return xpSuccess;
+ }
+ 
+ /*
+@@ -604,16 +604,16 @@ xpc_identify_act_IRQ_req(int nasid)
+ 	int reactivate = 0;
+ 	int stamp_diff;
+ 	struct timespec remote_rp_stamp = { 0, 0 };
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	/* pull over the reserved page structure */
+ 
+ 	remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer;
+ 
+ 	ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
+-	if (ret != xpcSuccess) {
++	if (ret != xpSuccess) {
+ 		dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
+ 			 "which sent interrupt, reason=%d\n", nasid, ret);
+ 		return;
+@@ -632,7 +632,7 @@ xpc_identify_act_IRQ_req(int nasid)
+ 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
+ 
+ 	ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
+-	if (ret != xpcSuccess) {
++	if (ret != xpSuccess) {
+ 
+ 		dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
+ 			 "which sent interrupt, reason=%d\n", nasid, ret);
+@@ -699,7 +699,7 @@ xpc_identify_act_IRQ_req(int nasid)
+ 					  &remote_rp_stamp, remote_rp_pa,
+ 					  remote_vars_pa, remote_vars);
+ 		part->reactivate_nasid = nasid;
+-		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
++		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
+ 		return;
+ 	}
+ 
+@@ -754,11 +754,11 @@ xpc_identify_act_IRQ_req(int nasid)
+ 
+ 	if (reactivate) {
+ 		part->reactivate_nasid = nasid;
+-		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
++		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
+ 
+ 	} else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
+ 		   xpc_partition_disengage_requested(1UL << partid)) {
+-		XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
++		XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
+ 	}
+ }
+ 
+@@ -825,7 +825,7 @@ xpc_identify_act_IRQ_sender(void)
+ int
+ xpc_partition_disengaged(struct xpc_partition *part)
+ {
+-	partid_t partid = XPC_PARTID(part);
++	short partid = XPC_PARTID(part);
+ 	int disengaged;
+ 
+ 	disengaged = (xpc_partition_engaged(1UL << partid) == 0);
+@@ -870,20 +870,20 @@ xpc_partition_disengaged(struct xpc_partition *part)
+ /*
+  * Mark specified partition as active.
+  */
+-enum xpc_retval
++enum xp_retval
+ xpc_mark_partition_active(struct xpc_partition *part)
+ {
+ 	unsigned long irq_flags;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
+ 
+ 	spin_lock_irqsave(&part->act_lock, irq_flags);
+ 	if (part->act_state == XPC_P_ACTIVATING) {
+ 		part->act_state = XPC_P_ACTIVE;
+-		ret = xpcSuccess;
++		ret = xpSuccess;
+ 	} else {
+-		DBUG_ON(part->reason == xpcSuccess);
++		DBUG_ON(part->reason == xpSuccess);
+ 		ret = part->reason;
+ 	}
+ 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
+@@ -896,7 +896,7 @@ xpc_mark_partition_active(struct xpc_partition *part)
+  */
+ void
+ xpc_deactivate_partition(const int line, struct xpc_partition *part,
+-			 enum xpc_retval reason)
++			 enum xp_retval reason)
+ {
+ 	unsigned long irq_flags;
+ 
+@@ -905,15 +905,15 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
+ 	if (part->act_state == XPC_P_INACTIVE) {
+ 		XPC_SET_REASON(part, reason, line);
+ 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
+-		if (reason == xpcReactivating) {
++		if (reason == xpReactivating) {
+ 			/* we interrupt ourselves to reactivate partition */
+ 			xpc_IPI_send_reactivate(part);
+ 		}
+ 		return;
+ 	}
+ 	if (part->act_state == XPC_P_DEACTIVATING) {
+-		if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
+-		    reason == xpcReactivating) {
++		if ((part->reason == xpUnloading && reason != xpUnloading) ||
++		    reason == xpReactivating) {
+ 			XPC_SET_REASON(part, reason, line);
+ 		}
+ 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
+@@ -982,10 +982,10 @@ xpc_discovery(void)
+ 	int max_regions;
+ 	int nasid;
+ 	struct xpc_rsvd_page *rp;
+-	partid_t partid;
++	short partid;
+ 	struct xpc_partition *part;
+ 	u64 *discovered_nasids;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
+ 						  xp_nasid_mask_bytes,
+@@ -1063,12 +1063,12 @@ xpc_discovery(void)
+ 
+ 			ret = xpc_get_remote_rp(nasid, discovered_nasids,
+ 						remote_rp, &remote_rp_pa);
+-			if (ret != xpcSuccess) {
++			if (ret != xpSuccess) {
+ 				dev_dbg(xpc_part, "unable to get reserved page "
+ 					"from nasid %d, reason=%d\n", nasid,
+ 					ret);
+ 
+-				if (ret == xpcLocalPartid)
++				if (ret == xpLocalPartid)
+ 					break;
+ 
+ 				continue;
+@@ -1082,7 +1082,7 @@ xpc_discovery(void)
+ 			/* pull over the cross partition variables */
+ 
+ 			ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
+-			if (ret != xpcSuccess) {
++			if (ret != xpSuccess) {
+ 				dev_dbg(xpc_part, "unable to get XPC variables "
+ 					"from nasid %d, reason=%d\n", nasid,
+ 					ret);
+@@ -1116,7 +1116,7 @@ xpc_discovery(void)
+ 					"register xp_addr region 0x%016lx\n",
+ 					partid, remote_vars->amos_page_pa);
+ 
+-				XPC_SET_REASON(part, xpcPhysAddrRegFailed,
++				XPC_SET_REASON(part, xpPhysAddrRegFailed,
+ 					       __LINE__);
+ 				break;
+ 			}
+@@ -1151,8 +1151,8 @@ xpc_discovery(void)
+  * Given a partid, get the nasids owned by that partition from the
+  * remote partition's reserved page.
+  */
+-enum xpc_retval
+-xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
++enum xp_retval
++xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
+ {
+ 	struct xpc_partition *part;
+ 	u64 part_nasid_pa;
+@@ -1160,7 +1160,7 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
+ 
+ 	part = &xpc_partitions[partid];
+ 	if (part->remote_rp_pa == 0)
+-		return xpcPartitionDown;
++		return xpPartitionDown;
+ 
+ 	memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
+ 
+diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
+index a9543c6..822dc8e 100644
+--- a/drivers/misc/sgi-xp/xpnet.c
++++ b/drivers/misc/sgi-xp/xpnet.c
+@@ -166,7 +166,7 @@ struct device *xpnet = &xpnet_dbg_subname;
+  * Packet was recevied by XPC and forwarded to us.
+  */
+ static void
+-xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
++xpnet_receive(short partid, int channel, struct xpnet_message *msg)
+ {
+ 	struct sk_buff *skb;
+ 	bte_result_t bret;
+@@ -282,7 +282,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
+  * state or message reception on a connection.
+  */
+ static void
+-xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
++xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
+ 			  void *data, void *key)
+ {
+ 	long bp;
+@@ -291,13 +291,13 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
+ 	DBUG_ON(channel != XPC_NET_CHANNEL);
+ 
+ 	switch (reason) {
+-	case xpcMsgReceived:	/* message received */
++	case xpMsgReceived:	/* message received */
+ 		DBUG_ON(data == NULL);
+ 
+ 		xpnet_receive(partid, channel, (struct xpnet_message *)data);
+ 		break;
+ 
+-	case xpcConnected:	/* connection completed to a partition */
++	case xpConnected:	/* connection completed to a partition */
+ 		spin_lock_bh(&xpnet_broadcast_lock);
+ 		xpnet_broadcast_partitions |= 1UL << (partid - 1);
+ 		bp = xpnet_broadcast_partitions;
+@@ -330,7 +330,7 @@ xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
+ static int
+ xpnet_dev_open(struct net_device *dev)
+ {
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 
+ 	dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
+ 		"%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
+@@ -340,7 +340,7 @@ xpnet_dev_open(struct net_device *dev)
+ 	ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
+ 			  XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
+ 			  XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
+-	if (ret != xpcSuccess) {
++	if (ret != xpSuccess) {
+ 		dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
+ 			"ret=%d\n", dev->name, ret);
+ 
+@@ -407,7 +407,7 @@ xpnet_dev_get_stats(struct net_device *dev)
+  * release the skb and then release our pending message structure.
+  */
+ static void
+-xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel,
++xpnet_send_completed(enum xp_retval reason, short partid, int channel,
+ 		     void *__qm)
+ {
+ 	struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm;
+@@ -439,12 +439,12 @@ static int
+ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct xpnet_pending_msg *queued_msg;
+-	enum xpc_retval ret;
++	enum xp_retval ret;
+ 	struct xpnet_message *msg;
+ 	u64 start_addr, end_addr;
+ 	long dp;
+ 	u8 second_mac_octet;
+-	partid_t dest_partid;
++	short dest_partid;
+ 	struct xpnet_dev_private *priv;
+ 	u16 embedded_bytes;
+ 
+@@ -528,7 +528,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 		ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
+ 				   XPC_NOWAIT, (void **)&msg);
+-		if (unlikely(ret != xpcSuccess))
++		if (unlikely(ret != xpSuccess))
+ 			continue;
+ 
+ 		msg->embedded_bytes = embedded_bytes;
+@@ -557,7 +557,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 		ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
+ 				      xpnet_send_completed, queued_msg);
+-		if (unlikely(ret != xpcSuccess)) {
++		if (unlikely(ret != xpSuccess)) {
+ 			atomic_dec(&queued_msg->use_count);
+ 			continue;
+ 		}
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 7fb02e1..299118d 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -187,7 +187,7 @@ struct sdhci_host {
+ 	struct mmc_request	*mrq;		/* Current request */
+ 	struct mmc_command	*cmd;		/* Current command */
+ 	struct mmc_data		*data;		/* Current data request */
+-	int			data_early:1;	/* Data finished before cmd */
++	unsigned int		data_early:1;	/* Data finished before cmd */
+ 
+ 	struct scatterlist	*cur_sg;	/* We're working on this */
+ 	int			num_sg;		/* Entries left */
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index d27f54a..9f6cc8a 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -2426,7 +2426,7 @@ config CHELSIO_T3
+ 
+ config EHEA
+ 	tristate "eHEA Ethernet support"
+-	depends on IBMEBUS && INET && SPARSEMEM
++	depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG
+ 	select INET_LRO
+ 	---help---
+ 	  This driver supports the IBM pSeries eHEA ethernet adapter.
+diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
+index 0afe522..9c2394d 100644
+--- a/drivers/net/atlx/atl1.c
++++ b/drivers/net/atlx/atl1.c
+@@ -1,7 +1,7 @@
+ /*
+  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+  * Copyright(c) 2006 - 2007 Chris Snook <csnook at redhat.com>
+- * Copyright(c) 2006 Jay Cliburn <jcliburn at gmail.com>
++ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn at gmail.com>
+  *
+  * Derived from Intel e1000 driver
+  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+@@ -36,7 +36,6 @@
+  * A very incomplete list of things that need to be dealt with:
+  *
+  * TODO:
+- * Wake on LAN.
+  * Add more ethtool functions.
+  * Fix abstruse irq enable/disable condition described here:
+  *	http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
+@@ -638,21 +637,18 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
+ }
+ 
+ /*
+- *TODO: do something or get rid of this
++ * Force the PHY into power saving mode using vendor magic.
+  */
+ #ifdef CONFIG_PM
+-static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
++static void atl1_phy_enter_power_saving(struct atl1_hw *hw)
+ {
+-/*    s32 ret_val;
+- *    u16 phy_data;
+- */
++	atl1_write_phy_reg(hw, MII_DBG_ADDR, 0);
++	atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E);
++	atl1_write_phy_reg(hw, MII_DBG_ADDR, 2);
++	atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
++	atl1_write_phy_reg(hw, MII_DBG_ADDR, 3);
++	atl1_write_phy_reg(hw, MII_DBG_DATA, 0);
+ 
+-/*
+-    ret_val = atl1_write_phy_reg(hw, ...);
+-    ret_val = atl1_write_phy_reg(hw, ...);
+-    ....
+-*/
+-	return 0;
+ }
+ #endif
+ 
+@@ -2784,64 +2780,93 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	struct atl1_hw *hw = &adapter->hw;
+ 	u32 ctrl = 0;
+ 	u32 wufc = adapter->wol;
++	u32 val;
++	int retval;
++	u16 speed;
++	u16 duplex;
+ 
+ 	netif_device_detach(netdev);
+ 	if (netif_running(netdev))
+ 		atl1_down(adapter);
+ 
++	retval = pci_save_state(pdev);
++	if (retval)
++		return retval;
++
+ 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+ 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+-	if (ctrl & BMSR_LSTATUS)
++	val = ctrl & BMSR_LSTATUS;
++	if (val)
+ 		wufc &= ~ATLX_WUFC_LNKC;
+ 
+-	/* reduce speed to 10/100M */
+-	if (wufc) {
+-		atl1_phy_enter_power_saving(hw);
+-		/* if resume, let driver to re- setup link */
+-		hw->phy_configured = false;
+-		atl1_set_mac_addr(hw);
+-		atlx_set_multi(netdev);
++	if (val && wufc) {
++		val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
++		if (val) {
++			if (netif_msg_ifdown(adapter))
++				dev_printk(KERN_DEBUG, &pdev->dev,
++					"error getting speed/duplex\n");
++			goto disable_wol;
++		}
+ 
+ 		ctrl = 0;
+-		/* turn on magic packet wol */
+-		if (wufc & ATLX_WUFC_MAG)
+-			ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+ 
+-		/* turn on Link change WOL */
+-		if (wufc & ATLX_WUFC_LNKC)
+-			ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
++		/* enable magic packet WOL */
++		if (wufc & ATLX_WUFC_MAG)
++			ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
+ 		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+-
+-		/* turn on all-multi mode if wake on multicast is enabled */
+-		ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
+-		ctrl &= ~MAC_CTRL_DBG;
+-		ctrl &= ~MAC_CTRL_PROMIS_EN;
+-		if (wufc & ATLX_WUFC_MC)
+-			ctrl |= MAC_CTRL_MC_ALL_EN;
+-		else
+-			ctrl &= ~MAC_CTRL_MC_ALL_EN;
+-
+-		/* turn on broadcast mode if wake on-BC is enabled */
+-		if (wufc & ATLX_WUFC_BC)
++		ioread32(hw->hw_addr + REG_WOL_CTRL);
++
++		/* configure the mac */
++		ctrl = MAC_CTRL_RX_EN;
++		ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
++			MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
++		if (duplex == FULL_DUPLEX)
++			ctrl |= MAC_CTRL_DUPLX;
++		ctrl |= (((u32)adapter->hw.preamble_len &
++			MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
++		if (adapter->vlgrp)
++			ctrl |= MAC_CTRL_RMV_VLAN;
++		if (wufc & ATLX_WUFC_MAG)
+ 			ctrl |= MAC_CTRL_BC_EN;
+-		else
+-			ctrl &= ~MAC_CTRL_BC_EN;
+-
+-		/* enable RX */
+-		ctrl |= MAC_CTRL_RX_EN;
+ 		iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
+-		pci_enable_wake(pdev, PCI_D3hot, 1);
+-		pci_enable_wake(pdev, PCI_D3cold, 1);
+-	} else {
+-		iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
+-		pci_enable_wake(pdev, PCI_D3hot, 0);
+-		pci_enable_wake(pdev, PCI_D3cold, 0);
++		ioread32(hw->hw_addr + REG_MAC_CTRL);
++
++		/* poke the PHY */
++		ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
++		ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
++		iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
++		ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
++
++		pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
++		goto exit;
+ 	}
+ 
+-	pci_save_state(pdev);
++	if (!val && wufc) {
++		ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
++		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
++		ioread32(hw->hw_addr + REG_WOL_CTRL);
++		iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
++		ioread32(hw->hw_addr + REG_MAC_CTRL);
++		hw->phy_configured = false;
++		pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
++		goto exit;
++	}
++
++disable_wol:
++	iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
++	ioread32(hw->hw_addr + REG_WOL_CTRL);
++	ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
++	ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
++	iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
++	ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
++	atl1_phy_enter_power_saving(hw);
++	hw->phy_configured = false;
++	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
++exit:
++	if (netif_running(netdev))
++		pci_disable_msi(adapter->pdev);
+ 	pci_disable_device(pdev);
+-
+-	pci_set_power_state(pdev, PCI_D3hot);
++	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ 
+ 	return 0;
+ }
+@@ -2855,20 +2880,26 @@ static int atl1_resume(struct pci_dev *pdev)
+ 	pci_set_power_state(pdev, PCI_D0);
+ 	pci_restore_state(pdev);
+ 
+-	/* FIXME: check and handle */
+ 	err = pci_enable_device(pdev);
++	if (err) {
++		if (netif_msg_ifup(adapter))
++			dev_printk(KERN_DEBUG, &pdev->dev,
++				"error enabling pci device\n");
++		return err;
++	}
++
++	pci_set_master(pdev);
++	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
+ 	pci_enable_wake(pdev, PCI_D3hot, 0);
+ 	pci_enable_wake(pdev, PCI_D3cold, 0);
+ 
+-	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
+-	atl1_reset(adapter);
++	atl1_reset_hw(&adapter->hw);
++	adapter->cmb.cmb->int_stats = 0;
+ 
+ 	if (netif_running(netdev))
+ 		atl1_up(adapter);
+ 	netif_device_attach(netdev);
+ 
+-	atl1_via_workaround(adapter);
+-
+ 	return 0;
+ }
+ #else
+@@ -2876,6 +2907,13 @@ static int atl1_resume(struct pci_dev *pdev)
+ #define atl1_resume NULL
+ #endif
+ 
++static void atl1_shutdown(struct pci_dev *pdev)
++{
++#ifdef CONFIG_PM
++	atl1_suspend(pdev, PMSG_SUSPEND);
++#endif
++}
++
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ static void atl1_poll_controller(struct net_device *netdev)
+ {
+@@ -3122,7 +3160,8 @@ static struct pci_driver atl1_driver = {
+ 	.probe = atl1_probe,
+ 	.remove = __devexit_p(atl1_remove),
+ 	.suspend = atl1_suspend,
+-	.resume = atl1_resume
++	.resume = atl1_resume,
++	.shutdown = atl1_shutdown
+ };
+ 
+ /*
+diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
+index 51893d6..a5015b1 100644
+--- a/drivers/net/atlx/atl1.h
++++ b/drivers/net/atlx/atl1.h
+@@ -1,7 +1,7 @@
+ /*
+  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+  * Copyright(c) 2006 - 2007 Chris Snook <csnook at redhat.com>
+- * Copyright(c) 2006 Jay Cliburn <jcliburn at gmail.com>
++ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn at gmail.com>
+  *
+  * Derived from Intel e1000 driver
+  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
+index f06b854..b3e7fcf 100644
+--- a/drivers/net/atlx/atlx.c
++++ b/drivers/net/atlx/atlx.c
+@@ -2,7 +2,7 @@
+  *
+  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+  * Copyright(c) 2006 - 2007 Chris Snook <csnook at redhat.com>
+- * Copyright(c) 2006 Jay Cliburn <jcliburn at gmail.com>
++ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn at gmail.com>
+  * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+  *
+  * Derived from Intel e1000 driver
+diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
+index 3be7c09..297a03d 100644
+--- a/drivers/net/atlx/atlx.h
++++ b/drivers/net/atlx/atlx.h
+@@ -2,7 +2,7 @@
+  *
+  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+  * Copyright(c) 2006 - 2007 Chris Snook <csnook at redhat.com>
+- * Copyright(c) 2006 Jay Cliburn <jcliburn at gmail.com>
++ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn at gmail.com>
+  * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+  *
+  * Derived from Intel e1000 driver
+@@ -29,7 +29,7 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ 
+-#define ATLX_DRIVER_VERSION "2.1.1"
++#define ATLX_DRIVER_VERSION "2.1.3"
+ MODULE_AUTHOR("Xiong Huang <xiong.huang at atheros.com>, \
+ 	Chris Snook <csnook at redhat.com>, Jay Cliburn <jcliburn at gmail.com>");
+ MODULE_LICENSE("GPL");
+@@ -460,6 +460,9 @@ MODULE_VERSION(ATLX_DRIVER_VERSION);
+ #define MII_ATLX_PSSR_100MBS		0x4000	/* 01=100Mbs */
+ #define MII_ATLX_PSSR_1000MBS		0x8000	/* 10=1000Mbs */
+ 
++#define MII_DBG_ADDR			0x1D
++#define MII_DBG_DATA			0x1E
++
+ /* PCI Command Register Bit Definitions */
+ #define PCI_REG_COMMAND			0x04	/* PCI Command Register */
+ #define CMD_IO_SPACE			0x0001
+diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
+index 4fdb13f..acebe43 100644
+--- a/drivers/net/cxgb3/adapter.h
++++ b/drivers/net/cxgb3/adapter.h
+@@ -71,6 +71,7 @@ enum {				/* adapter flags */
+ 	USING_MSIX = (1 << 2),
+ 	QUEUES_BOUND = (1 << 3),
+ 	TP_PARITY_INIT = (1 << 4),
++	NAPI_INIT = (1 << 5),
+ };
+ 
+ struct fl_pg_chunk {
+diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
+index 91ee727..579bee4 100644
+--- a/drivers/net/cxgb3/common.h
++++ b/drivers/net/cxgb3/common.h
+@@ -698,6 +698,7 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index);
+ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
+ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
+ 		    int reset);
++int t3_replay_prep_adapter(struct adapter *adapter);
+ void t3_led_ready(struct adapter *adapter);
+ void t3_fatal_err(struct adapter *adapter);
+ void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
+diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
+index ce949d5..3a31272 100644
+--- a/drivers/net/cxgb3/cxgb3_main.c
++++ b/drivers/net/cxgb3/cxgb3_main.c
+@@ -421,6 +421,13 @@ static void init_napi(struct adapter *adap)
+ 			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
+ 				       64);
+ 	}
++
++	/*
++	 * netif_napi_add() can be called only once per napi_struct because it
++	 * adds each new napi_struct to a list.  Be careful not to call it a
++	 * second time, e.g., during EEH recovery, by making a note of it.
++	 */
++	adap->flags |= NAPI_INIT;
+ }
+ 
+ /*
+@@ -896,7 +903,8 @@ static int cxgb_up(struct adapter *adap)
+ 			goto out;
+ 
+ 		setup_rss(adap);
+-		init_napi(adap);
++		if (!(adap->flags & NAPI_INIT))
++			init_napi(adap);
+ 		adap->flags |= FULL_INIT_DONE;
+ 	}
+ 
+@@ -999,7 +1007,7 @@ static int offload_open(struct net_device *dev)
+ 		return 0;
+ 
+ 	if (!adap_up && (err = cxgb_up(adapter)) < 0)
+-		return err;
++		goto out;
+ 
+ 	t3_tp_set_offload_mode(adapter, 1);
+ 	tdev->lldev = adapter->port[0];
+@@ -1061,10 +1069,8 @@ static int cxgb_open(struct net_device *dev)
+ 	int other_ports = adapter->open_device_map & PORT_MASK;
+ 	int err;
+ 
+-	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
+-		quiesce_rx(adapter);
++	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
+ 		return err;
+-	}
+ 
+ 	set_bit(pi->port_id, &adapter->open_device_map);
+ 	if (is_offload(adapter) && !ofld_disable) {
+@@ -2424,14 +2430,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
+ 	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
+ 		offload_close(&adapter->tdev);
+ 
+-	/* Free sge resources */
+-	t3_free_sge_resources(adapter);
+-
+ 	adapter->flags &= ~FULL_INIT_DONE;
+ 
+ 	pci_disable_device(pdev);
+ 
+-	/* Request a slot slot reset. */
++	/* Request a slot reset. */
+ 	return PCI_ERS_RESULT_NEED_RESET;
+ }
+ 
+@@ -2448,13 +2451,20 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
+ 	if (pci_enable_device(pdev)) {
+ 		dev_err(&pdev->dev,
+ 			"Cannot re-enable PCI device after reset.\n");
+-		return PCI_ERS_RESULT_DISCONNECT;
++		goto err;
+ 	}
+ 	pci_set_master(pdev);
++	pci_restore_state(pdev);
+ 
+-	t3_prep_adapter(adapter, adapter->params.info, 1);
++	/* Free sge resources */
++	t3_free_sge_resources(adapter);
++
++	if (t3_replay_prep_adapter(adapter))
++		goto err;
+ 
+ 	return PCI_ERS_RESULT_RECOVERED;
++err:
++	return PCI_ERS_RESULT_DISCONNECT;
+ }
+ 
+ /**
+@@ -2483,13 +2493,6 @@ static void t3_io_resume(struct pci_dev *pdev)
+ 			netif_device_attach(netdev);
+ 		}
+ 	}
+-
+-	if (is_offload(adapter)) {
+-		__set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
+-		if (offload_open(adapter->port[0]))
+-			printk(KERN_WARNING
+-			       "Could not bring back offload capabilities\n");
+-	}
+ }
+ 
+ static struct pci_error_handlers t3_err_handler = {
+@@ -2608,6 +2611,7 @@ static int __devinit init_one(struct pci_dev *pdev,
+ 	}
+ 
+ 	pci_set_master(pdev);
++	pci_save_state(pdev);
+ 
+ 	mmio_start = pci_resource_start(pdev, 0);
+ 	mmio_len = pci_resource_len(pdev, 0);
+diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
+index 02dbbb3..5671788 100644
+--- a/drivers/net/cxgb3/regs.h
++++ b/drivers/net/cxgb3/regs.h
+@@ -444,6 +444,14 @@
+ 
+ #define A_PCIE_CFG 0x88
+ 
++#define S_ENABLELINKDWNDRST    21
++#define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST)
++#define F_ENABLELINKDWNDRST    V_ENABLELINKDWNDRST(1U)
++
++#define S_ENABLELINKDOWNRST    20
++#define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST)
++#define F_ENABLELINKDOWNRST    V_ENABLELINKDOWNRST(1U)
++
+ #define S_PCIE_CLIDECEN    16
+ #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN)
+ #define F_PCIE_CLIDECEN    V_PCIE_CLIDECEN(1U)
+diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
+index 98a6bbd..796eb30 100644
+--- a/drivers/net/cxgb3/sge.c
++++ b/drivers/net/cxgb3/sge.c
+@@ -539,6 +539,31 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
+ }
+ 
+ /**
++ *	t3_reset_qset - reset a sge qset
++ *	@q: the queue set
++ *
++ *	Reset the qset structure.
++ *	the NAPI structure is preserved in the event of
++ *	the qset's reincarnation, for example during EEH recovery.
++ */
++static void t3_reset_qset(struct sge_qset *q)
++{
++	if (q->adap &&
++	    !(q->adap->flags & NAPI_INIT)) {
++		memset(q, 0, sizeof(*q));
++		return;
++	}
++
++	q->adap = NULL;
++	memset(&q->rspq, 0, sizeof(q->rspq));
++	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
++	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
++	q->txq_stopped = 0;
++	memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
++}
++
++
++/**
+  *	free_qset - free the resources of an SGE queue set
+  *	@adapter: the adapter owning the queue set
+  *	@q: the queue set
+@@ -594,7 +619,7 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
+ 				  q->rspq.desc, q->rspq.phys_addr);
+ 	}
+ 
+-	memset(q, 0, sizeof(*q));
++	t3_reset_qset(q);
+ }
+ 
+ /**
+@@ -1365,7 +1390,7 @@ static void restart_ctrlq(unsigned long data)
+  */
+ int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
+ {
+-	int ret; 
++	int ret;
+ 	local_bh_disable();
+ 	ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
+ 	local_bh_enable();
+diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
+index a99496a..d405a93 100644
+--- a/drivers/net/cxgb3/t3_hw.c
++++ b/drivers/net/cxgb3/t3_hw.c
+@@ -3264,6 +3264,7 @@ static void config_pcie(struct adapter *adap)
+ 
+ 	t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
+ 	t3_set_reg_field(adap, A_PCIE_CFG, 0,
++			 F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST |
+ 			 F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
+ }
+ 
+@@ -3655,3 +3656,30 @@ void t3_led_ready(struct adapter *adapter)
+ 	t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
+ 			 F_GPIO0_OUT_VAL);
+ }
++
++int t3_replay_prep_adapter(struct adapter *adapter)
++{
++	const struct adapter_info *ai = adapter->params.info;
++	unsigned int i, j = 0;
++	int ret;
++
++	early_hw_init(adapter, ai);
++	ret = init_parity(adapter);
++	if (ret)
++		return ret;
++
++	for_each_port(adapter, i) {
++		struct port_info *p = adap2pinfo(adapter, i);
++		while (!adapter->params.vpd.port_type[j])
++			++j;
++
++		p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
++					ai->mdio_ops);
++
++		p->phy.ops->power_down(&p->phy, 1);
++		++j;
++	}
++
++return 0;
++}
++
+diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
+index e6fe261..d45bcd2 100644
+--- a/drivers/net/dm9000.c
++++ b/drivers/net/dm9000.c
+@@ -117,6 +117,9 @@ typedef struct board_info {
+ 
+ 	struct mutex	 addr_lock;	/* phy and eeprom access lock */
+ 
++	struct delayed_work phy_poll;
++	struct net_device  *ndev;
++
+ 	spinlock_t lock;
+ 
+ 	struct mii_if_info mii;
+@@ -297,6 +300,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width)
+ 	}
+ }
+ 
++static void dm9000_schedule_poll(board_info_t *db)
++{
++	schedule_delayed_work(&db->phy_poll, HZ * 2);
++}
+ 
+ /* Our watchdog timed out. Called by the networking layer */
+ static void dm9000_timeout(struct net_device *dev)
+@@ -465,6 +472,17 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
+  	.set_eeprom		= dm9000_set_eeprom,
+ };
+ 
++static void
++dm9000_poll_work(struct work_struct *w)
++{
++	struct delayed_work *dw = container_of(w, struct delayed_work, work);
++	board_info_t *db = container_of(dw, board_info_t, phy_poll);
++
++	mii_check_media(&db->mii, netif_msg_link(db), 0);
++	
++	if (netif_running(db->ndev))
++		dm9000_schedule_poll(db);
++}
+ 
+ /* dm9000_release_board
+  *
+@@ -503,7 +521,7 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
+ /*
+  * Search DM9000 board, allocate space and register it
+  */
+-static int
++static int __devinit
+ dm9000_probe(struct platform_device *pdev)
+ {
+ 	struct dm9000_plat_data *pdata = pdev->dev.platform_data;
+@@ -525,17 +543,21 @@ dm9000_probe(struct platform_device *pdev)
+ 
+ 	SET_NETDEV_DEV(ndev, &pdev->dev);
+ 
+-	dev_dbg(&pdev->dev, "dm9000_probe()");
++	dev_dbg(&pdev->dev, "dm9000_probe()\n");
+ 
+ 	/* setup board info structure */
+ 	db = (struct board_info *) ndev->priv;
+ 	memset(db, 0, sizeof (*db));
+ 
+ 	db->dev = &pdev->dev;
++	db->ndev = ndev;
+ 
+ 	spin_lock_init(&db->lock);
+ 	mutex_init(&db->addr_lock);
+ 
++	INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
++
++
+ 	if (pdev->num_resources < 2) {
+ 		ret = -ENODEV;
+ 		goto out;
+@@ -761,6 +783,8 @@ dm9000_open(struct net_device *dev)
+ 
+ 	mii_check_media(&db->mii, netif_msg_link(db), 1);
+ 	netif_start_queue(dev);
++	
++	dm9000_schedule_poll(db);
+ 
+ 	return 0;
+ }
+@@ -879,6 +903,8 @@ dm9000_stop(struct net_device *ndev)
+ 	if (netif_msg_ifdown(db))
+ 		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+ 
++	cancel_delayed_work(&db->phy_poll);
++
+ 	netif_stop_queue(ndev);
+ 	netif_carrier_off(ndev);
+ 
+@@ -1288,6 +1314,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+ 	spin_unlock_irqrestore(&db->lock,flags);
+ 
+ 	mutex_unlock(&db->addr_lock);
++
++	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
+ 	return ret;
+ }
+ 
+@@ -1301,6 +1329,7 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
+ 	unsigned long flags;
+ 	unsigned long reg_save;
+ 
++	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
+ 	mutex_lock(&db->addr_lock);
+ 
+ 	spin_lock_irqsave(&db->lock,flags);
+@@ -1372,7 +1401,7 @@ dm9000_drv_resume(struct platform_device *dev)
+ 	return 0;
+ }
+ 
+-static int
++static int __devexit
+ dm9000_drv_remove(struct platform_device *pdev)
+ {
+ 	struct net_device *ndev = platform_get_drvdata(pdev);
+@@ -1393,7 +1422,7 @@ static struct platform_driver dm9000_driver = {
+ 		.owner	 = THIS_MODULE,
+ 	},
+ 	.probe   = dm9000_probe,
+-	.remove  = dm9000_drv_remove,
++	.remove  = __devexit_p(dm9000_drv_remove),
+ 	.suspend = dm9000_drv_suspend,
+ 	.resume  = dm9000_drv_resume,
+ };
+diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
+index f5dacce..fe872fb 100644
+--- a/drivers/net/ehea/ehea.h
++++ b/drivers/net/ehea/ehea.h
+@@ -40,7 +40,7 @@
+ #include <asm/io.h>
+ 
+ #define DRV_NAME	"ehea"
+-#define DRV_VERSION	"EHEA_0090"
++#define DRV_VERSION	"EHEA_0091"
+ 
+ /* eHEA capability flags */
+ #define DLPAR_PORT_ADD_REM 1
+@@ -118,6 +118,13 @@
+ #define EHEA_MR_ACC_CTRL       0x00800000
+ 
+ #define EHEA_BUSMAP_START      0x8000000000000000ULL
++#define EHEA_INVAL_ADDR        0xFFFFFFFFFFFFFFFFULL
++#define EHEA_DIR_INDEX_SHIFT 13                   /* 8k Entries in 64k block */
++#define EHEA_TOP_INDEX_SHIFT (EHEA_DIR_INDEX_SHIFT * 2)
++#define EHEA_MAP_ENTRIES (1 << EHEA_DIR_INDEX_SHIFT)
++#define EHEA_MAP_SIZE (0x10000)                   /* currently fixed map size */
++#define EHEA_INDEX_MASK (EHEA_MAP_ENTRIES - 1)
++
+ 
+ #define EHEA_WATCH_DOG_TIMEOUT 10*HZ
+ 
+@@ -192,10 +199,20 @@ struct h_epas {
+ 				   set to 0 if unused */
+ };
+ 
+-struct ehea_busmap {
+-	unsigned int entries;		/* total number of entries */
+-	unsigned int valid_sections;	/* number of valid sections */
+-	u64 *vaddr;
++/*
++ * Memory map data structures
++ */
++struct ehea_dir_bmap
++{
++	u64 ent[EHEA_MAP_ENTRIES];
++};
++struct ehea_top_bmap
++{
++	struct ehea_dir_bmap *dir[EHEA_MAP_ENTRIES];
++};
++struct ehea_bmap
++{
++	struct ehea_top_bmap *top[EHEA_MAP_ENTRIES];
+ };
+ 
+ struct ehea_qp;
+diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
+index f9bc21c..d1b6d4e 100644
+--- a/drivers/net/ehea/ehea_main.c
++++ b/drivers/net/ehea/ehea_main.c
+@@ -35,6 +35,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/notifier.h>
+ #include <linux/reboot.h>
++#include <linux/memory.h>
+ #include <asm/kexec.h>
+ #include <linux/mutex.h>
+ 
+@@ -3503,6 +3504,24 @@ void ehea_crash_handler(void)
+ 					      0, H_DEREG_BCMC);
+ }
+ 
++static int ehea_mem_notifier(struct notifier_block *nb,
++                             unsigned long action, void *data)
++{
++	switch (action) {
++	case MEM_OFFLINE:
++		ehea_info("memory has been removed");
++		ehea_rereg_mrs(NULL);
++		break;
++	default:
++		break;
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block ehea_mem_nb = {
++	.notifier_call = ehea_mem_notifier,
++};
++
+ static int ehea_reboot_notifier(struct notifier_block *nb,
+ 				unsigned long action, void *unused)
+ {
+@@ -3581,6 +3600,10 @@ int __init ehea_module_init(void)
+ 	if (ret)
+ 		ehea_info("failed registering reboot notifier");
+ 
++	ret = register_memory_notifier(&ehea_mem_nb);
++	if (ret)
++		ehea_info("failed registering memory remove notifier");
++
+ 	ret = crash_shutdown_register(&ehea_crash_handler);
+ 	if (ret)
+ 		ehea_info("failed registering crash handler");
+@@ -3604,6 +3627,7 @@ int __init ehea_module_init(void)
+ out3:
+ 	ibmebus_unregister_driver(&ehea_driver);
+ out2:
++	unregister_memory_notifier(&ehea_mem_nb);
+ 	unregister_reboot_notifier(&ehea_reboot_nb);
+ 	crash_shutdown_unregister(&ehea_crash_handler);
+ out:
+@@ -3621,6 +3645,7 @@ static void __exit ehea_module_exit(void)
+ 	ret = crash_shutdown_unregister(&ehea_crash_handler);
+ 	if (ret)
+ 		ehea_info("failed unregistering crash handler");
++	unregister_memory_notifier(&ehea_mem_nb);
+ 	kfree(ehea_fw_handles.arr);
+ 	kfree(ehea_bcmc_regs.arr);
+ 	ehea_destroy_busmap();
+diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
+index d522e90..140f05b 100644
+--- a/drivers/net/ehea/ehea_qmr.c
++++ b/drivers/net/ehea/ehea_qmr.c
+@@ -31,8 +31,8 @@
+ #include "ehea_phyp.h"
+ #include "ehea_qmr.h"
+ 
++struct ehea_bmap *ehea_bmap = NULL;
+ 
+-struct ehea_busmap ehea_bmap = { 0, 0, NULL };
+ 
+ 
+ static void *hw_qpageit_get_inc(struct hw_queue *queue)
+@@ -559,125 +559,253 @@ int ehea_destroy_qp(struct ehea_qp *qp)
+ 	return 0;
+ }
+ 
+-int ehea_create_busmap(void)
++static inline int ehea_calc_index(unsigned long i, unsigned long s)
+ {
+-	u64 vaddr = EHEA_BUSMAP_START;
+-	unsigned long high_section_index = 0;
+-	int i;
++	return (i >> s) & EHEA_INDEX_MASK;
++}
+ 
+-	/*
+-	 * Sections are not in ascending order -> Loop over all sections and
+-	 * find the highest PFN to compute the required map size.
+-	*/
+-	ehea_bmap.valid_sections = 0;
++static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap,
++				     int dir)
++{
++	if(!ehea_top_bmap->dir[dir]) {
++		ehea_top_bmap->dir[dir] =
++			kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL);
++		if (!ehea_top_bmap->dir[dir])
++			return -ENOMEM;
++	}
++	return 0;
++}
+ 
+-	for (i = 0; i < NR_MEM_SECTIONS; i++)
+-		if (valid_section_nr(i))
+-			high_section_index = i;
++static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir)
++{
++	if(!ehea_bmap->top[top]) {
++		ehea_bmap->top[top] =
++			kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL);
++		if (!ehea_bmap->top[top])
++			return -ENOMEM;
++	}
++	return ehea_init_top_bmap(ehea_bmap->top[top], dir);
++}
+ 
+-	ehea_bmap.entries = high_section_index + 1;
+-	ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr));
++static int ehea_create_busmap_callback(unsigned long pfn,
++				       unsigned long nr_pages, void *arg)
++{
++	unsigned long i, mr_len, start_section, end_section;
++	start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
++	end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
++	mr_len = *(unsigned long *)arg;
+ 
+-	if (!ehea_bmap.vaddr)
++	ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
++	if (!ehea_bmap)
+ 		return -ENOMEM;
+ 
+-	for (i = 0 ; i < ehea_bmap.entries; i++) {
+-		unsigned long pfn = section_nr_to_pfn(i);
++	for (i = start_section; i < end_section; i++) {
++		int ret;
++		int top, dir, idx;
++		u64 vaddr;
++
++		top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT);
++		dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT);
++
++		ret = ehea_init_bmap(ehea_bmap, top, dir);
++		if(ret)
++			return ret;
+ 
+-		if (pfn_valid(pfn)) {
+-			ehea_bmap.vaddr[i] = vaddr;
+-			vaddr += EHEA_SECTSIZE;
+-			ehea_bmap.valid_sections++;
+-		} else
+-			ehea_bmap.vaddr[i] = 0;
++		idx = i & EHEA_INDEX_MASK;
++		vaddr = EHEA_BUSMAP_START + mr_len + i * EHEA_SECTSIZE;
++
++		ehea_bmap->top[top]->dir[dir]->ent[idx] = vaddr;
+ 	}
+ 
++	mr_len += nr_pages * PAGE_SIZE;
++	*(unsigned long *)arg = mr_len;
++
+ 	return 0;
+ }
+ 
++static unsigned long ehea_mr_len;
++
++static DEFINE_MUTEX(ehea_busmap_mutex);
++
++int ehea_create_busmap(void)
++{
++	int ret;
++	mutex_lock(&ehea_busmap_mutex);
++	ehea_mr_len = 0;
++	ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, &ehea_mr_len,
++				   ehea_create_busmap_callback);
++	mutex_unlock(&ehea_busmap_mutex);
++	return ret;
++}
++
+ void ehea_destroy_busmap(void)
+ {
+-	vfree(ehea_bmap.vaddr);
++	int top, dir;
++	mutex_lock(&ehea_busmap_mutex);
++	if (!ehea_bmap)
++		goto out_destroy;
++
++	for (top = 0; top < EHEA_MAP_ENTRIES; top++) {
++		if (!ehea_bmap->top[top])
++			continue;
++
++		for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) {
++			if (!ehea_bmap->top[top]->dir[dir])
++				continue;
++
++			kfree(ehea_bmap->top[top]->dir[dir]);
++		}
++
++		kfree(ehea_bmap->top[top]);
++	}
++
++	kfree(ehea_bmap);
++	ehea_bmap = NULL;
++out_destroy:	
++	mutex_unlock(&ehea_busmap_mutex);
+ }
+ 
+ u64 ehea_map_vaddr(void *caddr)
+ {
+-	u64 mapped_addr;
+-	unsigned long index = __pa(caddr) >> SECTION_SIZE_BITS;
+-
+-	if (likely(index < ehea_bmap.entries)) {
+-		mapped_addr = ehea_bmap.vaddr[index];
+-		if (likely(mapped_addr))
+-			mapped_addr |= (((unsigned long)caddr)
+-					& (EHEA_SECTSIZE - 1));
+-		else
+-			mapped_addr = -1;
+-	} else
+-		mapped_addr = -1;
+-
+-	if (unlikely(mapped_addr == -1))
+-		if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
+-			schedule_work(&ehea_rereg_mr_task);
+-
+-	return mapped_addr;
++	int top, dir, idx;
++	unsigned long index, offset;
++
++	if (!ehea_bmap)
++		return EHEA_INVAL_ADDR;
++
++	index = virt_to_abs(caddr) >> SECTION_SIZE_BITS;
++	top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK;
++	if (!ehea_bmap->top[top])
++		return EHEA_INVAL_ADDR;
++
++	dir = (index >> EHEA_DIR_INDEX_SHIFT) & EHEA_INDEX_MASK;
++	if (!ehea_bmap->top[top]->dir[dir])
++		return EHEA_INVAL_ADDR;
++
++	idx = index & EHEA_INDEX_MASK;
++	if (!ehea_bmap->top[top]->dir[dir]->ent[idx])
++		return EHEA_INVAL_ADDR;
++
++	offset = (unsigned long)caddr & (EHEA_SECTSIZE - 1);
++	return ehea_bmap->top[top]->dir[dir]->ent[idx] | offset;
++}
++
++static inline void *ehea_calc_sectbase(int top, int dir, int idx)
++{
++	unsigned long ret = idx;
++	ret |= dir << EHEA_DIR_INDEX_SHIFT;
++	ret |= top << EHEA_TOP_INDEX_SHIFT;
++	return abs_to_virt(ret << SECTION_SIZE_BITS);
++}
++
++static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
++			       struct ehea_adapter *adapter,
++			       struct ehea_mr *mr)
++{
++	void *pg;
++	u64 j, m, hret;
++	unsigned long k = 0;
++	u64 pt_abs = virt_to_abs(pt);
++
++	void *sectbase = ehea_calc_sectbase(top, dir, idx);
++
++	for (j = 0; j < (EHEA_PAGES_PER_SECTION / EHEA_MAX_RPAGE); j++) {
++
++		for (m = 0; m < EHEA_MAX_RPAGE; m++) {
++			pg = sectbase + ((k++) * EHEA_PAGESIZE);
++			pt[m] = virt_to_abs(pg);
++		}
++		hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0,
++						0, pt_abs, EHEA_MAX_RPAGE);
++
++		if ((hret != H_SUCCESS)
++		    && (hret != H_PAGE_REGISTERED)) {
++			ehea_h_free_resource(adapter->handle, mr->handle,
++					     FORCE_FREE);
++			ehea_error("register_rpage_mr failed");
++			return hret;
++		}
++	}
++	return hret;
++}
++
++static u64 ehea_reg_mr_sections(int top, int dir, u64 *pt,
++				struct ehea_adapter *adapter,
++				struct ehea_mr *mr)
++{
++	u64 hret = H_SUCCESS;
++	int idx;
++
++	for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) {
++		if (!ehea_bmap->top[top]->dir[dir]->ent[idx])
++			continue;
++		
++		hret = ehea_reg_mr_section(top, dir, idx, pt, adapter, mr);
++		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
++			    	return hret;
++	}
++	return hret;
++}
++
++static u64 ehea_reg_mr_dir_sections(int top, u64 *pt,
++				    struct ehea_adapter *adapter,
++				    struct ehea_mr *mr)
++{
++	u64 hret = H_SUCCESS;
++	int dir;
++
++	for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) {
++		if (!ehea_bmap->top[top]->dir[dir])
++			continue;
++
++		hret = ehea_reg_mr_sections(top, dir, pt, adapter, mr);
++		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
++			    	return hret;
++	}
++	return hret;
+ }
+ 
+ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
+ {
+ 	int ret;
+ 	u64 *pt;
+-	void *pg;
+-	u64 hret, pt_abs, i, j, m, mr_len;
++	u64 hret;
+ 	u32 acc_ctrl = EHEA_MR_ACC_CTRL;
+ 
+-	mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE;
++	unsigned long top;
+ 
+-	pt =  kzalloc(PAGE_SIZE, GFP_KERNEL);
++	pt = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ 	if (!pt) {
+ 		ehea_error("no mem");
+ 		ret = -ENOMEM;
+ 		goto out;
+ 	}
+-	pt_abs = virt_to_abs(pt);
+ 
+-	hret = ehea_h_alloc_resource_mr(adapter->handle,
+-					EHEA_BUSMAP_START, mr_len,
+-					acc_ctrl, adapter->pd,
++	hret = ehea_h_alloc_resource_mr(adapter->handle, EHEA_BUSMAP_START,
++					ehea_mr_len, acc_ctrl, adapter->pd,
+ 					&mr->handle, &mr->lkey);
++
+ 	if (hret != H_SUCCESS) {
+ 		ehea_error("alloc_resource_mr failed");
+ 		ret = -EIO;
+ 		goto out;
+ 	}
+ 
+-	for (i = 0 ; i < ehea_bmap.entries; i++)
+-		if (ehea_bmap.vaddr[i]) {
+-			void *sectbase = __va(i << SECTION_SIZE_BITS);
+-			unsigned long k = 0;
+-
+-			for (j = 0; j < (EHEA_PAGES_PER_SECTION /
+-					 EHEA_MAX_RPAGE); j++) {
+-
+-				for (m = 0; m < EHEA_MAX_RPAGE; m++) {
+-					pg = sectbase + ((k++) * EHEA_PAGESIZE);
+-					pt[m] = virt_to_abs(pg);
+-				}
+-
+-				hret = ehea_h_register_rpage_mr(adapter->handle,
+-								mr->handle,
+-								0, 0, pt_abs,
+-								EHEA_MAX_RPAGE);
+-				if ((hret != H_SUCCESS)
+-				    && (hret != H_PAGE_REGISTERED)) {
+-					ehea_h_free_resource(adapter->handle,
+-							     mr->handle,
+-							     FORCE_FREE);
+-					ehea_error("register_rpage_mr failed");
+-					ret = -EIO;
+-					goto out;
+-				}
+-			}
+-		}
++	if (!ehea_bmap) {
++		ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
++		ehea_error("no busmap available");
++		ret = -EIO;
++		goto out;
++	}
++
++	for (top = 0; top < EHEA_MAP_ENTRIES; top++) {
++		if (!ehea_bmap->top[top])
++			continue;
++
++		hret = ehea_reg_mr_dir_sections(top, pt, adapter, mr);
++		if((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS))
++			break;
++	}
+ 
+ 	if (hret != H_SUCCESS) {
+ 		ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
+diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
+index 6f22f06..25bdd08 100644
+--- a/drivers/net/gianfar.c
++++ b/drivers/net/gianfar.c
+@@ -635,6 +635,8 @@ static void free_skb_resources(struct gfar_private *priv)
+ 			dev_kfree_skb_any(priv->tx_skbuff[i]);
+ 			priv->tx_skbuff[i] = NULL;
+ 		}
++
++		txbdp++;
+ 	}
+ 
+ 	kfree(priv->tx_skbuff);
+diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
+index ef63c8d..c91b12e 100644
+--- a/drivers/net/myri10ge/myri10ge.c
++++ b/drivers/net/myri10ge/myri10ge.c
+@@ -144,11 +144,13 @@ struct myri10ge_tx_buf {
+ 	char *req_bytes;
+ 	struct myri10ge_tx_buffer_state *info;
+ 	int mask;		/* number of transmit slots -1  */
+-	int boundary;		/* boundary transmits cannot cross */
+ 	int req ____cacheline_aligned;	/* transmit slots submitted     */
+ 	int pkt_start;		/* packets started */
++	int stop_queue;
++	int linearized;
+ 	int done ____cacheline_aligned;	/* transmit slots completed     */
+ 	int pkt_done;		/* packets completed */
++	int wake_queue;
+ };
+ 
+ struct myri10ge_rx_done {
+@@ -160,29 +162,50 @@ struct myri10ge_rx_done {
+ 	struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS];
+ };
+ 
+-struct myri10ge_priv {
+-	int running;		/* running?             */
+-	int csum_flag;		/* rx_csums?            */
++struct myri10ge_slice_netstats {
++	unsigned long rx_packets;
++	unsigned long tx_packets;
++	unsigned long rx_bytes;
++	unsigned long tx_bytes;
++	unsigned long rx_dropped;
++	unsigned long tx_dropped;
++};
++
++struct myri10ge_slice_state {
+ 	struct myri10ge_tx_buf tx;	/* transmit ring        */
+ 	struct myri10ge_rx_buf rx_small;
+ 	struct myri10ge_rx_buf rx_big;
+ 	struct myri10ge_rx_done rx_done;
++	struct net_device *dev;
++	struct napi_struct napi;
++	struct myri10ge_priv *mgp;
++	struct myri10ge_slice_netstats stats;
++	__be32 __iomem *irq_claim;
++	struct mcp_irq_data *fw_stats;
++	dma_addr_t fw_stats_bus;
++	int watchdog_tx_done;
++	int watchdog_tx_req;
++};
++
++struct myri10ge_priv {
++	struct myri10ge_slice_state ss;
++	int tx_boundary;	/* boundary transmits cannot cross */
++	int running;		/* running?             */
++	int csum_flag;		/* rx_csums?            */
+ 	int small_bytes;
+ 	int big_bytes;
++	int max_intr_slots;
+ 	struct net_device *dev;
+-	struct napi_struct napi;
+ 	struct net_device_stats stats;
++	spinlock_t stats_lock;
+ 	u8 __iomem *sram;
+ 	int sram_size;
+ 	unsigned long board_span;
+ 	unsigned long iomem_base;
+-	__be32 __iomem *irq_claim;
+ 	__be32 __iomem *irq_deassert;
+ 	char *mac_addr_string;
+ 	struct mcp_cmd_response *cmd;
+ 	dma_addr_t cmd_bus;
+-	struct mcp_irq_data *fw_stats;
+-	dma_addr_t fw_stats_bus;
+ 	struct pci_dev *pdev;
+ 	int msi_enabled;
+ 	u32 link_state;
+@@ -191,20 +214,16 @@ struct myri10ge_priv {
+ 	__be32 __iomem *intr_coal_delay_ptr;
+ 	int mtrr;
+ 	int wc_enabled;
+-	int wake_queue;
+-	int stop_queue;
+ 	int down_cnt;
+ 	wait_queue_head_t down_wq;
+ 	struct work_struct watchdog_work;
+ 	struct timer_list watchdog_timer;
+-	int watchdog_tx_done;
+-	int watchdog_tx_req;
+-	int watchdog_pause;
+ 	int watchdog_resets;
+-	int tx_linearized;
++	int watchdog_pause;
+ 	int pause;
+ 	char *fw_name;
+ 	char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE];
++	char *product_code_string;
+ 	char fw_version[128];
+ 	int fw_ver_major;
+ 	int fw_ver_minor;
+@@ -228,58 +247,54 @@ static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat";
+ 
+ static char *myri10ge_fw_name = NULL;
+ module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n");
++MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
+ 
+ static int myri10ge_ecrc_enable = 1;
+ module_param(myri10ge_ecrc_enable, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n");
+-
+-static int myri10ge_max_intr_slots = 1024;
+-module_param(myri10ge_max_intr_slots, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n");
++MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E");
+ 
+ static int myri10ge_small_bytes = -1;	/* -1 == auto */
+ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n");
++MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets");
+ 
+ static int myri10ge_msi = 1;	/* enable msi by default */
+ module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
++MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts");
+ 
+ static int myri10ge_intr_coal_delay = 75;
+ module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
++MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay");
+ 
+ static int myri10ge_flow_control = 1;
+ module_param(myri10ge_flow_control, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n");
++MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter");
+ 
+ static int myri10ge_deassert_wait = 1;
+ module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR);
+ MODULE_PARM_DESC(myri10ge_deassert_wait,
+-		 "Wait when deasserting legacy interrupts\n");
++		 "Wait when deasserting legacy interrupts");
+ 
+ static int myri10ge_force_firmware = 0;
+ module_param(myri10ge_force_firmware, int, S_IRUGO);
+ MODULE_PARM_DESC(myri10ge_force_firmware,
+-		 "Force firmware to assume aligned completions\n");
++		 "Force firmware to assume aligned completions");
+ 
+ static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
+ module_param(myri10ge_initial_mtu, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n");
++MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU");
+ 
+ static int myri10ge_napi_weight = 64;
+ module_param(myri10ge_napi_weight, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n");
++MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight");
+ 
+ static int myri10ge_watchdog_timeout = 1;
+ module_param(myri10ge_watchdog_timeout, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n");
++MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout");
+ 
+ static int myri10ge_max_irq_loops = 1048576;
+ module_param(myri10ge_max_irq_loops, int, S_IRUGO);
+ MODULE_PARM_DESC(myri10ge_max_irq_loops,
+-		 "Set stuck legacy IRQ detection threshold\n");
++		 "Set stuck legacy IRQ detection threshold");
+ 
+ #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK
+ 
+@@ -289,21 +304,22 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
+ 
+ static int myri10ge_lro = 1;
+ module_param(myri10ge_lro, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n");
++MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload");
+ 
+ static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
+ module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n");
++MODULE_PARM_DESC(myri10ge_lro_max_pkts,
++		 "Number of LRO packets to be aggregated");
+ 
+ static int myri10ge_fill_thresh = 256;
+ module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
++MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed");
+ 
+ static int myri10ge_reset_recover = 1;
+ 
+ static int myri10ge_wcfifo = 0;
+ module_param(myri10ge_wcfifo, int, S_IRUGO);
+-MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
++MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled");
+ 
+ #define MYRI10GE_FW_OFFSET 1024*1024
+ #define MYRI10GE_HIGHPART_TO_U32(X) \
+@@ -359,8 +375,10 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
+ 		for (sleep_total = 0;
+ 		     sleep_total < 1000
+ 		     && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
+-		     sleep_total += 10)
++		     sleep_total += 10) {
+ 			udelay(10);
++			mb();
++		}
+ 	} else {
+ 		/* use msleep for most command */
+ 		for (sleep_total = 0;
+@@ -420,6 +438,10 @@ static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp)
+ 				ptr += 1;
+ 			}
+ 		}
++		if (memcmp(ptr, "PC=", 3) == 0) {
++			ptr += 3;
++			mgp->product_code_string = ptr;
++		}
+ 		if (memcmp((const void *)ptr, "SN=", 3) == 0) {
+ 			ptr += 3;
+ 			mgp->serial_number = simple_strtoul(ptr, &ptr, 10);
+@@ -442,7 +464,7 @@ abort:
+ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
+ {
+ 	char __iomem *submit;
+-	__be32 buf[16];
++	__be32 buf[16] __attribute__ ((__aligned__(8)));
+ 	u32 dma_low, dma_high;
+ 	int i;
+ 
+@@ -609,13 +631,38 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
+ 	return status;
+ }
+ 
++int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp)
++{
++	struct myri10ge_cmd cmd;
++	int status;
++
++	/* probe for IPv6 TSO support */
++	mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
++	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
++				   &cmd, 0);
++	if (status == 0) {
++		mgp->max_tso6 = cmd.data0;
++		mgp->features |= NETIF_F_TSO6;
++	}
++
++	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
++	if (status != 0) {
++		dev_err(&mgp->pdev->dev,
++			"failed MXGEFW_CMD_GET_RX_RING_SIZE\n");
++		return -ENXIO;
++	}
++
++	mgp->max_intr_slots = 2 * (cmd.data0 / sizeof(struct mcp_dma_addr));
++
++	return 0;
++}
++
+ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+ {
+ 	char __iomem *submit;
+-	__be32 buf[16];
++	__be32 buf[16] __attribute__ ((__aligned__(8)));
+ 	u32 dma_low, dma_high, size;
+ 	int status, i;
+-	struct myri10ge_cmd cmd;
+ 
+ 	size = 0;
+ 	status = myri10ge_load_hotplug_firmware(mgp, &size);
+@@ -635,7 +682,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+ 		}
+ 		dev_info(&mgp->pdev->dev,
+ 			 "Successfully adopted running firmware\n");
+-		if (mgp->tx.boundary == 4096) {
++		if (mgp->tx_boundary == 4096) {
+ 			dev_warn(&mgp->pdev->dev,
+ 				 "Using firmware currently running on NIC"
+ 				 ".  For optimal\n");
+@@ -646,7 +693,9 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+ 		}
+ 
+ 		mgp->fw_name = "adopted";
+-		mgp->tx.boundary = 2048;
++		mgp->tx_boundary = 2048;
++		myri10ge_dummy_rdma(mgp, 1);
++		status = myri10ge_get_firmware_capabilities(mgp);
+ 		return status;
+ 	}
+ 
+@@ -681,26 +730,18 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+ 	msleep(1);
+ 	mb();
+ 	i = 0;
+-	while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) {
+-		msleep(1);
++	while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 9) {
++		msleep(1 << i);
+ 		i++;
+ 	}
+ 	if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) {
+ 		dev_err(&mgp->pdev->dev, "handoff failed\n");
+ 		return -ENXIO;
+ 	}
+-	dev_info(&mgp->pdev->dev, "handoff confirmed\n");
+ 	myri10ge_dummy_rdma(mgp, 1);
++	status = myri10ge_get_firmware_capabilities(mgp);
+ 
+-	/* probe for IPv6 TSO support */
+-	mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+-	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+-				   &cmd, 0);
+-	if (status == 0) {
+-		mgp->max_tso6 = cmd.data0;
+-		mgp->features |= NETIF_F_TSO6;
+-	}
+-	return 0;
++	return status;
+ }
+ 
+ static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr)
+@@ -772,7 +813,7 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
+ 	 * transfers took to complete.
+ 	 */
+ 
+-	len = mgp->tx.boundary;
++	len = mgp->tx_boundary;
+ 
+ 	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ 	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+@@ -834,17 +875,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
+ 
+ 	/* Now exchange information about interrupts  */
+ 
+-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+-	memset(mgp->rx_done.entry, 0, bytes);
++	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
++	memset(mgp->ss.rx_done.entry, 0, bytes);
+ 	cmd.data0 = (u32) bytes;
+ 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
+-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
+-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
++	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.rx_done.bus);
++	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.rx_done.bus);
+ 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0);
+ 
+ 	status |=
+ 	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
+-	mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
++	mgp->ss.irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
+ 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
+ 				    &cmd, 0);
+ 	mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
+@@ -858,17 +899,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
+ 	}
+ 	put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
+ 
+-	memset(mgp->rx_done.entry, 0, bytes);
++	memset(mgp->ss.rx_done.entry, 0, bytes);
+ 
+ 	/* reset mcp/driver shared state back to 0 */
+-	mgp->tx.req = 0;
+-	mgp->tx.done = 0;
+-	mgp->tx.pkt_start = 0;
+-	mgp->tx.pkt_done = 0;
+-	mgp->rx_big.cnt = 0;
+-	mgp->rx_small.cnt = 0;
+-	mgp->rx_done.idx = 0;
+-	mgp->rx_done.cnt = 0;
++	mgp->ss.tx.req = 0;
++	mgp->ss.tx.done = 0;
++	mgp->ss.tx.pkt_start = 0;
++	mgp->ss.tx.pkt_done = 0;
++	mgp->ss.rx_big.cnt = 0;
++	mgp->ss.rx_small.cnt = 0;
++	mgp->ss.rx_done.idx = 0;
++	mgp->ss.rx_done.cnt = 0;
+ 	mgp->link_changes = 0;
+ 	status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
+ 	myri10ge_change_pause(mgp, mgp->pause);
+@@ -1020,9 +1061,10 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
+ 				 * page into an skb */
+ 
+ static inline int
+-myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
++myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
+ 		 int bytes, int len, __wsum csum)
+ {
++	struct myri10ge_priv *mgp = ss->mgp;
+ 	struct sk_buff *skb;
+ 	struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
+ 	int i, idx, hlen, remainder;
+@@ -1052,11 +1094,10 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
+ 		rx_frags[0].page_offset += MXGEFW_PAD;
+ 		rx_frags[0].size -= MXGEFW_PAD;
+ 		len -= MXGEFW_PAD;
+-		lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags,
++		lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags,
+ 				  len, len,
+-				 /* opaque, will come back in get_frag_header */
+-				  (void *)(__force unsigned long)csum,
+-				  csum);
++				  /* opaque, will come back in get_frag_header */
++				  (void *)(__force unsigned long)csum, csum);
+ 		return 1;
+ 	}
+ 
+@@ -1096,10 +1137,11 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
+ 	return 1;
+ }
+ 
+-static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
++static inline void
++myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
+ {
+-	struct pci_dev *pdev = mgp->pdev;
+-	struct myri10ge_tx_buf *tx = &mgp->tx;
++	struct pci_dev *pdev = ss->mgp->pdev;
++	struct myri10ge_tx_buf *tx = &ss->tx;
+ 	struct sk_buff *skb;
+ 	int idx, len;
+ 
+@@ -1117,8 +1159,8 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
+ 		len = pci_unmap_len(&tx->info[idx], len);
+ 		pci_unmap_len_set(&tx->info[idx], len, 0);
+ 		if (skb) {
+-			mgp->stats.tx_bytes += skb->len;
+-			mgp->stats.tx_packets++;
++			ss->stats.tx_bytes += skb->len;
++			ss->stats.tx_packets++;
+ 			dev_kfree_skb_irq(skb);
+ 			if (len)
+ 				pci_unmap_single(pdev,
+@@ -1134,16 +1176,18 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
+ 		}
+ 	}
+ 	/* start the queue if we've stopped it */
+-	if (netif_queue_stopped(mgp->dev)
++	if (netif_queue_stopped(ss->dev)
+ 	    && tx->req - tx->done < (tx->mask >> 1)) {
+-		mgp->wake_queue++;
+-		netif_wake_queue(mgp->dev);
++		tx->wake_queue++;
++		netif_wake_queue(ss->dev);
+ 	}
+ }
+ 
+-static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget)
++static inline int
++myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
+ {
+-	struct myri10ge_rx_done *rx_done = &mgp->rx_done;
++	struct myri10ge_rx_done *rx_done = &ss->rx_done;
++	struct myri10ge_priv *mgp = ss->mgp;
+ 	unsigned long rx_bytes = 0;
+ 	unsigned long rx_packets = 0;
+ 	unsigned long rx_ok;
+@@ -1159,40 +1203,40 @@ static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget)
+ 		rx_done->entry[idx].length = 0;
+ 		checksum = csum_unfold(rx_done->entry[idx].checksum);
+ 		if (length <= mgp->small_bytes)
+-			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
++			rx_ok = myri10ge_rx_done(ss, &ss->rx_small,
+ 						 mgp->small_bytes,
+ 						 length, checksum);
+ 		else
+-			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big,
++			rx_ok = myri10ge_rx_done(ss, &ss->rx_big,
+ 						 mgp->big_bytes,
+ 						 length, checksum);
+ 		rx_packets += rx_ok;
+ 		rx_bytes += rx_ok * (unsigned long)length;
+ 		cnt++;
+-		idx = cnt & (myri10ge_max_intr_slots - 1);
++		idx = cnt & (mgp->max_intr_slots - 1);
+ 		work_done++;
+ 	}
+ 	rx_done->idx = idx;
+ 	rx_done->cnt = cnt;
+-	mgp->stats.rx_packets += rx_packets;
+-	mgp->stats.rx_bytes += rx_bytes;
++	ss->stats.rx_packets += rx_packets;
++	ss->stats.rx_bytes += rx_bytes;
+ 
+ 	if (myri10ge_lro)
+ 		lro_flush_all(&rx_done->lro_mgr);
+ 
+ 	/* restock receive rings if needed */
+-	if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
+-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
++	if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh)
++		myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
+ 					mgp->small_bytes + MXGEFW_PAD, 0);
+-	if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh)
+-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
++	if (ss->rx_big.fill_cnt - ss->rx_big.cnt < myri10ge_fill_thresh)
++		myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
+ 
+ 	return work_done;
+ }
+ 
+ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
+ {
+-	struct mcp_irq_data *stats = mgp->fw_stats;
++	struct mcp_irq_data *stats = mgp->ss.fw_stats;
+ 
+ 	if (unlikely(stats->stats_updated)) {
+ 		unsigned link_up = ntohl(stats->link_up);
+@@ -1219,9 +1263,9 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
+ 			}
+ 		}
+ 		if (mgp->rdma_tags_available !=
+-		    ntohl(mgp->fw_stats->rdma_tags_available)) {
++		    ntohl(stats->rdma_tags_available)) {
+ 			mgp->rdma_tags_available =
+-			    ntohl(mgp->fw_stats->rdma_tags_available);
++			    ntohl(stats->rdma_tags_available);
+ 			printk(KERN_WARNING "myri10ge: %s: RDMA timed out! "
+ 			       "%d tags left\n", mgp->dev->name,
+ 			       mgp->rdma_tags_available);
+@@ -1234,26 +1278,27 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
+ 
+ static int myri10ge_poll(struct napi_struct *napi, int budget)
+ {
+-	struct myri10ge_priv *mgp =
+-	    container_of(napi, struct myri10ge_priv, napi);
+-	struct net_device *netdev = mgp->dev;
++	struct myri10ge_slice_state *ss =
++	    container_of(napi, struct myri10ge_slice_state, napi);
++	struct net_device *netdev = ss->mgp->dev;
+ 	int work_done;
+ 
+ 	/* process as many rx events as NAPI will allow */
+-	work_done = myri10ge_clean_rx_done(mgp, budget);
++	work_done = myri10ge_clean_rx_done(ss, budget);
+ 
+ 	if (work_done < budget) {
+ 		netif_rx_complete(netdev, napi);
+-		put_be32(htonl(3), mgp->irq_claim);
++		put_be32(htonl(3), ss->irq_claim);
+ 	}
+ 	return work_done;
+ }
+ 
+ static irqreturn_t myri10ge_intr(int irq, void *arg)
+ {
+-	struct myri10ge_priv *mgp = arg;
+-	struct mcp_irq_data *stats = mgp->fw_stats;
+-	struct myri10ge_tx_buf *tx = &mgp->tx;
++	struct myri10ge_slice_state *ss = arg;
++	struct myri10ge_priv *mgp = ss->mgp;
++	struct mcp_irq_data *stats = ss->fw_stats;
++	struct myri10ge_tx_buf *tx = &ss->tx;
+ 	u32 send_done_count;
+ 	int i;
+ 
+@@ -1264,7 +1309,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
+ 	/* low bit indicates receives are present, so schedule
+ 	 * napi poll handler */
+ 	if (stats->valid & 1)
+-		netif_rx_schedule(mgp->dev, &mgp->napi);
++		netif_rx_schedule(ss->dev, &ss->napi);
+ 
+ 	if (!mgp->msi_enabled) {
+ 		put_be32(0, mgp->irq_deassert);
+@@ -1281,7 +1326,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
+ 		/* check for transmit completes and receives */
+ 		send_done_count = ntohl(stats->send_done_count);
+ 		if (send_done_count != tx->pkt_done)
+-			myri10ge_tx_done(mgp, (int)send_done_count);
++			myri10ge_tx_done(ss, (int)send_done_count);
+ 		if (unlikely(i > myri10ge_max_irq_loops)) {
+ 			printk(KERN_WARNING "myri10ge: %s: irq stuck?\n",
+ 			       mgp->dev->name);
+@@ -1296,16 +1341,46 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
+ 
+ 	myri10ge_check_statblock(mgp);
+ 
+-	put_be32(htonl(3), mgp->irq_claim + 1);
++	put_be32(htonl(3), ss->irq_claim + 1);
+ 	return (IRQ_HANDLED);
+ }
+ 
+ static int
+ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+ {
++	struct myri10ge_priv *mgp = netdev_priv(netdev);
++	char *ptr;
++	int i;
++
+ 	cmd->autoneg = AUTONEG_DISABLE;
+ 	cmd->speed = SPEED_10000;
+ 	cmd->duplex = DUPLEX_FULL;
++
++	/*
++	 * parse the product code to deterimine the interface type
++	 * (CX4, XFP, Quad Ribbon Fiber) by looking at the character
++	 * after the 3rd dash in the driver's cached copy of the
++	 * EEPROM's product code string.
++	 */
++	ptr = mgp->product_code_string;
++	if (ptr == NULL) {
++		printk(KERN_ERR "myri10ge: %s: Missing product code\n",
++		       netdev->name);
++		return 0;
++	}
++	for (i = 0; i < 3; i++, ptr++) {
++		ptr = strchr(ptr, '-');
++		if (ptr == NULL) {
++			printk(KERN_ERR "myri10ge: %s: Invalid product "
++			       "code %s\n", netdev->name,
++			       mgp->product_code_string);
++			return 0;
++		}
++	}
++	if (*ptr == 'R' || *ptr == 'Q') {
++		/* We've found either an XFP or quad ribbon fiber */
++		cmd->port = PORT_FIBRE;
++	}
+ 	return 0;
+ }
+ 
+@@ -1324,6 +1399,7 @@ static int
+ myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(netdev);
++
+ 	coal->rx_coalesce_usecs = mgp->intr_coal_delay;
+ 	return 0;
+ }
+@@ -1370,10 +1446,10 @@ myri10ge_get_ringparam(struct net_device *netdev,
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(netdev);
+ 
+-	ring->rx_mini_max_pending = mgp->rx_small.mask + 1;
+-	ring->rx_max_pending = mgp->rx_big.mask + 1;
++	ring->rx_mini_max_pending = mgp->ss.rx_small.mask + 1;
++	ring->rx_max_pending = mgp->ss.rx_big.mask + 1;
+ 	ring->rx_jumbo_max_pending = 0;
+-	ring->tx_max_pending = mgp->rx_small.mask + 1;
++	ring->tx_max_pending = mgp->ss.rx_small.mask + 1;
+ 	ring->rx_mini_pending = ring->rx_mini_max_pending;
+ 	ring->rx_pending = ring->rx_max_pending;
+ 	ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
+@@ -1383,6 +1459,7 @@ myri10ge_get_ringparam(struct net_device *netdev,
+ static u32 myri10ge_get_rx_csum(struct net_device *netdev)
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(netdev);
++
+ 	if (mgp->csum_flag)
+ 		return 1;
+ 	else
+@@ -1392,6 +1469,7 @@ static u32 myri10ge_get_rx_csum(struct net_device *netdev)
+ static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(netdev);
++
+ 	if (csum_enabled)
+ 		mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
+ 	else
+@@ -1411,7 +1489,7 @@ static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
+ 	return 0;
+ }
+ 
+-static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
++static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
+ 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+ 	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+ 	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
+@@ -1421,28 +1499,39 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
+ 	/* device-specific stats */
+ 	"tx_boundary", "WC", "irq", "MSI",
+ 	"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
+-	"serial_number", "tx_pkt_start", "tx_pkt_done",
+-	"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
+-	"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
++	"serial_number", "watchdog_resets",
+ 	"link_changes", "link_up", "dropped_link_overflow",
+ 	"dropped_link_error_or_filtered",
+ 	"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
+ 	"dropped_unicast_filtered", "dropped_multicast_filtered",
+ 	"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
+-	"dropped_no_big_buffer", "LRO aggregated", "LRO flushed",
++	"dropped_no_big_buffer"
++};
++
++static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = {
++	"----------- slice ---------",
++	"tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done",
++	"rx_small_cnt", "rx_big_cnt",
++	"wake_queue", "stop_queue", "tx_linearized", "LRO aggregated",
++	    "LRO flushed",
+ 	"LRO avg aggr", "LRO no_desc"
+ };
+ 
+ #define MYRI10GE_NET_STATS_LEN      21
+-#define MYRI10GE_STATS_LEN	ARRAY_SIZE(myri10ge_gstrings_stats)
++#define MYRI10GE_MAIN_STATS_LEN  ARRAY_SIZE(myri10ge_gstrings_main_stats)
++#define MYRI10GE_SLICE_STATS_LEN  ARRAY_SIZE(myri10ge_gstrings_slice_stats)
+ 
+ static void
+ myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
+ {
+ 	switch (stringset) {
+ 	case ETH_SS_STATS:
+-		memcpy(data, *myri10ge_gstrings_stats,
+-		       sizeof(myri10ge_gstrings_stats));
++		memcpy(data, *myri10ge_gstrings_main_stats,
++		       sizeof(myri10ge_gstrings_main_stats));
++		data += sizeof(myri10ge_gstrings_main_stats);
++		memcpy(data, *myri10ge_gstrings_slice_stats,
++		       sizeof(myri10ge_gstrings_slice_stats));
++		data += sizeof(myri10ge_gstrings_slice_stats);
+ 		break;
+ 	}
+ }
+@@ -1451,7 +1540,7 @@ static int myri10ge_get_sset_count(struct net_device *netdev, int sset)
+ {
+ 	switch (sset) {
+ 	case ETH_SS_STATS:
+-		return MYRI10GE_STATS_LEN;
++		return MYRI10GE_MAIN_STATS_LEN + MYRI10GE_SLICE_STATS_LEN;
+ 	default:
+ 		return -EOPNOTSUPP;
+ 	}
+@@ -1462,12 +1551,13 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
+ 			   struct ethtool_stats *stats, u64 * data)
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(netdev);
++	struct myri10ge_slice_state *ss;
+ 	int i;
+ 
+ 	for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
+ 		data[i] = ((unsigned long *)&mgp->stats)[i];
+ 
+-	data[i++] = (unsigned int)mgp->tx.boundary;
++	data[i++] = (unsigned int)mgp->tx_boundary;
+ 	data[i++] = (unsigned int)mgp->wc_enabled;
+ 	data[i++] = (unsigned int)mgp->pdev->irq;
+ 	data[i++] = (unsigned int)mgp->msi_enabled;
+@@ -1475,40 +1565,44 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
+ 	data[i++] = (unsigned int)mgp->write_dma;
+ 	data[i++] = (unsigned int)mgp->read_write_dma;
+ 	data[i++] = (unsigned int)mgp->serial_number;
+-	data[i++] = (unsigned int)mgp->tx.pkt_start;
+-	data[i++] = (unsigned int)mgp->tx.pkt_done;
+-	data[i++] = (unsigned int)mgp->tx.req;
+-	data[i++] = (unsigned int)mgp->tx.done;
+-	data[i++] = (unsigned int)mgp->rx_small.cnt;
+-	data[i++] = (unsigned int)mgp->rx_big.cnt;
+-	data[i++] = (unsigned int)mgp->wake_queue;
+-	data[i++] = (unsigned int)mgp->stop_queue;
+ 	data[i++] = (unsigned int)mgp->watchdog_resets;
+-	data[i++] = (unsigned int)mgp->tx_linearized;
+ 	data[i++] = (unsigned int)mgp->link_changes;
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
+-	data[i++] =
+-	    (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32);
++
++	/* firmware stats are useful only in the first slice */
++	ss = &mgp->ss;
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->link_up);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_link_overflow);
+ 	data[i++] =
+-	    (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered);
++	    (unsigned int)ntohl(ss->fw_stats->dropped_link_error_or_filtered);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_pause);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_phy);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_crc32);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_unicast_filtered);
+ 	data[i++] =
+-	    (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer);
+-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer);
+-	data[i++] = mgp->rx_done.lro_mgr.stats.aggregated;
+-	data[i++] = mgp->rx_done.lro_mgr.stats.flushed;
+-	if (mgp->rx_done.lro_mgr.stats.flushed)
+-		data[i++] = mgp->rx_done.lro_mgr.stats.aggregated /
+-		    mgp->rx_done.lro_mgr.stats.flushed;
++	    (unsigned int)ntohl(ss->fw_stats->dropped_multicast_filtered);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_runt);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_overrun);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_small_buffer);
++	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_big_buffer);
++
++	data[i++] = 0;
++	data[i++] = (unsigned int)ss->tx.pkt_start;
++	data[i++] = (unsigned int)ss->tx.pkt_done;
++	data[i++] = (unsigned int)ss->tx.req;
++	data[i++] = (unsigned int)ss->tx.done;
++	data[i++] = (unsigned int)ss->rx_small.cnt;
++	data[i++] = (unsigned int)ss->rx_big.cnt;
++	data[i++] = (unsigned int)ss->tx.wake_queue;
++	data[i++] = (unsigned int)ss->tx.stop_queue;
++	data[i++] = (unsigned int)ss->tx.linearized;
++	data[i++] = ss->rx_done.lro_mgr.stats.aggregated;
++	data[i++] = ss->rx_done.lro_mgr.stats.flushed;
++	if (ss->rx_done.lro_mgr.stats.flushed)
++		data[i++] = ss->rx_done.lro_mgr.stats.aggregated /
++		    ss->rx_done.lro_mgr.stats.flushed;
+ 	else
+ 		data[i++] = 0;
+-	data[i++] = mgp->rx_done.lro_mgr.stats.no_desc;
++	data[i++] = ss->rx_done.lro_mgr.stats.no_desc;
+ }
+ 
+ static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
+@@ -1544,19 +1638,17 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
+ 	.get_msglevel = myri10ge_get_msglevel
+ };
+ 
+-static int myri10ge_allocate_rings(struct net_device *dev)
++static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
+ {
+-	struct myri10ge_priv *mgp;
++	struct myri10ge_priv *mgp = ss->mgp;
+ 	struct myri10ge_cmd cmd;
++	struct net_device *dev = mgp->dev;
+ 	int tx_ring_size, rx_ring_size;
+ 	int tx_ring_entries, rx_ring_entries;
+ 	int i, status;
+ 	size_t bytes;
+ 
+-	mgp = netdev_priv(dev);
+-
+ 	/* get ring sizes */
+-
+ 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
+ 	tx_ring_size = cmd.data0;
+ 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+@@ -1566,144 +1658,142 @@ static int myri10ge_allocate_rings(struct net_device *dev)
+ 
+ 	tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
+ 	rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr);
+-	mgp->tx.mask = tx_ring_entries - 1;
+-	mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
++	ss->tx.mask = tx_ring_entries - 1;
++	ss->rx_small.mask = ss->rx_big.mask = rx_ring_entries - 1;
+ 
+ 	status = -ENOMEM;
+ 
+ 	/* allocate the host shadow rings */
+ 
+ 	bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
+-	    * sizeof(*mgp->tx.req_list);
+-	mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->tx.req_bytes == NULL)
++	    * sizeof(*ss->tx.req_list);
++	ss->tx.req_bytes = kzalloc(bytes, GFP_KERNEL);
++	if (ss->tx.req_bytes == NULL)
+ 		goto abort_with_nothing;
+ 
+ 	/* ensure req_list entries are aligned to 8 bytes */
+-	mgp->tx.req_list = (struct mcp_kreq_ether_send *)
+-	    ALIGN((unsigned long)mgp->tx.req_bytes, 8);
++	ss->tx.req_list = (struct mcp_kreq_ether_send *)
++	    ALIGN((unsigned long)ss->tx.req_bytes, 8);
+ 
+-	bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow);
+-	mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->rx_small.shadow == NULL)
++	bytes = rx_ring_entries * sizeof(*ss->rx_small.shadow);
++	ss->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
++	if (ss->rx_small.shadow == NULL)
+ 		goto abort_with_tx_req_bytes;
+ 
+-	bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow);
+-	mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->rx_big.shadow == NULL)
++	bytes = rx_ring_entries * sizeof(*ss->rx_big.shadow);
++	ss->rx_big.shadow = kzalloc(bytes, GFP_KERNEL);
++	if (ss->rx_big.shadow == NULL)
+ 		goto abort_with_rx_small_shadow;
+ 
+ 	/* allocate the host info rings */
+ 
+-	bytes = tx_ring_entries * sizeof(*mgp->tx.info);
+-	mgp->tx.info = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->tx.info == NULL)
++	bytes = tx_ring_entries * sizeof(*ss->tx.info);
++	ss->tx.info = kzalloc(bytes, GFP_KERNEL);
++	if (ss->tx.info == NULL)
+ 		goto abort_with_rx_big_shadow;
+ 
+-	bytes = rx_ring_entries * sizeof(*mgp->rx_small.info);
+-	mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->rx_small.info == NULL)
++	bytes = rx_ring_entries * sizeof(*ss->rx_small.info);
++	ss->rx_small.info = kzalloc(bytes, GFP_KERNEL);
++	if (ss->rx_small.info == NULL)
+ 		goto abort_with_tx_info;
+ 
+-	bytes = rx_ring_entries * sizeof(*mgp->rx_big.info);
+-	mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL);
+-	if (mgp->rx_big.info == NULL)
++	bytes = rx_ring_entries * sizeof(*ss->rx_big.info);
++	ss->rx_big.info = kzalloc(bytes, GFP_KERNEL);
++	if (ss->rx_big.info == NULL)
+ 		goto abort_with_rx_small_info;
+ 
+ 	/* Fill the receive rings */
+-	mgp->rx_big.cnt = 0;
+-	mgp->rx_small.cnt = 0;
+-	mgp->rx_big.fill_cnt = 0;
+-	mgp->rx_small.fill_cnt = 0;
+-	mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
+-	mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
+-	mgp->rx_small.watchdog_needed = 0;
+-	mgp->rx_big.watchdog_needed = 0;
+-	myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
++	ss->rx_big.cnt = 0;
++	ss->rx_small.cnt = 0;
++	ss->rx_big.fill_cnt = 0;
++	ss->rx_small.fill_cnt = 0;
++	ss->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
++	ss->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
++	ss->rx_small.watchdog_needed = 0;
++	ss->rx_big.watchdog_needed = 0;
++	myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
+ 				mgp->small_bytes + MXGEFW_PAD, 0);
+ 
+-	if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) {
++	if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) {
+ 		printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n",
+-		       dev->name, mgp->rx_small.fill_cnt);
++		       dev->name, ss->rx_small.fill_cnt);
+ 		goto abort_with_rx_small_ring;
+ 	}
+ 
+-	myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
+-	if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) {
++	myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
++	if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) {
+ 		printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n",
+-		       dev->name, mgp->rx_big.fill_cnt);
++		       dev->name, ss->rx_big.fill_cnt);
+ 		goto abort_with_rx_big_ring;
+ 	}
+ 
+ 	return 0;
+ 
+ abort_with_rx_big_ring:
+-	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
+-		int idx = i & mgp->rx_big.mask;
+-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
++	for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) {
++		int idx = i & ss->rx_big.mask;
++		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx],
+ 				       mgp->big_bytes);
+-		put_page(mgp->rx_big.info[idx].page);
++		put_page(ss->rx_big.info[idx].page);
+ 	}
+ 
+ abort_with_rx_small_ring:
+-	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
+-		int idx = i & mgp->rx_small.mask;
+-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
++	for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) {
++		int idx = i & ss->rx_small.mask;
++		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx],
+ 				       mgp->small_bytes + MXGEFW_PAD);
+-		put_page(mgp->rx_small.info[idx].page);
++		put_page(ss->rx_small.info[idx].page);
+ 	}
+ 
+-	kfree(mgp->rx_big.info);
++	kfree(ss->rx_big.info);
+ 
+ abort_with_rx_small_info:
+-	kfree(mgp->rx_small.info);
++	kfree(ss->rx_small.info);
+ 
+ abort_with_tx_info:
+-	kfree(mgp->tx.info);
++	kfree(ss->tx.info);
+ 
+ abort_with_rx_big_shadow:
+-	kfree(mgp->rx_big.shadow);
++	kfree(ss->rx_big.shadow);
+ 
+ abort_with_rx_small_shadow:
+-	kfree(mgp->rx_small.shadow);
++	kfree(ss->rx_small.shadow);
+ 
+ abort_with_tx_req_bytes:
+-	kfree(mgp->tx.req_bytes);
+-	mgp->tx.req_bytes = NULL;
+-	mgp->tx.req_list = NULL;
++	kfree(ss->tx.req_bytes);
++	ss->tx.req_bytes = NULL;
++	ss->tx.req_list = NULL;
+ 
+ abort_with_nothing:
+ 	return status;
+ }
+ 
+-static void myri10ge_free_rings(struct net_device *dev)
++static void myri10ge_free_rings(struct myri10ge_slice_state *ss)
+ {
+-	struct myri10ge_priv *mgp;
++	struct myri10ge_priv *mgp = ss->mgp;
+ 	struct sk_buff *skb;
+ 	struct myri10ge_tx_buf *tx;
+ 	int i, len, idx;
+ 
+-	mgp = netdev_priv(dev);
+-
+-	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
+-		idx = i & mgp->rx_big.mask;
+-		if (i == mgp->rx_big.fill_cnt - 1)
+-			mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
+-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
++	for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) {
++		idx = i & ss->rx_big.mask;
++		if (i == ss->rx_big.fill_cnt - 1)
++			ss->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
++		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx],
+ 				       mgp->big_bytes);
+-		put_page(mgp->rx_big.info[idx].page);
++		put_page(ss->rx_big.info[idx].page);
+ 	}
+ 
+-	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
+-		idx = i & mgp->rx_small.mask;
+-		if (i == mgp->rx_small.fill_cnt - 1)
+-			mgp->rx_small.info[idx].page_offset =
++	for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) {
++		idx = i & ss->rx_small.mask;
++		if (i == ss->rx_small.fill_cnt - 1)
++			ss->rx_small.info[idx].page_offset =
+ 			    MYRI10GE_ALLOC_SIZE;
+-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
++		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx],
+ 				       mgp->small_bytes + MXGEFW_PAD);
+-		put_page(mgp->rx_small.info[idx].page);
++		put_page(ss->rx_small.info[idx].page);
+ 	}
+-	tx = &mgp->tx;
++	tx = &ss->tx;
+ 	while (tx->done != tx->req) {
+ 		idx = tx->done & tx->mask;
+ 		skb = tx->info[idx].skb;
+@@ -1714,7 +1804,7 @@ static void myri10ge_free_rings(struct net_device *dev)
+ 		len = pci_unmap_len(&tx->info[idx], len);
+ 		pci_unmap_len_set(&tx->info[idx], len, 0);
+ 		if (skb) {
+-			mgp->stats.tx_dropped++;
++			ss->stats.tx_dropped++;
+ 			dev_kfree_skb_any(skb);
+ 			if (len)
+ 				pci_unmap_single(mgp->pdev,
+@@ -1729,19 +1819,19 @@ static void myri10ge_free_rings(struct net_device *dev)
+ 					       PCI_DMA_TODEVICE);
+ 		}
+ 	}
+-	kfree(mgp->rx_big.info);
++	kfree(ss->rx_big.info);
+ 
+-	kfree(mgp->rx_small.info);
++	kfree(ss->rx_small.info);
+ 
+-	kfree(mgp->tx.info);
++	kfree(ss->tx.info);
+ 
+-	kfree(mgp->rx_big.shadow);
++	kfree(ss->rx_big.shadow);
+ 
+-	kfree(mgp->rx_small.shadow);
++	kfree(ss->rx_small.shadow);
+ 
+-	kfree(mgp->tx.req_bytes);
+-	mgp->tx.req_bytes = NULL;
+-	mgp->tx.req_list = NULL;
++	kfree(ss->tx.req_bytes);
++	ss->tx.req_bytes = NULL;
++	ss->tx.req_list = NULL;
+ }
+ 
+ static int myri10ge_request_irq(struct myri10ge_priv *mgp)
+@@ -1840,13 +1930,11 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
+ 
+ static int myri10ge_open(struct net_device *dev)
+ {
+-	struct myri10ge_priv *mgp;
++	struct myri10ge_priv *mgp = netdev_priv(dev);
+ 	struct myri10ge_cmd cmd;
+ 	struct net_lro_mgr *lro_mgr;
+ 	int status, big_pow2;
+ 
+-	mgp = netdev_priv(dev);
+-
+ 	if (mgp->running != MYRI10GE_ETH_STOPPED)
+ 		return -EBUSY;
+ 
+@@ -1883,16 +1971,16 @@ static int myri10ge_open(struct net_device *dev)
+ 	/* get the lanai pointers to the send and receive rings */
+ 
+ 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
+-	mgp->tx.lanai =
++	mgp->ss.tx.lanai =
+ 	    (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0);
+ 
+ 	status |=
+ 	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0);
+-	mgp->rx_small.lanai =
++	mgp->ss.rx_small.lanai =
+ 	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
+ 
+ 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
+-	mgp->rx_big.lanai =
++	mgp->ss.rx_big.lanai =
+ 	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
+ 
+ 	if (status != 0) {
+@@ -1904,15 +1992,15 @@ static int myri10ge_open(struct net_device *dev)
+ 	}
+ 
+ 	if (myri10ge_wcfifo && mgp->wc_enabled) {
+-		mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
+-		mgp->rx_small.wc_fifo =
++		mgp->ss.tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
++		mgp->ss.rx_small.wc_fifo =
+ 		    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
+-		mgp->rx_big.wc_fifo =
++		mgp->ss.rx_big.wc_fifo =
+ 		    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG;
+ 	} else {
+-		mgp->tx.wc_fifo = NULL;
+-		mgp->rx_small.wc_fifo = NULL;
+-		mgp->rx_big.wc_fifo = NULL;
++		mgp->ss.tx.wc_fifo = NULL;
++		mgp->ss.rx_small.wc_fifo = NULL;
++		mgp->ss.rx_big.wc_fifo = NULL;
+ 	}
+ 
+ 	/* Firmware needs the big buff size as a power of 2.  Lie and
+@@ -1929,7 +2017,7 @@ static int myri10ge_open(struct net_device *dev)
+ 		mgp->big_bytes = big_pow2;
+ 	}
+ 
+-	status = myri10ge_allocate_rings(dev);
++	status = myri10ge_allocate_rings(&mgp->ss);
+ 	if (status != 0)
+ 		goto abort_with_irq;
+ 
+@@ -1948,12 +2036,12 @@ static int myri10ge_open(struct net_device *dev)
+ 		goto abort_with_rings;
+ 	}
+ 
+-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus);
+-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus);
++	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.fw_stats_bus);
++	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.fw_stats_bus);
+ 	cmd.data2 = sizeof(struct mcp_irq_data);
+ 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
+ 	if (status == -ENOSYS) {
+-		dma_addr_t bus = mgp->fw_stats_bus;
++		dma_addr_t bus = mgp->ss.fw_stats_bus;
+ 		bus += offsetof(struct mcp_irq_data, send_done_count);
+ 		cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus);
+ 		cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus);
+@@ -1974,20 +2062,20 @@ static int myri10ge_open(struct net_device *dev)
+ 	mgp->link_state = ~0U;
+ 	mgp->rdma_tags_available = 15;
+ 
+-	lro_mgr = &mgp->rx_done.lro_mgr;
++	lro_mgr = &mgp->ss.rx_done.lro_mgr;
+ 	lro_mgr->dev = dev;
+ 	lro_mgr->features = LRO_F_NAPI;
+ 	lro_mgr->ip_summed = CHECKSUM_COMPLETE;
+ 	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ 	lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
+-	lro_mgr->lro_arr = mgp->rx_done.lro_desc;
++	lro_mgr->lro_arr = mgp->ss.rx_done.lro_desc;
+ 	lro_mgr->get_frag_header = myri10ge_get_frag_header;
+ 	lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+ 	lro_mgr->frag_align_pad = 2;
+ 	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+ 		lro_mgr->max_aggr = MAX_SKB_FRAGS;
+ 
+-	napi_enable(&mgp->napi);	/* must happen prior to any irq */
++	napi_enable(&mgp->ss.napi);	/* must happen prior to any irq */
+ 
+ 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
+ 	if (status) {
+@@ -1996,8 +2084,8 @@ static int myri10ge_open(struct net_device *dev)
+ 		goto abort_with_rings;
+ 	}
+ 
+-	mgp->wake_queue = 0;
+-	mgp->stop_queue = 0;
++	mgp->ss.tx.wake_queue = 0;
++	mgp->ss.tx.stop_queue = 0;
+ 	mgp->running = MYRI10GE_ETH_RUNNING;
+ 	mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ;
+ 	add_timer(&mgp->watchdog_timer);
+@@ -2005,7 +2093,7 @@ static int myri10ge_open(struct net_device *dev)
+ 	return 0;
+ 
+ abort_with_rings:
+-	myri10ge_free_rings(dev);
++	myri10ge_free_rings(&mgp->ss);
+ 
+ abort_with_irq:
+ 	myri10ge_free_irq(mgp);
+@@ -2017,21 +2105,19 @@ abort_with_nothing:
+ 
+ static int myri10ge_close(struct net_device *dev)
+ {
+-	struct myri10ge_priv *mgp;
++	struct myri10ge_priv *mgp = netdev_priv(dev);
+ 	struct myri10ge_cmd cmd;
+ 	int status, old_down_cnt;
+ 
+-	mgp = netdev_priv(dev);
+-
+ 	if (mgp->running != MYRI10GE_ETH_RUNNING)
+ 		return 0;
+ 
+-	if (mgp->tx.req_bytes == NULL)
++	if (mgp->ss.tx.req_bytes == NULL)
+ 		return 0;
+ 
+ 	del_timer_sync(&mgp->watchdog_timer);
+ 	mgp->running = MYRI10GE_ETH_STOPPING;
+-	napi_disable(&mgp->napi);
++	napi_disable(&mgp->ss.napi);
+ 	netif_carrier_off(dev);
+ 	netif_stop_queue(dev);
+ 	old_down_cnt = mgp->down_cnt;
+@@ -2047,7 +2133,7 @@ static int myri10ge_close(struct net_device *dev)
+ 
+ 	netif_tx_disable(dev);
+ 	myri10ge_free_irq(mgp);
+-	myri10ge_free_rings(dev);
++	myri10ge_free_rings(&mgp->ss);
+ 
+ 	mgp->running = MYRI10GE_ETH_STOPPED;
+ 	return 0;
+@@ -2143,7 +2229,7 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx,
+ 
+ /*
+  * Transmit a packet.  We need to split the packet so that a single
+- * segment does not cross myri10ge->tx.boundary, so this makes segment
++ * segment does not cross myri10ge->tx_boundary, so this makes segment
+  * counting tricky.  So rather than try to count segments up front, we
+  * just give up if there are too few segments to hold a reasonably
+  * fragmented packet currently available.  If we run
+@@ -2154,8 +2240,9 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx,
+ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct myri10ge_priv *mgp = netdev_priv(dev);
++	struct myri10ge_slice_state *ss;
+ 	struct mcp_kreq_ether_send *req;
+-	struct myri10ge_tx_buf *tx = &mgp->tx;
++	struct myri10ge_tx_buf *tx;
+ 	struct skb_frag_struct *frag;
+ 	dma_addr_t bus;
+ 	u32 low;
+@@ -2166,6 +2253,9 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	int cum_len, seglen, boundary, rdma_count;
+ 	u8 flags, odd_flag;
+ 
++	/* always transmit through slot 0 */
++	ss = &mgp->ss;
++	tx = &ss->tx;
+ again:
+ 	req = tx->req_list;
+ 	avail = tx->mask - 1 - (tx->req - tx->done);
+@@ -2180,7 +2270,7 @@ again:
+ 
+ 	if ((unlikely(avail < max_segments))) {
+ 		/* we are out of transmit resources */
+-		mgp->stop_queue++;
++		tx->stop_queue++;
+ 		netif_stop_queue(dev);
+ 		return 1;
+ 	}
+@@ -2242,7 +2332,7 @@ again:
+ 			if (skb_padto(skb, ETH_ZLEN)) {
+ 				/* The packet is gone, so we must
+ 				 * return 0 */
+-				mgp->stats.tx_dropped += 1;
++				ss->stats.tx_dropped += 1;
+ 				return 0;
+ 			}
+ 			/* adjust the len to account for the zero pad
+@@ -2284,7 +2374,7 @@ again:
+ 
+ 	while (1) {
+ 		/* Break the SKB or Fragment up into pieces which
+-		 * do not cross mgp->tx.boundary */
++		 * do not cross mgp->tx_boundary */
+ 		low = MYRI10GE_LOWPART_TO_U32(bus);
+ 		high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
+ 		while (len) {
+@@ -2294,7 +2384,8 @@ again:
+ 			if (unlikely(count == max_segments))
+ 				goto abort_linearize;
+ 
+-			boundary = (low + tx->boundary) & ~(tx->boundary - 1);
++			boundary =
++			    (low + mgp->tx_boundary) & ~(mgp->tx_boundary - 1);
+ 			seglen = boundary - low;
+ 			if (seglen > len)
+ 				seglen = len;
+@@ -2378,7 +2469,7 @@ again:
+ 		myri10ge_submit_req_wc(tx, tx->req_list, count);
+ 	tx->pkt_start++;
+ 	if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
+-		mgp->stop_queue++;
++		tx->stop_queue++;
+ 		netif_stop_queue(dev);
+ 	}
+ 	dev->trans_start = jiffies;
+@@ -2420,12 +2511,12 @@ abort_linearize:
+ 	if (skb_linearize(skb))
+ 		goto drop;
+ 
+-	mgp->tx_linearized++;
++	tx->linearized++;
+ 	goto again;
+ 
+ drop:
+ 	dev_kfree_skb_any(skb);
+-	mgp->stats.tx_dropped += 1;
++	ss->stats.tx_dropped += 1;
+ 	return 0;
+ 
+ }
+@@ -2433,7 +2524,7 @@ drop:
+ static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct sk_buff *segs, *curr;
+-	struct myri10ge_priv *mgp = dev->priv;
++	struct myri10ge_priv *mgp = netdev_priv(dev);
+ 	int status;
+ 
+ 	segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
+@@ -2473,14 +2564,13 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
+ 
+ static void myri10ge_set_multicast_list(struct net_device *dev)
+ {
++	struct myri10ge_priv *mgp = netdev_priv(dev);
+ 	struct myri10ge_cmd cmd;
+-	struct myri10ge_priv *mgp;
+ 	struct dev_mc_list *mc_list;
+ 	__be32 data[2] = { 0, 0 };
+ 	int err;
+ 	DECLARE_MAC_BUF(mac);
+ 
+-	mgp = netdev_priv(dev);
+ 	/* can be called from atomic contexts,
+ 	 * pass 1 to force atomicity in myri10ge_send_cmd() */
+ 	myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1);
+@@ -2616,13 +2706,14 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
+ 	ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
+ 	if (ext_type != PCI_EXP_TYPE_ROOT_PORT) {
+ 		if (myri10ge_ecrc_enable > 1) {
+-			struct pci_dev *old_bridge = bridge;
++			struct pci_dev *prev_bridge, *old_bridge = bridge;
+ 
+ 			/* Walk the hierarchy up to the root port
+ 			 * where ECRC has to be enabled */
+ 			do {
++				prev_bridge = bridge;
+ 				bridge = bridge->bus->self;
+-				if (!bridge) {
++				if (!bridge || prev_bridge == bridge) {
+ 					dev_err(dev,
+ 						"Failed to find root port"
+ 						" to force ECRC\n");
+@@ -2681,9 +2772,9 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
+  * already been enabled, then it must use a firmware image which works
+  * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it
+  * should also ensure that it never gives the device a Read-DMA which is
+- * larger than 2KB by setting the tx.boundary to 2KB.  If ECRC is
++ * larger than 2KB by setting the tx_boundary to 2KB.  If ECRC is
+  * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat)
+- * firmware image, and set tx.boundary to 4KB.
++ * firmware image, and set tx_boundary to 4KB.
+  */
+ 
+ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
+@@ -2692,7 +2783,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
+ 	struct device *dev = &pdev->dev;
+ 	int status;
+ 
+-	mgp->tx.boundary = 4096;
++	mgp->tx_boundary = 4096;
+ 	/*
+ 	 * Verify the max read request size was set to 4KB
+ 	 * before trying the test with 4KB.
+@@ -2704,7 +2795,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
+ 	}
+ 	if (status != 4096) {
+ 		dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status);
+-		mgp->tx.boundary = 2048;
++		mgp->tx_boundary = 2048;
+ 	}
+ 	/*
+ 	 * load the optimized firmware (which assumes aligned PCIe
+@@ -2737,7 +2828,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
+ 			 "Please install up to date fw\n");
+ abort:
+ 	/* fall back to using the unaligned firmware */
+-	mgp->tx.boundary = 2048;
++	mgp->tx_boundary = 2048;
+ 	mgp->fw_name = myri10ge_fw_unaligned;
+ 
+ }
+@@ -2758,7 +2849,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+ 		if (link_width < 8) {
+ 			dev_info(&mgp->pdev->dev, "PCIE x%d Link\n",
+ 				 link_width);
+-			mgp->tx.boundary = 4096;
++			mgp->tx_boundary = 4096;
+ 			mgp->fw_name = myri10ge_fw_aligned;
+ 		} else {
+ 			myri10ge_firmware_probe(mgp);
+@@ -2767,12 +2858,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+ 		if (myri10ge_force_firmware == 1) {
+ 			dev_info(&mgp->pdev->dev,
+ 				 "Assuming aligned completions (forced)\n");
+-			mgp->tx.boundary = 4096;
++			mgp->tx_boundary = 4096;
+ 			mgp->fw_name = myri10ge_fw_aligned;
+ 		} else {
+ 			dev_info(&mgp->pdev->dev,
+ 				 "Assuming unaligned completions (forced)\n");
+-			mgp->tx.boundary = 2048;
++			mgp->tx_boundary = 2048;
+ 			mgp->fw_name = myri10ge_fw_unaligned;
+ 		}
+ 	}
+@@ -2889,6 +2980,7 @@ static void myri10ge_watchdog(struct work_struct *work)
+ {
+ 	struct myri10ge_priv *mgp =
+ 	    container_of(work, struct myri10ge_priv, watchdog_work);
++	struct myri10ge_tx_buf *tx;
+ 	u32 reboot;
+ 	int status;
+ 	u16 cmd, vendor;
+@@ -2938,15 +3030,16 @@ static void myri10ge_watchdog(struct work_struct *work)
+ 
+ 		printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n",
+ 		       mgp->dev->name);
++		tx = &mgp->ss.tx;
+ 		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
+-		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
+-		       mgp->tx.pkt_start, mgp->tx.pkt_done,
+-		       (int)ntohl(mgp->fw_stats->send_done_count));
++		       mgp->dev->name, tx->req, tx->done,
++		       tx->pkt_start, tx->pkt_done,
++		       (int)ntohl(mgp->ss.fw_stats->send_done_count));
+ 		msleep(2000);
+ 		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
+-		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
+-		       mgp->tx.pkt_start, mgp->tx.pkt_done,
+-		       (int)ntohl(mgp->fw_stats->send_done_count));
++		       mgp->dev->name, tx->req, tx->done,
++		       tx->pkt_start, tx->pkt_done,
++		       (int)ntohl(mgp->ss.fw_stats->send_done_count));
+ 	}
+ 	rtnl_lock();
+ 	myri10ge_close(mgp->dev);
+@@ -2969,28 +3062,31 @@ static void myri10ge_watchdog(struct work_struct *work)
+ static void myri10ge_watchdog_timer(unsigned long arg)
+ {
+ 	struct myri10ge_priv *mgp;
++	struct myri10ge_slice_state *ss;
+ 	u32 rx_pause_cnt;
+ 
+ 	mgp = (struct myri10ge_priv *)arg;
+ 
+-	if (mgp->rx_small.watchdog_needed) {
+-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
++	rx_pause_cnt = ntohl(mgp->ss.fw_stats->dropped_pause);
++
++	ss = &mgp->ss;
++	if (ss->rx_small.watchdog_needed) {
++		myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
+ 					mgp->small_bytes + MXGEFW_PAD, 1);
+-		if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >=
++		if (ss->rx_small.fill_cnt - ss->rx_small.cnt >=
+ 		    myri10ge_fill_thresh)
+-			mgp->rx_small.watchdog_needed = 0;
++			ss->rx_small.watchdog_needed = 0;
+ 	}
+-	if (mgp->rx_big.watchdog_needed) {
+-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1);
+-		if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >=
++	if (ss->rx_big.watchdog_needed) {
++		myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 1);
++		if (ss->rx_big.fill_cnt - ss->rx_big.cnt >=
+ 		    myri10ge_fill_thresh)
+-			mgp->rx_big.watchdog_needed = 0;
++			ss->rx_big.watchdog_needed = 0;
+ 	}
+-	rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause);
+ 
+-	if (mgp->tx.req != mgp->tx.done &&
+-	    mgp->tx.done == mgp->watchdog_tx_done &&
+-	    mgp->watchdog_tx_req != mgp->watchdog_tx_done) {
++	if (ss->tx.req != ss->tx.done &&
++	    ss->tx.done == ss->watchdog_tx_done &&
++	    ss->watchdog_tx_req != ss->watchdog_tx_done) {
+ 		/* nic seems like it might be stuck.. */
+ 		if (rx_pause_cnt != mgp->watchdog_pause) {
+ 			if (net_ratelimit())
+@@ -3005,8 +3101,8 @@ static void myri10ge_watchdog_timer(unsigned long arg)
+ 	/* rearm timer */
+ 	mod_timer(&mgp->watchdog_timer,
+ 		  jiffies + myri10ge_watchdog_timeout * HZ);
+-	mgp->watchdog_tx_done = mgp->tx.done;
+-	mgp->watchdog_tx_req = mgp->tx.req;
++	ss->watchdog_tx_done = ss->tx.done;
++	ss->watchdog_tx_req = ss->tx.req;
+ 	mgp->watchdog_pause = rx_pause_cnt;
+ }
+ 
+@@ -3030,7 +3126,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	mgp = netdev_priv(netdev);
+ 	mgp->dev = netdev;
+-	netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight);
++	netif_napi_add(netdev, &mgp->ss.napi, myri10ge_poll, myri10ge_napi_weight);
+ 	mgp->pdev = pdev;
+ 	mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
+ 	mgp->pause = myri10ge_flow_control;
+@@ -3076,9 +3172,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	if (mgp->cmd == NULL)
+ 		goto abort_with_netdev;
+ 
+-	mgp->fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+-					   &mgp->fw_stats_bus, GFP_KERNEL);
+-	if (mgp->fw_stats == NULL)
++	mgp->ss.fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
++					   &mgp->ss.fw_stats_bus, GFP_KERNEL);
++	if (mgp->ss.fw_stats == NULL)
+ 		goto abort_with_cmd;
+ 
+ 	mgp->board_span = pci_resource_len(pdev, 0);
+@@ -3118,12 +3214,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 		netdev->dev_addr[i] = mgp->mac_addr[i];
+ 
+ 	/* allocate rx done ring */
+-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+-	mgp->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
+-						&mgp->rx_done.bus, GFP_KERNEL);
+-	if (mgp->rx_done.entry == NULL)
++	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
++	mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
++						&mgp->ss.rx_done.bus, GFP_KERNEL);
++	if (mgp->ss.rx_done.entry == NULL)
+ 		goto abort_with_ioremap;
+-	memset(mgp->rx_done.entry, 0, bytes);
++	memset(mgp->ss.rx_done.entry, 0, bytes);
+ 
+ 	myri10ge_select_firmware(mgp);
+ 
+@@ -3183,7 +3279,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	}
+ 	dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
+ 		 (mgp->msi_enabled ? "MSI" : "xPIC"),
+-		 netdev->irq, mgp->tx.boundary, mgp->fw_name,
++		 netdev->irq, mgp->tx_boundary, mgp->fw_name,
+ 		 (mgp->wc_enabled ? "Enabled" : "Disabled"));
+ 
+ 	return 0;
+@@ -3195,9 +3291,9 @@ abort_with_firmware:
+ 	myri10ge_dummy_rdma(mgp, 0);
+ 
+ abort_with_rx_done:
+-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
++	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+ 	dma_free_coherent(&pdev->dev, bytes,
+-			  mgp->rx_done.entry, mgp->rx_done.bus);
++			  mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
+ 
+ abort_with_ioremap:
+ 	iounmap(mgp->sram);
+@@ -3207,8 +3303,8 @@ abort_with_wc:
+ 	if (mgp->mtrr >= 0)
+ 		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
+ #endif
+-	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+-			  mgp->fw_stats, mgp->fw_stats_bus);
++	dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
++			  mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
+ 
+ abort_with_cmd:
+ 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
+@@ -3246,9 +3342,9 @@ static void myri10ge_remove(struct pci_dev *pdev)
+ 	/* avoid a memory leak */
+ 	pci_restore_state(pdev);
+ 
+-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
++	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+ 	dma_free_coherent(&pdev->dev, bytes,
+-			  mgp->rx_done.entry, mgp->rx_done.bus);
++			  mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
+ 
+ 	iounmap(mgp->sram);
+ 
+@@ -3256,8 +3352,8 @@ static void myri10ge_remove(struct pci_dev *pdev)
+ 	if (mgp->mtrr >= 0)
+ 		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
+ #endif
+-	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
+-			  mgp->fw_stats, mgp->fw_stats_bus);
++	dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
++			  mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
+ 
+ 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
+ 			  mgp->cmd, mgp->cmd_bus);
+diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
+index 58e5717..fdbeeee 100644
+--- a/drivers/net/myri10ge/myri10ge_mcp.h
++++ b/drivers/net/myri10ge/myri10ge_mcp.h
+@@ -10,7 +10,7 @@ struct mcp_dma_addr {
+ 	__be32 low;
+ };
+ 
+-/* 4 Bytes.  8 Bytes for NDIS drivers. */
++/* 4 Bytes */
+ struct mcp_slot {
+ 	__sum16 checksum;
+ 	__be16 length;
+@@ -144,6 +144,7 @@ enum myri10ge_mcp_cmd_type {
+ 	 * a power of 2 number of entries.  */
+ 
+ 	MXGEFW_CMD_SET_INTRQ_SIZE,	/* in bytes */
++#define MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK  (1 << 31)
+ 
+ 	/* command to bring ethernet interface up.  Above parameters
+ 	 * (plus mtu & mac address) must have been exchanged prior
+@@ -221,10 +222,14 @@ enum myri10ge_mcp_cmd_type {
+ 	MXGEFW_CMD_GET_MAX_RSS_QUEUES,
+ 	MXGEFW_CMD_ENABLE_RSS_QUEUES,
+ 	/* data0 = number of slices n (0, 1, ..., n-1) to enable
+-	 * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
++	 * data1 = interrupt mode.
++	 * 0=share one INTx/MSI, 1=use one MSI-X per queue.
+ 	 * If all queues share one interrupt, the driver must have set
+ 	 * RSS_SHARED_INTERRUPT_DMA before enabling queues.
+ 	 */
++#define MXGEFW_SLICE_INTR_MODE_SHARED 0
++#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1
++
+ 	MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
+ 	MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
+ 	/* data0, data1 = bus address lsw, msw */
+@@ -241,10 +246,14 @@ enum myri10ge_mcp_cmd_type {
+ 	 * 0: disable rss.  nic does not distribute receive packets.
+ 	 * 1: enable rss.  nic distributes receive packets among queues.
+ 	 * data1 = hash type
+-	 * 1: IPV4
+-	 * 2: TCP_IPV4
+-	 * 3: IPV4 | TCP_IPV4
++	 * 1: IPV4            (required by RSS)
++	 * 2: TCP_IPV4        (required by RSS)
++	 * 3: IPV4 | TCP_IPV4 (required by RSS)
++	 * 4: source port
+ 	 */
++#define MXGEFW_RSS_HASH_TYPE_IPV4      0x1
++#define MXGEFW_RSS_HASH_TYPE_TCP_IPV4  0x2
++#define MXGEFW_RSS_HASH_TYPE_SRC_PORT  0x4
+ 
+ 	MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+ 	/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
+@@ -260,6 +269,8 @@ enum myri10ge_mcp_cmd_type {
+ 	 * 0: Linux/FreeBSD style (NIC default)
+ 	 * 1: NDIS/NetBSD style
+ 	 */
++#define MXGEFW_TSO_MODE_LINUX  0
++#define MXGEFW_TSO_MODE_NDIS   1
+ 
+ 	MXGEFW_CMD_MDIO_READ,
+ 	/* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
+@@ -286,6 +297,38 @@ enum myri10ge_mcp_cmd_type {
+ 	/* Return data = NIC memory offset of mcp_vpump_public_global */
+ 	MXGEFW_CMD_RESET_VPUMP,
+ 	/* Resets the VPUMP state */
++
++	MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE,
++	/* data0 = mcp_slot type to use.
++	 * 0 = the default 4B mcp_slot
++	 * 1 = 8B mcp_slot_8
++	 */
++#define MXGEFW_RSS_MCP_SLOT_TYPE_MIN        0
++#define MXGEFW_RSS_MCP_SLOT_TYPE_WITH_HASH  1
++
++	MXGEFW_CMD_SET_THROTTLE_FACTOR,
++	/* set the throttle factor for ethp_z8e
++	 * data0 = throttle_factor
++	 * throttle_factor = 256 * pcie-raw-speed / tx_speed
++	 * tx_speed = 256 * pcie-raw-speed / throttle_factor
++	 *
++	 * For PCI-E x8: pcie-raw-speed == 16Gb/s
++	 * For PCI-E x4: pcie-raw-speed == 8Gb/s
++	 *
++	 * ex1: throttle_factor == 0x1a0 (416), tx_speed == 1.23GB/s == 9.846 Gb/s
++	 * ex2: throttle_factor == 0x200 (512), tx_speed == 1.0GB/s == 8 Gb/s
++	 *
++	 * with tx_boundary == 2048, max-throttle-factor == 8191 => min-speed == 500Mb/s
++	 * with tx_boundary == 4096, max-throttle-factor == 4095 => min-speed == 1Gb/s
++	 */
++
++	MXGEFW_CMD_VPUMP_UP,
++	/* Allocates VPump Connection, Send Request and Zero copy buffer address tables */
++	MXGEFW_CMD_GET_VPUMP_CLK,
++	/* Get the lanai clock */
++
++	MXGEFW_CMD_GET_DCA_OFFSET,
++	/* offset of dca control for WDMAs */
+ };
+ 
+ enum myri10ge_mcp_cmd_status {
+@@ -302,7 +345,8 @@ enum myri10ge_mcp_cmd_status {
+ 	MXGEFW_CMD_ERROR_UNALIGNED,
+ 	MXGEFW_CMD_ERROR_NO_MDIO,
+ 	MXGEFW_CMD_ERROR_XFP_FAILURE,
+-	MXGEFW_CMD_ERROR_XFP_ABSENT
++	MXGEFW_CMD_ERROR_XFP_ABSENT,
++	MXGEFW_CMD_ERROR_BAD_PCIE_LINK
+ };
+ 
+ #define MXGEFW_OLD_IRQ_DATA_LEN 40
+diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+index 16a810d..07d65c2 100644
+--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
++++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+@@ -1,30 +1,6 @@
+ #ifndef __MYRI10GE_MCP_GEN_HEADER_H__
+ #define __MYRI10GE_MCP_GEN_HEADER_H__
+ 
+-/* this file define a standard header used as a first entry point to
+- * exchange information between firmware/driver and driver.  The
+- * header structure can be anywhere in the mcp. It will usually be in
+- * the .data section, because some fields needs to be initialized at
+- * compile time.
+- * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must
+- * contains the location of the header.
+- *
+- * Typically a MCP will start with the following:
+- * .text
+- * .space 52    ! to help catch MEMORY_INT errors
+- * bt start     ! jump to real code
+- * nop
+- * .long _gen_mcp_header
+- *
+- * The source will have a definition like:
+- *
+- * mcp_gen_header_t gen_mcp_header = {
+- * .header_length = sizeof(mcp_gen_header_t),
+- * .mcp_type = MCP_TYPE_XXX,
+- * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $",
+- * .mcp_globals = (unsigned)&Globals
+- * };
+- */
+ 
+ #define MCP_HEADER_PTR_OFFSET  0x3c
+ 
+@@ -32,13 +8,14 @@
+ #define MCP_TYPE_PCIE 0x70636965	/* "PCIE" pcie-only MCP */
+ #define MCP_TYPE_ETH 0x45544820	/* "ETH " */
+ #define MCP_TYPE_MCP0 0x4d435030	/* "MCP0" */
++#define MCP_TYPE_DFLT 0x20202020	/* "    " */
+ 
+ struct mcp_gen_header {
+ 	/* the first 4 fields are filled at compile time */
+ 	unsigned header_length;
+ 	__be32 mcp_type;
+ 	char version[128];
+-	unsigned mcp_globals;	/* pointer to mcp-type specific structure */
++	unsigned mcp_private;	/* pointer to mcp-type specific structure */
+ 
+ 	/* filled by the MCP at run-time */
+ 	unsigned sram_size;
+@@ -53,6 +30,18 @@ struct mcp_gen_header {
+ 	 *
+ 	 * Never remove any field.  Keep everything naturally align.
+ 	 */
++
++	/* Specifies if the running mcp is mcp0, 1, or 2. */
++	unsigned char mcp_index;
++	unsigned char disable_rabbit;
++	unsigned char unaligned_tlp;
++	unsigned char pad1;
++	unsigned counters_addr;
++	unsigned copy_block_info;	/* for small mcps loaded with "lload -d" */
++	unsigned short handoff_id_major;	/* must be equal */
++	unsigned short handoff_id_caps;	/* bitfield: new mcp must have superset */
++	unsigned msix_table_addr;	/* start address of msix table in firmware */
++	/* 8 */
+ };
+ 
+ #endif				/* __MYRI10GE_MCP_GEN_HEADER_H__ */
+diff --git a/drivers/net/niu.c b/drivers/net/niu.c
+index 57cfd72..918f802 100644
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -865,7 +865,6 @@ static int link_status_1g_serdes(struct niu *np, int *link_up_p)
+ 	return 0;
+ }
+ 
+-
+ static int link_status_10g_serdes(struct niu *np, int *link_up_p)
+ {
+ 	unsigned long flags;
+@@ -900,7 +899,6 @@ static int link_status_10g_serdes(struct niu *np, int *link_up_p)
+ 	return 0;
+ }
+ 
+-
+ static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
+ {
+ 	struct niu_link_config *lp = &np->link_config;
+@@ -957,7 +955,6 @@ out:
+ 	return err;
+ }
+ 
+-
+ static int bcm8704_reset(struct niu *np)
+ {
+ 	int err, limit;
+@@ -1357,8 +1354,6 @@ static int mii_reset(struct niu *np)
+ 	return 0;
+ }
+ 
+-
+-
+ static int xcvr_init_1g_rgmii(struct niu *np)
+ {
+ 	int err;
+@@ -1419,7 +1414,6 @@ static int xcvr_init_1g_rgmii(struct niu *np)
+ 	return 0;
+ }
+ 
+-
+ static int mii_init_common(struct niu *np)
+ {
+ 	struct niu_link_config *lp = &np->link_config;
+@@ -7008,31 +7002,20 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np,
+ 	return 0;
+ }
+ 
+-/* niu board models have a trailing dash version incremented
+- * with HW rev change. Need to ingnore the  dash version while
+- * checking for match
+- *
+- * for example, for the 10G card the current vpd.board_model
+- * is 501-5283-04, of which -04 is the  dash version and have
+- * to be ignored
+- */
+-static int niu_board_model_match(struct niu *np, const char *model)
+-{
+-	return !strncmp(np->vpd.board_model, model, strlen(model));
+-}
+-
+ static int niu_pci_vpd_get_nports(struct niu *np)
+ {
+ 	int ports = 0;
+ 
+-	if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) ||
+-	    (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) ||
+-	    (niu_board_model_match(np, NIU_ALONSO_BM_STR))) {
++	if ((!strcmp(np->vpd.model, NIU_QGC_LP_MDL_STR)) ||
++	    (!strcmp(np->vpd.model, NIU_QGC_PEM_MDL_STR)) ||
++	    (!strcmp(np->vpd.model, NIU_MARAMBA_MDL_STR)) ||
++	    (!strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) ||
++	    (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR))) {
+ 		ports = 4;
+-	} else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) ||
+-		   (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) ||
+-		   (niu_board_model_match(np, NIU_FOXXY_BM_STR)) ||
+-		   (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) {
++	} else if ((!strcmp(np->vpd.model, NIU_2XGF_LP_MDL_STR)) ||
++		   (!strcmp(np->vpd.model, NIU_2XGF_PEM_MDL_STR)) ||
++		   (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) ||
++		   (!strcmp(np->vpd.model, NIU_2XGF_MRVL_MDL_STR))) {
+ 		ports = 2;
+ 	}
+ 
+@@ -7053,8 +7036,8 @@ static void __devinit niu_pci_vpd_validate(struct niu *np)
+ 		return;
+ 	}
+ 
+-	if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
+-	    !strcmp(np->vpd.model, "SUNW,CP3260")) {
++	if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) ||
++	    !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) {
+ 		np->flags |= NIU_FLAGS_10G;
+ 		np->flags &= ~NIU_FLAGS_FIBER;
+ 		np->flags |= NIU_FLAGS_XCVR_SERDES;
+@@ -7065,7 +7048,7 @@ static void __devinit niu_pci_vpd_validate(struct niu *np)
+ 		}
+ 		if (np->flags & NIU_FLAGS_10G)
+ 			 np->mac_xcvr = MAC_XCVR_XPCS;
+-	} else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) {
++	} else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) {
+ 		np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
+ 			      NIU_FLAGS_HOTPLUG_PHY);
+ 	} else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) {
+@@ -7541,8 +7524,8 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent)
+ 	u32 val;
+ 	int err;
+ 
+-	if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
+-	    !strcmp(np->vpd.model, "SUNW,CP3260")) {
++	if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) ||
++	    !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) {
+ 		num_10g = 0;
+ 		num_1g = 2;
+ 		parent->plat_type = PLAT_TYPE_ATCA_CP3220;
+@@ -7551,7 +7534,7 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent)
+ 		       phy_encode(PORT_TYPE_1G, 1) |
+ 		       phy_encode(PORT_TYPE_1G, 2) |
+ 		       phy_encode(PORT_TYPE_1G, 3));
+-	} else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) {
++	} else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) {
+ 		num_10g = 2;
+ 		num_1g = 0;
+ 		parent->num_ports = 2;
+@@ -7946,6 +7929,7 @@ static int __devinit niu_get_of_props(struct niu *np)
+ 	struct device_node *dp;
+ 	const char *phy_type;
+ 	const u8 *mac_addr;
++	const char *model;
+ 	int prop_len;
+ 
+ 	if (np->parent->plat_type == PLAT_TYPE_NIU)
+@@ -8000,6 +7984,11 @@ static int __devinit niu_get_of_props(struct niu *np)
+ 
+ 	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
+ 
++	model = of_get_property(dp, "model", &prop_len);
++
++	if (model)
++		strcpy(np->vpd.model, model);
++
+ 	return 0;
+ #else
+ 	return -EINVAL;
+diff --git a/drivers/net/niu.h b/drivers/net/niu.h
+index 97ffbe1..12fd570 100644
+--- a/drivers/net/niu.h
++++ b/drivers/net/niu.h
+@@ -2946,6 +2946,15 @@ struct rx_ring_info {
+ #define	NIU_ALONSO_BM_STR	"373-0202"
+ #define	NIU_FOXXY_BM_STR	"501-7961"
+ #define	NIU_2XGF_MRVL_BM_STR	"SK-6E82"
++#define	NIU_QGC_LP_MDL_STR	"SUNW,pcie-qgc"
++#define	NIU_2XGF_LP_MDL_STR	"SUNW,pcie-2xgf"
++#define	NIU_QGC_PEM_MDL_STR	"SUNW,pcie-qgc-pem"
++#define	NIU_2XGF_PEM_MDL_STR	"SUNW,pcie-2xgf-pem"
++#define	NIU_ALONSO_MDL_STR	"SUNW,CP3220"
++#define	NIU_KIMI_MDL_STR	"SUNW,CP3260"
++#define	NIU_MARAMBA_MDL_STR	"SUNW,pcie-neptune"
++#define	NIU_FOXXY_MDL_STR	"SUNW,pcie-rfem"
++#define	NIU_2XGF_MRVL_MDL_STR	"SysKonnect,pcie-2xgf"
+ 
+ #define NIU_VPD_MIN_MAJOR	3
+ #define NIU_VPD_MIN_MINOR	4
+diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
+index d3207c0..1f4ca2b 100644
+--- a/drivers/net/ppp_generic.c
++++ b/drivers/net/ppp_generic.c
+@@ -2458,6 +2458,7 @@ ppp_create_interface(int unit, int *retp)
+ 
+ out3:
+ 	atomic_dec(&ppp_unit_count);
++	unregister_netdev(dev);
+ out2:
+ 	mutex_unlock(&all_ppp_mutex);
+ 	free_netdev(dev);
+diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
+index 244d783..7935991 100644
+--- a/drivers/net/pppol2tp.c
++++ b/drivers/net/pppol2tp.c
+@@ -1621,9 +1621,16 @@ out_no_ppp:
+ end:
+ 	release_sock(sk);
+ 
+-	if (error != 0)
+-		PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
+-		       "%s: connect failed: %d\n", session->name, error);
++	if (error != 0) {
++		if (session)
++			PRINTK(session->debug,
++				PPPOL2TP_MSG_CONTROL, KERN_WARNING,
++				"%s: connect failed: %d\n",
++				session->name, error);
++		else
++			PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
++				"connect failed: %d\n", error);
++	}
+ 
+ 	return error;
+ }
+diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
+index 0d32123..1dae1f2 100644
+--- a/drivers/net/ps3_gelic_wireless.c
++++ b/drivers/net/ps3_gelic_wireless.c
+@@ -2474,6 +2474,8 @@ static void gelic_wl_free(struct gelic_wl_info *wl)
+ 
+ 	pr_debug("%s: <-\n", __func__);
+ 
++	free_page((unsigned long)wl->buf);
++
+ 	pr_debug("%s: destroy queues\n", __func__);
+ 	destroy_workqueue(wl->eurus_cmd_queue);
+ 	destroy_workqueue(wl->event_queue);
+diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
+index 0f02344..1d2daee 100644
+--- a/drivers/net/sfc/Makefile
++++ b/drivers/net/sfc/Makefile
+@@ -1,5 +1,5 @@
+ sfc-y			+= efx.o falcon.o tx.o rx.o falcon_xmac.o \
+-			   i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \
+-			   tenxpress.o boards.o sfe4001.o
++			   i2c-direct.o selftest.o ethtool.o xfp_phy.o \
++			   mdio_10g.o tenxpress.o boards.o sfe4001.o
+ 
+ obj-$(CONFIG_SFC)	+= sfc.o
+diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
+index f56341d..695764d 100644
+--- a/drivers/net/sfc/boards.h
++++ b/drivers/net/sfc/boards.h
+@@ -22,5 +22,7 @@ enum efx_board_type {
+ extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
+ extern int sfe4001_poweron(struct efx_nic *efx);
+ extern void sfe4001_poweroff(struct efx_nic *efx);
++/* Are we putting the PHY into flash config mode */
++extern unsigned int sfe4001_phy_flash_cfg;
+ 
+ #endif
+diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
+index 59edcf7..418f2e5 100644
+--- a/drivers/net/sfc/efx.c
++++ b/drivers/net/sfc/efx.c
+@@ -1873,6 +1873,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
+ 		tx_queue->queue = i;
+ 		tx_queue->buffer = NULL;
+ 		tx_queue->channel = &efx->channel[0]; /* for safety */
++		tx_queue->tso_headers_free = NULL;
+ 	}
+ 	for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
+ 		rx_queue = &efx->rx_queue[i];
+@@ -2071,7 +2072,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
+ 	net_dev = alloc_etherdev(sizeof(*efx));
+ 	if (!net_dev)
+ 		return -ENOMEM;
+-	net_dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA;
++	net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
++			      NETIF_F_HIGHDMA | NETIF_F_TSO);
+ 	if (lro)
+ 		net_dev->features |= NETIF_F_LRO;
+ 	efx = net_dev->priv;
+diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
+index 43663a4..c53290d 100644
+--- a/drivers/net/sfc/enum.h
++++ b/drivers/net/sfc/enum.h
+@@ -10,6 +10,55 @@
+ #ifndef EFX_ENUM_H
+ #define EFX_ENUM_H
+ 
++/**
++ * enum efx_loopback_mode - loopback modes
++ * @LOOPBACK_NONE: no loopback
++ * @LOOPBACK_XGMII: loopback within MAC at XGMII level
++ * @LOOPBACK_XGXS: loopback within MAC at XGXS level
++ * @LOOPBACK_XAUI: loopback within MAC at XAUI level
++ * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level
++ * @LOOPBACK_PCS: loopback within PHY at PCS level
++ * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level
++ * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!)
++ */
++/* Please keep in order and up-to-date w.r.t the following two #defines */
++enum efx_loopback_mode {
++	LOOPBACK_NONE = 0,
++	LOOPBACK_MAC = 1,
++	LOOPBACK_XGMII = 2,
++	LOOPBACK_XGXS = 3,
++	LOOPBACK_XAUI = 4,
++	LOOPBACK_PHY = 5,
++	LOOPBACK_PHYXS = 6,
++	LOOPBACK_PCS = 7,
++	LOOPBACK_PMAPMD = 8,
++	LOOPBACK_NETWORK = 9,
++	LOOPBACK_MAX
++};
++
++#define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD
++
++extern const char *efx_loopback_mode_names[];
++#define LOOPBACK_MODE_NAME(mode)			\
++	STRING_TABLE_LOOKUP(mode, efx_loopback_mode)
++#define LOOPBACK_MODE(efx)				\
++	LOOPBACK_MODE_NAME(efx->loopback_mode)
++
++/* These loopbacks occur within the controller */
++#define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \
++				(1 << LOOPBACK_XGXS) | \
++				(1 << LOOPBACK_XAUI))
++
++#define LOOPBACK_MASK(_efx)			\
++	(1 << (_efx)->loopback_mode)
++
++#define LOOPBACK_INTERNAL(_efx)						\
++	((LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)) ? 1 : 0)
++
++#define LOOPBACK_OUT_OF(_from, _to, _mask)		\
++	(((LOOPBACK_MASK(_from) & (_mask)) &&		\
++	  ((LOOPBACK_MASK(_to) & (_mask)) == 0)) ? 1 : 0)
++
+ /*****************************************************************************/
+ 
+ /**
+diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
+index ad541ba..e2c75d1 100644
+--- a/drivers/net/sfc/ethtool.c
++++ b/drivers/net/sfc/ethtool.c
+@@ -12,12 +12,26 @@
+ #include <linux/ethtool.h>
+ #include <linux/rtnetlink.h>
+ #include "net_driver.h"
++#include "selftest.h"
+ #include "efx.h"
+ #include "ethtool.h"
+ #include "falcon.h"
+ #include "gmii.h"
+ #include "mac.h"
+ 
++const char *efx_loopback_mode_names[] = {
++	[LOOPBACK_NONE]		= "NONE",
++	[LOOPBACK_MAC]		= "MAC",
++	[LOOPBACK_XGMII]	= "XGMII",
++	[LOOPBACK_XGXS]		= "XGXS",
++	[LOOPBACK_XAUI] 	= "XAUI",
++	[LOOPBACK_PHY]		= "PHY",
++	[LOOPBACK_PHYXS]	= "PHY(XS)",
++	[LOOPBACK_PCS]	 	= "PHY(PCS)",
++	[LOOPBACK_PMAPMD]	= "PHY(PMAPMD)",
++	[LOOPBACK_NETWORK]	= "NETWORK",
++};
++
+ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);
+ 
+ struct ethtool_string {
+@@ -217,23 +231,179 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev,
+ 	strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
+ }
+ 
++/**
++ * efx_fill_test - fill in an individual self-test entry
++ * @test_index:		Index of the test
++ * @strings:		Ethtool strings, or %NULL
++ * @data:		Ethtool test results, or %NULL
++ * @test:		Pointer to test result (used only if data != %NULL)
++ * @unit_format:	Unit name format (e.g. "channel\%d")
++ * @unit_id:		Unit id (e.g. 0 for "channel0")
++ * @test_format:	Test name format (e.g. "loopback.\%s.tx.sent")
++ * @test_id:		Test id (e.g. "PHY" for "loopback.PHY.tx_sent")
++ *
++ * Fill in an individual self-test entry.
++ */
++static void efx_fill_test(unsigned int test_index,
++			  struct ethtool_string *strings, u64 *data,
++			  int *test, const char *unit_format, int unit_id,
++			  const char *test_format, const char *test_id)
++{
++	struct ethtool_string unit_str, test_str;
++
++	/* Fill data value, if applicable */
++	if (data)
++		data[test_index] = *test;
++
++	/* Fill string, if applicable */
++	if (strings) {
++		snprintf(unit_str.name, sizeof(unit_str.name),
++			 unit_format, unit_id);
++		snprintf(test_str.name, sizeof(test_str.name),
++			 test_format, test_id);
++		snprintf(strings[test_index].name,
++			 sizeof(strings[test_index].name),
++			 "%-9s%-17s", unit_str.name, test_str.name);
++	}
++}
++
++#define EFX_PORT_NAME "port%d", 0
++#define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel
++#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
++#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
++#define EFX_LOOPBACK_NAME(_mode, _counter)			\
++	"loopback.%s." _counter, LOOPBACK_MODE_NAME(mode)
++
++/**
++ * efx_fill_loopback_test - fill in a block of loopback self-test entries
++ * @efx:		Efx NIC
++ * @lb_tests:		Efx loopback self-test results structure
++ * @mode:		Loopback test mode
++ * @test_index:		Starting index of the test
++ * @strings:		Ethtool strings, or %NULL
++ * @data:		Ethtool test results, or %NULL
++ */
++static int efx_fill_loopback_test(struct efx_nic *efx,
++				  struct efx_loopback_self_tests *lb_tests,
++				  enum efx_loopback_mode mode,
++				  unsigned int test_index,
++				  struct ethtool_string *strings, u64 *data)
++{
++	struct efx_tx_queue *tx_queue;
++
++	efx_for_each_tx_queue(tx_queue, efx) {
++		efx_fill_test(test_index++, strings, data,
++			      &lb_tests->tx_sent[tx_queue->queue],
++			      EFX_TX_QUEUE_NAME(tx_queue),
++			      EFX_LOOPBACK_NAME(mode, "tx_sent"));
++		efx_fill_test(test_index++, strings, data,
++			      &lb_tests->tx_done[tx_queue->queue],
++			      EFX_TX_QUEUE_NAME(tx_queue),
++			      EFX_LOOPBACK_NAME(mode, "tx_done"));
++	}
++	efx_fill_test(test_index++, strings, data,
++		      &lb_tests->rx_good,
++		      EFX_PORT_NAME,
++		      EFX_LOOPBACK_NAME(mode, "rx_good"));
++	efx_fill_test(test_index++, strings, data,
++		      &lb_tests->rx_bad,
++		      EFX_PORT_NAME,
++		      EFX_LOOPBACK_NAME(mode, "rx_bad"));
++
++	return test_index;
++}
++
++/**
++ * efx_ethtool_fill_self_tests - get self-test details
++ * @efx:		Efx NIC
++ * @tests:		Efx self-test results structure, or %NULL
++ * @strings:		Ethtool strings, or %NULL
++ * @data:		Ethtool test results, or %NULL
++ */
++static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
++				       struct efx_self_tests *tests,
++				       struct ethtool_string *strings,
++				       u64 *data)
++{
++	struct efx_channel *channel;
++	unsigned int n = 0;
++	enum efx_loopback_mode mode;
++
++	/* Interrupt */
++	efx_fill_test(n++, strings, data, &tests->interrupt,
++		      "core", 0, "interrupt", NULL);
++
++	/* Event queues */
++	efx_for_each_channel(channel, efx) {
++		efx_fill_test(n++, strings, data,
++			      &tests->eventq_dma[channel->channel],
++			      EFX_CHANNEL_NAME(channel),
++			      "eventq.dma", NULL);
++		efx_fill_test(n++, strings, data,
++			      &tests->eventq_int[channel->channel],
++			      EFX_CHANNEL_NAME(channel),
++			      "eventq.int", NULL);
++		efx_fill_test(n++, strings, data,
++			      &tests->eventq_poll[channel->channel],
++			      EFX_CHANNEL_NAME(channel),
++			      "eventq.poll", NULL);
++	}
++
++	/* PHY presence */
++	efx_fill_test(n++, strings, data, &tests->phy_ok,
++		      EFX_PORT_NAME, "phy_ok", NULL);
++
++	/* Loopback tests */
++	efx_fill_test(n++, strings, data, &tests->loopback_speed,
++		      EFX_PORT_NAME, "loopback.speed", NULL);
++	efx_fill_test(n++, strings, data, &tests->loopback_full_duplex,
++		      EFX_PORT_NAME, "loopback.full_duplex", NULL);
++	for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
++		if (!(efx->loopback_modes & (1 << mode)))
++			continue;
++		n = efx_fill_loopback_test(efx,
++					   &tests->loopback[mode], mode, n,
++					   strings, data);
++	}
++
++	return n;
++}
++
+ static int efx_ethtool_get_stats_count(struct net_device *net_dev)
+ {
+ 	return EFX_ETHTOOL_NUM_STATS;
+ }
+ 
++static int efx_ethtool_self_test_count(struct net_device *net_dev)
++{
++	struct efx_nic *efx = net_dev->priv;
++
++	return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
++}
++
+ static void efx_ethtool_get_strings(struct net_device *net_dev,
+ 				    u32 string_set, u8 *strings)
+ {
++	struct efx_nic *efx = net_dev->priv;
+ 	struct ethtool_string *ethtool_strings =
+ 		(struct ethtool_string *)strings;
+ 	int i;
+ 
+-	if (string_set == ETH_SS_STATS)
++	switch (string_set) {
++	case ETH_SS_STATS:
+ 		for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++)
+ 			strncpy(ethtool_strings[i].name,
+ 				efx_ethtool_stats[i].name,
+ 				sizeof(ethtool_strings[i].name));
++		break;
++	case ETH_SS_TEST:
++		efx_ethtool_fill_self_tests(efx, NULL,
++					    ethtool_strings, NULL);
++		break;
++	default:
++		/* No other string sets */
++		break;
++	}
+ }
+ 
+ static void efx_ethtool_get_stats(struct net_device *net_dev,
+@@ -272,6 +442,22 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
+ 	}
+ }
+ 
++static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
++{
++	int rc;
++
++	/* Our TSO requires TX checksumming, so force TX checksumming
++	 * on when TSO is enabled.
++	 */
++	if (enable) {
++		rc = efx_ethtool_set_tx_csum(net_dev, 1);
++		if (rc)
++			return rc;
++	}
++
++	return ethtool_op_set_tso(net_dev, enable);
++}
++
+ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
+ {
+ 	struct efx_nic *efx = net_dev->priv;
+@@ -283,6 +469,15 @@ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
+ 
+ 	efx_flush_queues(efx);
+ 
++	/* Our TSO requires TX checksumming, so disable TSO when
++	 * checksumming is disabled
++	 */
++	if (!enable) {
++		rc = efx_ethtool_set_tso(net_dev, 0);
++		if (rc)
++			return rc;
++	}
++
+ 	return 0;
+ }
+ 
+@@ -305,6 +500,64 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
+ 	return efx->rx_checksum_enabled;
+ }
+ 
++static void efx_ethtool_self_test(struct net_device *net_dev,
++				  struct ethtool_test *test, u64 *data)
++{
++	struct efx_nic *efx = net_dev->priv;
++	struct efx_self_tests efx_tests;
++	int offline, already_up;
++	int rc;
++
++	ASSERT_RTNL();
++	if (efx->state != STATE_RUNNING) {
++		rc = -EIO;
++		goto fail1;
++	}
++
++	/* We need rx buffers and interrupts. */
++	already_up = (efx->net_dev->flags & IFF_UP);
++	if (!already_up) {
++		rc = dev_open(efx->net_dev);
++		if (rc) {
++			EFX_ERR(efx, "failed opening device.\n");
++			goto fail2;
++		}
++	}
++
++	memset(&efx_tests, 0, sizeof(efx_tests));
++	offline = (test->flags & ETH_TEST_FL_OFFLINE);
++
++	/* Perform online self tests first */
++	rc = efx_online_test(efx, &efx_tests);
++	if (rc)
++		goto out;
++
++	/* Perform offline tests only if online tests passed */
++	if (offline) {
++		/* Stop the kernel from sending packets during the test. */
++		efx_stop_queue(efx);
++		rc = efx_flush_queues(efx);
++		if (!rc)
++			rc = efx_offline_test(efx, &efx_tests,
++					      efx->loopback_modes);
++		efx_wake_queue(efx);
++	}
++
++ out:
++	if (!already_up)
++		dev_close(efx->net_dev);
++
++	EFX_LOG(efx, "%s all %sline self-tests\n",
++		rc == 0 ? "passed" : "failed", offline ? "off" : "on");
++
++ fail2:
++ fail1:
++	/* Fill ethtool results structures */
++	efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data);
++	if (rc)
++		test->flags |= ETH_TEST_FL_FAILED;
++}
++
+ /* Restart autonegotiation */
+ static int efx_ethtool_nway_reset(struct net_device *net_dev)
+ {
+@@ -451,8 +704,12 @@ struct ethtool_ops efx_ethtool_ops = {
+ 	.set_tx_csum		= efx_ethtool_set_tx_csum,
+ 	.get_sg			= ethtool_op_get_sg,
+ 	.set_sg			= ethtool_op_set_sg,
++	.get_tso		= ethtool_op_get_tso,
++	.set_tso		= efx_ethtool_set_tso,
+ 	.get_flags		= ethtool_op_get_flags,
+ 	.set_flags		= ethtool_op_set_flags,
++	.self_test_count	= efx_ethtool_self_test_count,
++	.self_test		= efx_ethtool_self_test,
+ 	.get_strings		= efx_ethtool_get_strings,
+ 	.phys_id		= efx_ethtool_phys_id,
+ 	.get_stats_count	= efx_ethtool_get_stats_count,
+diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
+index 46db549..b57cc68 100644
+--- a/drivers/net/sfc/falcon.c
++++ b/drivers/net/sfc/falcon.c
+@@ -1129,6 +1129,7 @@ static void falcon_handle_driver_event(struct efx_channel *channel,
+ 	case RX_RECOVERY_EV_DECODE:
+ 		EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. "
+ 			"Resetting.\n", channel->channel);
++		atomic_inc(&efx->rx_reset);
+ 		efx_schedule_reset(efx,
+ 				   EFX_WORKAROUND_6555(efx) ?
+ 				   RESET_TYPE_RX_RECOVERY :
+@@ -1731,7 +1732,8 @@ void falcon_drain_tx_fifo(struct efx_nic *efx)
+ 	efx_oword_t temp;
+ 	int count;
+ 
+-	if (FALCON_REV(efx) < FALCON_REV_B0)
++	if ((FALCON_REV(efx) < FALCON_REV_B0) ||
++	    (efx->loopback_mode != LOOPBACK_NONE))
+ 		return;
+ 
+ 	falcon_read(efx, &temp, MAC0_CTRL_REG_KER);
+@@ -2091,6 +2093,8 @@ static int falcon_probe_phy(struct efx_nic *efx)
+ 			efx->phy_type);
+ 		return -1;
+ 	}
++
++	efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks;
+ 	return 0;
+ }
+ 
+@@ -2468,14 +2472,12 @@ int falcon_probe_nic(struct efx_nic *efx)
+  fail5:
+ 	falcon_free_buffer(efx, &efx->irq_status);
+  fail4:
+-	/* fall-thru */
+  fail3:
+ 	if (nic_data->pci_dev2) {
+ 		pci_dev_put(nic_data->pci_dev2);
+ 		nic_data->pci_dev2 = NULL;
+ 	}
+  fail2:
+-	/* fall-thru */
+  fail1:
+ 	kfree(efx->nic_data);
+ 	return rc;
+diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
+index 0485a63..06e2d68 100644
+--- a/drivers/net/sfc/falcon_hwdefs.h
++++ b/drivers/net/sfc/falcon_hwdefs.h
+@@ -636,6 +636,14 @@
+ #define XX_HIDRVA_WIDTH 1
+ #define XX_LODRVA_LBN 8
+ #define XX_LODRVA_WIDTH 1
++#define XX_LPBKD_LBN 3
++#define XX_LPBKD_WIDTH 1
++#define XX_LPBKC_LBN 2
++#define XX_LPBKC_WIDTH 1
++#define XX_LPBKB_LBN 1
++#define XX_LPBKB_WIDTH 1
++#define XX_LPBKA_LBN 0
++#define XX_LPBKA_WIDTH 1
+ 
+ #define XX_TXDRV_CTL_REG_MAC 0x12
+ #define XX_DEQD_LBN 28
+@@ -656,8 +664,14 @@
+ #define XX_DTXA_WIDTH 4
+ 
+ /* XAUI XGXS core status register */
+-#define XX_FORCE_SIG_DECODE_FORCED 0xff
+ #define XX_CORE_STAT_REG_MAC 0x16
++#define XX_FORCE_SIG_LBN 24
++#define XX_FORCE_SIG_WIDTH 8
++#define XX_FORCE_SIG_DECODE_FORCED 0xff
++#define XX_XGXS_LB_EN_LBN 23
++#define XX_XGXS_LB_EN_WIDTH 1
++#define XX_XGMII_LB_EN_LBN 22
++#define XX_XGMII_LB_EN_WIDTH 1
+ #define XX_ALIGN_DONE_LBN 20
+ #define XX_ALIGN_DONE_WIDTH 1
+ #define XX_SYNC_STAT_LBN 16
+diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
+index aa7521b..a74b793 100644
+--- a/drivers/net/sfc/falcon_xmac.c
++++ b/drivers/net/sfc/falcon_xmac.c
+@@ -32,7 +32,7 @@
+ 	(FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))
+ 
+ void falcon_xmac_writel(struct efx_nic *efx,
+-			efx_dword_t *value, unsigned int mac_reg)
++			 efx_dword_t *value, unsigned int mac_reg)
+ {
+ 	efx_oword_t temp;
+ 
+@@ -69,6 +69,10 @@ static int falcon_reset_xmac(struct efx_nic *efx)
+ 		udelay(10);
+ 	}
+ 
++	/* This often fails when DSP is disabled, ignore it */
++	if (sfe4001_phy_flash_cfg != 0)
++		return 0;
++
+ 	EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
+ 	return -ETIMEDOUT;
+ }
+@@ -223,7 +227,7 @@ static int falcon_xgmii_status(struct efx_nic *efx)
+ 	/* The ISR latches, so clear it and re-read */
+ 	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
+ 	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
+-	
++
+ 	if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
+ 	    EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
+ 		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
+@@ -237,7 +241,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
+ {
+ 	efx_dword_t reg;
+ 
+-	if (FALCON_REV(efx) < FALCON_REV_B0)
++	if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
+ 		return;
+ 
+ 	/* Flush the ISR */
+@@ -284,6 +288,9 @@ int falcon_xaui_link_ok(struct efx_nic *efx)
+ 	efx_dword_t reg;
+ 	int align_done, sync_status, link_ok = 0;
+ 
++	if (LOOPBACK_INTERNAL(efx))
++		return 1;
++
+ 	/* Read link status */
+ 	falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
+ 
+@@ -374,6 +381,61 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
+ 	falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC);
+ }
+ 
++static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
++{
++	efx_dword_t reg;
++	int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
++	int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
++	int xgmii_loopback =
++		(efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
++
++	/* XGXS block is flaky and will need to be reset if moving
++	 * into our out of XGMII, XGXS or XAUI loopbacks. */
++	if (EFX_WORKAROUND_5147(efx)) {
++		int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
++		int reset_xgxs;
++
++		falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
++		old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
++		old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
++
++		falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
++		old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
++
++		/* The PHY driver may have turned XAUI off */
++		reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
++			      (xaui_loopback != old_xaui_loopback) ||
++			      (xgmii_loopback != old_xgmii_loopback));
++		if (reset_xgxs) {
++			falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
++			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
++			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
++			falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
++			udelay(1);
++			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
++			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
++			falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
++			udelay(1);
++		}
++	}
++
++	falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
++	EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
++			    (xgxs_loopback || xaui_loopback) ?
++			    XX_FORCE_SIG_DECODE_FORCED : 0);
++	EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
++	EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
++	falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
++
++	falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
++	EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
++	EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
++	EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
++	EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
++	falcon_xmac_writel(efx, &reg, XX_SD_CTL_REG_MAC);
++}
++
++
+ /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
+  * to come back up. Bash it until it comes back up */
+ static int falcon_check_xaui_link_up(struct efx_nic *efx)
+@@ -382,7 +444,8 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx)
+ 	tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
+ 	max_tries = tries;
+ 
+-	if (efx->phy_type == PHY_TYPE_NONE)
++	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
++	    (efx->phy_type == PHY_TYPE_NONE))
+ 		return 0;
+ 
+ 	while (tries) {
+@@ -408,8 +471,13 @@ void falcon_reconfigure_xmac(struct efx_nic *efx)
+ 	falcon_mask_status_intr(efx, 0);
+ 
+ 	falcon_deconfigure_mac_wrapper(efx);
++
++	efx->tx_disabled = LOOPBACK_INTERNAL(efx);
+ 	efx->phy_op->reconfigure(efx);
++
++	falcon_reconfigure_xgxs_core(efx);
+ 	falcon_reconfigure_xmac_core(efx);
++
+ 	falcon_reconfigure_mac_wrapper(efx);
+ 
+ 	/* Ensure XAUI link is up */
+@@ -491,13 +559,15 @@ void falcon_update_stats_xmac(struct efx_nic *efx)
+ 		(mac_stats->rx_bytes - mac_stats->rx_good_bytes);
+ }
+ 
+-#define EFX_XAUI_RETRAIN_MAX 8
+-
+ int falcon_check_xmac(struct efx_nic *efx)
+ {
+ 	unsigned xaui_link_ok;
+ 	int rc;
+ 
++	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
++	    (efx->phy_type == PHY_TYPE_NONE))
++		return 0;
++
+ 	falcon_mask_status_intr(efx, 0);
+ 	xaui_link_ok = falcon_xaui_link_ok(efx);
+ 
+diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
+index dc06bb0..c4f540e 100644
+--- a/drivers/net/sfc/mdio_10g.c
++++ b/drivers/net/sfc/mdio_10g.c
+@@ -44,6 +44,9 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
+ 	int status;
+ 	int phy_id = efx->mii.phy_id;
+ 
++	if (LOOPBACK_INTERNAL(efx))
++		return 0;
++
+ 	/* Read MMD STATUS2 to check it is responding. */
+ 	status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2);
+ 	if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
+@@ -164,6 +167,22 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+ 	int mmd = 0;
+ 	int good;
+ 
++	/* If the port is in loopback, then we should only consider a subset
++	 * of mmd's */
++	if (LOOPBACK_INTERNAL(efx))
++		return 1;
++	else if (efx->loopback_mode == LOOPBACK_NETWORK)
++		return 0;
++	else if (efx->loopback_mode == LOOPBACK_PHYXS)
++		mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS |
++			      MDIO_MMDREG_DEVS0_PCS |
++			      MDIO_MMDREG_DEVS0_PMAPMD);
++	else if (efx->loopback_mode == LOOPBACK_PCS)
++		mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS |
++			      MDIO_MMDREG_DEVS0_PMAPMD);
++	else if (efx->loopback_mode == LOOPBACK_PMAPMD)
++		mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD;
++
+ 	while (mmd_mask) {
+ 		if (mmd_mask & 1) {
+ 			/* Double reads because link state is latched, and a
+@@ -182,6 +201,65 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+ 	return ok;
+ }
+ 
++void mdio_clause45_transmit_disable(struct efx_nic *efx)
++{
++	int phy_id = efx->mii.phy_id;
++	int ctrl1, ctrl2;
++
++	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
++					   MDIO_MMDREG_TXDIS);
++	if (efx->tx_disabled)
++		ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
++	else
++		ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
++	if (ctrl1 != ctrl2)
++		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
++				    MDIO_MMDREG_TXDIS, ctrl2);
++}
++
++void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
++{
++	int phy_id = efx->mii.phy_id;
++	int ctrl1, ctrl2;
++
++	/* Handle (with debouncing) PMA/PMD loopback */
++	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
++					   MDIO_MMDREG_CTRL1);
++
++	if (efx->loopback_mode == LOOPBACK_PMAPMD)
++		ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
++	else
++		ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
++
++	if (ctrl1 != ctrl2)
++		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
++				    MDIO_MMDREG_CTRL1, ctrl2);
++
++	/* Handle (with debouncing) PCS loopback */
++	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
++					   MDIO_MMDREG_CTRL1);
++	if (efx->loopback_mode == LOOPBACK_PCS)
++		ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
++	else
++		ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
++
++	if (ctrl1 != ctrl2)
++		mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS,
++				    MDIO_MMDREG_CTRL1, ctrl2);
++
++	/* Handle (with debouncing) PHYXS network loopback */
++	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
++					   MDIO_MMDREG_CTRL1);
++	if (efx->loopback_mode == LOOPBACK_NETWORK)
++		ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
++	else
++		ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
++
++	if (ctrl1 != ctrl2)
++		mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
++				    MDIO_MMDREG_CTRL1, ctrl2);
++}
++
+ /**
+  * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
+  * @efx:		Efx NIC
+diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
+index 2214b6d..cb99f3f 100644
+--- a/drivers/net/sfc/mdio_10g.h
++++ b/drivers/net/sfc/mdio_10g.h
+@@ -44,11 +44,16 @@
+ #define MDIO_MMDREG_DEVS1	(6)
+ #define MDIO_MMDREG_CTRL2	(7)
+ #define MDIO_MMDREG_STAT2	(8)
++#define MDIO_MMDREG_TXDIS	(9)
+ 
+ /* Bits in MMDREG_CTRL1 */
+ /* Reset */
+ #define MDIO_MMDREG_CTRL1_RESET_LBN	(15)
+ #define MDIO_MMDREG_CTRL1_RESET_WIDTH	(1)
++/* Loopback */
++/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
++#define MDIO_MMDREG_CTRL1_LBACK_LBN	(14)
++#define MDIO_MMDREG_CTRL1_LBACK_WIDTH	(1)
+ 
+ /* Bits in MMDREG_STAT1 */
+ #define MDIO_MMDREG_STAT1_FAULT_LBN	(7)
+@@ -56,6 +61,9 @@
+ /* Link state */
+ #define MDIO_MMDREG_STAT1_LINK_LBN	(2)
+ #define MDIO_MMDREG_STAT1_LINK_WIDTH	(1)
++/* Low power ability */
++#define MDIO_MMDREG_STAT1_LPABLE_LBN	(1)
++#define MDIO_MMDREG_STAT1_LPABLE_WIDTH	(1)
+ 
+ /* Bits in ID reg */
+ #define MDIO_ID_REV(_id32)	(_id32 & 0xf)
+@@ -76,6 +84,14 @@
+ #define MDIO_MMDREG_STAT2_PRESENT_LBN	(14)
+ #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
+ 
++/* Bits in MMDREG_TXDIS */
++#define MDIO_MMDREG_TXDIS_GLOBAL_LBN    (0)
++#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH  (1)
++
++/* MMD-specific bits, ordered by MMD, then register */
++#define MDIO_PMAPMD_CTRL1_LBACK_LBN	(0)
++#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH	(1)
++
+ /* PMA type (4 bits) */
+ #define MDIO_PMAPMD_CTRL2_10G_CX4	(0x0)
+ #define MDIO_PMAPMD_CTRL2_10G_EW	(0x1)
+@@ -95,7 +111,7 @@
+ #define MDIO_PMAPMD_CTRL2_10_BT		(0xf)
+ #define MDIO_PMAPMD_CTRL2_TYPE_MASK	(0xf)
+ 
+-/* /\* PHY XGXS lane state *\/ */
++/* PHY XGXS lane state */
+ #define MDIO_PHYXS_LANE_STATE		(0x18)
+ #define MDIO_PHYXS_LANE_ALIGNED_LBN	(12)
+ 
+@@ -217,6 +233,12 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
+ extern int mdio_clause45_links_ok(struct efx_nic *efx,
+ 				  unsigned int mmd_mask);
+ 
++/* Generic transmit disable support though PMAPMD */
++extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
++
++/* Generic part of reconfigure: set/clear loopback bits */
++extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
++
+ /* Read (some of) the PHY settings over MDIO */
+ extern void mdio_clause45_get_settings(struct efx_nic *efx,
+ 				       struct ethtool_cmd *ecmd);
+diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
+index c505482..59f261b 100644
+--- a/drivers/net/sfc/net_driver.h
++++ b/drivers/net/sfc/net_driver.h
+@@ -134,6 +134,8 @@ struct efx_special_buffer {
+  *	Set only on the final fragment of a packet; %NULL for all other
+  *	fragments.  When this fragment completes, then we can free this
+  *	skb.
++ * @tsoh: The associated TSO header structure, or %NULL if this
++ *	buffer is not a TSO header.
+  * @dma_addr: DMA address of the fragment.
+  * @len: Length of this fragment.
+  *	This field is zero when the queue slot is empty.
+@@ -144,6 +146,7 @@ struct efx_special_buffer {
+  */
+ struct efx_tx_buffer {
+ 	const struct sk_buff *skb;
++	struct efx_tso_header *tsoh;
+ 	dma_addr_t dma_addr;
+ 	unsigned short len;
+ 	unsigned char continuation;
+@@ -187,6 +190,13 @@ struct efx_tx_buffer {
+  *	variable indicates that the queue is full.  This is to
+  *	avoid cache-line ping-pong between the xmit path and the
+  *	completion path.
++ * @tso_headers_free: A list of TSO headers allocated for this TX queue
++ *	that are not in use, and so available for new TSO sends. The list
++ *	is protected by the TX queue lock.
++ * @tso_bursts: Number of times TSO xmit invoked by kernel
++ * @tso_long_headers: Number of packets with headers too long for standard
++ *	blocks
++ * @tso_packets: Number of packets via the TSO xmit path
+  */
+ struct efx_tx_queue {
+ 	/* Members which don't change on the fast path */
+@@ -206,6 +216,10 @@ struct efx_tx_queue {
+ 	unsigned int insert_count ____cacheline_aligned_in_smp;
+ 	unsigned int write_count;
+ 	unsigned int old_read_count;
++	struct efx_tso_header *tso_headers_free;
++	unsigned int tso_bursts;
++	unsigned int tso_long_headers;
++	unsigned int tso_packets;
+ };
+ 
+ /**
+@@ -434,6 +448,9 @@ struct efx_board {
+ 	struct efx_blinker blinker;
+ };
+ 
++#define STRING_TABLE_LOOKUP(val, member)	\
++	member ## _names[val]
++
+ enum efx_int_mode {
+ 	/* Be careful if altering to correct macro below */
+ 	EFX_INT_MODE_MSIX = 0,
+@@ -506,6 +523,7 @@ enum efx_fc_type {
+  * @check_hw: Check hardware
+  * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset)
+  * @mmds: MMD presence mask
++ * @loopbacks: Supported loopback modes mask
+  */
+ struct efx_phy_operations {
+ 	int (*init) (struct efx_nic *efx);
+@@ -515,6 +533,7 @@ struct efx_phy_operations {
+ 	int (*check_hw) (struct efx_nic *efx);
+ 	void (*reset_xaui) (struct efx_nic *efx);
+ 	int mmds;
++	unsigned loopbacks;
+ };
+ 
+ /*
+@@ -653,7 +672,6 @@ union efx_multicast_hash {
+  * @phy_op: PHY interface
+  * @phy_data: PHY private data (including PHY-specific stats)
+  * @mii: PHY interface
+- * @phy_powered: PHY power state
+  * @tx_disabled: PHY transmitter turned off
+  * @link_up: Link status
+  * @link_options: Link options (MII/GMII format)
+@@ -662,6 +680,9 @@ union efx_multicast_hash {
+  * @multicast_hash: Multicast hash table
+  * @flow_control: Flow control flags - separate RX/TX so can't use link_options
+  * @reconfigure_work: work item for dealing with PHY events
++ * @loopback_mode: Loopback status
++ * @loopback_modes: Supported loopback mode bitmask
++ * @loopback_selftest: Offline self-test private state
+  *
+  * The @priv field of the corresponding &struct net_device points to
+  * this.
+@@ -721,6 +742,7 @@ struct efx_nic {
+ 	struct efx_phy_operations *phy_op;
+ 	void *phy_data;
+ 	struct mii_if_info mii;
++	unsigned tx_disabled;
+ 
+ 	int link_up;
+ 	unsigned int link_options;
+@@ -732,6 +754,10 @@ struct efx_nic {
+ 	struct work_struct reconfigure_work;
+ 
+ 	atomic_t rx_reset;
++	enum efx_loopback_mode loopback_mode;
++	unsigned int loopback_modes;
++
++	void *loopback_selftest;
+ };
+ 
+ /**
+diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
+index 551299b..6706223 100644
+--- a/drivers/net/sfc/rx.c
++++ b/drivers/net/sfc/rx.c
+@@ -19,6 +19,7 @@
+ #include "rx.h"
+ #include "efx.h"
+ #include "falcon.h"
++#include "selftest.h"
+ #include "workarounds.h"
+ 
+ /* Number of RX descriptors pushed at once. */
+@@ -683,6 +684,15 @@ void __efx_rx_packet(struct efx_channel *channel,
+ 	struct sk_buff *skb;
+ 	int lro = efx->net_dev->features & NETIF_F_LRO;
+ 
++	/* If we're in loopback test, then pass the packet directly to the
++	 * loopback layer, and free the rx_buf here
++	 */
++	if (unlikely(efx->loopback_selftest)) {
++		efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len);
++		efx_free_rx_buffer(efx, rx_buf);
++		goto done;
++	}
++
+ 	if (rx_buf->skb) {
+ 		prefetch(skb_shinfo(rx_buf->skb));
+ 
+@@ -736,7 +746,6 @@ void __efx_rx_packet(struct efx_channel *channel,
+ 	/* Update allocation strategy method */
+ 	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
+ 
+-	/* fall-thru */
+ done:
+ 	efx->net_dev->last_rx = jiffies;
+ }
+diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
+new file mode 100644
+index 0000000..cbda159
+--- /dev/null
++++ b/drivers/net/sfc/selftest.c
+@@ -0,0 +1,717 @@
++/****************************************************************************
++ * Driver for Solarflare Solarstorm network controllers and boards
++ * Copyright 2005-2006 Fen Systems Ltd.
++ * Copyright 2006-2008 Solarflare Communications Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation, incorporated herein by reference.
++ */
++
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/kernel_stat.h>
++#include <linux/pci.h>
++#include <linux/ethtool.h>
++#include <linux/ip.h>
++#include <linux/in.h>
++#include <linux/udp.h>
++#include <linux/rtnetlink.h>
++#include <asm/io.h>
++#include "net_driver.h"
++#include "ethtool.h"
++#include "efx.h"
++#include "falcon.h"
++#include "selftest.h"
++#include "boards.h"
++#include "workarounds.h"
++#include "mac.h"
++
++/*
++ * Loopback test packet structure
++ *
++ * The self-test should stress every RSS vector, and unfortunately
++ * Falcon only performs RSS on TCP/UDP packets.
++ */
++struct efx_loopback_payload {
++	struct ethhdr header;
++	struct iphdr ip;
++	struct udphdr udp;
++	__be16 iteration;
++	const char msg[64];
++} __attribute__ ((packed));
++
++/* Loopback test source MAC address */
++static const unsigned char payload_source[ETH_ALEN] = {
++	0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b,
++};
++
++static const char *payload_msg =
++	"Hello world! This is an Efx loopback test in progress!";
++
++/**
++ * efx_selftest_state - persistent state during a selftest
++ * @flush:		Drop all packets in efx_loopback_rx_packet
++ * @packet_count:	Number of packets being used in this test
++ * @skbs:		An array of skbs transmitted
++ * @rx_good:		RX good packet count
++ * @rx_bad:		RX bad packet count
++ * @payload:		Payload used in tests
++ */
++struct efx_selftest_state {
++	int flush;
++	int packet_count;
++	struct sk_buff **skbs;
++	atomic_t rx_good;
++	atomic_t rx_bad;
++	struct efx_loopback_payload payload;
++};
++
++/**************************************************************************
++ *
++ * Configurable values
++ *
++ **************************************************************************/
++
++/* Level of loopback testing
++ *
++ * The maximum packet burst length is 16**(n-1), i.e.
++ *
++ * - Level 0 : no packets
++ * - Level 1 : 1 packet
++ * - Level 2 : 17 packets (1 * 1 packet, 1 * 16 packets)
++ * - Level 3 : 273 packets (1 * 1 packet, 1 * 16 packet, 1 * 256 packets)
++ *
++ */
++static unsigned int loopback_test_level = 3;
++
++/**************************************************************************
++ *
++ * Interrupt and event queue testing
++ *
++ **************************************************************************/
++
++/* Test generation and receipt of interrupts */
++static int efx_test_interrupts(struct efx_nic *efx,
++			       struct efx_self_tests *tests)
++{
++	struct efx_channel *channel;
++
++	EFX_LOG(efx, "testing interrupts\n");
++	tests->interrupt = -1;
++
++	/* Reset interrupt flag */
++	efx->last_irq_cpu = -1;
++	smp_wmb();
++
++	/* ACK each interrupting event queue. Receiving an interrupt due to
++	 * traffic before a test event is raised is considered a pass */
++	efx_for_each_channel_with_interrupt(channel, efx) {
++		if (channel->work_pending)
++			efx_process_channel_now(channel);
++		if (efx->last_irq_cpu >= 0)
++			goto success;
++	}
++
++	falcon_generate_interrupt(efx);
++
++	/* Wait for arrival of test interrupt. */
++	EFX_LOG(efx, "waiting for test interrupt\n");
++	schedule_timeout_uninterruptible(HZ / 10);
++	if (efx->last_irq_cpu >= 0)
++		goto success;
++
++	EFX_ERR(efx, "timed out waiting for interrupt\n");
++	return -ETIMEDOUT;
++
++ success:
++	EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n",
++		efx->interrupt_mode, efx->last_irq_cpu);
++	tests->interrupt = 1;
++	return 0;
++}
++
++/* Test generation and receipt of non-interrupting events */
++static int efx_test_eventq(struct efx_channel *channel,
++			   struct efx_self_tests *tests)
++{
++	unsigned int magic;
++
++	/* Channel specific code, limited to 20 bits */
++	magic = (0x00010150 + channel->channel);
++	EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n",
++		channel->channel, magic);
++
++	tests->eventq_dma[channel->channel] = -1;
++	tests->eventq_int[channel->channel] = 1;	/* fake pass */
++	tests->eventq_poll[channel->channel] = 1;	/* fake pass */
++
++	/* Reset flag and zero magic word */
++	channel->efx->last_irq_cpu = -1;
++	channel->eventq_magic = 0;
++	smp_wmb();
++
++	falcon_generate_test_event(channel, magic);
++	udelay(1);
++
++	efx_process_channel_now(channel);
++	if (channel->eventq_magic != magic) {
++		EFX_ERR(channel->efx, "channel %d  failed to see test event\n",
++			channel->channel);
++		return -ETIMEDOUT;
++	} else {
++		tests->eventq_dma[channel->channel] = 1;
++	}
++
++	return 0;
++}
++
++/* Test generation and receipt of interrupting events */
++static int efx_test_eventq_irq(struct efx_channel *channel,
++			       struct efx_self_tests *tests)
++{
++	unsigned int magic, count;
++
++	/* Channel specific code, limited to 20 bits */
++	magic = (0x00010150 + channel->channel);
++	EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n",
++		channel->channel, magic);
++
++	tests->eventq_dma[channel->channel] = -1;
++	tests->eventq_int[channel->channel] = -1;
++	tests->eventq_poll[channel->channel] = -1;
++
++	/* Reset flag and zero magic word */
++	channel->efx->last_irq_cpu = -1;
++	channel->eventq_magic = 0;
++	smp_wmb();
++
++	falcon_generate_test_event(channel, magic);
++
++	/* Wait for arrival of interrupt */
++	count = 0;
++	do {
++		schedule_timeout_uninterruptible(HZ / 100);
++
++		if (channel->work_pending)
++			efx_process_channel_now(channel);
++
++		if (channel->eventq_magic == magic)
++			goto eventq_ok;
++	} while (++count < 2);
++
++	EFX_ERR(channel->efx, "channel %d timed out waiting for event queue\n",
++		channel->channel);
++
++	/* See if interrupt arrived */
++	if (channel->efx->last_irq_cpu >= 0) {
++		EFX_ERR(channel->efx, "channel %d saw interrupt on CPU%d "
++			"during event queue test\n", channel->channel,
++			raw_smp_processor_id());
++		tests->eventq_int[channel->channel] = 1;
++	}
++
++	/* Check to see if event was received even if interrupt wasn't */
++	efx_process_channel_now(channel);
++	if (channel->eventq_magic == magic) {
++		EFX_ERR(channel->efx, "channel %d event was generated, but "
++			"failed to trigger an interrupt\n", channel->channel);
++		tests->eventq_dma[channel->channel] = 1;
++	}
++
++	return -ETIMEDOUT;
++ eventq_ok:
++	EFX_LOG(channel->efx, "channel %d event queue passed\n",
++		channel->channel);
++	tests->eventq_dma[channel->channel] = 1;
++	tests->eventq_int[channel->channel] = 1;
++	tests->eventq_poll[channel->channel] = 1;
++	return 0;
++}
++
++/**************************************************************************
++ *
++ * PHY testing
++ *
++ **************************************************************************/
++
++/* Check PHY presence by reading the PHY ID registers */
++static int efx_test_phy(struct efx_nic *efx,
++			struct efx_self_tests *tests)
++{
++	u16 physid1, physid2;
++	struct mii_if_info *mii = &efx->mii;
++	struct net_device *net_dev = efx->net_dev;
++
++	if (efx->phy_type == PHY_TYPE_NONE)
++		return 0;
++
++	EFX_LOG(efx, "testing PHY presence\n");
++	tests->phy_ok = -1;
++
++	physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
++	physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
++
++	if ((physid1 != 0x0000) && (physid1 != 0xffff) &&
++	    (physid2 != 0x0000) && (physid2 != 0xffff)) {
++		EFX_LOG(efx, "found MII PHY %d ID 0x%x:%x\n",
++			mii->phy_id, physid1, physid2);
++		tests->phy_ok = 1;
++		return 0;
++	}
++
++	EFX_ERR(efx, "no MII PHY present with ID %d\n", mii->phy_id);
++	return -ENODEV;
++}
++
++/**************************************************************************
++ *
++ * Loopback testing
++ * NB Only one loopback test can be executing concurrently.
++ *
++ **************************************************************************/
++
++/* Loopback test RX callback
++ * This is called for each received packet during loopback testing.
++ */
++void efx_loopback_rx_packet(struct efx_nic *efx,
++			    const char *buf_ptr, int pkt_len)
++{
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct efx_loopback_payload *received;
++	struct efx_loopback_payload *payload;
++
++	BUG_ON(!buf_ptr);
++
++	/* If we are just flushing, then drop the packet */
++	if ((state == NULL) || state->flush)
++		return;
++
++	payload = &state->payload;
++	
++	received = (struct efx_loopback_payload *)(char *) buf_ptr;
++	received->ip.saddr = payload->ip.saddr;
++	received->ip.check = payload->ip.check;
++	
++	/* Check that header exists */
++	if (pkt_len < sizeof(received->header)) {
++		EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
++			"test\n", pkt_len, LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Check that the ethernet header exists */
++	if (memcmp(&received->header, &payload->header, ETH_HLEN) != 0) {
++		EFX_ERR(efx, "saw non-loopback RX packet in %s loopback test\n",
++			LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Check packet length */
++	if (pkt_len != sizeof(*payload)) {
++		EFX_ERR(efx, "saw incorrect RX packet length %d (wanted %d) in "
++			"%s loopback test\n", pkt_len, (int)sizeof(*payload),
++			LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Check that IP header matches */
++	if (memcmp(&received->ip, &payload->ip, sizeof(payload->ip)) != 0) {
++		EFX_ERR(efx, "saw corrupted IP header in %s loopback test\n",
++			LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Check that msg and padding matches */
++	if (memcmp(&received->msg, &payload->msg, sizeof(received->msg)) != 0) {
++		EFX_ERR(efx, "saw corrupted RX packet in %s loopback test\n",
++			LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Check that iteration matches */
++	if (received->iteration != payload->iteration) {
++		EFX_ERR(efx, "saw RX packet from iteration %d (wanted %d) in "
++			"%s loopback test\n", ntohs(received->iteration),
++			ntohs(payload->iteration), LOOPBACK_MODE(efx));
++		goto err;
++	}
++
++	/* Increase correct RX count */
++	EFX_TRACE(efx, "got loopback RX in %s loopback test\n",
++		  LOOPBACK_MODE(efx));
++
++	atomic_inc(&state->rx_good);
++	return;
++
++ err:
++#ifdef EFX_ENABLE_DEBUG
++	if (atomic_read(&state->rx_bad) == 0) {
++		EFX_ERR(efx, "received packet:\n");
++		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
++			       buf_ptr, pkt_len, 0);
++		EFX_ERR(efx, "expected packet:\n");
++		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
++			       &state->payload, sizeof(state->payload), 0);
++	}
++#endif
++	atomic_inc(&state->rx_bad);
++}
++
++/* Initialise an efx_selftest_state for a new iteration */
++static void efx_iterate_state(struct efx_nic *efx)
++{
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct net_device *net_dev = efx->net_dev;
++	struct efx_loopback_payload *payload = &state->payload;
++
++	/* Initialise the layerII header */
++	memcpy(&payload->header.h_dest, net_dev->dev_addr, ETH_ALEN);
++	memcpy(&payload->header.h_source, &payload_source, ETH_ALEN);
++	payload->header.h_proto = htons(ETH_P_IP);
++
++	/* saddr set later and used as incrementing count */
++	payload->ip.daddr = htonl(INADDR_LOOPBACK);
++	payload->ip.ihl = 5;
++	payload->ip.check = htons(0xdead);
++	payload->ip.tot_len = htons(sizeof(*payload) - sizeof(struct ethhdr));
++	payload->ip.version = IPVERSION;
++	payload->ip.protocol = IPPROTO_UDP;
++
++	/* Initialise udp header */
++	payload->udp.source = 0;
++	payload->udp.len = htons(sizeof(*payload) - sizeof(struct ethhdr) -
++				 sizeof(struct iphdr));
++	payload->udp.check = 0;	/* checksum ignored */
++
++	/* Fill out payload */
++	payload->iteration = htons(ntohs(payload->iteration) + 1);
++	memcpy(&payload->msg, payload_msg, sizeof(payload_msg));
++
++	/* Fill out remaining state members */
++	atomic_set(&state->rx_good, 0);
++	atomic_set(&state->rx_bad, 0);
++	smp_wmb();
++}
++
++static int efx_tx_loopback(struct efx_tx_queue *tx_queue)
++{
++	struct efx_nic *efx = tx_queue->efx;
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct efx_loopback_payload *payload;
++	struct sk_buff *skb;
++	int i, rc;
++
++	/* Transmit N copies of buffer */
++	for (i = 0; i < state->packet_count; i++) {
++		/* Allocate an skb, holding an extra reference for 
++		 * transmit completion counting */
++		skb = alloc_skb(sizeof(state->payload), GFP_KERNEL);
++		if (!skb)
++			return -ENOMEM;
++		state->skbs[i] = skb;
++		skb_get(skb);
++
++		/* Copy the payload in, incrementing the source address to
++		 * exercise the rss vectors */
++		payload = ((struct efx_loopback_payload *)
++			   skb_put(skb, sizeof(state->payload)));
++		memcpy(payload, &state->payload, sizeof(state->payload));
++		payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2));
++
++		/* Ensure everything we've written is visible to the
++		 * interrupt handler. */
++		smp_wmb();
++
++		if (NET_DEV_REGISTERED(efx))
++			netif_tx_lock_bh(efx->net_dev);
++		rc = efx_xmit(efx, tx_queue, skb);
++		if (NET_DEV_REGISTERED(efx))
++			netif_tx_unlock_bh(efx->net_dev);
++
++		if (rc != NETDEV_TX_OK) {
++			EFX_ERR(efx, "TX queue %d could not transmit packet %d "
++				"of %d in %s loopback test\n", tx_queue->queue,
++				i + 1, state->packet_count, LOOPBACK_MODE(efx));
++
++			/* Defer cleaning up the other skbs for the caller */
++			kfree_skb(skb);
++			return -EPIPE;
++		}
++	}
++
++	return 0;
++}
++
++static int efx_rx_loopback(struct efx_tx_queue *tx_queue,
++			   struct efx_loopback_self_tests *lb_tests)
++{
++	struct efx_nic *efx = tx_queue->efx;
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct sk_buff *skb;
++	int tx_done = 0, rx_good, rx_bad;
++	int i, rc = 0;
++
++	if (NET_DEV_REGISTERED(efx))
++		netif_tx_lock_bh(efx->net_dev);
++
++	/* Count the number of tx completions, and decrement the refcnt. Any
++	 * skbs not already completed will be free'd when the queue is flushed */
++	for (i=0; i < state->packet_count; i++) {
++		skb = state->skbs[i];
++		if (skb && !skb_shared(skb))
++			++tx_done;
++		dev_kfree_skb_any(skb);
++	}
++
++	if (NET_DEV_REGISTERED(efx))
++		netif_tx_unlock_bh(efx->net_dev);
++
++	/* Check TX completion and received packet counts */
++	rx_good = atomic_read(&state->rx_good);
++	rx_bad = atomic_read(&state->rx_bad);
++	if (tx_done != state->packet_count) {
++		/* Don't free the skbs; they will be picked up on TX
++		 * overflow or channel teardown.
++		 */
++		EFX_ERR(efx, "TX queue %d saw only %d out of an expected %d "
++			"TX completion events in %s loopback test\n",
++			tx_queue->queue, tx_done, state->packet_count,
++			LOOPBACK_MODE(efx));
++		rc = -ETIMEDOUT;
++		/* Allow to fall through so we see the RX errors as well */
++	}
++
++	/* We may always be up to a flush away from our desired packet total */
++	if (rx_good != state->packet_count) {
++		EFX_LOG(efx, "TX queue %d saw only %d out of an expected %d "
++			"received packets in %s loopback test\n",
++			tx_queue->queue, rx_good, state->packet_count,
++			LOOPBACK_MODE(efx));
++		rc = -ETIMEDOUT;
++		/* Fall through */
++	}
++
++	/* Update loopback test structure */
++	lb_tests->tx_sent[tx_queue->queue] += state->packet_count;
++	lb_tests->tx_done[tx_queue->queue] += tx_done;
++	lb_tests->rx_good += rx_good;
++	lb_tests->rx_bad += rx_bad;
++
++	return rc;
++}
++
++static int
++efx_test_loopback(struct efx_tx_queue *tx_queue,
++		  struct efx_loopback_self_tests *lb_tests)
++{
++	struct efx_nic *efx = tx_queue->efx;
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct efx_channel *channel;
++	int i, rc = 0;
++
++	for (i = 0; i < loopback_test_level; i++) {
++		/* Determine how many packets to send */
++		state->packet_count = (efx->type->txd_ring_mask + 1) / 3;
++		state->packet_count = min(1 << (i << 2), state->packet_count);
++		state->skbs = kzalloc(sizeof(state->skbs[0]) *
++				      state->packet_count, GFP_KERNEL);
++		state->flush = 0;
++
++		EFX_LOG(efx, "TX queue %d testing %s loopback with %d "
++			"packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
++			state->packet_count);
++
++		efx_iterate_state(efx);
++		rc = efx_tx_loopback(tx_queue);
++		
++		/* NAPI polling is not enabled, so process channels synchronously */
++		schedule_timeout_uninterruptible(HZ / 50);
++		efx_for_each_channel_with_interrupt(channel, efx) {
++			if (channel->work_pending)
++				efx_process_channel_now(channel);
++		}
++
++		rc |= efx_rx_loopback(tx_queue, lb_tests);
++		kfree(state->skbs);
++
++		if (rc) {
++			/* Wait a while to ensure there are no packets
++			 * floating around after a failure. */
++			schedule_timeout_uninterruptible(HZ / 10);
++			return rc;
++		}
++	}
++
++	EFX_LOG(efx, "TX queue %d passed %s loopback test with a burst length "
++		"of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
++		state->packet_count);
++
++	return rc;
++}
++
++static int efx_test_loopbacks(struct efx_nic *efx,
++			      struct efx_self_tests *tests,
++			      unsigned int loopback_modes)
++{
++	struct efx_selftest_state *state = efx->loopback_selftest;
++	struct ethtool_cmd ecmd, ecmd_loopback;
++	struct efx_tx_queue *tx_queue;
++	enum efx_loopback_mode old_mode, mode;
++	int count, rc = 0, link_up;
++	
++	rc = efx_ethtool_get_settings(efx->net_dev, &ecmd);
++	if (rc) {
++		EFX_ERR(efx, "could not get GMII settings\n");
++		return rc;
++	}
++	old_mode = efx->loopback_mode;
++
++	/* Disable autonegotiation for the purposes of loopback */
++	memcpy(&ecmd_loopback, &ecmd, sizeof(ecmd_loopback));
++	if (ecmd_loopback.autoneg == AUTONEG_ENABLE) {
++		ecmd_loopback.autoneg = AUTONEG_DISABLE;
++		ecmd_loopback.duplex = DUPLEX_FULL;
++		ecmd_loopback.speed = SPEED_10000;
++	}
++
++	rc = efx_ethtool_set_settings(efx->net_dev, &ecmd_loopback);
++	if (rc) {
++		EFX_ERR(efx, "could not disable autonegotiation\n");
++		goto out;
++	}
++	tests->loopback_speed = ecmd_loopback.speed;
++	tests->loopback_full_duplex = ecmd_loopback.duplex;
++
++	/* Test all supported loopback modes */
++	for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
++		if (!(loopback_modes & (1 << mode)))
++			continue;
++
++		/* Move the port into the specified loopback mode. */
++		state->flush = 1;
++		efx->loopback_mode = mode;
++		efx_reconfigure_port(efx);
++
++		/* Wait for the PHY to signal the link is up */
++		count = 0;
++		do {
++			struct efx_channel *channel = &efx->channel[0];
++
++			falcon_check_xmac(efx);
++			schedule_timeout_uninterruptible(HZ / 10);
++			if (channel->work_pending)
++				efx_process_channel_now(channel);
++			/* Wait for PHY events to be processed */
++			flush_workqueue(efx->workqueue);
++			rmb();
++
++			/* efx->link_up can be 1 even if the XAUI link is down,
++			 * (bug5762). Usually, it's not worth bothering with the
++			 * difference, but for selftests, we need that extra
++			 * guarantee that the link is really, really, up.
++			 */
++			link_up = efx->link_up;
++			if (!falcon_xaui_link_ok(efx))
++				link_up = 0;
++
++		} while ((++count < 20) && !link_up);
++
++		/* The link should now be up. If it isn't, there is no point
++		 * in attempting a loopback test */
++		if (!link_up) {
++			EFX_ERR(efx, "loopback %s never came up\n",
++				LOOPBACK_MODE(efx));
++			rc = -EIO;
++			goto out;
++		}
++
++		EFX_LOG(efx, "link came up in %s loopback in %d iterations\n",
++			LOOPBACK_MODE(efx), count);
++
++		/* Test every TX queue */
++		efx_for_each_tx_queue(tx_queue, efx) {
++			rc |= efx_test_loopback(tx_queue,
++						&tests->loopback[mode]);
++			if (rc)
++				goto out;
++		}
++	}
++
++ out:
++	/* Take out of loopback and restore PHY settings */
++	state->flush = 1;
++	efx->loopback_mode = old_mode;
++	efx_ethtool_set_settings(efx->net_dev, &ecmd);
++
++	return rc;
++}
++
++/**************************************************************************
++ *
++ * Entry points
++ *
++ *************************************************************************/
++
++/* Online (i.e. non-disruptive) testing
++ * This checks interrupt generation, event delivery and PHY presence. */
++int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests)
++{
++	struct efx_channel *channel;
++	int rc = 0;
++
++	EFX_LOG(efx, "performing online self-tests\n");
++
++	rc |= efx_test_interrupts(efx, tests);
++	efx_for_each_channel(channel, efx) {
++		if (channel->has_interrupt)
++			rc |= efx_test_eventq_irq(channel, tests);
++		else
++			rc |= efx_test_eventq(channel, tests);
++	}
++	rc |= efx_test_phy(efx, tests);
++
++	if (rc)
++		EFX_ERR(efx, "failed online self-tests\n");
++
++	return rc;
++}
++
++/* Offline (i.e. disruptive) testing
++ * This checks MAC and PHY loopback on the specified port. */
++int efx_offline_test(struct efx_nic *efx,
++		     struct efx_self_tests *tests, unsigned int loopback_modes)
++{
++	struct efx_selftest_state *state;
++	int rc = 0;
++
++	EFX_LOG(efx, "performing offline self-tests\n");
++
++	/* Create a selftest_state structure to hold state for the test */
++	state = kzalloc(sizeof(*state), GFP_KERNEL);
++	if (state == NULL) {
++		rc = -ENOMEM;
++		goto out;
++	}
++
++	/* Set the port loopback_selftest member. From this point on
++	 * all received packets will be dropped. Mark the state as
++	 * "flushing" so all inflight packets are dropped */
++	BUG_ON(efx->loopback_selftest);
++	state->flush = 1;
++	efx->loopback_selftest = (void *)state;
++
++	rc = efx_test_loopbacks(efx, tests, loopback_modes);
++
++	efx->loopback_selftest = NULL;
++	wmb();
++	kfree(state);
++
++ out:
++	if (rc)
++		EFX_ERR(efx, "failed offline self-tests\n");
++
++	return rc;
++}
++
+diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
+new file mode 100644
+index 0000000..f6999c2
+--- /dev/null
++++ b/drivers/net/sfc/selftest.h
+@@ -0,0 +1,50 @@
++/****************************************************************************
++ * Driver for Solarflare Solarstorm network controllers and boards
++ * Copyright 2005-2006 Fen Systems Ltd.
++ * Copyright 2006-2008 Solarflare Communications Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation, incorporated herein by reference.
++ */
++
++#ifndef EFX_SELFTEST_H
++#define EFX_SELFTEST_H
++
++#include "net_driver.h"
++
++/*
++ * Self tests
++ */
++
++struct efx_loopback_self_tests {
++	int tx_sent[EFX_MAX_TX_QUEUES];
++	int tx_done[EFX_MAX_TX_QUEUES];
++	int rx_good;
++	int rx_bad;
++};
++
++/* Efx self test results
++ * For fields which are not counters, 1 indicates success and -1
++ * indicates failure.
++ */
++struct efx_self_tests {
++	int interrupt;
++	int eventq_dma[EFX_MAX_CHANNELS];
++	int eventq_int[EFX_MAX_CHANNELS];
++	int eventq_poll[EFX_MAX_CHANNELS];
++	int phy_ok;
++	int loopback_speed;
++	int loopback_full_duplex;
++	struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX];
++};
++
++extern void efx_loopback_rx_packet(struct efx_nic *efx,
++				   const char *buf_ptr, int pkt_len);
++extern int efx_online_test(struct efx_nic *efx,
++			   struct efx_self_tests *tests);
++extern int efx_offline_test(struct efx_nic *efx,
++			    struct efx_self_tests *tests,
++			    unsigned int loopback_modes);
++
++#endif /* EFX_SELFTEST_H */
+diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
+index 11fa9fb..725d1a5 100644
+--- a/drivers/net/sfc/sfe4001.c
++++ b/drivers/net/sfc/sfe4001.c
+@@ -130,6 +130,15 @@ void sfe4001_poweroff(struct efx_nic *efx)
+ 	(void) efx_i2c_read(i2c, MAX6647, RSL, &in, 1);
+ }
+ 
++/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected
++ * to the FLASH_CFG_1 input on the DSP.  We must keep it high at power-
++ * up to allow writing the flash (done through MDIO from userland).
++ */
++unsigned int sfe4001_phy_flash_cfg;
++module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444);
++MODULE_PARM_DESC(phy_flash_cfg,
++		 "Force PHY to enter flash configuration mode");
++
+ /* This board uses an I2C expander to provider power to the PHY, which needs to
+  * be turned on before the PHY can be used.
+  * Context: Process context, rtnl lock held
+@@ -203,6 +212,8 @@ int sfe4001_poweron(struct efx_nic *efx)
+ 		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
+ 			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
+ 			       (1 << P0_X_TRST_LBN));
++		if (sfe4001_phy_flash_cfg)
++			out |= 1 << P0_EN_3V3X_LBN;
+ 
+ 		rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
+ 		if (rc)
+@@ -226,6 +237,9 @@ int sfe4001_poweron(struct efx_nic *efx)
+ 		if (in & (1 << P1_AFE_PWD_LBN))
+ 			goto done;
+ 
++		/* DSP doesn't look powered in flash config mode */
++		if (sfe4001_phy_flash_cfg)
++			goto done;
+ 	} while (++count < 20);
+ 
+ 	EFX_INFO(efx, "timed out waiting for power\n");
+diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
+index a2e9f79..b1cd6de 100644
+--- a/drivers/net/sfc/tenxpress.c
++++ b/drivers/net/sfc/tenxpress.c
+@@ -24,6 +24,11 @@
+ 				 MDIO_MMDREG_DEVS0_PCS    | \
+ 				 MDIO_MMDREG_DEVS0_PHYXS)
+ 
++#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) |	\
++			     (1 << LOOPBACK_PCS) |	\
++			     (1 << LOOPBACK_PMAPMD) |	\
++			     (1 << LOOPBACK_NETWORK))
++
+ /* We complain if we fail to see the link partner as 10G capable this many
+  * times in a row (must be > 1 as sampling the autoneg. registers is racy)
+  */
+@@ -72,6 +77,10 @@
+ #define PMA_PMD_BIST_RXD_LBN	(1)
+ #define PMA_PMD_BIST_AFE_LBN	(0)
+ 
++/* Special Software reset register */
++#define PMA_PMD_EXT_CTRL_REG 49152
++#define PMA_PMD_EXT_SSR_LBN 15
++
+ #define BIST_MAX_DELAY	(1000)
+ #define BIST_POLL_DELAY	(10)
+ 
+@@ -86,6 +95,11 @@
+ #define	PCS_TEST_SELECT_REG 0xd807	/* PRM 10.5.8 */
+ #define	CLK312_EN_LBN 3
+ 
++/* PHYXS registers */
++#define PHYXS_TEST1         (49162)
++#define LOOPBACK_NEAR_LBN   (8)
++#define LOOPBACK_NEAR_WIDTH (1)
++
+ /* Boot status register */
+ #define PCS_BOOT_STATUS_REG	(0xd000)
+ #define PCS_BOOT_FATAL_ERR_LBN	(0)
+@@ -106,7 +120,9 @@ MODULE_PARM_DESC(crc_error_reset_threshold,
+ 
+ struct tenxpress_phy_data {
+ 	enum tenxpress_state state;
++	enum efx_loopback_mode loopback_mode;
+ 	atomic_t bad_crc_count;
++	int tx_disabled;
+ 	int bad_lp_tries;
+ };
+ 
+@@ -199,10 +215,12 @@ static int tenxpress_phy_init(struct efx_nic *efx)
+ 
+ 	tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL);
+ 
+-	rc = mdio_clause45_wait_reset_mmds(efx,
+-					   TENXPRESS_REQUIRED_DEVS);
+-	if (rc < 0)
+-		goto fail;
++	if (!sfe4001_phy_flash_cfg) {
++		rc = mdio_clause45_wait_reset_mmds(efx,
++						   TENXPRESS_REQUIRED_DEVS);
++		if (rc < 0)
++			goto fail;
++	}
+ 
+ 	rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
+ 	if (rc < 0)
+@@ -225,6 +243,35 @@ static int tenxpress_phy_init(struct efx_nic *efx)
+ 	return rc;
+ }
+ 
++static int tenxpress_special_reset(struct efx_nic *efx)
++{
++	int rc, reg;
++
++	EFX_TRACE(efx, "%s\n", __func__);
++
++	/* Initiate reset */
++	reg = mdio_clause45_read(efx, efx->mii.phy_id,
++				 MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG);
++	reg |= (1 << PMA_PMD_EXT_SSR_LBN);
++	mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
++			    PMA_PMD_EXT_CTRL_REG, reg);
++
++	msleep(200);
++
++	/* Wait for the blocks to come out of reset */
++	rc = mdio_clause45_wait_reset_mmds(efx,
++					   TENXPRESS_REQUIRED_DEVS);
++	if (rc < 0)
++		return rc;
++
++	/* Try and reconfigure the device */
++	rc = tenxpress_init(efx);
++	if (rc < 0)
++		return rc;
++
++	return 0;
++}
++
+ static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp)
+ {
+ 	struct tenxpress_phy_data *pd = efx->phy_data;
+@@ -299,11 +346,46 @@ static int tenxpress_link_ok(struct efx_nic *efx, int check_lp)
+ 	return ok;
+ }
+ 
++static void tenxpress_phyxs_loopback(struct efx_nic *efx)
++{
++	int phy_id = efx->mii.phy_id;
++	int ctrl1, ctrl2;
++
++	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
++					   PHYXS_TEST1);
++	if (efx->loopback_mode == LOOPBACK_PHYXS)
++		ctrl2 |= (1 << LOOPBACK_NEAR_LBN);
++	else
++		ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN);
++	if (ctrl1 != ctrl2)
++		mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
++				    PHYXS_TEST1, ctrl2);
++}
++
+ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
+ {
++	struct tenxpress_phy_data *phy_data = efx->phy_data;
++	int loop_change = LOOPBACK_OUT_OF(phy_data, efx,
++					  TENXPRESS_LOOPBACKS);
++
+ 	if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL))
+ 		return;
+ 
++	/* When coming out of transmit disable, coming out of low power
++	 * mode, or moving out of any PHY internal loopback mode,
++	 * perform a special software reset */
++	if ((phy_data->tx_disabled && !efx->tx_disabled) ||
++	    loop_change) {
++		(void) tenxpress_special_reset(efx);
++		falcon_reset_xaui(efx);
++	}
++
++	mdio_clause45_transmit_disable(efx);
++	mdio_clause45_phy_reconfigure(efx);
++	tenxpress_phyxs_loopback(efx);
++
++	phy_data->tx_disabled = efx->tx_disabled;
++	phy_data->loopback_mode = efx->loopback_mode;
+ 	efx->link_up = tenxpress_link_ok(efx, 0);
+ 	efx->link_options = GM_LPA_10000FULL;
+ }
+@@ -431,4 +513,5 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
+ 	.clear_interrupt  = tenxpress_phy_clear_interrupt,
+ 	.reset_xaui       = tenxpress_reset_xaui,
+ 	.mmds             = TENXPRESS_REQUIRED_DEVS,
++	.loopbacks        = TENXPRESS_LOOPBACKS,
+ };
+diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
+index fbb866b..9b436f5 100644
+--- a/drivers/net/sfc/tx.c
++++ b/drivers/net/sfc/tx.c
+@@ -82,6 +82,46 @@ static inline void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
+ 	}
+ }
+ 
++/**
++ * struct efx_tso_header - a DMA mapped buffer for packet headers
++ * @next: Linked list of free ones.
++ *	The list is protected by the TX queue lock.
++ * @dma_unmap_len: Length to unmap for an oversize buffer, or 0.
++ * @dma_addr: The DMA address of the header below.
++ *
++ * This controls the memory used for a TSO header.  Use TSOH_DATA()
++ * to find the packet header data.  Use TSOH_SIZE() to calculate the
++ * total size required for a given packet header length.  TSO headers
++ * in the free list are exactly %TSOH_STD_SIZE bytes in size.
++ */
++struct efx_tso_header {
++	union {
++		struct efx_tso_header *next;
++		size_t unmap_len;
++	};
++	dma_addr_t dma_addr;
++};
++
++static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
++			       const struct sk_buff *skb);
++static void efx_fini_tso(struct efx_tx_queue *tx_queue);
++static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue,
++			       struct efx_tso_header *tsoh);
++
++static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue,
++				 struct efx_tx_buffer *buffer)
++{
++	if (buffer->tsoh) {
++		if (likely(!buffer->tsoh->unmap_len)) {
++			buffer->tsoh->next = tx_queue->tso_headers_free;
++			tx_queue->tso_headers_free = buffer->tsoh;
++		} else {
++			efx_tsoh_heap_free(tx_queue, buffer->tsoh);
++		}
++		buffer->tsoh = NULL;
++	}
++}
++
+ 
+ /*
+  * Add a socket buffer to a TX queue
+@@ -114,6 +154,9 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
+ 
+ 	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
+ 
++	if (skb_shinfo((struct sk_buff *)skb)->gso_size)
++		return efx_enqueue_skb_tso(tx_queue, skb);
++
+ 	/* Get size of the initial fragment */
+ 	len = skb_headlen(skb);
+ 
+@@ -166,6 +209,8 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
+ 			insert_ptr = (tx_queue->insert_count &
+ 				      efx->type->txd_ring_mask);
+ 			buffer = &tx_queue->buffer[insert_ptr];
++			efx_tsoh_free(tx_queue, buffer);
++			EFX_BUG_ON_PARANOID(buffer->tsoh);
+ 			EFX_BUG_ON_PARANOID(buffer->skb);
+ 			EFX_BUG_ON_PARANOID(buffer->len);
+ 			EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+@@ -432,6 +477,9 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue)
+ 
+ 	efx_release_tx_buffers(tx_queue);
+ 
++	/* Free up TSO header cache */
++	efx_fini_tso(tx_queue);
++
+ 	/* Release queue's stop on port, if any */
+ 	if (tx_queue->stopped) {
+ 		tx_queue->stopped = 0;
+@@ -450,3 +498,619 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
+ }
+ 
+ 
++/* Efx TCP segmentation acceleration.
++ *
++ * Why?  Because by doing it here in the driver we can go significantly
++ * faster than the GSO.
++ *
++ * Requires TX checksum offload support.
++ */
++
++/* Number of bytes inserted at the start of a TSO header buffer,
++ * similar to NET_IP_ALIGN.
++ */
++#if defined(__i386__) || defined(__x86_64__)
++#define TSOH_OFFSET	0
++#else
++#define TSOH_OFFSET	NET_IP_ALIGN
++#endif
++
++#define TSOH_BUFFER(tsoh)	((u8 *)(tsoh + 1) + TSOH_OFFSET)
++
++/* Total size of struct efx_tso_header, buffer and padding */
++#define TSOH_SIZE(hdr_len)					\
++	(sizeof(struct efx_tso_header) + TSOH_OFFSET + hdr_len)
++
++/* Size of blocks on free list.  Larger blocks must be allocated from
++ * the heap.
++ */
++#define TSOH_STD_SIZE		128
++
++#define PTR_DIFF(p1, p2)  ((u8 *)(p1) - (u8 *)(p2))
++#define ETH_HDR_LEN(skb)  (skb_network_header(skb) - (skb)->data)
++#define SKB_TCP_OFF(skb)  PTR_DIFF(tcp_hdr(skb), (skb)->data)
++#define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data)
++
++/**
++ * struct tso_state - TSO state for an SKB
++ * @remaining_len: Bytes of data we've yet to segment
++ * @seqnum: Current sequence number
++ * @packet_space: Remaining space in current packet
++ * @ifc: Input fragment cursor.
++ *	Where we are in the current fragment of the incoming SKB.  These
++ *	values get updated in place when we split a fragment over
++ *	multiple packets.
++ * @p: Parameters.
++ *	These values are set once at the start of the TSO send and do
++ *	not get changed as the routine progresses.
++ *
++ * The state used during segmentation.  It is put into this data structure
++ * just to make it easy to pass into inline functions.
++ */
++struct tso_state {
++	unsigned remaining_len;
++	unsigned seqnum;
++	unsigned packet_space;
++
++	struct {
++		/* DMA address of current position */
++		dma_addr_t dma_addr;
++		/* Remaining length */
++		unsigned int len;
++		/* DMA address and length of the whole fragment */
++		unsigned int unmap_len;
++		dma_addr_t unmap_addr;
++		struct page *page;
++		unsigned page_off;
++	} ifc;
++
++	struct {
++		/* The number of bytes of header */
++		unsigned int header_length;
++
++		/* The number of bytes to put in each outgoing segment. */
++		int full_packet_size;
++
++		/* Current IPv4 ID, host endian. */
++		unsigned ipv4_id;
++	} p;
++};
++
++
++/*
++ * Verify that our various assumptions about sk_buffs and the conditions
++ * under which TSO will be attempted hold true.
++ */
++static inline void efx_tso_check_safe(const struct sk_buff *skb)
++{
++	EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP));
++	EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto !=
++			    skb->protocol);
++	EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
++	EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data)
++			     + (tcp_hdr(skb)->doff << 2u)) >
++			    skb_headlen(skb));
++}
++
++
++/*
++ * Allocate a page worth of efx_tso_header structures, and string them
++ * into the tx_queue->tso_headers_free linked list. Return 0 or -ENOMEM.
++ */
++static int efx_tsoh_block_alloc(struct efx_tx_queue *tx_queue)
++{
++
++	struct pci_dev *pci_dev = tx_queue->efx->pci_dev;
++	struct efx_tso_header *tsoh;
++	dma_addr_t dma_addr;
++	u8 *base_kva, *kva;
++
++	base_kva = pci_alloc_consistent(pci_dev, PAGE_SIZE, &dma_addr);
++	if (base_kva == NULL) {
++		EFX_ERR(tx_queue->efx, "Unable to allocate page for TSO"
++			" headers\n");
++		return -ENOMEM;
++	}
++
++	/* pci_alloc_consistent() allocates pages. */
++	EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1u));
++
++	for (kva = base_kva; kva < base_kva + PAGE_SIZE; kva += TSOH_STD_SIZE) {
++		tsoh = (struct efx_tso_header *)kva;
++		tsoh->dma_addr = dma_addr + (TSOH_BUFFER(tsoh) - base_kva);
++		tsoh->next = tx_queue->tso_headers_free;
++		tx_queue->tso_headers_free = tsoh;
++	}
++
++	return 0;
++}
++
++
++/* Free up a TSO header, and all others in the same page. */
++static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue,
++				struct efx_tso_header *tsoh,
++				struct pci_dev *pci_dev)
++{
++	struct efx_tso_header **p;
++	unsigned long base_kva;
++	dma_addr_t base_dma;
++
++	base_kva = (unsigned long)tsoh & PAGE_MASK;
++	base_dma = tsoh->dma_addr & PAGE_MASK;
++
++	p = &tx_queue->tso_headers_free;
++	while (*p != NULL)
++		if (((unsigned long)*p & PAGE_MASK) == base_kva)
++			*p = (*p)->next;
++		else
++			p = &(*p)->next;
++
++	pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma);
++}
++
++static struct efx_tso_header *
++efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len)
++{
++	struct efx_tso_header *tsoh;
++
++	tsoh = kmalloc(TSOH_SIZE(header_len), GFP_ATOMIC | GFP_DMA);
++	if (unlikely(!tsoh))
++		return NULL;
++
++	tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev,
++					TSOH_BUFFER(tsoh), header_len,
++					PCI_DMA_TODEVICE);
++	if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) {
++		kfree(tsoh);
++		return NULL;
++	}
++
++	tsoh->unmap_len = header_len;
++	return tsoh;
++}
++
++static void
++efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh)
++{
++	pci_unmap_single(tx_queue->efx->pci_dev,
++			 tsoh->dma_addr, tsoh->unmap_len,
++			 PCI_DMA_TODEVICE);
++	kfree(tsoh);
++}
++
++/**
++ * efx_tx_queue_insert - push descriptors onto the TX queue
++ * @tx_queue:		Efx TX queue
++ * @dma_addr:		DMA address of fragment
++ * @len:		Length of fragment
++ * @skb:		Only non-null for end of last segment
++ * @end_of_packet:	True if last fragment in a packet
++ * @unmap_addr:		DMA address of fragment for unmapping
++ * @unmap_len:		Only set this in last segment of a fragment
++ *
++ * Push descriptors onto the TX queue.  Return 0 on success or 1 if
++ * @tx_queue full.
++ */
++static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
++			       dma_addr_t dma_addr, unsigned len,
++			       const struct sk_buff *skb, int end_of_packet,
++			       dma_addr_t unmap_addr, unsigned unmap_len)
++{
++	struct efx_tx_buffer *buffer;
++	struct efx_nic *efx = tx_queue->efx;
++	unsigned dma_len, fill_level, insert_ptr, misalign;
++	int q_space;
++
++	EFX_BUG_ON_PARANOID(len <= 0);
++
++	fill_level = tx_queue->insert_count - tx_queue->old_read_count;
++	/* -1 as there is no way to represent all descriptors used */
++	q_space = efx->type->txd_ring_mask - 1 - fill_level;
++
++	while (1) {
++		if (unlikely(q_space-- <= 0)) {
++			/* It might be that completions have happened
++			 * since the xmit path last checked.  Update
++			 * the xmit path's copy of read_count.
++			 */
++			++tx_queue->stopped;
++			/* This memory barrier protects the change of
++			 * stopped from the access of read_count. */
++			smp_mb();
++			tx_queue->old_read_count =
++				*(volatile unsigned *)&tx_queue->read_count;
++			fill_level = (tx_queue->insert_count
++				      - tx_queue->old_read_count);
++			q_space = efx->type->txd_ring_mask - 1 - fill_level;
++			if (unlikely(q_space-- <= 0))
++				return 1;
++			smp_mb();
++			--tx_queue->stopped;
++		}
++
++		insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask;
++		buffer = &tx_queue->buffer[insert_ptr];
++		++tx_queue->insert_count;
++
++		EFX_BUG_ON_PARANOID(tx_queue->insert_count -
++				    tx_queue->read_count >
++				    efx->type->txd_ring_mask);
++
++		efx_tsoh_free(tx_queue, buffer);
++		EFX_BUG_ON_PARANOID(buffer->len);
++		EFX_BUG_ON_PARANOID(buffer->unmap_len);
++		EFX_BUG_ON_PARANOID(buffer->skb);
++		EFX_BUG_ON_PARANOID(buffer->continuation != 1);
++		EFX_BUG_ON_PARANOID(buffer->tsoh);
++
++		buffer->dma_addr = dma_addr;
++
++		/* Ensure we do not cross a boundary unsupported by H/W */
++		dma_len = (~dma_addr & efx->type->tx_dma_mask) + 1;
++
++		misalign = (unsigned)dma_addr & efx->type->bug5391_mask;
++		if (misalign && dma_len + misalign > 512)
++			dma_len = 512 - misalign;
++
++		/* If there is enough space to send then do so */
++		if (dma_len >= len)
++			break;
++
++		buffer->len = dma_len; /* Don't set the other members */
++		dma_addr += dma_len;
++		len -= dma_len;
++	}
++
++	EFX_BUG_ON_PARANOID(!len);
++	buffer->len = len;
++	buffer->skb = skb;
++	buffer->continuation = !end_of_packet;
++	buffer->unmap_addr = unmap_addr;
++	buffer->unmap_len = unmap_len;
++	return 0;
++}
++
++
++/*
++ * Put a TSO header into the TX queue.
++ *
++ * This is special-cased because we know that it is small enough to fit in
++ * a single fragment, and we know it doesn't cross a page boundary.  It
++ * also allows us to not worry about end-of-packet etc.
++ */
++static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue,
++				      struct efx_tso_header *tsoh, unsigned len)
++{
++	struct efx_tx_buffer *buffer;
++
++	buffer = &tx_queue->buffer[tx_queue->insert_count &
++				   tx_queue->efx->type->txd_ring_mask];
++	efx_tsoh_free(tx_queue, buffer);
++	EFX_BUG_ON_PARANOID(buffer->len);
++	EFX_BUG_ON_PARANOID(buffer->unmap_len);
++	EFX_BUG_ON_PARANOID(buffer->skb);
++	EFX_BUG_ON_PARANOID(buffer->continuation != 1);
++	EFX_BUG_ON_PARANOID(buffer->tsoh);
++	buffer->len = len;
++	buffer->dma_addr = tsoh->dma_addr;
++	buffer->tsoh = tsoh;
++
++	++tx_queue->insert_count;
++}
++
++
++/* Remove descriptors put into a tx_queue. */
++static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
++{
++	struct efx_tx_buffer *buffer;
++
++	/* Work backwards until we hit the original insert pointer value */
++	while (tx_queue->insert_count != tx_queue->write_count) {
++		--tx_queue->insert_count;
++		buffer = &tx_queue->buffer[tx_queue->insert_count &
++					   tx_queue->efx->type->txd_ring_mask];
++		efx_tsoh_free(tx_queue, buffer);
++		EFX_BUG_ON_PARANOID(buffer->skb);
++		buffer->len = 0;
++		buffer->continuation = 1;
++		if (buffer->unmap_len) {
++			pci_unmap_page(tx_queue->efx->pci_dev,
++				       buffer->unmap_addr,
++				       buffer->unmap_len, PCI_DMA_TODEVICE);
++			buffer->unmap_len = 0;
++		}
++	}
++}
++
++
++/* Parse the SKB header and initialise state. */
++static inline void tso_start(struct tso_state *st, const struct sk_buff *skb)
++{
++	/* All ethernet/IP/TCP headers combined size is TCP header size
++	 * plus offset of TCP header relative to start of packet.
++	 */
++	st->p.header_length = ((tcp_hdr(skb)->doff << 2u)
++			       + PTR_DIFF(tcp_hdr(skb), skb->data));
++	st->p.full_packet_size = (st->p.header_length
++				  + skb_shinfo(skb)->gso_size);
++
++	st->p.ipv4_id = ntohs(ip_hdr(skb)->id);
++	st->seqnum = ntohl(tcp_hdr(skb)->seq);
++
++	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg);
++	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn);
++	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst);
++
++	st->packet_space = st->p.full_packet_size;
++	st->remaining_len = skb->len - st->p.header_length;
++}
++
++
++/**
++ * tso_get_fragment - record fragment details and map for DMA
++ * @st:			TSO state
++ * @efx:		Efx NIC
++ * @data:		Pointer to fragment data
++ * @len:		Length of fragment
++ *
++ * Record fragment details and map for DMA.  Return 0 on success, or
++ * -%ENOMEM if DMA mapping fails.
++ */
++static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx,
++				   int len, struct page *page, int page_off)
++{
++
++	st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off,
++					  len, PCI_DMA_TODEVICE);
++	if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) {
++		st->ifc.unmap_len = len;
++		st->ifc.len = len;
++		st->ifc.dma_addr = st->ifc.unmap_addr;
++		st->ifc.page = page;
++		st->ifc.page_off = page_off;
++		return 0;
++	}
++	return -ENOMEM;
++}
++
++
++/**
++ * tso_fill_packet_with_fragment - form descriptors for the current fragment
++ * @tx_queue:		Efx TX queue
++ * @skb:		Socket buffer
++ * @st:			TSO state
++ *
++ * Form descriptors for the current fragment, until we reach the end
++ * of fragment or end-of-packet.  Return 0 on success, 1 if not enough
++ * space in @tx_queue.
++ */
++static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue,
++						const struct sk_buff *skb,
++						struct tso_state *st)
++{
++
++	int n, end_of_packet, rc;
++
++	if (st->ifc.len == 0)
++		return 0;
++	if (st->packet_space == 0)
++		return 0;
++
++	EFX_BUG_ON_PARANOID(st->ifc.len <= 0);
++	EFX_BUG_ON_PARANOID(st->packet_space <= 0);
++
++	n = min(st->ifc.len, st->packet_space);
++
++	st->packet_space -= n;
++	st->remaining_len -= n;
++	st->ifc.len -= n;
++	st->ifc.page_off += n;
++	end_of_packet = st->remaining_len == 0 || st->packet_space == 0;
++
++	rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n,
++				 st->remaining_len ? NULL : skb,
++				 end_of_packet, st->ifc.unmap_addr,
++				 st->ifc.len ? 0 : st->ifc.unmap_len);
++
++	st->ifc.dma_addr += n;
++
++	return rc;
++}
++
++
++/**
++ * tso_start_new_packet - generate a new header and prepare for the new packet
++ * @tx_queue:		Efx TX queue
++ * @skb:		Socket buffer
++ * @st:			TSO state
++ *
++ * Generate a new header and prepare for the new packet.  Return 0 on
++ * success, or -1 if failed to alloc header.
++ */
++static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
++				       const struct sk_buff *skb,
++				       struct tso_state *st)
++{
++	struct efx_tso_header *tsoh;
++	struct iphdr *tsoh_iph;
++	struct tcphdr *tsoh_th;
++	unsigned ip_length;
++	u8 *header;
++
++	/* Allocate a DMA-mapped header buffer. */
++	if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) {
++		if (tx_queue->tso_headers_free == NULL)
++			if (efx_tsoh_block_alloc(tx_queue))
++				return -1;
++		EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free);
++		tsoh = tx_queue->tso_headers_free;
++		tx_queue->tso_headers_free = tsoh->next;
++		tsoh->unmap_len = 0;
++	} else {
++		tx_queue->tso_long_headers++;
++		tsoh = efx_tsoh_heap_alloc(tx_queue, st->p.header_length);
++		if (unlikely(!tsoh))
++			return -1;
++	}
++
++	header = TSOH_BUFFER(tsoh);
++	tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb));
++	tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb));
++
++	/* Copy and update the headers. */
++	memcpy(header, skb->data, st->p.header_length);
++
++	tsoh_th->seq = htonl(st->seqnum);
++	st->seqnum += skb_shinfo(skb)->gso_size;
++	if (st->remaining_len > skb_shinfo(skb)->gso_size) {
++		/* This packet will not finish the TSO burst. */
++		ip_length = st->p.full_packet_size - ETH_HDR_LEN(skb);
++		tsoh_th->fin = 0;
++		tsoh_th->psh = 0;
++	} else {
++		/* This packet will be the last in the TSO burst. */
++		ip_length = (st->p.header_length - ETH_HDR_LEN(skb)
++			     + st->remaining_len);
++		tsoh_th->fin = tcp_hdr(skb)->fin;
++		tsoh_th->psh = tcp_hdr(skb)->psh;
++	}
++	tsoh_iph->tot_len = htons(ip_length);
++
++	/* Linux leaves suitable gaps in the IP ID space for us to fill. */
++	tsoh_iph->id = htons(st->p.ipv4_id);
++	st->p.ipv4_id++;
++
++	st->packet_space = skb_shinfo(skb)->gso_size;
++	++tx_queue->tso_packets;
++
++	/* Form a descriptor for this header. */
++	efx_tso_put_header(tx_queue, tsoh, st->p.header_length);
++
++	return 0;
++}
++
++
++/**
++ * efx_enqueue_skb_tso - segment and transmit a TSO socket buffer
++ * @tx_queue:		Efx TX queue
++ * @skb:		Socket buffer
++ *
++ * Context: You must hold netif_tx_lock() to call this function.
++ *
++ * Add socket buffer @skb to @tx_queue, doing TSO or return != 0 if
++ * @skb was not enqueued.  In all cases @skb is consumed.  Return
++ * %NETDEV_TX_OK or %NETDEV_TX_BUSY.
++ */
++static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
++			       const struct sk_buff *skb)
++{
++	int frag_i, rc, rc2 = NETDEV_TX_OK;
++	struct tso_state state;
++	skb_frag_t *f;
++
++	/* Verify TSO is safe - these checks should never fail. */
++	efx_tso_check_safe(skb);
++
++	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
++
++	tso_start(&state, skb);
++
++	/* Assume that skb header area contains exactly the headers, and
++	 * all payload is in the frag list.
++	 */
++	if (skb_headlen(skb) == state.p.header_length) {
++		/* Grab the first payload fragment. */
++		EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1);
++		frag_i = 0;
++		f = &skb_shinfo(skb)->frags[frag_i];
++		rc = tso_get_fragment(&state, tx_queue->efx,
++				      f->size, f->page, f->page_offset);
++		if (rc)
++			goto mem_err;
++	} else {
++		/* It may look like this code fragment assumes that the
++		 * skb->data portion does not cross a page boundary, but
++		 * that is not the case.  It is guaranteed to be direct
++		 * mapped memory, and therefore is physically contiguous,
++		 * and so DMA will work fine.  kmap_atomic() on this region
++		 * will just return the direct mapping, so that will work
++		 * too.
++		 */
++		int page_off = (unsigned long)skb->data & (PAGE_SIZE - 1);
++		int hl = state.p.header_length;
++		rc = tso_get_fragment(&state, tx_queue->efx,
++				      skb_headlen(skb) - hl,
++				      virt_to_page(skb->data), page_off + hl);
++		if (rc)
++			goto mem_err;
++		frag_i = -1;
++	}
++
++	if (tso_start_new_packet(tx_queue, skb, &state) < 0)
++		goto mem_err;
++
++	while (1) {
++		rc = tso_fill_packet_with_fragment(tx_queue, skb, &state);
++		if (unlikely(rc))
++			goto stop;
++
++		/* Move onto the next fragment? */
++		if (state.ifc.len == 0) {
++			if (++frag_i >= skb_shinfo(skb)->nr_frags)
++				/* End of payload reached. */
++				break;
++			f = &skb_shinfo(skb)->frags[frag_i];
++			rc = tso_get_fragment(&state, tx_queue->efx,
++					      f->size, f->page, f->page_offset);
++			if (rc)
++				goto mem_err;
++		}
++
++		/* Start at new packet? */
++		if (state.packet_space == 0 &&
++		    tso_start_new_packet(tx_queue, skb, &state) < 0)
++			goto mem_err;
++	}
++
++	/* Pass off to hardware */
++	falcon_push_buffers(tx_queue);
++
++	tx_queue->tso_bursts++;
++	return NETDEV_TX_OK;
++
++ mem_err:
++	EFX_ERR(tx_queue->efx, "Out of memory for TSO headers, or PCI mapping"
++		" error\n");
++	dev_kfree_skb_any((struct sk_buff *)skb);
++	goto unwind;
++
++ stop:
++	rc2 = NETDEV_TX_BUSY;
++
++	/* Stop the queue if it wasn't stopped before. */
++	if (tx_queue->stopped == 1)
++		efx_stop_queue(tx_queue->efx);
++
++ unwind:
++	efx_enqueue_unwind(tx_queue);
++	return rc2;
++}
++
++
++/*
++ * Free up all TSO datastructures associated with tx_queue. This
++ * routine should be called only once the tx_queue is both empty and
++ * will no longer be used.
++ */
++static void efx_fini_tso(struct efx_tx_queue *tx_queue)
++{
++	unsigned i;
++
++	if (tx_queue->buffer)
++		for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i)
++			efx_tsoh_free(tx_queue, &tx_queue->buffer[i]);
++
++	while (tx_queue->tso_headers_free != NULL)
++		efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free,
++				    tx_queue->efx->pci_dev);
++}
+diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
+index 66dd5bf..3b9f9dd 100644
+--- a/drivers/net/sfc/xfp_phy.c
++++ b/drivers/net/sfc/xfp_phy.c
+@@ -24,6 +24,10 @@
+ 			   MDIO_MMDREG_DEVS0_PMAPMD |	\
+ 			   MDIO_MMDREG_DEVS0_PHYXS)
+ 
++#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
++		       (1 << LOOPBACK_PMAPMD) |		\
++		       (1 << LOOPBACK_NETWORK))
++
+ /****************************************************************************/
+ /* Quake-specific MDIO registers */
+ #define MDIO_QUAKE_LED0_REG	(0xD006)
+@@ -35,6 +39,10 @@ void xfp_set_led(struct efx_nic *p, int led, int mode)
+ 			    mode);
+ }
+ 
++struct xfp_phy_data {
++	int tx_disabled;
++};
++
+ #define XFP_MAX_RESET_TIME 500
+ #define XFP_RESET_WAIT 10
+ 
+@@ -72,18 +80,31 @@ static int xfp_reset_phy(struct efx_nic *efx)
+ 
+ static int xfp_phy_init(struct efx_nic *efx)
+ {
++	struct xfp_phy_data *phy_data;
+ 	u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
+ 	int rc;
+ 
++	phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
++	efx->phy_data = (void *) phy_data;
++
+ 	EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
+ 		 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
+ 		 MDIO_ID_REV(devid));
+ 
++	phy_data->tx_disabled = efx->tx_disabled;
++
+ 	rc = xfp_reset_phy(efx);
+ 
+ 	EFX_INFO(efx, "XFP: PHY init %s.\n",
+ 		 rc ? "failed" : "successful");
++	if (rc < 0)
++		goto fail;
+ 
++	return 0;
++
++ fail:
++	kfree(efx->phy_data);
++	efx->phy_data = NULL;
+ 	return rc;
+ }
+ 
+@@ -110,6 +131,16 @@ static int xfp_phy_check_hw(struct efx_nic *efx)
+ 
+ static void xfp_phy_reconfigure(struct efx_nic *efx)
+ {
++	struct xfp_phy_data *phy_data = efx->phy_data;
++
++	/* Reset the PHY when moving from tx off to tx on */
++	if (phy_data->tx_disabled && !efx->tx_disabled)
++		xfp_reset_phy(efx);
++
++	mdio_clause45_transmit_disable(efx);
++	mdio_clause45_phy_reconfigure(efx);
++
++	phy_data->tx_disabled = efx->tx_disabled;
+ 	efx->link_up = xfp_link_ok(efx);
+ 	efx->link_options = GM_LPA_10000FULL;
+ }
+@@ -119,6 +150,10 @@ static void xfp_phy_fini(struct efx_nic *efx)
+ {
+ 	/* Clobber the LED if it was blinking */
+ 	efx->board_info.blink(efx, 0);
++
++	/* Free the context block */
++	kfree(efx->phy_data);
++	efx->phy_data = NULL;
+ }
+ 
+ struct efx_phy_operations falcon_xfp_phy_ops = {
+@@ -129,4 +164,5 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
+ 	.clear_interrupt = xfp_phy_clear_interrupt,
+ 	.reset_xaui      = efx_port_dummy_op_void,
+ 	.mmds            = XFP_REQUIRED_DEVS,
++	.loopbacks       = XFP_LOOPBACKS,
+ };
+diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
+index 7bb3ba9..c0a5eea 100644
+--- a/drivers/net/sky2.h
++++ b/drivers/net/sky2.h
+@@ -1966,13 +1966,13 @@ struct sky2_status_le {
+ struct tx_ring_info {
+ 	struct sk_buff	*skb;
+ 	DECLARE_PCI_UNMAP_ADDR(mapaddr);
+-	DECLARE_PCI_UNMAP_ADDR(maplen);
++	DECLARE_PCI_UNMAP_LEN(maplen);
+ };
+ 
+ struct rx_ring_info {
+ 	struct sk_buff	*skb;
+ 	dma_addr_t	data_addr;
+-	DECLARE_PCI_UNMAP_ADDR(data_size);
++	DECLARE_PCI_UNMAP_LEN(data_size);
+ 	dma_addr_t	frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
+ };
+ 
+diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
+index 8005dd1..d5140ae 100644
+--- a/drivers/net/wan/Kconfig
++++ b/drivers/net/wan/Kconfig
+@@ -150,11 +150,9 @@ config HDLC_FR
+ 
+ config HDLC_PPP
+ 	tristate "Synchronous Point-to-Point Protocol (PPP) support"
+-	depends on HDLC && BROKEN
++	depends on HDLC
+ 	help
+ 	  Generic HDLC driver supporting PPP over WAN connections.
+-	  This module is currently broken and will cause a kernel panic
+-	  when a device configured in PPP mode is activated.
+ 
+ 	  It will be replaced by new PPP implementation in Linux 2.6.26.
+ 
+diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
+index 45ddfc9..b0fce13 100644
+--- a/drivers/net/wan/cosa.c
++++ b/drivers/net/wan/cosa.c
+@@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan)
+ 	d->base_addr = chan->cosa->datareg;
+ 	d->irq = chan->cosa->irq;
+ 	d->dma = chan->cosa->dma;
+-	d->priv = chan;
++	d->ml_priv = chan;
+ 	sppp_attach(&chan->pppdev);
+ 	if (register_netdev(d)) {
+ 		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
+@@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan)
+ 
+ static int cosa_sppp_open(struct net_device *d)
+ {
+-	struct channel_data *chan = d->priv;
++	struct channel_data *chan = d->ml_priv;
+ 	int err;
+ 	unsigned long flags;
+ 
+@@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d)
+ 
+ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct channel_data *chan = dev->priv;
++	struct channel_data *chan = dev->ml_priv;
+ 
+ 	netif_stop_queue(dev);
+ 
+@@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
+ 
+ static void cosa_sppp_timeout(struct net_device *dev)
+ {
+-	struct channel_data *chan = dev->priv;
++	struct channel_data *chan = dev->ml_priv;
+ 
+ 	if (test_bit(RXBIT, &chan->cosa->rxtx)) {
+ 		chan->stats.rx_errors++;
+@@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev)
+ 
+ static int cosa_sppp_close(struct net_device *d)
+ {
+-	struct channel_data *chan = d->priv;
++	struct channel_data *chan = d->ml_priv;
+ 	unsigned long flags;
+ 
+ 	netif_stop_queue(d);
+@@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size)
+ 
+ static struct net_device_stats *cosa_net_stats(struct net_device *dev)
+ {
+-	struct channel_data *chan = dev->priv;
++	struct channel_data *chan = dev->ml_priv;
+ 	return &chan->stats;
+ }
+ 
+@@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr,
+ 	int cmd)
+ {
+ 	int rv;
+-	struct channel_data *chan = dev->priv;
++	struct channel_data *chan = dev->ml_priv;
+ 	rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
+ 	if (rv == -ENOIOCTLCMD) {
+ 		return sppp_do_ioctl(dev, ifr, cmd);
+diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
+index 10396d9..0030833 100644
+--- a/drivers/net/wan/hdlc_ppp.c
++++ b/drivers/net/wan/hdlc_ppp.c
+@@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev)
+ 	int (*old_ioctl)(struct net_device *, struct ifreq *, int);
+ 	int result;
+ 
+-	dev->priv = &state(hdlc)->syncppp_ptr;
++	dev->ml_priv = &state(hdlc)->syncppp_ptr;
+ 	state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
+ 	state(hdlc)->pppdev.dev = dev;
+ 
+diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
+index 83dbc92..f3065d3 100644
+--- a/drivers/net/wan/hostess_sv11.c
++++ b/drivers/net/wan/hostess_sv11.c
+@@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
+  
+ static int hostess_open(struct net_device *d)
+ {
+-	struct sv11_device *sv11=d->priv;
++	struct sv11_device *sv11=d->ml_priv;
+ 	int err = -1;
+ 	
+ 	/*
+@@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d)
+ 
+ static int hostess_close(struct net_device *d)
+ {
+-	struct sv11_device *sv11=d->priv;
++	struct sv11_device *sv11=d->ml_priv;
+ 	/*
+ 	 *	Discard new frames
+ 	 */
+@@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d)
+ 
+ static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
+ {
+-	/* struct sv11_device *sv11=d->priv;
++	/* struct sv11_device *sv11=d->ml_priv;
+ 	   z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
+ 	return sppp_do_ioctl(d, ifr,cmd);
+ }
+ 
+ static struct net_device_stats *hostess_get_stats(struct net_device *d)
+ {
+-	struct sv11_device *sv11=d->priv;
++	struct sv11_device *sv11=d->ml_priv;
+ 	if(sv11)
+ 		return z8530_get_stats(&sv11->sync.chanA);
+ 	else
+@@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d)
+  
+ static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
+ {
+-	struct sv11_device *sv11=d->priv;
++	struct sv11_device *sv11=d->ml_priv;
+ 	return z8530_queue_xmit(&sv11->sync.chanA, skb);
+ }
+ 
+@@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
+ 		/* 
+ 		 *	Initialise the PPP components
+ 		 */
++		d->ml_priv = sv;
+ 		sppp_attach(&sv->netdev);
+ 		
+ 		/*
+@@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
+ 		
+ 		d->base_addr = iobase;
+ 		d->irq = irq;
+-		d->priv = sv;
+ 		
+ 		if(register_netdev(d))
+ 		{
+diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
+index 6635ece..62133ce 100644
+--- a/drivers/net/wan/lmc/lmc_main.c
++++ b/drivers/net/wan/lmc/lmc_main.c
+@@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
+ 
+     /* Initialize the sppp layer */
+     /* An ioctl can cause a subsequent detach for raw frame interface */
++    dev->ml_priv = sc;
+     sc->if_type = LMC_PPP;
+     sc->check = 0xBEAFCAFE;
+     dev->base_addr = pci_resource_start(pdev, 0);
+diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
+index 11276bf..44a89df 100644
+--- a/drivers/net/wan/sealevel.c
++++ b/drivers/net/wan/sealevel.c
+@@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq)
+ 		return NULL;
+ 
+ 	sv = d->priv;
++	d->ml_priv = sv;
+ 	sv->if_ptr = &sv->pppdev;
+ 	sv->pppdev.dev = d;
+ 	d->base_addr = iobase;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
+index d340683..62a3d8f 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -666,7 +666,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
+ 	rx_status.flag = 0;
+ 	rx_status.mactime = le64_to_cpu(rx_end->timestamp);
+ 	rx_status.freq =
+-		ieee80211_frequency_to_channel(le16_to_cpu(rx_hdr->channel));
++		ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
+ 	rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+ 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ 
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+index b608e1c..c9847b1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+@@ -163,8 +163,8 @@ struct iwl4965_lq_sta {
+ 	struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
+ #endif
+ 	struct iwl4965_rate dbg_fixed;
+-	struct iwl_priv *drv;
+ #endif
++	struct iwl_priv *drv;
+ };
+ 
+ static void rs_rate_scale_perform(struct iwl_priv *priv,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
+index 17f629f..bf19eb8 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -3978,7 +3978,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
+ 
+ 	rx_status.mactime = le64_to_cpu(rx_start->timestamp);
+ 	rx_status.freq =
+-		ieee80211_frequency_to_channel(le16_to_cpu(rx_start->channel));
++		ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
+ 	rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+ 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ 	rx_status.rate_idx =
+diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
+index 04c2638..9196825 100644
+--- a/drivers/net/wireless/prism54/islpci_dev.c
++++ b/drivers/net/wireless/prism54/islpci_dev.c
+@@ -388,8 +388,15 @@ islpci_open(struct net_device *ndev)
+ 
+ 	netif_start_queue(ndev);
+ 
+-	/* Turn off carrier unless we know we have associated */
+-	netif_carrier_off(ndev);
++	/* Turn off carrier if in STA or Ad-hoc mode. It will be turned on
++	 * once the firmware receives a trap of being associated
++	 * (GEN_OID_LINKSTATE). In other modes (AP or WDS or monitor) we
++	 * should just leave the carrier on as its expected the firmware
++	 * won't send us a trigger. */
++	if (priv->iw_mode == IW_MODE_INFRA || priv->iw_mode == IW_MODE_ADHOC)
++		netif_carrier_off(ndev);
++	else
++		netif_carrier_on(ndev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
+index 8d8657f..b22c027 100644
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1032,8 +1032,10 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
+ 	 * Initialize the device.
+ 	 */
+ 	status = rt2x00dev->ops->lib->initialize(rt2x00dev);
+-	if (status)
+-		goto exit;
++	if (status) {
++		rt2x00queue_uninitialize(rt2x00dev);
++		return status;
++	}
+ 
+ 	__set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags);
+ 
+@@ -1043,11 +1045,6 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
+ 	rt2x00rfkill_register(rt2x00dev);
+ 
+ 	return 0;
+-
+-exit:
+-	rt2x00lib_uninitialize(rt2x00dev);
+-
+-	return status;
+ }
+ 
+ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
+diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
+index 7867ec6..971af25 100644
+--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
+@@ -314,13 +314,14 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
+ 	if (status) {
+ 		ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
+ 		      pci_dev->irq, status);
+-		return status;
++		goto exit;
+ 	}
+ 
+ 	return 0;
+ 
+ exit:
+-	rt2x00pci_uninitialize(rt2x00dev);
++	queue_for_each(rt2x00dev, queue)
++		rt2x00pci_free_queue_dma(rt2x00dev, queue);
+ 
+ 	return status;
+ }
+diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
+index ae12dcd..14bc7b2 100644
+--- a/drivers/net/wireless/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/rt2x00/rt61pci.c
+@@ -2366,6 +2366,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+ {
+ 	struct rt2x00_dev *rt2x00dev = hw->priv;
+ 	struct rt2x00_intf *intf = vif_to_intf(control->vif);
++	struct queue_entry_priv_pci_tx *priv_tx;
+ 	struct skb_frame_desc *skbdesc;
+ 	unsigned int beacon_base;
+ 	u32 reg;
+@@ -2373,21 +2374,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+ 	if (unlikely(!intf->beacon))
+ 		return -ENOBUFS;
+ 
+-	/*
+-	 * We need to append the descriptor in front of the
+-	 * beacon frame.
+-	 */
+-	if (skb_headroom(skb) < intf->beacon->queue->desc_size) {
+-		if (pskb_expand_head(skb, intf->beacon->queue->desc_size,
+-				     0, GFP_ATOMIC))
+-			return -ENOMEM;
+-	}
+-
+-	/*
+-	 * Add the descriptor in front of the skb.
+-	 */
+-	skb_push(skb, intf->beacon->queue->desc_size);
+-	memset(skb->data, 0, intf->beacon->queue->desc_size);
++	priv_tx = intf->beacon->priv_data;
++	memset(priv_tx->desc, 0, intf->beacon->queue->desc_size);
+ 
+ 	/*
+ 	 * Fill in skb descriptor
+@@ -2395,9 +2383,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+ 	skbdesc = get_skb_frame_desc(skb);
+ 	memset(skbdesc, 0, sizeof(*skbdesc));
+ 	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
+-	skbdesc->data = skb->data + intf->beacon->queue->desc_size;
+-	skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
+-	skbdesc->desc = skb->data;
++	skbdesc->data = skb->data;
++	skbdesc->data_len = skb->len;
++	skbdesc->desc = priv_tx->desc;
+ 	skbdesc->desc_len = intf->beacon->queue->desc_size;
+ 	skbdesc->entry = intf->beacon;
+ 
+@@ -2425,7 +2413,10 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+ 	 */
+ 	beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
+ 	rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
+-				      skb->data, skb->len);
++				      skbdesc->desc, skbdesc->desc_len);
++	rt2x00pci_register_multiwrite(rt2x00dev,
++				      beacon_base + skbdesc->desc_len,
++				      skbdesc->data, skbdesc->data_len);
+ 	rt61pci_kick_tx_queue(rt2x00dev, control->queue);
+ 
+ 	return 0;
+@@ -2490,7 +2481,7 @@ static const struct data_queue_desc rt61pci_queue_tx = {
+ 
+ static const struct data_queue_desc rt61pci_queue_bcn = {
+ 	.entry_num		= 4 * BEACON_ENTRIES,
+-	.data_size		= MGMT_FRAME_SIZE,
++	.data_size		= 0, /* No DMA required for beacons */
+ 	.desc_size		= TXINFO_SIZE,
+ 	.priv_size		= sizeof(struct queue_entry_priv_pci_tx),
+ };
+diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
+index 5dd23c9..883af89 100644
+--- a/drivers/net/wireless/strip.c
++++ b/drivers/net/wireless/strip.c
+@@ -2611,7 +2611,7 @@ static int strip_open(struct tty_struct *tty)
+ 	 * We need a write method.
+ 	 */
+ 
+-	if (tty->ops->write == NULL)
++	if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
+ 		return -EOPNOTSUPP;
+ 
+ 	/*
+diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
+index 03384a4..49ae970 100644
+--- a/drivers/net/wireless/wavelan.c
++++ b/drivers/net/wireless/wavelan.c
+@@ -908,9 +908,9 @@ static void wv_psa_show(psa_t * p)
+ 	     p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
+ 	     p->psa_call_code[6], p->psa_call_code[7]);
+ #ifdef DEBUG_SHOW_UNUSED
+-	printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
++	printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
+ 	       p->psa_reserved[0],
+-	       p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]);
++	       p->psa_reserved[1]);
+ #endif				/* DEBUG_SHOW_UNUSED */
+ 	printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
+ 	printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
+diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
+index baf7401..b584c0e 100644
+--- a/drivers/net/wireless/wavelan_cs.c
++++ b/drivers/net/wireless/wavelan_cs.c
+@@ -1074,11 +1074,9 @@ wv_psa_show(psa_t *	p)
+ 	 p->psa_call_code[6],
+ 	 p->psa_call_code[7]);
+ #ifdef DEBUG_SHOW_UNUSED
+-  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
++  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
+ 	 p->psa_reserved[0],
+-	 p->psa_reserved[1],
+-	 p->psa_reserved[2],
+-	 p->psa_reserved[3]);
++	 p->psa_reserved[1]);
+ #endif	/* DEBUG_SHOW_UNUSED */
+   printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
+   printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
+diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
+index 5316074..12e24f0 100644
+--- a/drivers/net/wireless/zd1211rw/zd_usb.c
++++ b/drivers/net/wireless/zd1211rw/zd_usb.c
+@@ -889,9 +889,13 @@ static void tx_urb_complete(struct urb *urb)
+ 	}
+ free_urb:
+ 	skb = (struct sk_buff *)urb->context;
+-	zd_mac_tx_to_dev(skb, urb->status);
++	/*
++	 * grab 'usb' pointer before handing off the skb (since
++	 * it might be freed by zd_mac_tx_to_dev or mac80211)
++	 */
+ 	cb = (struct zd_tx_skb_control_block *)skb->cb;
+ 	usb = &zd_hw_mac(cb->hw)->chip.usb;
++	zd_mac_tx_to_dev(skb, urb->status);
+ 	free_tx_urb(usb, urb);
+ 	tx_dec_submitted_urbs(usb);
+ 	return;
+diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
+index efcbf4b..2450b3a 100644
+--- a/drivers/oprofile/cpu_buffer.c
++++ b/drivers/oprofile/cpu_buffer.c
+@@ -27,7 +27,7 @@
+ #include "buffer_sync.h"
+ #include "oprof.h"
+ 
+-DEFINE_PER_CPU_SHARED_ALIGNED(struct oprofile_cpu_buffer, cpu_buffer);
++DEFINE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
+ 
+ static void wq_sync_buffer(struct work_struct *work);
+ 
+diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
+index 1358817..c3e366b 100644
+--- a/drivers/oprofile/cpu_buffer.h
++++ b/drivers/oprofile/cpu_buffer.h
+@@ -46,7 +46,7 @@ struct oprofile_cpu_buffer {
+ 	unsigned long sample_invalid_eip;
+ 	int cpu;
+ 	struct delayed_work work;
+-} ____cacheline_aligned;
++};
+ 
+ DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
+ 
+diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
+index 1fd8bb7..66c0fd2 100644
+--- a/drivers/pci/intel-iommu.c
++++ b/drivers/pci/intel-iommu.c
+@@ -49,7 +49,7 @@
+ 
+ #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+ 
+-#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
++#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
+ 
+ #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
+ 
+@@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu)
+ 
+ #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
+ {\
+-	unsigned long start_time = jiffies;\
++	cycles_t start_time = get_cycles();\
+ 	while (1) {\
+ 		sts = op (iommu->reg + offset);\
+ 		if (cond)\
+ 			break;\
+-		if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
++		if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
+ 			panic("DMAR hardware is malfunctioning\n");\
+ 		cpu_relax();\
+ 	}\
+diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
+index 72f7476..9d6fc8e 100644
+--- a/drivers/pci/pci-acpi.c
++++ b/drivers/pci/pci-acpi.c
+@@ -19,8 +19,31 @@
+ #include <linux/pci-acpi.h>
+ #include "pci.h"
+ 
+-static u32 ctrlset_buf[3] = {0, 0, 0};
+-static u32 global_ctrlsets = 0;
++struct acpi_osc_data {
++	acpi_handle handle;
++	u32 ctrlset_buf[3];
++	u32 global_ctrlsets;
++	struct list_head sibiling;
++};
++static LIST_HEAD(acpi_osc_data_list);
++
++static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
++{
++	struct acpi_osc_data *data;
++
++	list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
++		if (data->handle == handle)
++			return data;
++	}
++	data = kzalloc(sizeof(*data), GFP_KERNEL);
++	if (!data)
++		return NULL;
++	INIT_LIST_HEAD(&data->sibiling);
++	data->handle = handle;
++	list_add_tail(&data->sibiling, &acpi_osc_data_list);
++	return data;
++}
++
+ static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+ 
+ static acpi_status  
+@@ -37,8 +60,27 @@ acpi_query_osc (
+ 	union acpi_object 	*out_obj;
+ 	u32			osc_dw0;
+ 	acpi_status *ret_status = (acpi_status *)retval;
++	struct acpi_osc_data *osc_data;
++	u32 flags = (unsigned long)context, temp;
++	acpi_handle tmp;
++
++	status = acpi_get_handle(handle, "_OSC", &tmp);
++	if (ACPI_FAILURE(status))
++		return status;
++
++	osc_data = acpi_get_osc_data(handle);
++	if (!osc_data) {
++		printk(KERN_ERR "acpi osc data array is full\n");
++		return AE_ERROR;
++	}
++
++	osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
++
++	/* do _OSC query for all possible controls */
++	temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE];
++	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
++	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+ 
+-	
+ 	/* Setting up input parameters */
+ 	input.count = 4;
+ 	input.pointer = in_params;
+@@ -51,13 +93,11 @@ acpi_query_osc (
+ 	in_params[2].integer.value	= 3;
+ 	in_params[3].type		= ACPI_TYPE_BUFFER;
+ 	in_params[3].buffer.length 	= 12;
+-	in_params[3].buffer.pointer 	= (u8 *)context;
++	in_params[3].buffer.pointer 	= (u8 *)osc_data->ctrlset_buf;
+ 
+ 	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+-	if (ACPI_FAILURE (status)) {
+-		*ret_status = status;
+-		return status;
+-	}
++	if (ACPI_FAILURE(status))
++		goto out_nofree;
+ 	out_obj = output.pointer;
+ 
+ 	if (out_obj->type != ACPI_TYPE_BUFFER) {
+@@ -76,7 +116,8 @@ acpi_query_osc (
+ 			printk(KERN_DEBUG "_OSC invalid revision\n"); 
+ 		if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
+ 			/* Update Global Control Set */
+-			global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
++			osc_data->global_ctrlsets =
++				*((u32 *)(out_obj->buffer.pointer + 8));
+ 			status = AE_OK;
+ 			goto query_osc_out;
+ 		}
+@@ -85,12 +126,21 @@ acpi_query_osc (
+ 	}
+ 
+ 	/* Update Global Control Set */
+-	global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
++	osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
+ 	status = AE_OK;
+ 
+ query_osc_out:
+ 	kfree(output.pointer);
++out_nofree:
+ 	*ret_status = status;
++
++	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
++	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp;
++	if (ACPI_FAILURE(status)) {
++		/* no osc support at all */
++		osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
++	}
++
+ 	return status;
+ }
+ 
+@@ -165,28 +215,15 @@ run_osc_out:
+  **/
+ acpi_status __pci_osc_support_set(u32 flags, const char *hid)
+ {
+-	u32 temp;
+-	acpi_status retval;
++	acpi_status retval = AE_NOT_FOUND;
+ 
+ 	if (!(flags & OSC_SUPPORT_MASKS)) {
+ 		return AE_TYPE;
+ 	}
+-	ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
+-
+-	/* do _OSC query for all possible controls */
+-	temp = ctrlset_buf[OSC_CONTROL_TYPE];
+-	ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+-	ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+ 	acpi_get_devices(hid,
+ 			acpi_query_osc,
+-			ctrlset_buf,
++			(void *)(unsigned long)flags,
+ 			(void **) &retval );
+-	ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
+-	ctrlset_buf[OSC_CONTROL_TYPE] = temp;
+-	if (ACPI_FAILURE(retval)) {
+-		/* no osc support at all */
+-		ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
+-	}
+ 	return AE_OK;
+ }
+ 
+@@ -201,19 +238,31 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
+ {
+ 	acpi_status	status;
+ 	u32		ctrlset;
++	acpi_handle tmp;
++	struct acpi_osc_data *osc_data;
++
++	status = acpi_get_handle(handle, "_OSC", &tmp);
++	if (ACPI_FAILURE(status))
++		return status;
++
++	osc_data = acpi_get_osc_data(handle);
++	if (!osc_data) {
++		printk(KERN_ERR "acpi osc data array is full\n");
++		return AE_ERROR;
++	}
+ 
+ 	ctrlset = (flags & OSC_CONTROL_MASKS);
+ 	if (!ctrlset) {
+ 		return AE_TYPE;
+ 	}
+-	if (ctrlset_buf[OSC_SUPPORT_TYPE] && 
+-	 	((global_ctrlsets & ctrlset) != ctrlset)) {
++	if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] &&
++		((osc_data->global_ctrlsets & ctrlset) != ctrlset)) {
+ 		return AE_SUPPORT;
+ 	}
+-	ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
+-	status = acpi_run_osc(handle, ctrlset_buf);
++	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
++	status = acpi_run_osc(handle, osc_data->ctrlset_buf);
+ 	if (ACPI_FAILURE (status)) {
+-		ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
++		osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
+ 	}
+ 	
+ 	return status;
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index afd914e..f2d9c77 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1826,6 +1826,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+ 	}
+ }
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+ 
+ static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
+ {
+diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
+index 4fe7c58..886dac8 100644
+--- a/drivers/pnp/base.h
++++ b/drivers/pnp/base.h
+@@ -19,6 +19,7 @@ void pnp_remove_card(struct pnp_card *card);
+ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
+ void pnp_remove_card_device(struct pnp_dev *dev);
+ 
++struct pnp_option *pnp_build_option(int priority);
+ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
+ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
+ 						 int priority);
+diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
+index 5d9301d..5695a79 100644
+--- a/drivers/pnp/interface.c
++++ b/drivers/pnp/interface.c
+@@ -424,7 +424,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
+ 				start = simple_strtoul(buf, &buf, 0);
+ 				pnp_res = pnp_add_irq_resource(dev, start, 0);
+ 				if (pnp_res)
+-					nirq++;
++					pnp_res->index = nirq++;
+ 				continue;
+ 			}
+ 			if (!strnicmp(buf, "dma", 3)) {
+diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
+index d049a22..ffdb12a 100644
+--- a/drivers/pnp/quirks.c
++++ b/drivers/pnp/quirks.c
+@@ -111,6 +111,113 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
+ 		dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
+ }
+ 
++static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
++{
++	struct pnp_option *head = NULL;
++	struct pnp_option *prev = NULL;
++	struct pnp_option *res;
++
++	/*
++	 * Build a functional IRQ-less variant of each MPU option.
++	 */
++
++	for (res = dev->dependent; res; res = res->next) {
++		struct pnp_option *curr;
++		struct pnp_port *port;
++		struct pnp_port *copy;
++
++		port = res->port;
++		if (!port || !res->irq)
++			continue;
++
++		copy = pnp_alloc(sizeof *copy);
++		if (!copy)
++			break;
++
++		copy->min = port->min;
++		copy->max = port->max;
++		copy->align = port->align;
++		copy->size = port->size;
++		copy->flags = port->flags;
++
++		curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
++		if (!curr) {
++			kfree(copy);
++			break;
++		}
++		curr->port = copy;
++
++		if (prev)
++			prev->next = curr;
++		else
++			head = curr;
++		prev = curr;
++	}
++	if (head)
++		dev_info(&dev->dev, "adding IRQ-less MPU options\n");
++
++	return head;
++}
++
++static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
++{
++	struct pnp_option *res;
++	struct pnp_irq *irq;
++
++	/*
++	 * Distribute the independent IRQ over the dependent options
++	 */
++
++	res = dev->independent;
++	if (!res)
++		return;
++
++	irq = res->irq;
++	if (!irq || irq->next)
++		return;
++
++	res = dev->dependent;
++	if (!res)
++		return;
++
++	while (1) {
++		struct pnp_irq *copy;
++
++		copy = pnp_alloc(sizeof *copy);
++		if (!copy)
++			break;
++
++		memcpy(copy->map, irq->map, sizeof copy->map);
++		copy->flags = irq->flags;
++
++		copy->next = res->irq; /* Yes, this is NULL */
++		res->irq = copy;
++
++		if (!res->next)
++			break;
++		res = res->next;
++	}
++	kfree(irq);
++
++	res->next = quirk_isapnp_mpu_options(dev);
++
++	res = dev->independent;
++	res->irq = NULL;
++}
++
++static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
++{
++	struct pnp_option *res;
++
++	res = dev->dependent;
++	if (!res)
++		return;
++
++	while (res->next)
++		res = res->next;
++
++	res->next = quirk_isapnp_mpu_options(dev);
++}
+ 
+ #include <linux/pci.h>
+ 
+@@ -205,6 +312,11 @@ static struct pnp_fixup pnp_fixups[] = {
+ 	{"CTL0043", quirk_sb16audio_resources},
+ 	{"CTL0044", quirk_sb16audio_resources},
+ 	{"CTL0045", quirk_sb16audio_resources},
++	/* Add IRQ-less MPU options */
++	{"ADS7151", quirk_ad1815_mpu_resources},
++	{"ADS7181", quirk_isapnp_mpu_resources},
++	{"AZT0002", quirk_isapnp_mpu_resources},
++	/* PnP resources that might overlap PCI BARs */
+ 	{"PNP0c01", quirk_system_pci_resources},
+ 	{"PNP0c02", quirk_system_pci_resources},
+ 	{""}
+@@ -212,20 +324,16 @@ static struct pnp_fixup pnp_fixups[] = {
+ 
+ void pnp_fixup_device(struct pnp_dev *dev)
+ {
+-	int i = 0;
+-	void (*quirk)(struct pnp_dev *);
+-
+-	while (*pnp_fixups[i].id) {
+-		if (compare_pnp_id(dev->id, pnp_fixups[i].id)) {
+-			quirk = pnp_fixups[i].quirk_function;
++	struct pnp_fixup *f;
+ 
++	for (f = pnp_fixups; *f->id; f++) {
++		if (!compare_pnp_id(dev->id, f->id))
++			continue;
+ #ifdef DEBUG
+-			dev_dbg(&dev->dev, "calling ");
+-			print_fn_descriptor_symbol("%s()\n",
+-				(unsigned long) *quirk);
++		dev_dbg(&dev->dev, "%s: calling ", f->id);
++		print_fn_descriptor_symbol("%s\n",
++				(unsigned long) f->quirk_function);
+ #endif
+-			(*quirk)(dev);
+-		}
+-		i++;
++		f->quirk_function(dev);
+ 	}
+ }
+diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
+index 2041620..390b500 100644
+--- a/drivers/pnp/resource.c
++++ b/drivers/pnp/resource.c
+@@ -28,7 +28,7 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 };	/* reserve (don't use) some
+  * option registration
+  */
+ 
+-static struct pnp_option *pnp_build_option(int priority)
++struct pnp_option *pnp_build_option(int priority)
+ {
+ 	struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
+ 
+diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
+index 3eba85e..95b076c 100644
+--- a/drivers/pnp/support.c
++++ b/drivers/pnp/support.c
+@@ -45,10 +45,10 @@ void pnp_eisa_id_to_string(u32 id, char *str)
+ 	str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
+ 	str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
+ 	str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
+-	str[3] = hex_asc((id >> 12) & 0xf);
+-	str[4] = hex_asc((id >>  8) & 0xf);
+-	str[5] = hex_asc((id >>  4) & 0xf);
+-	str[6] = hex_asc((id >>  0) & 0xf);
++	str[3] = hex_asc_hi(id >> 8);
++	str[4] = hex_asc_lo(id >> 8);
++	str[5] = hex_asc_hi(id);
++	str[6] = hex_asc_lo(id);
+ 	str[7] = '\0';
+ }
+ 
+diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
+index ba795a4..9f996ec 100644
+--- a/drivers/rtc/rtc-lib.c
++++ b/drivers/rtc/rtc-lib.c
+@@ -51,7 +51,7 @@ EXPORT_SYMBOL(rtc_year_days);
+  */
+ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
+ {
+-	register int days, month, year;
++	unsigned int days, month, year;
+ 
+ 	days = time / 86400;
+ 	time -= days * 86400;
+diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
+index 316bfaa..a3e0880 100644
+--- a/drivers/rtc/rtc-m41t80.c
++++ b/drivers/rtc/rtc-m41t80.c
+@@ -15,6 +15,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/i2c.h>
+@@ -803,6 +804,7 @@ static int m41t80_probe(struct i2c_client *client,
+ 
+ #ifdef CONFIG_RTC_DRV_M41T80_WDT
+ 	if (clientdata->features & M41T80_FEATURE_HT) {
++		save_client = client;
+ 		rc = misc_register(&wdt_dev);
+ 		if (rc)
+ 			goto exit;
+@@ -811,7 +813,6 @@ static int m41t80_probe(struct i2c_client *client,
+ 			misc_deregister(&wdt_dev);
+ 			goto exit;
+ 		}
+-		save_client = client;
+ 	}
+ #endif
+ 	return 0;
+diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
+index f5215fd..1dca177 100644
+--- a/drivers/scsi/aha152x.c
++++ b/drivers/scsi/aha152x.c
+@@ -3830,7 +3830,7 @@ static int __init aha152x_init(void)
+ 			iounmap(p);
+ 		}
+ 		if (!ok && setup_count == 0)
+-			return 0;
++			return -ENODEV;
+ 
+ 		printk(KERN_INFO "aha152x: BIOS test: passed, ");
+ #else
+@@ -3909,14 +3909,14 @@ static int __init aha152x_init(void)
+ #endif
+ 	}
+ 
+-	return 1;
++	return 0;
+ }
+ 
+ static void __exit aha152x_exit(void)
+ {
+-	struct aha152x_hostdata *hd;
++	struct aha152x_hostdata *hd, *tmp;
+ 
+-	list_for_each_entry(hd, &aha152x_host_list, host_list) {
++	list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
+ 		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
+ 
+ 		aha152x_release(shost);
+diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
+index 8e2e964..46771d4 100644
+--- a/drivers/scsi/gdth.c
++++ b/drivers/scsi/gdth.c
+@@ -550,7 +550,6 @@ static int __init gdth_search_isa(ulong32 bios_adr)
+ #endif /* CONFIG_ISA */
+ 
+ #ifdef CONFIG_PCI
+-static bool gdth_pci_registered;
+ 
+ static bool gdth_search_vortex(ushort device)
+ {
+@@ -3724,6 +3723,8 @@ static void gdth_log_event(gdth_evt_data *dvr, char *buffer)
+ }
+ 
+ #ifdef GDTH_STATISTICS
++static unchar	gdth_timer_running;
++
+ static void gdth_timeout(ulong data)
+ {
+     ulong32 i;
+@@ -3731,7 +3732,10 @@ static void gdth_timeout(ulong data)
+     gdth_ha_str *ha;
+     ulong flags;
+ 
+-    BUG_ON(list_empty(&gdth_instances));
++    if(unlikely(list_empty(&gdth_instances))) {
++	    gdth_timer_running = 0;
++	    return;
++    }
+ 
+     ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
+     spin_lock_irqsave(&ha->smp_lock, flags);
+@@ -3751,6 +3755,22 @@ static void gdth_timeout(ulong data)
+     add_timer(&gdth_timer);
+     spin_unlock_irqrestore(&ha->smp_lock, flags);
+ }
++
++static void gdth_timer_init(void)
++{
++	if (gdth_timer_running)
++		return;
++	gdth_timer_running = 1;
++	TRACE2(("gdth_detect(): Initializing timer !\n"));
++	gdth_timer.expires = jiffies + HZ;
++	gdth_timer.data = 0L;
++	gdth_timer.function = gdth_timeout;
++	add_timer(&gdth_timer);
++}
++#else
++static inline void gdth_timer_init(void)
++{
++}
+ #endif
+ 
+ static void __init internal_setup(char *str,int *ints)
+@@ -4735,6 +4755,7 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios)
+ 	if (error)
+ 		goto out_free_coal_stat;
+ 	list_add_tail(&ha->list, &gdth_instances);
++	gdth_timer_init();
+ 
+ 	scsi_scan_host(shp);
+ 
+@@ -4865,6 +4886,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
+ 	if (error)
+ 		goto out_free_coal_stat;
+ 	list_add_tail(&ha->list, &gdth_instances);
++	gdth_timer_init();
+ 
+ 	scsi_scan_host(shp);
+ 
+@@ -5011,6 +5033,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr,
+ 	list_add_tail(&ha->list, &gdth_instances);
+ 
+ 	pci_set_drvdata(ha->pdev, ha);
++	gdth_timer_init();
+ 
+ 	scsi_scan_host(shp);
+ 
+@@ -5110,6 +5133,7 @@ static int __init gdth_init(void)
+ 	/* initializations */
+ 	gdth_polling = TRUE;
+ 	gdth_clear_events();
++	init_timer(&gdth_timer);
+ 
+ 	/* As default we do not probe for EISA or ISA controllers */
+ 	if (probe_eisa_isa) {
+@@ -5132,23 +5156,17 @@ static int __init gdth_init(void)
+ 
+ #ifdef CONFIG_PCI
+ 	/* scanning for PCI controllers */
+-	if (pci_register_driver(&gdth_pci_driver) == 0)
+-		gdth_pci_registered = true;
++	if (pci_register_driver(&gdth_pci_driver)) {
++		gdth_ha_str *ha;
++
++		list_for_each_entry(ha, &gdth_instances, list)
++			gdth_remove_one(ha);
++		return -ENODEV;
++	}
+ #endif /* CONFIG_PCI */
+ 
+ 	TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
+ 
+-	if (list_empty(&gdth_instances))
+-		return -ENODEV;
+-
+-#ifdef GDTH_STATISTICS
+-	TRACE2(("gdth_detect(): Initializing timer !\n"));
+-	init_timer(&gdth_timer);
+-	gdth_timer.expires = jiffies + HZ;
+-	gdth_timer.data = 0L;
+-	gdth_timer.function = gdth_timeout;
+-	add_timer(&gdth_timer);
+-#endif
+ 	major = register_chrdev(0,"gdth", &gdth_fops);
+ 	register_reboot_notifier(&gdth_notifier);
+ 	gdth_polling = FALSE;
+@@ -5167,8 +5185,7 @@ static void __exit gdth_exit(void)
+ #endif
+ 
+ #ifdef CONFIG_PCI
+-	if (gdth_pci_registered)
+-		pci_unregister_driver(&gdth_pci_driver);
++	pci_unregister_driver(&gdth_pci_driver);
+ #endif
+ 
+ 	list_for_each_entry(ha, &gdth_instances, list)
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index 010c1b9..b43bf1d 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -730,7 +730,9 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ 				if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
+ 						   datalen))
+ 					rc = ISCSI_ERR_CONN_FAILED;
+-			}
++			} else
++				mod_timer(&conn->transport_timer,
++					  jiffies + conn->recv_timeout);
+ 			iscsi_free_mgmt_task(conn, mtask);
+ 			break;
+ 		default:
+@@ -1453,19 +1455,20 @@ static void iscsi_check_transport_timeouts(unsigned long data)
+ {
+ 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
+ 	struct iscsi_session *session = conn->session;
+-	unsigned long timeout, next_timeout = 0, last_recv;
++	unsigned long recv_timeout, next_timeout = 0, last_recv;
+ 
+ 	spin_lock(&session->lock);
+ 	if (session->state != ISCSI_STATE_LOGGED_IN)
+ 		goto done;
+ 
+-	timeout = conn->recv_timeout;
+-	if (!timeout)
++	recv_timeout = conn->recv_timeout;
++	if (!recv_timeout)
+ 		goto done;
+ 
+-	timeout *= HZ;
++	recv_timeout *= HZ;
+ 	last_recv = conn->last_recv;
+-	if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
++	if (conn->ping_mtask &&
++	    time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
+ 			   jiffies)) {
+ 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
+ 				  "expired, last rx %lu, last ping %lu, "
+@@ -1476,15 +1479,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
+ 		return;
+ 	}
+ 
+-	if (time_before_eq(last_recv + timeout, jiffies)) {
+-		if (time_before_eq(conn->last_ping, last_recv)) {
+-			/* send a ping to try to provoke some traffic */
+-			debug_scsi("Sending nopout as ping on conn %p\n", conn);
+-			iscsi_send_nopout(conn, NULL);
+-		}
+-		next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
++	if (time_before_eq(last_recv + recv_timeout, jiffies)) {
++		/* send a ping to try to provoke some traffic */
++		debug_scsi("Sending nopout as ping on conn %p\n", conn);
++		iscsi_send_nopout(conn, NULL);
++		next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
+ 	} else
+-		next_timeout = last_recv + timeout;
++		next_timeout = last_recv + recv_timeout;
+ 
+ 	debug_scsi("Setting next tmo %lu\n", next_timeout);
+ 	mod_timer(&conn->transport_timer, next_timeout);
+diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
+index fa06093..51e2f29 100644
+--- a/drivers/scsi/qla1280.c
++++ b/drivers/scsi/qla1280.c
+@@ -2007,7 +2007,7 @@ qla1280_set_defaults(struct scsi_qla_host *ha)
+ 		nv->bus[bus].config_2.req_ack_active_negation = 1;
+ 		nv->bus[bus].config_2.data_line_active_negation = 1;
+ 		nv->bus[bus].selection_timeout = 250;
+-		nv->bus[bus].max_queue_depth = 256;
++		nv->bus[bus].max_queue_depth = 32;
+ 
+ 		if (IS_ISP1040(ha)) {
+ 			nv->bus[bus].bus_reset_delay = 3;
+@@ -2051,7 +2051,7 @@ qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
+ 	status = qla1280_mailbox_command(ha, 0x0f, mb);
+ 
+ 	/* Save Tag queuing enable flag. */
+-	flag = (BIT_0 << target) & mb[0];
++	flag = (BIT_0 << target);
+ 	if (nv->bus[bus].target[target].parameter.tag_queuing)
+ 		ha->bus_settings[bus].qtag_enables |= flag;
+ 
+diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
+index 36acbcc..62e6eb1 100644
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -976,11 +976,15 @@ config SERIAL_68328_RTS_CTS
+ 	depends on SERIAL_68328
+ 
+ config SERIAL_COLDFIRE
+-	bool "ColdFire serial support"
++	bool "ColdFire serial support (DEPRECATED)"
+ 	depends on COLDFIRE
+ 	help
+ 	  This driver supports the built-in serial ports of the Motorola ColdFire
+ 	  family of CPUs.
++	  This driver is deprecated because it supports only the old interface
++	  for serial drivers and features like magic keys are not working.
++	  Please switch to the new style driver because this driver will be
++	  removed soon.
+ 
+ config SERIAL_MCF
+ 	bool "Coldfire serial support (new style driver)"
+diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
+index f9fa237..3e0366e 100644
+--- a/drivers/serial/crisv10.c
++++ b/drivers/serial/crisv10.c
+@@ -3808,7 +3808,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
+ 
+ 	shutdown(info);
+ 	rs_flush_buffer(tty);
+-	tty_ldisc_flush_buffer(tty);
++	tty_ldisc_flush(tty);
+ 	tty->closing = 0;
+ 	info->event = 0;
+ 	info->tty = 0;
+diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
+index 43af40d..56007cc 100644
+--- a/drivers/serial/mcfserial.c
++++ b/drivers/serial/mcfserial.c
+@@ -1,3 +1,4 @@
++#warning This driver is deprecated. Check Kconfig for details.
+ /*
+  * mcfserial.c -- serial driver for ColdFire internal UARTS.
+  *
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index fae9e8f..66ec5d8 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -126,7 +126,6 @@ config SPI_MPC52xx_PSC
+ config SPI_MPC83xx
+ 	tristate "Freescale MPC83xx/QUICC Engine SPI controller"
+ 	depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
+-	select SPI_BITBANG
+ 	help
+ 	  This enables using the Freescale MPC83xx and QUICC Engine SPI
+ 	  controllers in master mode.
+diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
+index 9072946..681d623 100644
+--- a/drivers/spi/mpc52xx_psc_spi.c
++++ b/drivers/spi/mpc52xx_psc_spi.c
+@@ -1,5 +1,5 @@
+ /*
+- * MPC52xx SPC in SPI mode driver.
++ * MPC52xx PSC in SPI mode driver.
+  *
+  * Maintainer: Dragos Carp
+  *
+diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
+index 654bb58..0c452c4 100644
+--- a/drivers/spi/pxa2xx_spi.c
++++ b/drivers/spi/pxa2xx_spi.c
+@@ -1567,7 +1567,7 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
+ 	int status = 0;
+ 
+ 	/* Enable the SSP clock */
+-	clk_disable(ssp->clk);
++	clk_enable(ssp->clk);
+ 
+ 	/* Start the queue running */
+ 	status = start_queue(drv_data);
+diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
+index 189f706..6832da6 100644
+--- a/drivers/spi/spi_mpc83xx.c
++++ b/drivers/spi/spi_mpc83xx.c
+@@ -49,6 +49,7 @@ struct mpc83xx_spi_reg {
+ #define	SPMODE_LEN(x)		((x) << 20)
+ #define	SPMODE_PM(x)		((x) << 16)
+ #define	SPMODE_OP		(1 << 14)
++#define	SPMODE_CG(x)		((x) << 7)
+ 
+ /*
+  * Default for SPI Mode:
+@@ -67,10 +68,6 @@ struct mpc83xx_spi_reg {
+ 
+ /* SPI Controller driver's private data. */
+ struct mpc83xx_spi {
+-	/* bitbang has to be first */
+-	struct spi_bitbang bitbang;
+-	struct completion done;
+-
+ 	struct mpc83xx_spi_reg __iomem *base;
+ 
+ 	/* rx & tx bufs from the spi_transfer */
+@@ -82,7 +79,7 @@ struct mpc83xx_spi {
+ 	u32(*get_tx) (struct mpc83xx_spi *);
+ 
+ 	unsigned int count;
+-	u32 irq;
++	int irq;
+ 
+ 	unsigned nsecs;		/* (clock cycle time)/2 */
+ 
+@@ -94,6 +91,25 @@ struct mpc83xx_spi {
+ 
+ 	void (*activate_cs) (u8 cs, u8 polarity);
+ 	void (*deactivate_cs) (u8 cs, u8 polarity);
++
++	u8 busy;
++
++	struct workqueue_struct *workqueue;
++	struct work_struct work;
++
++	struct list_head queue;
++	spinlock_t lock;
++
++	struct completion done;
++};
++
++struct spi_mpc83xx_cs {
++	/* functions to deal with different sized buffers */
++	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
++	u32 (*get_tx) (struct mpc83xx_spi *);
++	u32 rx_shift;		/* RX data reg shift when in qe mode */
++	u32 tx_shift;		/* TX data reg shift when in qe mode */
++	u32 hw_mode;		/* Holds HW mode register settings */
+ };
+ 
+ static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
+@@ -137,6 +153,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
+ {
+ 	struct mpc83xx_spi *mpc83xx_spi;
+ 	u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
++	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+ 
+ 	mpc83xx_spi = spi_master_get_devdata(spi->master);
+ 
+@@ -147,50 +164,26 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
+ 
+ 	if (value == BITBANG_CS_ACTIVE) {
+ 		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+-		u32 len = spi->bits_per_word;
+-		u8 pm;
+ 
+-		if (len == 32)
+-			len = 0;
+-		else
+-			len = len - 1;
+-
+-		/* mask out bits we are going to set */
+-		regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
+-				| SPMODE_LEN(0xF) | SPMODE_DIV16
+-				| SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP);
+-
+-		if (spi->mode & SPI_CPHA)
+-			regval |= SPMODE_CP_BEGIN_EDGECLK;
+-		if (spi->mode & SPI_CPOL)
+-			regval |= SPMODE_CI_INACTIVEHIGH;
+-		if (!(spi->mode & SPI_LSB_FIRST))
+-			regval |= SPMODE_REV;
+-		if (spi->mode & SPI_LOOP)
+-			regval |= SPMODE_LOOP;
+-
+-		regval |= SPMODE_LEN(len);
+-
+-		if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) {
+-			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1;
+-			if (pm > 0x0f) {
+-				dev_err(&spi->dev, "Requested speed is too "
+-					"low: %d Hz. Will use %d Hz instead.\n",
+-					spi->max_speed_hz,
+-					mpc83xx_spi->spibrg / 1024);
+-				pm = 0x0f;
+-			}
+-			regval |= SPMODE_PM(pm) | SPMODE_DIV16;
+-		} else {
+-			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4);
+-			if (pm)
+-				pm--;
+-			regval |= SPMODE_PM(pm);
++		mpc83xx_spi->rx_shift = cs->rx_shift;
++		mpc83xx_spi->tx_shift = cs->tx_shift;
++		mpc83xx_spi->get_rx = cs->get_rx;
++		mpc83xx_spi->get_tx = cs->get_tx;
++
++		if (cs->hw_mode != regval) {
++			unsigned long flags;
++			void *tmp_ptr = &mpc83xx_spi->base->mode;
++
++			regval = cs->hw_mode;
++			/* Turn off IRQs locally to minimize time that
++			 * SPI is disabled
++			 */
++			local_irq_save(flags);
++			/* Turn off SPI unit prior changing mode */
++			mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
++			mpc83xx_spi_write_reg(tmp_ptr, regval);
++			local_irq_restore(flags);
+ 		}
+-
+-		/* Turn off SPI unit prior changing mode */
+-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
+-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+ 		if (mpc83xx_spi->activate_cs)
+ 			mpc83xx_spi->activate_cs(spi->chip_select, pol);
+ 	}
+@@ -201,8 +194,9 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+ {
+ 	struct mpc83xx_spi *mpc83xx_spi;
+ 	u32 regval;
+-	u8 bits_per_word;
++	u8 bits_per_word, pm;
+ 	u32 hz;
++	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+ 
+ 	mpc83xx_spi = spi_master_get_devdata(spi->master);
+ 
+@@ -223,61 +217,191 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+ 	    || ((bits_per_word > 16) && (bits_per_word != 32)))
+ 		return -EINVAL;
+ 
+-	mpc83xx_spi->rx_shift = 0;
+-	mpc83xx_spi->tx_shift = 0;
++	if (!hz)
++		hz = spi->max_speed_hz;
++
++	cs->rx_shift = 0;
++	cs->tx_shift = 0;
+ 	if (bits_per_word <= 8) {
+-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
+-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
++		cs->get_rx = mpc83xx_spi_rx_buf_u8;
++		cs->get_tx = mpc83xx_spi_tx_buf_u8;
+ 		if (mpc83xx_spi->qe_mode) {
+-			mpc83xx_spi->rx_shift = 16;
+-			mpc83xx_spi->tx_shift = 24;
++			cs->rx_shift = 16;
++			cs->tx_shift = 24;
+ 		}
+ 	} else if (bits_per_word <= 16) {
+-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
+-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
++		cs->get_rx = mpc83xx_spi_rx_buf_u16;
++		cs->get_tx = mpc83xx_spi_tx_buf_u16;
+ 		if (mpc83xx_spi->qe_mode) {
+-			mpc83xx_spi->rx_shift = 16;
+-			mpc83xx_spi->tx_shift = 16;
++			cs->rx_shift = 16;
++			cs->tx_shift = 16;
+ 		}
+ 	} else if (bits_per_word <= 32) {
+-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
+-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
++		cs->get_rx = mpc83xx_spi_rx_buf_u32;
++		cs->get_tx = mpc83xx_spi_tx_buf_u32;
+ 	} else
+ 		return -EINVAL;
+ 
+ 	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
+-		mpc83xx_spi->tx_shift = 0;
++		cs->tx_shift = 0;
+ 		if (bits_per_word <= 8)
+-			mpc83xx_spi->rx_shift = 8;
++			cs->rx_shift = 8;
+ 		else
+-			mpc83xx_spi->rx_shift = 0;
++			cs->rx_shift = 0;
+ 	}
+ 
+-	/* nsecs = (clock period)/2 */
+-	if (!hz)
+-		hz = spi->max_speed_hz;
+-	mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
+-	if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
+-		return -EINVAL;
++	mpc83xx_spi->rx_shift = cs->rx_shift;
++	mpc83xx_spi->tx_shift = cs->tx_shift;
++	mpc83xx_spi->get_rx = cs->get_rx;
++	mpc83xx_spi->get_tx = cs->get_tx;
+ 
+ 	if (bits_per_word == 32)
+ 		bits_per_word = 0;
+ 	else
+ 		bits_per_word = bits_per_word - 1;
+ 
+-	regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+-
+ 	/* mask out bits we are going to set */
+-	regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV);
+-	regval |= SPMODE_LEN(bits_per_word);
+-	if (!(spi->mode & SPI_LSB_FIRST))
+-		regval |= SPMODE_REV;
++	cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16
++				  | SPMODE_PM(0xF));
++
++	cs->hw_mode |= SPMODE_LEN(bits_per_word);
++
++	if ((mpc83xx_spi->spibrg / hz) >= 64) {
++		pm = mpc83xx_spi->spibrg / (hz * 64) - 1;
++		if (pm > 0x0f) {
++			dev_err(&spi->dev, "Requested speed is too "
++				"low: %d Hz. Will use %d Hz instead.\n",
++				hz, mpc83xx_spi->spibrg / 1024);
++			pm = 0x0f;
++		}
++		cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16;
++	} else {
++		pm = mpc83xx_spi->spibrg / (hz * 4);
++		if (pm)
++			pm--;
++		cs->hw_mode |= SPMODE_PM(pm);
++	}
++	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
++	if (cs->hw_mode != regval) {
++		unsigned long flags;
++		void *tmp_ptr = &mpc83xx_spi->base->mode;
++
++		regval = cs->hw_mode;
++		/* Turn off IRQs locally to minimize time
++		 * that SPI is disabled
++		 */
++		local_irq_save(flags);
++		/* Turn off SPI unit prior changing mode */
++		mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
++		mpc83xx_spi_write_reg(tmp_ptr, regval);
++		local_irq_restore(flags);
++	}
++	return 0;
++}
+ 
+-	/* Turn off SPI unit prior changing mode */
+-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
+-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
++static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
++{
++	struct mpc83xx_spi *mpc83xx_spi;
++	u32 word, len, bits_per_word;
+ 
+-	return 0;
++	mpc83xx_spi = spi_master_get_devdata(spi->master);
++
++	mpc83xx_spi->tx = t->tx_buf;
++	mpc83xx_spi->rx = t->rx_buf;
++	bits_per_word = spi->bits_per_word;
++	if (t->bits_per_word)
++		bits_per_word = t->bits_per_word;
++	len = t->len;
++	if (bits_per_word > 8)
++		len /= 2;
++	if (bits_per_word > 16)
++		len /= 2;
++	mpc83xx_spi->count = len;
++	INIT_COMPLETION(mpc83xx_spi->done);
++
++	/* enable rx ints */
++	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
++
++	/* transmit word */
++	word = mpc83xx_spi->get_tx(mpc83xx_spi);
++	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
++
++	wait_for_completion(&mpc83xx_spi->done);
++
++	/* disable rx ints */
++	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
++
++	return mpc83xx_spi->count;
++}
++
++static void mpc83xx_spi_work(struct work_struct *work)
++{
++	struct mpc83xx_spi *mpc83xx_spi =
++		container_of(work, struct mpc83xx_spi, work);
++
++	spin_lock_irq(&mpc83xx_spi->lock);
++	mpc83xx_spi->busy = 1;
++	while (!list_empty(&mpc83xx_spi->queue)) {
++		struct spi_message *m;
++		struct spi_device *spi;
++		struct spi_transfer *t = NULL;
++		unsigned cs_change;
++		int status, nsecs = 50;
++
++		m = container_of(mpc83xx_spi->queue.next,
++				struct spi_message, queue);
++		list_del_init(&m->queue);
++		spin_unlock_irq(&mpc83xx_spi->lock);
++
++		spi = m->spi;
++		cs_change = 1;
++		status = 0;
++		list_for_each_entry(t, &m->transfers, transfer_list) {
++			if (t->bits_per_word || t->speed_hz) {
++				/* Don't allow changes if CS is active */
++				status = -EINVAL;
++
++				if (cs_change)
++					status = mpc83xx_spi_setup_transfer(spi, t);
++				if (status < 0)
++					break;
++			}
++
++			if (cs_change)
++				mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
++			cs_change = t->cs_change;
++			if (t->len)
++				status = mpc83xx_spi_bufs(spi, t);
++			if (status) {
++				status = -EMSGSIZE;
++				break;
++			}
++			m->actual_length += t->len;
++
++			if (t->delay_usecs)
++				udelay(t->delay_usecs);
++
++			if (cs_change) {
++				ndelay(nsecs);
++				mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
++				ndelay(nsecs);
++			}
++		}
++
++		m->status = status;
++		m->complete(m->context);
++
++		if (status || !cs_change) {
++			ndelay(nsecs);
++			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
++		}
++
++		mpc83xx_spi_setup_transfer(spi, NULL);
++
++		spin_lock_irq(&mpc83xx_spi->lock);
++	}
++	mpc83xx_spi->busy = 0;
++	spin_unlock_irq(&mpc83xx_spi->lock);
+ }
+ 
+ /* the spi->mode bits understood by this driver: */
+@@ -286,9 +410,10 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+ 
+ static int mpc83xx_spi_setup(struct spi_device *spi)
+ {
+-	struct spi_bitbang *bitbang;
+ 	struct mpc83xx_spi *mpc83xx_spi;
+ 	int retval;
++	u32 hw_mode;
++	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+ 
+ 	if (spi->mode & ~MODEBITS) {
+ 		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+@@ -299,63 +424,56 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
+ 	if (!spi->max_speed_hz)
+ 		return -EINVAL;
+ 
+-	bitbang = spi_master_get_devdata(spi->master);
++	if (!cs) {
++		cs = kzalloc(sizeof *cs, GFP_KERNEL);
++		if (!cs)
++			return -ENOMEM;
++		spi->controller_state = cs;
++	}
+ 	mpc83xx_spi = spi_master_get_devdata(spi->master);
+ 
+ 	if (!spi->bits_per_word)
+ 		spi->bits_per_word = 8;
+ 
++	hw_mode = cs->hw_mode; /* Save orginal settings */
++	cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
++	/* mask out bits we are going to set */
++	cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
++			 | SPMODE_REV | SPMODE_LOOP);
++
++	if (spi->mode & SPI_CPHA)
++		cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
++	if (spi->mode & SPI_CPOL)
++		cs->hw_mode |= SPMODE_CI_INACTIVEHIGH;
++	if (!(spi->mode & SPI_LSB_FIRST))
++		cs->hw_mode |= SPMODE_REV;
++	if (spi->mode & SPI_LOOP)
++		cs->hw_mode |= SPMODE_LOOP;
++
+ 	retval = mpc83xx_spi_setup_transfer(spi, NULL);
+-	if (retval < 0)
++	if (retval < 0) {
++		cs->hw_mode = hw_mode; /* Restore settings */
+ 		return retval;
++	}
+ 
+-	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
++	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
+ 		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
+-		spi->bits_per_word, 2 * mpc83xx_spi->nsecs);
+-
++		spi->bits_per_word, spi->max_speed_hz);
++#if 0 /* Don't think this is needed */
+ 	/* NOTE we _need_ to call chipselect() early, ideally with adapter
+ 	 * setup, unless the hardware defaults cooperate to avoid confusion
+ 	 * between normal (active low) and inverted chipselects.
+ 	 */
+ 
+ 	/* deselect chip (low or high) */
+-	spin_lock(&bitbang->lock);
+-	if (!bitbang->busy) {
+-		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
+-		ndelay(mpc83xx_spi->nsecs);
+-	}
+-	spin_unlock(&bitbang->lock);
+-
++	spin_lock(&mpc83xx_spi->lock);
++	if (!mpc83xx_spi->busy)
++		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
++	spin_unlock(&mpc83xx_spi->lock);
++#endif
+ 	return 0;
+ }
+ 
+-static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
+-{
+-	struct mpc83xx_spi *mpc83xx_spi;
+-	u32 word;
+-
+-	mpc83xx_spi = spi_master_get_devdata(spi->master);
+-
+-	mpc83xx_spi->tx = t->tx_buf;
+-	mpc83xx_spi->rx = t->rx_buf;
+-	mpc83xx_spi->count = t->len;
+-	INIT_COMPLETION(mpc83xx_spi->done);
+-
+-	/* enable rx ints */
+-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+-
+-	/* transmit word */
+-	word = mpc83xx_spi->get_tx(mpc83xx_spi);
+-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+-
+-	wait_for_completion(&mpc83xx_spi->done);
+-
+-	/* disable rx ints */
+-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+-
+-	return t->len - mpc83xx_spi->count;
+-}
+-
+ irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+ {
+ 	struct mpc83xx_spi *mpc83xx_spi = context_data;
+@@ -395,6 +513,28 @@ irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+ 
+ 	return ret;
+ }
++static int mpc83xx_spi_transfer(struct spi_device *spi,
++				struct spi_message *m)
++{
++	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
++	unsigned long flags;
++
++	m->actual_length = 0;
++	m->status = -EINPROGRESS;
++
++	spin_lock_irqsave(&mpc83xx_spi->lock, flags);
++	list_add_tail(&m->queue, &mpc83xx_spi->queue);
++	queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
++	spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
++
++	return 0;
++}
++
++
++static void mpc83xx_spi_cleanup(struct spi_device *spi)
++{
++	kfree(spi->controller_state);
++}
+ 
+ static int __init mpc83xx_spi_probe(struct platform_device *dev)
+ {
+@@ -426,11 +566,11 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
+ 		ret = -ENODEV;
+ 		goto free_master;
+ 	}
++	master->setup = mpc83xx_spi_setup;
++	master->transfer = mpc83xx_spi_transfer;
++	master->cleanup = mpc83xx_spi_cleanup;
++
+ 	mpc83xx_spi = spi_master_get_devdata(master);
+-	mpc83xx_spi->bitbang.master = spi_master_get(master);
+-	mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
+-	mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
+-	mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
+ 	mpc83xx_spi->activate_cs = pdata->activate_cs;
+ 	mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
+ 	mpc83xx_spi->qe_mode = pdata->qe_mode;
+@@ -445,7 +585,6 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
+ 		mpc83xx_spi->tx_shift = 24;
+ 	}
+ 
+-	mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
+ 	init_completion(&mpc83xx_spi->done);
+ 
+ 	mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
+@@ -483,11 +622,21 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
+ 		regval |= SPMODE_OP;
+ 
+ 	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
++	spin_lock_init(&mpc83xx_spi->lock);
++	init_completion(&mpc83xx_spi->done);
++	INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
++	INIT_LIST_HEAD(&mpc83xx_spi->queue);
+ 
+-	ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
+-
+-	if (ret != 0)
++	mpc83xx_spi->workqueue = create_singlethread_workqueue(
++		master->dev.parent->bus_id);
++	if (mpc83xx_spi->workqueue == NULL) {
++		ret = -EBUSY;
+ 		goto free_irq;
++	}
++
++	ret = spi_register_master(master);
++	if (ret < 0)
++		goto unreg_master;
+ 
+ 	printk(KERN_INFO
+ 	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
+@@ -495,6 +644,8 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
+ 
+ 	return ret;
+ 
++unreg_master:
++	destroy_workqueue(mpc83xx_spi->workqueue);
+ free_irq:
+ 	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+ unmap_io:
+@@ -515,10 +666,12 @@ static int __exit mpc83xx_spi_remove(struct platform_device *dev)
+ 	master = platform_get_drvdata(dev);
+ 	mpc83xx_spi = spi_master_get_devdata(master);
+ 
+-	spi_bitbang_stop(&mpc83xx_spi->bitbang);
++	flush_workqueue(mpc83xx_spi->workqueue);
++	destroy_workqueue(mpc83xx_spi->workqueue);
++	spi_unregister_master(master);
++
+ 	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+ 	iounmap(mpc83xx_spi->base);
+-	spi_master_put(mpc83xx_spi->bitbang.master);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
+index f3430b3..5100fbb 100644
+--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
++++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
+@@ -23,6 +23,7 @@
+ 
+ #include <asm/byteorder.h>
+ #include <linux/io.h>
++#include <linux/jiffies.h>
+ #include <linux/usb/c67x00.h>
+ #include "c67x00.h"
+ 
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index cefe7f2..63c3404 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1248,6 +1248,9 @@ static struct usb_device_id acm_ids[] = {
+ 	{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
+ 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ 	},
++	{ USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
++	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
++	},
+ 
+ 	/* control interfaces with various AT-command sets */
+ 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
+index 99e5a68..fae55a3 100644
+--- a/drivers/usb/core/endpoint.c
++++ b/drivers/usb/core/endpoint.c
+@@ -156,6 +156,10 @@ static struct attribute *ep_dev_attrs[] = {
+ static struct attribute_group ep_dev_attr_grp = {
+ 	.attrs = ep_dev_attrs,
+ };
++static struct attribute_group *ep_dev_groups[] = {
++	&ep_dev_attr_grp,
++	NULL
++};
+ 
+ static int usb_endpoint_major_init(void)
+ {
+@@ -298,6 +302,7 @@ int usb_create_ep_files(struct device *parent,
+ 
+ 	ep_dev->desc = &endpoint->desc;
+ 	ep_dev->udev = udev;
++	ep_dev->dev.groups = ep_dev_groups;
+ 	ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor);
+ 	ep_dev->dev.class = ep_class->class;
+ 	ep_dev->dev.parent = parent;
+@@ -309,9 +314,6 @@ int usb_create_ep_files(struct device *parent,
+ 	retval = device_register(&ep_dev->dev);
+ 	if (retval)
+ 		goto error_chrdev;
+-	retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
+-	if (retval)
+-		goto error_group;
+ 
+ 	/* create the symlink to the old-style "ep_XX" directory */
+ 	sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
+@@ -322,8 +324,6 @@ int usb_create_ep_files(struct device *parent,
+ 	return retval;
+ 
+ error_link:
+-	sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
+-error_group:
+ 	device_unregister(&ep_dev->dev);
+ 	destroy_endpoint_class();
+ 	return retval;
+@@ -348,7 +348,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
+ 
+ 		sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
+ 		sysfs_remove_link(&ep_dev->dev.parent->kobj, name);
+-		sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
+ 		device_unregister(&ep_dev->dev);
+ 		endpoint->ep_dev = NULL;
+ 		destroy_endpoint_class();
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 3e69266..fe47d14 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -1607,6 +1607,7 @@ free_interfaces:
+ 		intf->dev.driver = NULL;
+ 		intf->dev.bus = &usb_bus_type;
+ 		intf->dev.type = &usb_if_device_type;
++		intf->dev.groups = usb_interface_groups;
+ 		intf->dev.dma_mask = dev->dev.dma_mask;
+ 		device_initialize(&intf->dev);
+ 		mark_quiesced(intf);
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+index 5b20a60..c783cb1 100644
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -538,6 +538,46 @@ static struct attribute_group dev_attr_grp = {
+ 	.attrs = dev_attrs,
+ };
+ 
++/* When modifying this list, be sure to modify dev_string_attrs_are_visible()
++ * accordingly.
++ */
++static struct attribute *dev_string_attrs[] = {
++	&dev_attr_manufacturer.attr,
++	&dev_attr_product.attr,
++	&dev_attr_serial.attr,
++	NULL
++};
++
++static mode_t dev_string_attrs_are_visible(struct kobject *kobj,
++		struct attribute *a, int n)
++{
++	struct usb_device *udev = to_usb_device(
++			container_of(kobj, struct device, kobj));
++
++	if (a == &dev_attr_manufacturer.attr) {
++		if (udev->manufacturer == NULL)
++			return 0;
++	} else if (a == &dev_attr_product.attr) {
++		if (udev->product == NULL)
++			return 0;
++	} else if (a == &dev_attr_serial.attr) {
++		if (udev->serial == NULL)
++			return 0;
++	}
++	return a->mode;
++}
++
++static struct attribute_group dev_string_attr_grp = {
++	.attrs =	dev_string_attrs,
++	.is_visible =	dev_string_attrs_are_visible,
++};
++
++struct attribute_group *usb_device_groups[] = {
++	&dev_attr_grp,
++	&dev_string_attr_grp,
++	NULL
++};
++
+ /* Binary descriptors */
+ 
+ static ssize_t
+@@ -591,10 +631,9 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
+ 	struct device *dev = &udev->dev;
+ 	int retval;
+ 
+-	retval = sysfs_create_group(&dev->kobj, &dev_attr_grp);
+-	if (retval)
+-		return retval;
+-
++	/* Unforunately these attributes cannot be created before
++	 * the uevent is broadcast.
++	 */
+ 	retval = device_create_bin_file(dev, &dev_bin_attr_descriptors);
+ 	if (retval)
+ 		goto error;
+@@ -607,21 +646,6 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
+ 	if (retval)
+ 		goto error;
+ 
+-	if (udev->manufacturer) {
+-		retval = device_create_file(dev, &dev_attr_manufacturer);
+-		if (retval)
+-			goto error;
+-	}
+-	if (udev->product) {
+-		retval = device_create_file(dev, &dev_attr_product);
+-		if (retval)
+-			goto error;
+-	}
+-	if (udev->serial) {
+-		retval = device_create_file(dev, &dev_attr_serial);
+-		if (retval)
+-			goto error;
+-	}
+ 	retval = usb_create_ep_files(dev, &udev->ep0, udev);
+ 	if (retval)
+ 		goto error;
+@@ -636,13 +660,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
+ 	struct device *dev = &udev->dev;
+ 
+ 	usb_remove_ep_files(&udev->ep0);
+-	device_remove_file(dev, &dev_attr_manufacturer);
+-	device_remove_file(dev, &dev_attr_product);
+-	device_remove_file(dev, &dev_attr_serial);
+ 	remove_power_attributes(dev);
+ 	remove_persist_attributes(dev);
+ 	device_remove_bin_file(dev, &dev_bin_attr_descriptors);
+-	sysfs_remove_group(&dev->kobj, &dev_attr_grp);
+ }
+ 
+ /* Interface Accociation Descriptor fields */
+@@ -688,17 +708,15 @@ static ssize_t show_interface_string(struct device *dev,
+ 		struct device_attribute *attr, char *buf)
+ {
+ 	struct usb_interface *intf;
+-	struct usb_device *udev;
+-	int len;
++	char *string;
+ 
+ 	intf = to_usb_interface(dev);
+-	udev = interface_to_usbdev(intf);
+-	len = snprintf(buf, 256, "%s", intf->cur_altsetting->string);
+-	if (len < 0)
++	string = intf->cur_altsetting->string;
++	barrier();		/* The altsetting might change! */
++
++	if (!string)
+ 		return 0;
+-	buf[len] = '\n';
+-	buf[len+1] = 0;
+-	return len+1;
++	return sprintf(buf, "%s\n", string);
+ }
+ static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
+ 
+@@ -727,18 +745,6 @@ static ssize_t show_modalias(struct device *dev,
+ }
+ static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+ 
+-static struct attribute *intf_assoc_attrs[] = {
+-	&dev_attr_iad_bFirstInterface.attr,
+-	&dev_attr_iad_bInterfaceCount.attr,
+-	&dev_attr_iad_bFunctionClass.attr,
+-	&dev_attr_iad_bFunctionSubClass.attr,
+-	&dev_attr_iad_bFunctionProtocol.attr,
+-	NULL,
+-};
+-static struct attribute_group intf_assoc_attr_grp = {
+-	.attrs = intf_assoc_attrs,
+-};
+-
+ static struct attribute *intf_attrs[] = {
+ 	&dev_attr_bInterfaceNumber.attr,
+ 	&dev_attr_bAlternateSetting.attr,
+@@ -753,6 +759,37 @@ static struct attribute_group intf_attr_grp = {
+ 	.attrs = intf_attrs,
+ };
+ 
++static struct attribute *intf_assoc_attrs[] = {
++	&dev_attr_iad_bFirstInterface.attr,
++	&dev_attr_iad_bInterfaceCount.attr,
++	&dev_attr_iad_bFunctionClass.attr,
++	&dev_attr_iad_bFunctionSubClass.attr,
++	&dev_attr_iad_bFunctionProtocol.attr,
++	NULL,
++};
++
++static mode_t intf_assoc_attrs_are_visible(struct kobject *kobj,
++		struct attribute *a, int n)
++{
++	struct usb_interface *intf = to_usb_interface(
++			container_of(kobj, struct device, kobj));
++
++	if (intf->intf_assoc == NULL)
++		return 0;
++	return a->mode;
++}
++
++static struct attribute_group intf_assoc_attr_grp = {
++	.attrs =	intf_assoc_attrs,
++	.is_visible =	intf_assoc_attrs_are_visible,
++};
++
++struct attribute_group *usb_interface_groups[] = {
++	&intf_attr_grp,
++	&intf_assoc_attr_grp,
++	NULL
++};
++
+ static inline void usb_create_intf_ep_files(struct usb_interface *intf,
+ 		struct usb_device *udev)
+ {
+@@ -777,23 +814,21 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf)
+ 
+ int usb_create_sysfs_intf_files(struct usb_interface *intf)
+ {
+-	struct device *dev = &intf->dev;
+ 	struct usb_device *udev = interface_to_usbdev(intf);
+ 	struct usb_host_interface *alt = intf->cur_altsetting;
+ 	int retval;
+ 
+ 	if (intf->sysfs_files_created)
+ 		return 0;
+-	retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
+-	if (retval)
+-		return retval;
+ 
++	/* The interface string may be present in some altsettings
++	 * and missing in others.  Hence its attribute cannot be created
++	 * before the uevent is broadcast.
++	 */
+ 	if (alt->string == NULL)
+ 		alt->string = usb_cache_string(udev, alt->desc.iInterface);
+ 	if (alt->string)
+-		retval = device_create_file(dev, &dev_attr_interface);
+-	if (intf->intf_assoc)
+-		retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
++		retval = device_create_file(&intf->dev, &dev_attr_interface);
+ 	usb_create_intf_ep_files(intf, udev);
+ 	intf->sysfs_files_created = 1;
+ 	return 0;
+@@ -807,7 +842,5 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
+ 		return;
+ 	usb_remove_intf_ep_files(intf);
+ 	device_remove_file(dev, &dev_attr_interface);
+-	sysfs_remove_group(&dev->kobj, &intf_attr_grp);
+-	sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
+ 	intf->sysfs_files_created = 0;
+ }
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 1f0db51..3257743 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -291,6 +291,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
+ 	device_initialize(&dev->dev);
+ 	dev->dev.bus = &usb_bus_type;
+ 	dev->dev.type = &usb_device_type;
++	dev->dev.groups = usb_device_groups;
+ 	dev->dev.dma_mask = bus->controller->dma_mask;
+ 	set_dev_node(&dev->dev, dev_to_node(bus->controller));
+ 	dev->state = USB_STATE_ATTACHED;
+diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
+index 1bf8ccb..1a8bc21 100644
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -130,6 +130,10 @@ static inline int is_active(const struct usb_interface *f)
+ /* for labeling diagnostics */
+ extern const char *usbcore_name;
+ 
++/* sysfs stuff */
++extern struct attribute_group *usb_device_groups[];
++extern struct attribute_group *usb_interface_groups[];
++
+ /* usbfs stuff */
+ extern struct mutex usbfs_mutex;
+ extern struct usb_driver usbfs_driver;
+diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
+index ce337cb..f261d2a 100644
+--- a/drivers/usb/gadget/amd5536udc.c
++++ b/drivers/usb/gadget/amd5536udc.c
+@@ -3251,7 +3251,7 @@ static int udc_pci_probe(
+ 	/* pci setup */
+ 	if (pci_enable_device(pdev) < 0) {
+ 		kfree(dev);
+-		dev = 0;
++		dev = NULL;
+ 		retval = -ENODEV;
+ 		goto finished;
+ 	}
+@@ -3264,7 +3264,7 @@ static int udc_pci_probe(
+ 	if (!request_mem_region(resource, len, name)) {
+ 		dev_dbg(&pdev->dev, "pci device used already\n");
+ 		kfree(dev);
+-		dev = 0;
++		dev = NULL;
+ 		retval = -EBUSY;
+ 		goto finished;
+ 	}
+@@ -3274,7 +3274,7 @@ static int udc_pci_probe(
+ 	if (dev->virt_addr == NULL) {
+ 		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
+ 		kfree(dev);
+-		dev = 0;
++		dev = NULL;
+ 		retval = -EFAULT;
+ 		goto finished;
+ 	}
+@@ -3282,7 +3282,7 @@ static int udc_pci_probe(
+ 	if (!pdev->irq) {
+ 		dev_err(&dev->pdev->dev, "irq not set\n");
+ 		kfree(dev);
+-		dev = 0;
++		dev = NULL;
+ 		retval = -ENODEV;
+ 		goto finished;
+ 	}
+@@ -3290,7 +3290,7 @@ static int udc_pci_probe(
+ 	if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
+ 		dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
+ 		kfree(dev);
+-		dev = 0;
++		dev = NULL;
+ 		retval = -EBUSY;
+ 		goto finished;
+ 	}
+diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
+index e756023..07e5a0b 100644
+--- a/drivers/usb/gadget/atmel_usba_udc.c
++++ b/drivers/usb/gadget/atmel_usba_udc.c
+@@ -649,7 +649,13 @@ static int usba_ep_disable(struct usb_ep *_ep)
+ 
+ 	if (!ep->desc) {
+ 		spin_unlock_irqrestore(&udc->lock, flags);
+-		DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name);
++		/* REVISIT because this driver disables endpoints in
++		 * reset_all_endpoints() before calling disconnect(),
++		 * most gadget drivers would trigger this non-error ...
++		 */
++		if (udc->gadget.speed != USB_SPEED_UNKNOWN)
++			DBG(DBG_ERR, "ep_disable: %s not enabled\n",
++					ep->ep.name);
+ 		return -EINVAL;
+ 	}
+ 	ep->desc = NULL;
+@@ -1032,8 +1038,6 @@ static struct usba_udc the_udc = {
+ 			.release	= nop_release,
+ 		},
+ 	},
+-
+-	.lock	= SPIN_LOCK_UNLOCKED,
+ };
+ 
+ /*
+@@ -1052,6 +1056,12 @@ static void reset_all_endpoints(struct usba_udc *udc)
+ 		request_complete(ep, req, -ECONNRESET);
+ 	}
+ 
++	/* NOTE:  normally, the next call to the gadget driver is in
++	 * charge of disabling endpoints... usually disconnect().
++	 * The exception would be entering a high speed test mode.
++	 *
++	 * FIXME remove this code ... and retest thoroughly.
++	 */
+ 	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+ 		if (ep->desc) {
+ 			spin_unlock(&udc->lock);
+@@ -1219,7 +1229,7 @@ static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
+ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
+ 		struct usb_ctrlrequest *crq)
+ {
+-	int retval = 0;;
++	int retval = 0;
+ 
+ 	switch (crq->bRequest) {
+ 	case USB_REQ_GET_STATUS: {
+@@ -1693,6 +1703,14 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
+ 		usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
+ 		reset_all_endpoints(udc);
+ 
++		if (udc->gadget.speed != USB_SPEED_UNKNOWN
++				&& udc->driver->disconnect) {
++			udc->gadget.speed = USB_SPEED_UNKNOWN;
++			spin_unlock(&udc->lock);
++			udc->driver->disconnect(&udc->gadget);
++			spin_lock(&udc->lock);
++		}
++
+ 		if (status & USBA_HIGH_SPEED) {
+ 			DBG(DBG_BUS, "High-speed bus reset detected\n");
+ 			udc->gadget.speed = USB_SPEED_HIGH;
+@@ -1716,9 +1734,13 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
+ 				| USBA_DET_SUSPEND
+ 				| USBA_END_OF_RESUME));
+ 
++		/*
++		 * Unclear why we hit this irregularly, e.g. in usbtest,
++		 * but it's clearly harmless...
++		 */
+ 		if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED))
+-			dev_warn(&udc->pdev->dev,
+-				 "WARNING: EP0 configuration is invalid!\n");
++			dev_dbg(&udc->pdev->dev,
++				 "ODD: EP0 configuration is invalid!\n");
+ 	}
+ 
+ 	spin_unlock(&udc->lock);
+@@ -1751,9 +1773,11 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
+ 			reset_all_endpoints(udc);
+ 			toggle_bias(0);
+ 			usba_writel(udc, CTRL, USBA_DISABLE_MASK);
+-			spin_unlock(&udc->lock);
+-			udc->driver->disconnect(&udc->gadget);
+-			spin_lock(&udc->lock);
++			if (udc->driver->disconnect) {
++				spin_unlock(&udc->lock);
++				udc->driver->disconnect(&udc->gadget);
++				spin_lock(&udc->lock);
++			}
+ 		}
+ 		udc->vbus_prev = vbus;
+ 	}
+@@ -1825,7 +1849,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ 
+ 	if (!udc->pdev)
+ 		return -ENODEV;
+-	if (driver != udc->driver)
++	if (driver != udc->driver || !driver->unbind)
+ 		return -EINVAL;
+ 
+ 	if (udc->vbus_pin != -1)
+@@ -1840,6 +1864,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ 	toggle_bias(0);
+ 	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
+ 
++	if (udc->driver->disconnect)
++		udc->driver->disconnect(&udc->gadget);
++
+ 	driver->unbind(&udc->gadget);
+ 	udc->gadget.dev.driver = NULL;
+ 	udc->driver = NULL;
+@@ -1879,6 +1906,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
+ 		goto err_get_hclk;
+ 	}
+ 
++	spin_lock_init(&udc->lock);
+ 	udc->pdev = pdev;
+ 	udc->pclk = pclk;
+ 	udc->hclk = hclk;
+diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
+index 75eba20..499b7a2 100644
+--- a/drivers/usb/gadget/pxa27x_udc.c
++++ b/drivers/usb/gadget/pxa27x_udc.c
+@@ -1546,7 +1546,6 @@ static __init void udc_init_data(struct pxa_udc *dev)
+ 	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
+ 	dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
+ 	ep0_idle(dev);
+-	strcpy(dev->dev->bus_id, "");
+ 
+ 	/* PXA endpoints init */
+ 	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
+@@ -1746,13 +1745,10 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc,
+ 		ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
+ 	}
+ 
+-	le16_to_cpus(&u.r.wValue);
+-	le16_to_cpus(&u.r.wIndex);
+-	le16_to_cpus(&u.r.wLength);
+-
+ 	ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+ 		u.r.bRequestType, u.r.bRequest,
+-		u.r.wValue, u.r.wIndex, u.r.wLength);
++		le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex),
++		le16_to_cpu(u.r.wLength));
+ 	if (unlikely(have_extrabytes))
+ 		goto stall;
+ 
+@@ -2296,7 +2292,8 @@ static void pxa_udc_shutdown(struct platform_device *_dev)
+ {
+ 	struct pxa_udc *udc = platform_get_drvdata(_dev);
+ 
+-	udc_disable(udc);
++	if (udc_readl(udc, UDCCR) & UDCCR_UDE)
++		udc_disable(udc);
+ }
+ 
+ #ifdef CONFIG_PM
+@@ -2361,9 +2358,8 @@ static int pxa_udc_resume(struct platform_device *_dev)
+ 	 * Upon exit from sleep mode and before clearing OTGPH,
+ 	 * Software must configure the USB OTG pad, UDC, and UHC
+ 	 * to the state they were in before entering sleep mode.
+-	 *
+-	 * Should be : PSSR |= PSSR_OTGPH;
+ 	 */
++	PSSR |= PSSR_OTGPH;
+ 
+ 	return 0;
+ }
+@@ -2387,6 +2383,9 @@ static struct platform_driver udc_driver = {
+ 
+ static int __init udc_init(void)
+ {
++	if (!cpu_is_pxa27x())
++		return -ENODEV;
++
+ 	printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
+ 	return platform_driver_probe(&udc_driver, pxa_udc_probe);
+ }
+diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
+index 1d1b793..97453db 100644
+--- a/drivers/usb/gadget/pxa27x_udc.h
++++ b/drivers/usb/gadget/pxa27x_udc.h
+@@ -484,4 +484,12 @@ static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget)
+ #define ep_warn(ep, fmt, arg...) \
+ 	dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg)
+ 
++/*
++ * Cannot include pxa-regs.h, as register names are similar.
++ * So PSSR is redefined here. This should be removed once UDC registers will
++ * be gone from pxa-regs.h.
++ */
++#define PSSR		__REG(0x40F00004)	/* Power Manager Sleep Status */
++#define PSSR_OTGPH	(1 << 6)		/* OTG Peripheral Hold */
++
+ #endif /* __LINUX_USB_GADGET_PXA27X_H */
+diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
+index 54cdd6f..fa019fa 100644
+--- a/drivers/usb/gadget/serial.c
++++ b/drivers/usb/gadget/serial.c
+@@ -14,7 +14,6 @@
+  * This software is distributed under the terms of the GNU General
+  * Public License ("GPL") as published by the Free Software Foundation,
+  * either version 2 of that License or (at your option) any later version.
+- *
+  */
+ 
+ #include <linux/kernel.h>
+@@ -33,7 +32,7 @@
+ /* Defines */
+ 
+ #define GS_VERSION_STR			"v2.2"
+-#define GS_VERSION_NUM			0x0202
++#define GS_VERSION_NUM			0x2200
+ 
+ #define GS_LONG_NAME			"Gadget Serial"
+ #define GS_SHORT_NAME			"g_serial"
+@@ -41,7 +40,11 @@
+ #define GS_MAJOR			127
+ #define GS_MINOR_START			0
+ 
+-#define GS_NUM_PORTS			16
++/* REVISIT only one port is supported for now;
++ * see gs_{send,recv}_packet() ... no multiplexing,
++ * and no support for multiple ACM devices.
++ */
++#define GS_NUM_PORTS			1
+ 
+ #define GS_NUM_CONFIGS			1
+ #define GS_NO_CONFIG_ID			0
+@@ -65,6 +68,9 @@
+ 
+ #define GS_DEFAULT_USE_ACM		0
+ 
++/* 9600-8-N-1 ... matches init_termios.c_cflag and defaults
++ * expected by "usbser.sys" on MS-Windows.
++ */
+ #define GS_DEFAULT_DTE_RATE		9600
+ #define GS_DEFAULT_DATA_BITS		8
+ #define GS_DEFAULT_PARITY		USB_CDC_NO_PARITY
+@@ -107,10 +113,6 @@ static int debug = 1;
+ #define GS_NOTIFY_MAXPACKET		8
+ 
+ 
+-/* Structures */
+-
+-struct gs_dev;
+-
+ /* circular buffer */
+ struct gs_buf {
+ 	unsigned int		buf_size;
+@@ -119,12 +121,6 @@ struct gs_buf {
+ 	char			*buf_put;
+ };
+ 
+-/* list of requests */
+-struct gs_req_entry {
+-	struct list_head	re_entry;
+-	struct usb_request	*re_req;
+-};
+-
+ /* the port structure holds info for each port, one for each minor number */
+ struct gs_port {
+ 	struct gs_dev		*port_dev;	/* pointer to device struct */
+@@ -164,26 +160,7 @@ struct gs_dev {
+ 
+ /* Functions */
+ 
+-/* module */
+-static int __init gs_module_init(void);
+-static void __exit gs_module_exit(void);
+-
+-/* tty driver */
+-static int gs_open(struct tty_struct *tty, struct file *file);
+-static void gs_close(struct tty_struct *tty, struct file *file);
+-static int gs_write(struct tty_struct *tty,
+-	const unsigned char *buf, int count);
+-static int gs_put_char(struct tty_struct *tty, unsigned char ch);
+-static void gs_flush_chars(struct tty_struct *tty);
+-static int gs_write_room(struct tty_struct *tty);
+-static int gs_chars_in_buffer(struct tty_struct *tty);
+-static void gs_throttle(struct tty_struct * tty);
+-static void gs_unthrottle(struct tty_struct * tty);
+-static void gs_break(struct tty_struct *tty, int break_state);
+-static int  gs_ioctl(struct tty_struct *tty, struct file *file,
+-	unsigned int cmd, unsigned long arg);
+-static void gs_set_termios(struct tty_struct *tty, struct ktermios *old);
+-
++/* tty driver internals */
+ static int gs_send(struct gs_dev *dev);
+ static int gs_send_packet(struct gs_dev *dev, char *packet,
+ 	unsigned int size);
+@@ -192,19 +169,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet,
+ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req);
+ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req);
+ 
+-/* gadget driver */
+-static int gs_bind(struct usb_gadget *gadget);
+-static void gs_unbind(struct usb_gadget *gadget);
+-static int gs_setup(struct usb_gadget *gadget,
+-	const struct usb_ctrlrequest *ctrl);
+-static int gs_setup_standard(struct usb_gadget *gadget,
+-	const struct usb_ctrlrequest *ctrl);
+-static int gs_setup_class(struct usb_gadget *gadget,
+-	const struct usb_ctrlrequest *ctrl);
+-static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req);
+-static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
+-	struct usb_request *req);
+-static void gs_disconnect(struct usb_gadget *gadget);
++/* gadget driver internals */
+ static int gs_set_config(struct gs_dev *dev, unsigned config);
+ static void gs_reset_config(struct gs_dev *dev);
+ static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
+@@ -214,10 +179,6 @@ static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
+ 	gfp_t kmalloc_flags);
+ static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
+ 
+-static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
+-	gfp_t kmalloc_flags);
+-static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
+-
+ static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
+ static void gs_free_ports(struct gs_dev *dev);
+ 
+@@ -232,62 +193,15 @@ static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf,
+ static unsigned int gs_buf_get(struct gs_buf *gb, char *buf,
+ 	unsigned int count);
+ 
+-/* external functions */
+-extern int net2280_set_fifo_mode(struct usb_gadget *gadget, int mode);
+-
+ 
+ /* Globals */
+ 
+ static struct gs_dev *gs_device;
+ 
+-static const char *EP_IN_NAME;
+-static const char *EP_OUT_NAME;
+-static const char *EP_NOTIFY_NAME;
+-
+ static struct mutex gs_open_close_lock[GS_NUM_PORTS];
+ 
+-static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
+-static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
+-
+-static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
+-
+-static unsigned int use_acm = GS_DEFAULT_USE_ACM;
+-
+-
+-/* tty driver struct */
+-static const struct tty_operations gs_tty_ops = {
+-	.open =			gs_open,
+-	.close =		gs_close,
+-	.write =		gs_write,
+-	.put_char =		gs_put_char,
+-	.flush_chars =		gs_flush_chars,
+-	.write_room =		gs_write_room,
+-	.ioctl =		gs_ioctl,
+-	.set_termios =		gs_set_termios,
+-	.throttle =		gs_throttle,
+-	.unthrottle =		gs_unthrottle,
+-	.break_ctl =		gs_break,
+-	.chars_in_buffer =	gs_chars_in_buffer,
+-};
+-static struct tty_driver *gs_tty_driver;
+-
+-/* gadget driver struct */
+-static struct usb_gadget_driver gs_gadget_driver = {
+-#ifdef CONFIG_USB_GADGET_DUALSPEED
+-	.speed =		USB_SPEED_HIGH,
+-#else
+-	.speed =		USB_SPEED_FULL,
+-#endif /* CONFIG_USB_GADGET_DUALSPEED */
+-	.function =		GS_LONG_NAME,
+-	.bind =			gs_bind,
+-	.unbind =		gs_unbind,
+-	.setup =		gs_setup,
+-	.disconnect =		gs_disconnect,
+-	.driver = {
+-		.name =		GS_SHORT_NAME,
+-	},
+-};
+ 
++/*-------------------------------------------------------------------------*/
+ 
+ /* USB descriptors */
+ 
+@@ -304,7 +218,6 @@ static char manufacturer[50];
+ static struct usb_string gs_strings[] = {
+ 	{ GS_MANUFACTURER_STR_ID, manufacturer },
+ 	{ GS_PRODUCT_STR_ID, GS_LONG_NAME },
+-	{ GS_SERIAL_STR_ID, "0" },
+ 	{ GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" },
+ 	{ GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" },
+ 	{ GS_CONTROL_STR_ID, "Gadget Serial Control" },
+@@ -327,7 +240,6 @@ static struct usb_device_descriptor gs_device_desc = {
+ 	.idProduct =		__constant_cpu_to_le16(GS_PRODUCT_ID),
+ 	.iManufacturer =	GS_MANUFACTURER_STR_ID,
+ 	.iProduct =		GS_PRODUCT_STR_ID,
+-	.iSerialNumber =	GS_SERIAL_STR_ID,
+ 	.bNumConfigurations =	GS_NUM_CONFIGS,
+ };
+ 
+@@ -364,7 +276,7 @@ static const struct usb_interface_descriptor gs_bulk_interface_desc = {
+ 	.bDescriptorType =	USB_DT_INTERFACE,
+ 	.bInterfaceNumber =	GS_BULK_INTERFACE_ID,
+ 	.bNumEndpoints =	2,
+-	.bInterfaceClass =	USB_CLASS_CDC_DATA,
++	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
+ 	.bInterfaceSubClass =	0,
+ 	.bInterfaceProtocol =	0,
+ 	.iInterface =		GS_DATA_STR_ID,
+@@ -521,6 +433,8 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = {
+ };
+ 
+ 
++/*-------------------------------------------------------------------------*/
++
+ /* Module */
+ MODULE_DESCRIPTION(GS_LONG_NAME);
+ MODULE_AUTHOR("Al Borchers");
+@@ -531,84 +445,23 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
+ #endif
+ 
++static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
+ module_param(read_q_size, uint, S_IRUGO);
+ MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
+ 
++static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
+ module_param(write_q_size, uint, S_IRUGO);
+ MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32");
+ 
++static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
+ module_param(write_buf_size, uint, S_IRUGO);
+ MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192");
+ 
++static unsigned int use_acm = GS_DEFAULT_USE_ACM;
+ module_param(use_acm, uint, S_IRUGO);
+ MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no");
+ 
+-module_init(gs_module_init);
+-module_exit(gs_module_exit);
+-
+-/*
+-*  gs_module_init
+-*
+-*  Register as a USB gadget driver and a tty driver.
+-*/
+-static int __init gs_module_init(void)
+-{
+-	int i;
+-	int retval;
+-
+-	retval = usb_gadget_register_driver(&gs_gadget_driver);
+-	if (retval) {
+-		pr_err("gs_module_init: cannot register gadget driver, "
+-			"ret=%d\n", retval);
+-		return retval;
+-	}
+-
+-	gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
+-	if (!gs_tty_driver)
+-		return -ENOMEM;
+-	gs_tty_driver->owner = THIS_MODULE;
+-	gs_tty_driver->driver_name = GS_SHORT_NAME;
+-	gs_tty_driver->name = "ttygs";
+-	gs_tty_driver->major = GS_MAJOR;
+-	gs_tty_driver->minor_start = GS_MINOR_START;
+-	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+-	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+-	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+-	gs_tty_driver->init_termios = tty_std_termios;
+-	gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+-	tty_set_operations(gs_tty_driver, &gs_tty_ops);
+-
+-	for (i=0; i < GS_NUM_PORTS; i++)
+-		mutex_init(&gs_open_close_lock[i]);
+-
+-	retval = tty_register_driver(gs_tty_driver);
+-	if (retval) {
+-		usb_gadget_unregister_driver(&gs_gadget_driver);
+-		put_tty_driver(gs_tty_driver);
+-		pr_err("gs_module_init: cannot register tty driver, "
+-				"ret=%d\n", retval);
+-		return retval;
+-	}
+-
+-	pr_info("gs_module_init: %s %s loaded\n",
+-			GS_LONG_NAME, GS_VERSION_STR);
+-	return 0;
+-}
+-
+-/*
+-* gs_module_exit
+-*
+-* Unregister as a tty driver and a USB gadget driver.
+-*/
+-static void __exit gs_module_exit(void)
+-{
+-	tty_unregister_driver(gs_tty_driver);
+-	put_tty_driver(gs_tty_driver);
+-	usb_gadget_unregister_driver(&gs_gadget_driver);
+-
+-	pr_info("gs_module_exit: %s %s unloaded\n",
+-			GS_LONG_NAME, GS_VERSION_STR);
+-}
++/*-------------------------------------------------------------------------*/
+ 
+ /* TTY Driver */
+ 
+@@ -753,15 +606,15 @@ exit_unlock_dev:
+  * gs_close
+  */
+ 
+-#define GS_WRITE_FINISHED_EVENT_SAFELY(p)			\
+-({								\
+-	int cond;						\
+-								\
+-	spin_lock_irq(&(p)->port_lock);				\
+-	cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
+-	spin_unlock_irq(&(p)->port_lock);			\
+-	cond;							\
+-})
++static int gs_write_finished_event_safely(struct gs_port *p)
++{
++	int cond;
++
++	spin_lock_irq(&(p)->port_lock);
++	cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf);
++	spin_unlock_irq(&(p)->port_lock);
++	return cond;
++}
+ 
+ static void gs_close(struct tty_struct *tty, struct file *file)
+ {
+@@ -807,7 +660,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
+ 	if (gs_buf_data_avail(port->port_write_buf) > 0) {
+ 		spin_unlock_irq(&port->port_lock);
+ 		wait_event_interruptible_timeout(port->port_write_wait,
+-					GS_WRITE_FINISHED_EVENT_SAFELY(port),
++					gs_write_finished_event_safely(port),
+ 					GS_CLOSE_TIMEOUT * HZ);
+ 		spin_lock_irq(&port->port_lock);
+ 	}
+@@ -1065,6 +918,23 @@ static void gs_set_termios(struct tty_struct *tty, struct ktermios *old)
+ {
+ }
+ 
++static const struct tty_operations gs_tty_ops = {
++	.open =			gs_open,
++	.close =		gs_close,
++	.write =		gs_write,
++	.put_char =		gs_put_char,
++	.flush_chars =		gs_flush_chars,
++	.write_room =		gs_write_room,
++	.ioctl =		gs_ioctl,
++	.set_termios =		gs_set_termios,
++	.throttle =		gs_throttle,
++	.unthrottle =		gs_unthrottle,
++	.break_ctl =		gs_break,
++	.chars_in_buffer =	gs_chars_in_buffer,
++};
++
++/*-------------------------------------------------------------------------*/
++
+ /*
+ * gs_send
+ *
+@@ -1080,7 +950,6 @@ static int gs_send(struct gs_dev *dev)
+ 	unsigned long flags;
+ 	struct usb_ep *ep;
+ 	struct usb_request *req;
+-	struct gs_req_entry *req_entry;
+ 
+ 	if (dev == NULL) {
+ 		pr_err("gs_send: NULL device pointer\n");
+@@ -1093,10 +962,8 @@ static int gs_send(struct gs_dev *dev)
+ 
+ 	while(!list_empty(&dev->dev_req_list)) {
+ 
+-		req_entry = list_entry(dev->dev_req_list.next,
+-			struct gs_req_entry, re_entry);
+-
+-		req = req_entry->re_req;
++		req = list_entry(dev->dev_req_list.next,
++				struct usb_request, list);
+ 
+ 		len = gs_send_packet(dev, req->buf, ep->maxpacket);
+ 
+@@ -1106,7 +973,7 @@ static int gs_send(struct gs_dev *dev)
+ 					*((unsigned char *)req->buf),
+ 					*((unsigned char *)req->buf+1),
+ 					*((unsigned char *)req->buf+2));
+-			list_del(&req_entry->re_entry);
++			list_del(&req->list);
+ 			req->length = len;
+ 			spin_unlock_irqrestore(&dev->dev_lock, flags);
+ 			if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
+@@ -1289,7 +1156,6 @@ requeue:
+ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+ 	struct gs_dev *dev = ep->driver_data;
+-	struct gs_req_entry *gs_req = req->context;
+ 
+ 	if (dev == NULL) {
+ 		pr_err("gs_write_complete: NULL device pointer\n");
+@@ -1300,13 +1166,8 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
+ 	case 0:
+ 		/* normal completion */
+ requeue:
+-		if (gs_req == NULL) {
+-			pr_err("gs_write_complete: NULL request pointer\n");
+-			return;
+-		}
+-
+ 		spin_lock(&dev->dev_lock);
+-		list_add(&gs_req->re_entry, &dev->dev_req_list);
++		list_add(&req->list, &dev->dev_req_list);
+ 		spin_unlock(&dev->dev_lock);
+ 
+ 		gs_send(dev);
+@@ -1328,9 +1189,39 @@ requeue:
+ 	}
+ }
+ 
++/*-------------------------------------------------------------------------*/
++
+ /* Gadget Driver */
+ 
+ /*
++ * gs_unbind
++ *
++ * Called on module unload.  Frees the control request and device
++ * structure.
++ */
++static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
++{
++	struct gs_dev *dev = get_gadget_data(gadget);
++
++	gs_device = NULL;
++
++	/* read/write requests already freed, only control request remains */
++	if (dev != NULL) {
++		if (dev->dev_ctrl_req != NULL) {
++			gs_free_req(gadget->ep0, dev->dev_ctrl_req);
++			dev->dev_ctrl_req = NULL;
++		}
++		gs_reset_config(dev);
++		gs_free_ports(dev);
++		kfree(dev);
++		set_gadget_data(gadget, NULL);
++	}
++
++	pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
++		GS_VERSION_STR);
++}
++
++/*
+  * gs_bind
+  *
+  * Called on module load.  Allocates and initializes the device
+@@ -1362,19 +1253,23 @@ static int __init gs_bind(struct usb_gadget *gadget)
+ 			__constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
+ 	}
+ 
++	dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
++	if (dev == NULL)
++		return -ENOMEM;
++
+ 	usb_ep_autoconfig_reset(gadget);
+ 
+ 	ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
+ 	if (!ep)
+ 		goto autoconf_fail;
+-	EP_IN_NAME = ep->name;
+-	ep->driver_data = ep;	/* claim the endpoint */
++	dev->dev_in_ep = ep;
++	ep->driver_data = dev;	/* claim the endpoint */
+ 
+ 	ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc);
+ 	if (!ep)
+ 		goto autoconf_fail;
+-	EP_OUT_NAME = ep->name;
+-	ep->driver_data = ep;	/* claim the endpoint */
++	dev->dev_out_ep = ep;
++	ep->driver_data = dev;	/* claim the endpoint */
+ 
+ 	if (use_acm) {
+ 		ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
+@@ -1384,8 +1279,8 @@ static int __init gs_bind(struct usb_gadget *gadget)
+ 		}
+ 		gs_device_desc.idProduct = __constant_cpu_to_le16(
+ 						GS_CDC_PRODUCT_ID),
+-		EP_NOTIFY_NAME = ep->name;
+-		ep->driver_data = ep;	/* claim the endpoint */
++		dev->dev_notify_ep = ep;
++		ep->driver_data = dev;	/* claim the endpoint */
+ 	}
+ 
+ 	gs_device_desc.bDeviceClass = use_acm
+@@ -1415,9 +1310,7 @@ static int __init gs_bind(struct usb_gadget *gadget)
+ 		gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ 	}
+ 
+-	gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
+-	if (dev == NULL)
+-		return -ENOMEM;
++	gs_device = dev;
+ 
+ 	snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
+ 		init_utsname()->sysname, init_utsname()->release,
+@@ -1441,8 +1334,6 @@ static int __init gs_bind(struct usb_gadget *gadget)
+ 		gs_unbind(gadget);
+ 		return -ENOMEM;
+ 	}
+-	dev->dev_ctrl_req->complete = gs_setup_complete;
+-
+ 	gadget->ep0->driver_data = dev;
+ 
+ 	pr_info("gs_bind: %s %s bound\n",
+@@ -1451,99 +1342,11 @@ static int __init gs_bind(struct usb_gadget *gadget)
+ 	return 0;
+ 
+ autoconf_fail:
++	kfree(dev);
+ 	pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
+ 	return -ENODEV;
+ }
+ 
+-/*
+- * gs_unbind
+- *
+- * Called on module unload.  Frees the control request and device
+- * structure.
+- */
+-static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
+-{
+-	struct gs_dev *dev = get_gadget_data(gadget);
+-
+-	gs_device = NULL;
+-
+-	/* read/write requests already freed, only control request remains */
+-	if (dev != NULL) {
+-		if (dev->dev_ctrl_req != NULL) {
+-			gs_free_req(gadget->ep0, dev->dev_ctrl_req);
+-			dev->dev_ctrl_req = NULL;
+-		}
+-		gs_free_ports(dev);
+-		if (dev->dev_notify_ep)
+-			usb_ep_disable(dev->dev_notify_ep);
+-		if (dev->dev_in_ep)
+-			usb_ep_disable(dev->dev_in_ep);
+-		if (dev->dev_out_ep)
+-			usb_ep_disable(dev->dev_out_ep);
+-		kfree(dev);
+-		set_gadget_data(gadget, NULL);
+-	}
+-
+-	pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
+-		GS_VERSION_STR);
+-}
+-
+-/*
+- * gs_setup
+- *
+- * Implements all the control endpoint functionality that's not
+- * handled in hardware or the hardware driver.
+- *
+- * Returns the size of the data sent to the host, or a negative
+- * error number.
+- */
+-static int gs_setup(struct usb_gadget *gadget,
+-	const struct usb_ctrlrequest *ctrl)
+-{
+-	int ret = -EOPNOTSUPP;
+-	struct gs_dev *dev = get_gadget_data(gadget);
+-	struct usb_request *req = dev->dev_ctrl_req;
+-	u16 wIndex = le16_to_cpu(ctrl->wIndex);
+-	u16 wValue = le16_to_cpu(ctrl->wValue);
+-	u16 wLength = le16_to_cpu(ctrl->wLength);
+-
+-	req->complete = gs_setup_complete;
+-
+-	switch (ctrl->bRequestType & USB_TYPE_MASK) {
+-	case USB_TYPE_STANDARD:
+-		ret = gs_setup_standard(gadget,ctrl);
+-		break;
+-
+-	case USB_TYPE_CLASS:
+-		ret = gs_setup_class(gadget,ctrl);
+-		break;
+-
+-	default:
+-		pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
+-			"value=%04x, index=%04x, length=%d\n",
+-			ctrl->bRequestType, ctrl->bRequest,
+-			wValue, wIndex, wLength);
+-		break;
+-	}
+-
+-	/* respond with data transfer before status phase? */
+-	if (ret >= 0) {
+-		req->length = ret;
+-		req->zero = ret < wLength
+-				&& (ret % gadget->ep0->maxpacket) == 0;
+-		ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
+-		if (ret < 0) {
+-			pr_err("gs_setup: cannot queue response, ret=%d\n",
+-				ret);
+-			req->status = 0;
+-			gs_setup_complete(gadget->ep0, req);
+-		}
+-	}
+-
+-	/* device either stalls (ret < 0) or reports success */
+-	return ret;
+-}
+-
+ static int gs_setup_standard(struct usb_gadget *gadget,
+ 	const struct usb_ctrlrequest *ctrl)
+ {
+@@ -1673,6 +1476,42 @@ set_interface_done:
+ 	return ret;
+ }
+ 
++static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
++		struct usb_request *req)
++{
++	struct gs_dev *dev = ep->driver_data;
++	struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
++
++	switch (req->status) {
++	case 0:
++		/* normal completion */
++		if (req->actual != sizeof(port->port_line_coding))
++			usb_ep_set_halt(ep);
++		else if (port) {
++			struct usb_cdc_line_coding	*value = req->buf;
++
++			/* REVISIT:  we currently just remember this data.
++			 * If we change that, (a) validate it first, then
++			 * (b) update whatever hardware needs updating.
++			 */
++			spin_lock(&port->port_lock);
++			port->port_line_coding = *value;
++			spin_unlock(&port->port_lock);
++		}
++		break;
++
++	case -ESHUTDOWN:
++		/* disconnect */
++		gs_free_req(ep, req);
++		break;
++
++	default:
++		/* unexpected */
++		break;
++	}
++	return;
++}
++
+ static int gs_setup_class(struct usb_gadget *gadget,
+ 	const struct usb_ctrlrequest *ctrl)
+ {
+@@ -1734,52 +1573,72 @@ static int gs_setup_class(struct usb_gadget *gadget,
+ 	return ret;
+ }
+ 
+-static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
+-		struct usb_request *req)
++/*
++ * gs_setup_complete
++ */
++static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+-	struct gs_dev *dev = ep->driver_data;
+-	struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
++	if (req->status || req->actual != req->length) {
++		pr_err("gs_setup_complete: status error, status=%d, "
++			"actual=%d, length=%d\n",
++			req->status, req->actual, req->length);
++	}
++}
+ 
+-	switch (req->status) {
+-	case 0:
+-		/* normal completion */
+-		if (req->actual != sizeof(port->port_line_coding))
+-			usb_ep_set_halt(ep);
+-		else if (port) {
+-			struct usb_cdc_line_coding	*value = req->buf;
++/*
++ * gs_setup
++ *
++ * Implements all the control endpoint functionality that's not
++ * handled in hardware or the hardware driver.
++ *
++ * Returns the size of the data sent to the host, or a negative
++ * error number.
++ */
++static int gs_setup(struct usb_gadget *gadget,
++	const struct usb_ctrlrequest *ctrl)
++{
++	int		ret = -EOPNOTSUPP;
++	struct gs_dev	*dev = get_gadget_data(gadget);
++	struct usb_request *req = dev->dev_ctrl_req;
++	u16		wIndex = le16_to_cpu(ctrl->wIndex);
++	u16		wValue = le16_to_cpu(ctrl->wValue);
++	u16		wLength = le16_to_cpu(ctrl->wLength);
+ 
+-			/* REVISIT:  we currently just remember this data.
+-			 * If we change that, (a) validate it first, then
+-			 * (b) update whatever hardware needs updating.
+-			 */
+-			spin_lock(&port->port_lock);
+-			port->port_line_coding = *value;
+-			spin_unlock(&port->port_lock);
+-		}
++	req->complete = gs_setup_complete;
++
++	switch (ctrl->bRequestType & USB_TYPE_MASK) {
++	case USB_TYPE_STANDARD:
++		ret = gs_setup_standard(gadget, ctrl);
+ 		break;
+ 
+-	case -ESHUTDOWN:
+-		/* disconnect */
+-		gs_free_req(ep, req);
++	case USB_TYPE_CLASS:
++		ret = gs_setup_class(gadget, ctrl);
+ 		break;
+ 
+ 	default:
+-		/* unexpected */
++		pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
++			"value=%04x, index=%04x, length=%d\n",
++			ctrl->bRequestType, ctrl->bRequest,
++			wValue, wIndex, wLength);
+ 		break;
+ 	}
+-	return;
+-}
+ 
+-/*
+- * gs_setup_complete
+- */
+-static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
+-{
+-	if (req->status || req->actual != req->length) {
+-		pr_err("gs_setup_complete: status error, status=%d, "
+-			"actual=%d, length=%d\n",
+-			req->status, req->actual, req->length);
++	/* respond with data transfer before status phase? */
++	if (ret >= 0) {
++		req->length = ret;
++		req->zero = ret < wLength
++				&& (ret % gadget->ep0->maxpacket) == 0;
++		ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
++		if (ret < 0) {
++			pr_err("gs_setup: cannot queue response, ret=%d\n",
++				ret);
++			req->status = 0;
++			gs_setup_complete(gadget->ep0, req);
++		}
+ 	}
++
++	/* device either stalls (ret < 0) or reports success */
++	return ret;
+ }
+ 
+ /*
+@@ -1811,6 +1670,23 @@ static void gs_disconnect(struct usb_gadget *gadget)
+ 	pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
+ }
+ 
++static struct usb_gadget_driver gs_gadget_driver = {
++#ifdef CONFIG_USB_GADGET_DUALSPEED
++	.speed =		USB_SPEED_HIGH,
++#else
++	.speed =		USB_SPEED_FULL,
++#endif /* CONFIG_USB_GADGET_DUALSPEED */
++	.function =		GS_LONG_NAME,
++	.bind =			gs_bind,
++	.unbind =		gs_unbind,
++	.setup =		gs_setup,
++	.disconnect =		gs_disconnect,
++	.driver = {
++		.name =		GS_SHORT_NAME,
++		.owner =	THIS_MODULE,
++	},
++};
++
+ /*
+  * gs_set_config
+  *
+@@ -1826,9 +1702,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
+ 	int ret = 0;
+ 	struct usb_gadget *gadget = dev->dev_gadget;
+ 	struct usb_ep *ep;
+-	struct usb_endpoint_descriptor *ep_desc;
++	struct usb_endpoint_descriptor *out, *in, *notify;
+ 	struct usb_request *req;
+-	struct gs_req_entry *req_entry;
+ 
+ 	if (dev == NULL) {
+ 		pr_err("gs_set_config: NULL device pointer\n");
+@@ -1846,86 +1721,62 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
+ 	case GS_BULK_CONFIG_ID:
+ 		if (use_acm)
+ 			return -EINVAL;
+-		/* device specific optimizations */
+-		if (gadget_is_net2280(gadget))
+-			net2280_set_fifo_mode(gadget, 1);
+ 		break;
+ 	case GS_ACM_CONFIG_ID:
+ 		if (!use_acm)
+ 			return -EINVAL;
+-		/* device specific optimizations */
+-		if (gadget_is_net2280(gadget))
+-			net2280_set_fifo_mode(gadget, 1);
+ 		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+ 
+-	dev->dev_config = config;
+-
+-	gadget_for_each_ep(ep, gadget) {
+-
+-		if (EP_NOTIFY_NAME
+-		&& strcmp(ep->name, EP_NOTIFY_NAME) == 0) {
+-			ep_desc = choose_ep_desc(gadget,
++	in = choose_ep_desc(gadget,
++			&gs_highspeed_in_desc,
++			&gs_fullspeed_in_desc);
++	out = choose_ep_desc(gadget,
++			&gs_highspeed_out_desc,
++			&gs_fullspeed_out_desc);
++	notify = dev->dev_notify_ep
++		? choose_ep_desc(gadget,
+ 				&gs_highspeed_notify_desc,
+-				&gs_fullspeed_notify_desc);
+-			ret = usb_ep_enable(ep,ep_desc);
+-			if (ret == 0) {
+-				ep->driver_data = dev;
+-				dev->dev_notify_ep = ep;
+-				dev->dev_notify_ep_desc = ep_desc;
+-			} else {
+-				pr_err("gs_set_config: cannot enable NOTIFY "
+-					"endpoint %s, ret=%d\n",
+-					ep->name, ret);
+-				goto exit_reset_config;
+-			}
+-		}
+-
+-		else if (strcmp(ep->name, EP_IN_NAME) == 0) {
+-			ep_desc = choose_ep_desc(gadget,
+-				&gs_highspeed_in_desc,
+-				&gs_fullspeed_in_desc);
+-			ret = usb_ep_enable(ep,ep_desc);
+-			if (ret == 0) {
+-				ep->driver_data = dev;
+-				dev->dev_in_ep = ep;
+-				dev->dev_in_ep_desc = ep_desc;
+-			} else {
+-				pr_err("gs_set_config: cannot enable IN "
+-					"endpoint %s, ret=%d\n",
+-					ep->name, ret);
+-				goto exit_reset_config;
+-			}
+-		}
++				&gs_fullspeed_notify_desc)
++		: NULL;
+ 
+-		else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
+-			ep_desc = choose_ep_desc(gadget,
+-				&gs_highspeed_out_desc,
+-				&gs_fullspeed_out_desc);
+-			ret = usb_ep_enable(ep,ep_desc);
+-			if (ret == 0) {
+-				ep->driver_data = dev;
+-				dev->dev_out_ep = ep;
+-				dev->dev_out_ep_desc = ep_desc;
+-			} else {
+-				pr_err("gs_set_config: cannot enable OUT "
+-					"endpoint %s, ret=%d\n",
+-					ep->name, ret);
+-				goto exit_reset_config;
+-			}
+-		}
++	ret = usb_ep_enable(dev->dev_in_ep, in);
++	if (ret == 0) {
++		dev->dev_in_ep_desc = in;
++	} else {
++		pr_debug("%s: cannot enable %s %s, ret=%d\n",
++			__func__, "IN", dev->dev_in_ep->name, ret);
++		return ret;
++	}
+ 
++	ret = usb_ep_enable(dev->dev_out_ep, out);
++	if (ret == 0) {
++		dev->dev_out_ep_desc = out;
++	} else {
++		pr_debug("%s: cannot enable %s %s, ret=%d\n",
++			__func__, "OUT", dev->dev_out_ep->name, ret);
++fail0:
++		usb_ep_disable(dev->dev_in_ep);
++		return ret;
+ 	}
+ 
+-	if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL
+-	|| (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) {
+-		pr_err("gs_set_config: cannot find endpoints\n");
+-		ret = -ENODEV;
+-		goto exit_reset_config;
++	if (notify) {
++		ret = usb_ep_enable(dev->dev_notify_ep, notify);
++		if (ret == 0) {
++			dev->dev_notify_ep_desc = notify;
++		} else {
++			pr_debug("%s: cannot enable %s %s, ret=%d\n",
++				__func__, "NOTIFY",
++				dev->dev_notify_ep->name, ret);
++			usb_ep_disable(dev->dev_out_ep);
++			goto fail0;
++		}
+ 	}
+ 
++	dev->dev_config = config;
++
+ 	/* allocate and queue read requests */
+ 	ep = dev->dev_out_ep;
+ 	for (i=0; i<read_q_size && ret == 0; i++) {
+@@ -1946,9 +1797,10 @@ static int gs_set_config(struct gs_dev *dev, unsigned config)
+ 	/* allocate write requests, and put on free list */
+ 	ep = dev->dev_in_ep;
+ 	for (i=0; i<write_q_size; i++) {
+-		if ((req_entry=gs_alloc_req_entry(ep, ep->maxpacket, GFP_ATOMIC))) {
+-			req_entry->re_req->complete = gs_write_complete;
+-			list_add(&req_entry->re_entry, &dev->dev_req_list);
++		req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
++		if (req) {
++			req->complete = gs_write_complete;
++			list_add(&req->list, &dev->dev_req_list);
+ 		} else {
+ 			pr_err("gs_set_config: cannot allocate "
+ 					"write requests\n");
+@@ -1986,7 +1838,7 @@ exit_reset_config:
+  */
+ static void gs_reset_config(struct gs_dev *dev)
+ {
+-	struct gs_req_entry *req_entry;
++	struct usb_request *req;
+ 
+ 	if (dev == NULL) {
+ 		pr_err("gs_reset_config: NULL device pointer\n");
+@@ -2000,26 +1852,18 @@ static void gs_reset_config(struct gs_dev *dev)
+ 
+ 	/* free write requests on the free list */
+ 	while(!list_empty(&dev->dev_req_list)) {
+-		req_entry = list_entry(dev->dev_req_list.next,
+-			struct gs_req_entry, re_entry);
+-		list_del(&req_entry->re_entry);
+-		gs_free_req_entry(dev->dev_in_ep, req_entry);
++		req = list_entry(dev->dev_req_list.next,
++				struct usb_request, list);
++		list_del(&req->list);
++		gs_free_req(dev->dev_in_ep, req);
+ 	}
+ 
+ 	/* disable endpoints, forcing completion of pending i/o; */
+ 	/* completion handlers free their requests in this case */
+-	if (dev->dev_notify_ep) {
++	if (dev->dev_notify_ep)
+ 		usb_ep_disable(dev->dev_notify_ep);
+-		dev->dev_notify_ep = NULL;
+-	}
+-	if (dev->dev_in_ep) {
+-		usb_ep_disable(dev->dev_in_ep);
+-		dev->dev_in_ep = NULL;
+-	}
+-	if (dev->dev_out_ep) {
+-		usb_ep_disable(dev->dev_out_ep);
+-		dev->dev_out_ep = NULL;
+-	}
++	usb_ep_disable(dev->dev_in_ep);
++	usb_ep_disable(dev->dev_out_ep);
+ }
+ 
+ /*
+@@ -2113,46 +1957,6 @@ static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
+ }
+ 
+ /*
+- * gs_alloc_req_entry
+- *
+- * Allocates a request and its buffer, using the given
+- * endpoint, buffer len, and kmalloc flags.
+- */
+-static struct gs_req_entry *
+-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
+-{
+-	struct gs_req_entry	*req;
+-
+-	req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags);
+-	if (req == NULL)
+-		return NULL;
+-
+-	req->re_req = gs_alloc_req(ep, len, kmalloc_flags);
+-	if (req->re_req == NULL) {
+-		kfree(req);
+-		return NULL;
+-	}
+-
+-	req->re_req->context = req;
+-
+-	return req;
+-}
+-
+-/*
+- * gs_free_req_entry
+- *
+- * Frees a request and its buffer.
+- */
+-static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req)
+-{
+-	if (ep != NULL && req != NULL) {
+-		if (req->re_req != NULL)
+-			gs_free_req(ep, req->re_req);
+-		kfree(req);
+-	}
+-}
+-
+-/*
+  * gs_alloc_ports
+  *
+  * Allocate all ports and set the gs_dev struct to point to them.
+@@ -2233,6 +2037,8 @@ static void gs_free_ports(struct gs_dev *dev)
+ 	}
+ }
+ 
++/*-------------------------------------------------------------------------*/
++
+ /* Circular Buffer */
+ 
+ /*
+@@ -2393,3 +2199,77 @@ gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
+ 
+ 	return count;
+ }
++
++/*-------------------------------------------------------------------------*/
++
++static struct tty_driver *gs_tty_driver;
++
++/*
++ *  gs_module_init
++ *
++ *  Register as a USB gadget driver and a tty driver.
++ */
++static int __init gs_module_init(void)
++{
++	int i;
++	int retval;
++
++	retval = usb_gadget_register_driver(&gs_gadget_driver);
++	if (retval) {
++		pr_err("gs_module_init: cannot register gadget driver, "
++			"ret=%d\n", retval);
++		return retval;
++	}
++
++	gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
++	if (!gs_tty_driver)
++		return -ENOMEM;
++	gs_tty_driver->owner = THIS_MODULE;
++	gs_tty_driver->driver_name = GS_SHORT_NAME;
++	gs_tty_driver->name = "ttygs";
++	gs_tty_driver->major = GS_MAJOR;
++	gs_tty_driver->minor_start = GS_MINOR_START;
++	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
++	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
++	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
++	gs_tty_driver->init_termios = tty_std_termios;
++	/* must match GS_DEFAULT_DTE_RATE and friends */
++	gs_tty_driver->init_termios.c_cflag =
++		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE;
++	gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE;
++	tty_set_operations(gs_tty_driver, &gs_tty_ops);
++
++	for (i = 0; i < GS_NUM_PORTS; i++)
++		mutex_init(&gs_open_close_lock[i]);
++
++	retval = tty_register_driver(gs_tty_driver);
++	if (retval) {
++		usb_gadget_unregister_driver(&gs_gadget_driver);
++		put_tty_driver(gs_tty_driver);
++		pr_err("gs_module_init: cannot register tty driver, "
++				"ret=%d\n", retval);
++		return retval;
++	}
++
++	pr_info("gs_module_init: %s %s loaded\n",
++			GS_LONG_NAME, GS_VERSION_STR);
++	return 0;
++}
++module_init(gs_module_init);
++
++/*
++ * gs_module_exit
++ *
++ * Unregister as a tty driver and a USB gadget driver.
++ */
++static void __exit gs_module_exit(void)
++{
++	tty_unregister_driver(gs_tty_driver);
++	put_tty_driver(gs_tty_driver);
++	usb_gadget_unregister_driver(&gs_gadget_driver);
++
++	pr_info("gs_module_exit: %s %s unloaded\n",
++			GS_LONG_NAME, GS_VERSION_STR);
++}
++module_exit(gs_module_exit);
+diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
+index 4ba96c1..c9cec87 100644
+--- a/drivers/usb/host/isp1760-hcd.c
++++ b/drivers/usb/host/isp1760-hcd.c
+@@ -988,7 +988,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
+ 			 * This did not trigger for a long time now.
+ 			 */
+ 			printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
+-					"%d of %d done: %08x cur: %08x\n", qtd,
++					"%d of %zu done: %08x cur: %08x\n", qtd,
+ 					urb, qh, PTD_XFERRED_LENGTH(dw3),
+ 					qtd->length, done_map,
+ 					(1 << queue_entry));
+@@ -1088,7 +1088,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
+ 		} else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
+ 			/* short BULK received */
+ 
+-			printk(KERN_ERR "short bulk, %d instead %d\n", length,
++			printk(KERN_ERR "short bulk, %d instead %zu\n", length,
+ 					qtd->length);
+ 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
+ 				urb->status = -EREMOTEIO;
+diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
+index 73fb2a3..440bf94 100644
+--- a/drivers/usb/host/isp1760-if.c
++++ b/drivers/usb/host/isp1760-if.c
+@@ -256,7 +256,7 @@ static struct pci_driver isp1761_pci_driver = {
+ 
+ static int __init isp1760_init(void)
+ {
+-	int ret;
++	int ret = -ENODEV;
+ 
+ 	init_kmem_once();
+ 
+diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
+index 77204f0..e899a77 100644
+--- a/drivers/usb/host/ohci-sm501.c
++++ b/drivers/usb/host/ohci-sm501.c
+@@ -90,7 +90,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
+ 	struct device *dev = &pdev->dev;
+ 	struct resource	*res, *mem;
+ 	int retval, irq;
+-	struct usb_hcd *hcd = 0;
++	struct usb_hcd *hcd = NULL;
+ 
+ 	irq = retval = platform_get_irq(pdev, 0);
+ 	if (retval < 0)
+diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
+index 7aafd53..189a9db 100644
+--- a/drivers/usb/misc/ldusb.c
++++ b/drivers/usb/misc/ldusb.c
+@@ -63,9 +63,6 @@
+ #define USB_DEVICE_ID_VERNIER_CYCLOPS	0x0004
+ #define USB_DEVICE_ID_VERNIER_LCSPEC	0x0006
+ 
+-#define USB_VENDOR_ID_MICROCHIP		0x04d8
+-#define USB_DEVICE_ID_PICDEM		0x000c
+-
+ #ifdef CONFIG_USB_DYNAMIC_MINORS
+ #define USB_LD_MINOR_BASE	0
+ #else
+@@ -92,7 +89,6 @@ static struct usb_device_id ld_usb_table [] = {
+ 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
+-	{ USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
+ 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
+ 	{ }					/* Terminating entry */
+ };
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+index 742be3c..054dedd 100644
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -856,6 +856,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
+ 		struct urb		*u;
+ 		struct usb_ctrlrequest	req;
+ 		struct subcase		*reqp;
++
++		/* sign of this variable means:
++		 *  -: tested code must return this (negative) error code
++		 *  +: tested code may return this (negative too) error code
++		 */
+ 		int			expected = 0;
+ 
+ 		/* requests here are mostly expected to succeed on any
+diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
+index 2cffec8..9ba64cc 100644
+--- a/drivers/usb/serial/Kconfig
++++ b/drivers/usb/serial/Kconfig
+@@ -447,6 +447,15 @@ config USB_SERIAL_MOS7840
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called mos7840.  If unsure, choose N.
+ 
++config USB_SERIAL_MOTOROLA
++	tristate "USB Motorola Phone modem driver"
++	---help---
++	  Say Y here if you want to use a Motorola phone with a USB
++	  connector as a modem link.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called moto_modem.  If unsure, choose N.
++
+ config USB_SERIAL_NAVMAN
+ 	tristate "USB Navman GPS device"
+ 	help
+diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
+index 7568595..17a762a 100644
+--- a/drivers/usb/serial/Makefile
++++ b/drivers/usb/serial/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)		+= kobil_sct.o
+ obj-$(CONFIG_USB_SERIAL_MCT_U232)		+= mct_u232.o
+ obj-$(CONFIG_USB_SERIAL_MOS7720)		+= mos7720.o
+ obj-$(CONFIG_USB_SERIAL_MOS7840)		+= mos7840.o
++obj-$(CONFIG_USB_SERIAL_MOTOROLA)		+= moto_modem.o
+ obj-$(CONFIG_USB_SERIAL_NAVMAN)			+= navman.o
+ obj-$(CONFIG_USB_SERIAL_OMNINET)		+= omninet.o
+ obj-$(CONFIG_USB_SERIAL_OPTION)			+= option.o
+diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c
+new file mode 100644
+index 0000000..2e8e054
+--- /dev/null
++++ b/drivers/usb/serial/moto_modem.c
+@@ -0,0 +1,70 @@
++/*
++ * Motorola USB Phone driver
++ *
++ * Copyright (C) 2008 Greg Kroah-Hartman <greg at kroah.com>
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ *
++ * {sigh}
++ * Mororola should be using the CDC ACM USB spec, but instead
++ * they try to just "do their own thing"...  This driver should handle a
++ * few phones in which a basic "dumb serial connection" is needed to be
++ * able to get a connection through to them.
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/tty.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++#include <linux/usb/serial.h>
++
++static struct usb_device_id id_table [] = {
++	{ USB_DEVICE(0x05c6, 0x3197) },	/* unknown Motorola phone */
++	{ USB_DEVICE(0x0c44, 0x0022) },	/* unknown Mororola phone */
++	{ USB_DEVICE(0x22b8, 0x2a64) },	/* Motorola KRZR K1m */
++	{ },
++};
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static struct usb_driver moto_driver = {
++	.name =		"moto-modem",
++	.probe =	usb_serial_probe,
++	.disconnect =	usb_serial_disconnect,
++	.id_table =	id_table,
++	.no_dynamic_id = 	1,
++};
++
++static struct usb_serial_driver moto_device = {
++	.driver = {
++		.owner =	THIS_MODULE,
++		.name =		"moto-modem",
++	},
++	.id_table =		id_table,
++	.num_ports =		1,
++};
++
++static int __init moto_init(void)
++{
++	int retval;
++
++	retval = usb_serial_register(&moto_device);
++	if (retval)
++		return retval;
++	retval = usb_register(&moto_driver);
++	if (retval)
++		usb_serial_deregister(&moto_device);
++	return retval;
++}
++
++static void __exit moto_exit(void)
++{
++	usb_deregister(&moto_driver);
++	usb_serial_deregister(&moto_device);
++}
++
++module_init(moto_init);
++module_exit(moto_exit);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index e4be2d4..e7e016e 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -154,8 +154,6 @@ static int  option_send_setup(struct usb_serial_port *port);
+ #define NOVATELWIRELESS_PRODUCT_MC727		0x4100
+ #define NOVATELWIRELESS_PRODUCT_MC950D		0x4400
+ 
+-#define NOVATELWIRELESS_PRODUCT_U727		0x5010
+-
+ /* FUTURE NOVATEL PRODUCTS */
+ #define NOVATELWIRELESS_PRODUCT_EVDO_1		0x6000
+ #define NOVATELWIRELESS_PRODUCT_HSPA_1		0x7000
+@@ -184,6 +182,9 @@ static int  option_send_setup(struct usb_serial_port *port);
+ #define AXESSTEL_VENDOR_ID			0x1726
+ #define AXESSTEL_PRODUCT_MV110H			0x1000
+ 
++#define ONDA_VENDOR_ID				0x19d2
++#define ONDA_PRODUCT_ET502HS			0x0002
++
+ #define BANDRICH_VENDOR_ID			0x1A8D
+ #define BANDRICH_PRODUCT_C100_1			0x1002
+ #define BANDRICH_PRODUCT_C100_2			0x1003
+@@ -269,7 +270,6 @@ static struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
+-	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel U727 */
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
+@@ -293,14 +293,17 @@ static struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8136) },	/* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
+ 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8137) },	/* Dell Wireless HSDPA 5520 */
++	{ USB_DEVICE(DELL_VENDOR_ID, 0x8138) },	/* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
+ 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
+ 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+ 	{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
++	{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
+ 	{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
+ 	{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
+ 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
+ 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+ 	{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
++	{ USB_DEVICE(0x19d2, 0x0001) }, 	/* Telstra NextG CDMA */
+ 	{ } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index a0ed889..1b09578 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -401,6 +401,14 @@ UNUSUAL_DEV(  0x04a5, 0x3010, 0x0100, 0x0100,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_IGNORE_RESIDUE ),
+ 
++#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
++UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
++		"Cypress",
++		"Cypress AT2LP",
++		US_SC_CYP_ATACB, US_PR_BULK, NULL,
++		0),
++#endif
++
+ /* Reported by Simon Levitt <simon at whattf.com>
+  * This entry needs Sub and Proto fields */
+ UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
+@@ -539,17 +547,6 @@ UNUSUAL_DEV(  0x04e6, 0x0101, 0x0200, 0x0200,
+ 		"CD-RW Device",
+ 		US_SC_8020, US_PR_CB, NULL, 0),
+ 
+-/* Entry and supporting patch by Theodore Kilgore <kilgota at auburn.edu>.
+- * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
+- * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
+- */
+-
+-UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
+-		"Kobian Mercury",
+-		"Binocam DCB-132",
+-		US_SC_DEVICE, US_PR_DEVICE, NULL,
+-		US_FL_BULK32),
+-
+ #ifdef CONFIG_USB_STORAGE_USBAT
+ UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
+ 		"Shuttle/SCM",
+@@ -565,6 +562,16 @@ UNUSUAL_DEV(  0x04e8, 0x507c, 0x0220, 0x0220,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_MAX_SECTORS_64),
+ 
++/* Entry and supporting patch by Theodore Kilgore <kilgota at auburn.edu>.
++ * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
++ * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
++ */
++UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
++		"Kobian Mercury",
++		"Binocam DCB-132",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_BULK32),
++
+ /* Reported by Bob Sass <rls at vectordb.com> -- only rev 1.33 tested */
+ UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
+ 		"Belkin",
+@@ -1304,6 +1311,16 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_IGNORE_DEVICE ),
+ 
++/* Reported by F. Aben <f.aben at option.com>
++ * This device (wrongly) has a vendor-specific device descriptor.
++ * The entry is needed so usb-storage can bind to it's mass-storage
++ * interface as an interface driver */
++UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
++		"Option",
++		"GI 0401 SD-Card",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		0 ),
++
+ #ifdef CONFIG_USB_STORAGE_ISD200
+ UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
+ 		"ATI",
+@@ -1361,13 +1378,6 @@ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_FIX_INQUIRY),
+ 
+-/* Reported by Rohan Hart <rohan.hart17 at gmail.com> */
+-UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
+-		"INTOVA",
+-		"Pixtreme",
+-		US_SC_DEVICE, US_PR_DEVICE, NULL,
+-		US_FL_FIX_CAPACITY ),
+-
+ /*
+  * Entry for Jenoptik JD 5200z3
+  *
+@@ -1684,6 +1694,16 @@ UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_IGNORE_RESIDUE ),
+ 
++/* Reported by Mauro Andreolini <andreoli at weblab.ing.unimo.it>
++ * This entry is needed to bypass the ZeroCD mechanism
++ * and to properly load as a modem device.
++ */
++UNUSUAL_DEV(  0x19d2, 0x2000, 0x0000, 0x0000,
++		"Onda ET502HS",
++		"USB MMC Storage",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_IGNORE_DEVICE),
++
+ /* patch submitted by Davide Perini <perini.davide at dpsoftware.org>
+  * and Renato Perini <rperini at email.it>
+  */
+@@ -1721,6 +1741,13 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_GO_SLOW ),
+ 
++/* Reported by Rohan Hart <rohan.hart17 at gmail.com> */
++UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
++		"INTOVA",
++		"Pixtreme",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_FIX_CAPACITY ),
++
+ /*
+  * David Härdeman <david at 2gen.com>
+  * The key makes the SCSI stack print confusing (but harmless) messages
+@@ -1745,14 +1772,6 @@ UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_CAPACITY_HEURISTICS),
+ 
+-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
+-UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
+-		"Cypress",
+-		"Cypress AT2LP",
+-		US_SC_CYP_ATACB, US_PR_BULK, NULL,
+-		0),
+-#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),
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index bb1dada..2cdaf1f 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -171,7 +171,6 @@ config FB_SYS_FOPS
+ config FB_DEFERRED_IO
+ 	bool
+ 	depends on FB
+-	default y
+ 
+ config FB_METRONOME
+ 	tristate
+diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
+index 8ffdf35..b004036 100644
+--- a/drivers/video/atmel_lcdfb.c
++++ b/drivers/video/atmel_lcdfb.c
+@@ -441,14 +441,15 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
+ 
+ 	value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
+ 
+-	value = (value / 2) - 1;
+-	dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n", value);
+-
+-	if (value <= 0) {
++	if (value < 2) {
+ 		dev_notice(info->device, "Bypassing pixel clock divider\n");
+ 		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
+ 	} else {
+-		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
++		value = (value / 2) - 1;
++		dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n",
++				value);
++		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
++				value << ATMEL_LCDC_CLKVAL_OFFSET);
+ 		info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
+ 		dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
+ 					PICOS2KHZ(info->var.pixclock));
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index ad31983..5fa8b76 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -1853,6 +1853,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ 	struct display *p = &fb_display[vc->vc_num];
+ 	int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
++	unsigned short saved_ec;
++	int ret;
+ 
+ 	if (fbcon_is_inactive(vc, info))
+ 		return -EINVAL;
+@@ -1865,6 +1867,11 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 	 *           whole screen (prevents flicker).
+ 	 */
+ 
++	saved_ec = vc->vc_video_erase_char;
++	vc->vc_video_erase_char = vc->vc_scrl_erase_char;
++
++	ret = 0;
++
+ 	switch (dir) {
+ 	case SM_UP:
+ 		if (count > vc->vc_rows)	/* Maximum realistic size */
+@@ -1883,7 +1890,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 							(b - count)),
+ 				    vc->vc_scrl_erase_char,
+ 				    vc->vc_size_row * count);
+-			return 1;
++			ret = 1;
+ 			break;
+ 
+ 		case SCROLL_WRAP_MOVE:
+@@ -1955,7 +1962,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 							(b - count)),
+ 				    vc->vc_scrl_erase_char,
+ 				    vc->vc_size_row * count);
+-			return 1;
++			ret = 1;
++			break;
+ 		}
+ 		break;
+ 
+@@ -1974,7 +1982,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 							t),
+ 				    vc->vc_scrl_erase_char,
+ 				    vc->vc_size_row * count);
+-			return 1;
++			ret = 1;
+ 			break;
+ 
+ 		case SCROLL_WRAP_MOVE:
+@@ -2044,10 +2052,13 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 							t),
+ 				    vc->vc_scrl_erase_char,
+ 				    vc->vc_size_row * count);
+-			return 1;
++			ret = 1;
++			break;
+ 		}
++		break;
+ 	}
+-	return 0;
++	vc->vc_video_erase_char = saved_ec;
++	return ret;
+ }
+ 
+ 
+@@ -2507,6 +2518,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
+ 			c = vc->vc_video_erase_char;
+ 			vc->vc_video_erase_char =
+ 			    ((c & 0xfe00) >> 1) | (c & 0xff);
++			c = vc->vc_def_color;
++			vc->vc_scrl_erase_char =
++			    ((c & 0xFE00) >> 1) | (c & 0xFF);
+ 			vc->vc_attr >>= 1;
+ 		}
+ 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
+@@ -2537,9 +2551,14 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
+ 			if (vc->vc_can_do_color) {
+ 				vc->vc_video_erase_char =
+ 				    ((c & 0xff00) << 1) | (c & 0xff);
++				c = vc->vc_def_color;
++				vc->vc_scrl_erase_char =
++				    ((c & 0xFF00) << 1) | (c & 0xFF);
+ 				vc->vc_attr <<= 1;
+-			} else
++			} else {
+ 				vc->vc_video_erase_char = c & ~0x100;
++				vc->vc_scrl_erase_char = c & ~0x100;
++			}
+ 		}
+ 
+ 	}
+diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
+index cd9d4cc..aaef916 100644
+--- a/drivers/video/geode/lxfb_ops.c
++++ b/drivers/video/geode/lxfb_ops.c
+@@ -63,54 +63,32 @@ static const struct {
+   { 0x00014284,  19688 },
+   { 0x00011104,  20400 },
+   { 0x00016363,  23625 },
+-  { 0x00015303,  24380 },
+   { 0x000031AC,  24923 },
+   { 0x0000215D,  25175 },
+   { 0x00001087,  27000 },
+   { 0x0000216C,  28322 },
+   { 0x0000218D,  28560 },
+-  { 0x00010041,  29913 },
+   { 0x000010C9,  31200 },
+   { 0x00003147,  31500 },
+-  { 0x000141A1,  32400 },
+   { 0x000010A7,  33032 },
+-  { 0x00012182,  33375 },
+-  { 0x000141B1,  33750 },
+   { 0x00002159,  35112 },
+   { 0x00004249,  35500 },
+   { 0x00000057,  36000 },
+-  { 0x000141E1,  37125 },
+   { 0x0000219A,  37889 },
+   { 0x00002158,  39168 },
+   { 0x00000045,  40000 },
+-  { 0x000131A1,  40500 },
+-  { 0x00010061,  42301 },
+   { 0x00000089,  43163 },
+-  { 0x00012151,  43875 },
+   { 0x000010E7,  44900 },
+   { 0x00002136,  45720 },
+-  { 0x000152E1,  47250 },
+-  { 0x00010071,  48000 },
+   { 0x00003207,  49500 },
+   { 0x00002187,  50000 },
+-  { 0x00014291,  50625 },
+-  { 0x00011101,  51188 },
+-  { 0x00017481,  54563 },
+   { 0x00004286,  56250 },
+-  { 0x00014170,  57375 },
+-  { 0x00016210,  58500 },
+   { 0x000010E5,  60065 },
+-  { 0x00013140,  62796 },
+   { 0x00004214,  65000 },
+-  { 0x00016250,  65250 },
+   { 0x00001105,  68179 },
+-  { 0x000141C0,  69600 },
+-  { 0x00015220,  70160 },
+-  { 0x00010050,  72000 },
+   { 0x000031E4,  74250 },
+   { 0x00003183,  75000 },
+   { 0x00004284,  78750 },
+-  { 0x00012130,  80052 },
+   { 0x00001104,  81600 },
+   { 0x00006363,  94500 },
+   { 0x00005303,  97520 },
+diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
+index 9de1c11..39ac49e 100644
+--- a/drivers/video/logo/Kconfig
++++ b/drivers/video/logo/Kconfig
+@@ -27,6 +27,16 @@ config LOGO_LINUX_CLUT224
+ 	bool "Standard 224-color Linux logo"
+ 	default y
+ 
++config LOGO_BLACKFIN_VGA16
++	bool "16-colour Blackfin Processor Linux logo"
++	depends on BLACKFIN
++	default y
++
++config LOGO_BLACKFIN_CLUT224
++	bool "224-colour Blackfin Processor Linux logo"
++	depends on BLACKFIN
++	default y
++
+ config LOGO_DEC_CLUT224
+ 	bool "224-color Digital Equipment Corporation Linux logo"
+ 	depends on MACH_DECSTATION || ALPHA
+diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
+index a5fc4ed..b91251d 100644
+--- a/drivers/video/logo/Makefile
++++ b/drivers/video/logo/Makefile
+@@ -4,6 +4,8 @@ obj-$(CONFIG_LOGO)			+= logo.o
+ obj-$(CONFIG_LOGO_LINUX_MONO)		+= logo_linux_mono.o
+ obj-$(CONFIG_LOGO_LINUX_VGA16)		+= logo_linux_vga16.o
+ obj-$(CONFIG_LOGO_LINUX_CLUT224)	+= logo_linux_clut224.o
++obj-$(CONFIG_LOGO_BLACKFIN_CLUT224)	+= logo_blackfin_clut224.o
++obj-$(CONFIG_LOGO_BLACKFIN_VGA16)	+= logo_blackfin_vga16.o
+ obj-$(CONFIG_LOGO_DEC_CLUT224)		+= logo_dec_clut224.o
+ obj-$(CONFIG_LOGO_MAC_CLUT224)		+= logo_mac_clut224.o
+ obj-$(CONFIG_LOGO_PARISC_CLUT224)	+= logo_parisc_clut224.o
+diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
+index fc72684..2e85a2b 100644
+--- a/drivers/video/logo/logo.c
++++ b/drivers/video/logo/logo.c
+@@ -24,6 +24,8 @@
+ extern const struct linux_logo logo_linux_mono;
+ extern const struct linux_logo logo_linux_vga16;
+ extern const struct linux_logo logo_linux_clut224;
++extern const struct linux_logo logo_blackfin_vga16;
++extern const struct linux_logo logo_blackfin_clut224;
+ extern const struct linux_logo logo_dec_clut224;
+ extern const struct linux_logo logo_mac_clut224;
+ extern const struct linux_logo logo_parisc_clut224;
+@@ -65,6 +67,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
+ 		/* Generic Linux logo */
+ 		logo = &logo_linux_vga16;
+ #endif
++#ifdef CONFIG_LOGO_BLACKFIN_VGA16
++		/* Blackfin processor logo */
++		logo = &logo_blackfin_vga16;
++#endif
+ #ifdef CONFIG_LOGO_SUPERH_VGA16
+ 		/* SuperH Linux logo */
+ 		logo = &logo_superh_vga16;
+@@ -76,6 +82,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
+ 		/* Generic Linux logo */
+ 		logo = &logo_linux_clut224;
+ #endif
++#ifdef CONFIG_LOGO_BLACKFIN_CLUT224
++		/* Blackfin Linux logo */
++		logo = &logo_blackfin_clut224;
++#endif
+ #ifdef CONFIG_LOGO_DEC_CLUT224
+ 		/* DEC Linux logo on MIPS/MIPS64 or ALPHA */
+ 		logo = &logo_dec_clut224;
+diff --git a/drivers/video/logo/logo_blackfin_clut224.ppm b/drivers/video/logo/logo_blackfin_clut224.ppm
+new file mode 100644
+index 0000000..dc9a50a
+--- /dev/null
++++ b/drivers/video/logo/logo_blackfin_clut224.ppm
+@@ -0,0 +1,1127 @@
++P3
++# This was generated by the GIMP & Netpbm tools
++# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm)
++# pnmquant 224 linux_bf.ppm | pnmnoraw > logo_blackfin_clut224.ppm
++#
++80 80
++255
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++1 1 1  3 3 3  4 6 6  6 6 6  4 6 6  3 3 3
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  2 2 2  10 10 10  26 26 27
++44 44 45  66 66 66  78 81 81  78 81 81  75 75 76  60 60 60
++39 39 39  20 20 20  6 6 6  1 1 1  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  2 2 2  14 14 14  47 47 47  84 84 84  75 75 76
++47 47 47  12 12 12  0 0 0  0 0 0  0 0 0  20 20 20
++53 54 54  81 81 82  74 74 74  31 31 31  6 6 6  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++4 4 4  34 34 35  84 84 84  60 60 60  4 4 4  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  17 18 18  75 75 76  66 66 66  17 18 18
++1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  3 3 3
++42 42 43  84 84 84  8 8 8  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 3 3  36 40 40  10 16 16  0 0 0  31 31 31  84 84 84
++29 29 30  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  26 27 27
++84 84 84  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++15 19 19  114 115 115  110 114 114  44 46 46  0 0 0  12 12 12
++90 87 86  24 24 24  1 1 1  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  8 8 8  75 75 76
++14 14 14  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++30 40 40  133 133 133  129 130 130  78 85 85  23 31 30  0 0 0
++19 19 19  78 81 81  13 13 13  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  26 27 27  81 81 82
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++36 40 40  89 90 91  55 63 63  23 31 30  4 6 6  0 0 0
++0 0 0  60 60 60  47 47 47  2 2 2  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  2 2 2  53 54 54  34 34 35
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++4 10 10  7 9 9  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  1 1 1  84 84 84  13 13 13  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  4 6 6  78 81 81  2 2 2
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  65 64 64  36 36 36  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  10 11 11  81 81 82  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  12 12 12  67 70 70  4 4 4  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  16 16 16  81 81 82  0 0 0
++0 0 0  0 0 0  4 10 10  44 50 50  18 21 21  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 1 1  78 85 85  120 121 122  7 9 9  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  82 82 81  12 12 12  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  81 81 82  0 0 0
++0 0 0  2 2 2  8 8 8  55 63 63  108 110 110  52 58 58
++0 0 0  0 0 0  0 0 0  0 0 0  42 42 43  129 130 130
++140 142 143  114 115 115  110 114 114  129 130 130  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  75 75 76  24 24 24  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  74 74 74  0 0 0
++4 6 6  167 168 167  196 196 197  196 196 197  61 65 66  78 85 85
++0 0 0  0 0 0  0 0 0  118 118 118  202 202 203  219 219 219
++219 219 219  214 214 215  187 187 188  78 85 85  29 33 34  0 0 0
++0 0 0  0 0 0  0 0 0  60 60 60  39 39 39  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  72 71 71  0 0 0
++185 185 184  244 245 245  250 251 252  251 251 252  247 248 249  36 36 36
++0 0 0  0 0 0  13 13 13  243 243 241  252 252 252  253 253 253
++253 253 253  252 252 252  247 247 246  193 193 194  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  42 42 43  50 51 51  1 1 1
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  78 81 81  0 0 0
++247 247 246  193 193 194  95 97 97  193 193 194  255 255 255  237 237 238
++0 0 0  0 0 0  202 202 203  255 255 255  247 247 246  108 107 107
++82 85 86  167 168 167  255 255 255  248 248 249  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  34 34 35  56 56 56  2 2 2
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  78 81 81  0 0 0
++250 250 251  50 51 51  153 154 155  150 151 151  244 245 245  244 245 245
++44 50 50  84 89 89  153 154 155  255 255 255  140 142 143  0 0 0
++149 149 150  156 155 156  237 237 238  254 254 254  67 70 70  0 0 0
++0 0 0  0 0 0  0 0 0  39 39 39  47 47 47  1 1 1
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  19 19 19  81 81 82  0 0 0
++248 248 249  34 34 35  72 71 71  165 165 165  202 202 203  244 245 245
++10 16 16  82 85 86  89 90 91  255 255 255  95 97 97  0 0 0
++0 0 0  53 54 54  177 177 174  255 255 255  127 127 126  0 0 0
++0 0 0  0 0 0  0 0 0  39 39 39  36 36 36  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  14 14 14  78 81 81  0 0 0
++243 243 243  89 90 91  0 0 0  36 40 40  201 147 55  241 205 27
++241 205 27  241 205 27  241 205 27  238 192 33  108 110 110  0 0 0
++0 0 0  0 0 0  191 190 190  254 254 254  34 34 35  0 0 0
++0 0 0  0 0 0  0 0 0  42 42 43  42 42 43  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  10 10 10  75 75 76  0 0 0
++202 202 203  218 217 217  21 19 17  230 165 41  199 129 48  213 157 40
++244 212 23  243 206 27  180 121 62  243 206 27  244 209 25  226 179 40
++15 10 7  103 103 103  254 254 254  251 251 252  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  17 18 18  58 58 58  2 2 2
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  9 9 9  84 84 84  0 0 0
++0 0 0  226 226 219  213 157 40  244 209 25  245 211 23  245 211 23
++245 214 38  245 214 38  245 211 23  245 211 23  245 211 23  244 212 23
++244 212 23  241 205 27  226 179 40  196 196 197  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  4 6 6
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  7 7 7  84 84 84  0 0 0
++54 42 32  213 157 40  243 206 27  245 211 23  245 211 23  245 211 23
++245 215 41  245 214 35  245 211 23  245 211 23  245 214 35  245 215 41
++245 214 35  245 211 23  245 211 23  238 204 29  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  81 81 82  12 12 12
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  4 6 6  74 74 74  0 0 0
++201 147 55  241 205 27  245 211 23  245 211 23  245 211 23  245 213 29
++245 214 38  245 211 23  245 211 23  245 214 35  245 215 41  245 215 41
++245 213 29  142 83 36  142 83 36  244 209 25  1 1 1  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  25 25 26
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  4 4 4  72 71 71  6 6 6
++213 157 40  244 209 25  245 211 23  245 211 23  245 211 23  245 213 29
++244 212 23  245 211 23  245 214 35  245 215 41  245 215 41  245 213 29
++142 83 36  142 83 36  238 192 33  241 205 27  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  44 44 44  49 50 50
++2 2 2  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  3 3 3  65 64 64  17 18 18
++199 129 48  199 129 48  245 211 23  245 211 23  245 211 23  245 211 23
++245 211 23  244 212 23  245 214 38  245 214 38  142 83 36  142 83 36
++142 83 36  245 211 23  244 210 23  230 165 41  0 0 0  0 0 0
++78 81 81  114 115 115  73 79 79  0 0 0  3 3 3  81 81 82
++9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  1 1 1  49 50 50  29 29 30
++90 87 86  199 129 48  173 101 51  173 101 51  245 211 23  245 211 23
++245 211 23  230 165 41  142 83 36  142 83 36  142 83 36  245 211 23
++244 210 23  241 205 27  230 165 41  175 173 165  3 3 3  0 0 0
++44 46 46  118 118 118  118 118 118  108 110 110  0 0 0  75 75 76
++28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  1 1 1  52 53 53  26 26 27
++118 118 118  175 173 165  199 129 48  173 101 51  173 101 51  173 101 51
++173 101 51  142 83 36  173 101 51  245 211 23  244 209 25  238 204 29
++213 157 40  214 196 166  227 227 227  214 214 215  120 121 122  0 0 0
++0 0 0  108 110 110  118 118 118  118 118 118  0 0 0  23 23 23
++66 66 66  4 6 6  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  7 7 7  75 75 76  4 4 4
++127 127 126  205 205 205  181 181 181  199 129 48  226 179 40  244 209 25
++244 209 25  244 209 25  243 206 27  238 192 33  213 157 40  187 166 103
++234 234 234  248 248 249  251 252 252  248 248 249  214 214 215  0 0 0
++0 0 0  0 0 0  103 103 103  100 103 103  0 0 0  0 0 0
++78 81 81  24 24 24  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  26 27 27  82 82 81  0 0 0
++146 146 147  234 234 234  222 221 221  178 178 179  180 121 62  213 157 40
++213 157 40  213 157 40  201 147 55  180 121 62  219 219 219  243 243 241
++253 253 253  255 255 255  255 255 255  255 255 255  250 250 251  120 121 122
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++20 20 20  72 71 71  8 8 8  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  10 10 10  75 75 76  22 22 22  0 0 0
++205 205 205  253 253 253  247 248 249  212 211 212  178 178 179  161 161 162
++165 165 165  181 181 181  205 205 205  227 227 227  244 245 245  254 254 254
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  239 239 240
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  67 70 70  39 39 39  2 2 2  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  4 4 4  50 51 51  60 60 60  0 0 0  16 16 16
++249 250 251  255 255 255  255 255 255  240 240 240  209 210 210  193 193 194
++200 200 197  212 211 212  231 231 231  246 247 248  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  253 253 253
++153 154 155  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  3 3 3  84 84 84  20 20 20  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++2 2 2  33 33 34  81 81 82  0 0 0  0 0 0  231 231 231
++255 255 255  255 255 255  255 255 255  253 253 253  234 234 234  222 221 221
++227 227 227  237 237 238  250 250 251  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++240 240 240  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  26 27 27  72 71 71  8 8 8  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
++21 21 22  84 84 84  7 7 7  0 0 0  150 151 151  252 252 252
++255 255 255  255 255 255  255 255 255  255 255 255  252 252 252  244 245 245
++246 247 248  253 253 253  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++251 251 252  9 9 9  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  65 64 64  47 47 47  3 3 3
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  12 12 12
++75 75 76  26 26 27  0 0 0  1 1 1  239 239 240  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  202 202 203  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  84 84 84  28 28 29
++1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  4 4 4  55 55 55
++60 60 60  0 0 0  0 0 0  95 97 97  248 248 249  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  244 245 245  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  14 14 14  82 82 81
++15 15 15  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  1 1 1  29 29 30  84 84 84
++0 0 0  0 0 0  0 0 0  156 155 156  247 247 246  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  247 247 246  240 240 240  232 232 233  232 232 233
++243 243 243  253 253 253  53 54 54  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  44 44 44
++60 60 60  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  10 10 10  81 81 82  14 14 14
++0 0 0  0 0 0  6 6 6  150 151 151  214 214 215  250 251 252
++255 255 255  255 255 255  255 255 255  246 247 248  218 217 217  214 214 215
++218 217 217  244 245 245  255 255 255  255 255 255  255 255 255  250 248 249
++232 232 233  214 214 215  196 196 197  182 183 184  181 181 181  181 181 181
++187 187 188  240 240 240  232 232 233  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++78 81 81  34 34 35  1 1 1  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  1 1 1  39 39 39  74 74 74  0 0 0
++0 0 0  0 0 0  60 60 60  161 161 162  200 200 197  229 229 230
++251 251 252  255 255 255  255 255 255  255 255 255  243 243 241  214 214 215
++248 248 249  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
++239 239 240  214 214 215  193 193 194  182 183 184  178 178 179  176 177 177
++176 177 177  182 183 184  248 248 249  14 14 14  0 0 0  61 65 66
++10 16 16  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++10 10 10  84 84 84  13 13 13  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  10 11 11  82 82 81  7 7 7  0 0 0
++0 0 0  0 0 0  165 165 165  229 229 230  249 250 251  254 254 254
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  253 253 253  240 240 240  227 227 227  205 205 205
++181 181 181  176 177 177  191 190 190  227 227 227  0 0 0  44 50 50
++84 89 89  61 65 66  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  58 58 58  49 50 50  3 3 3  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  1 1 1  36 36 36  66 66 66  0 0 0  29 33 34
++0 3 3  26 27 27  234 234 234  254 254 254  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++254 254 254  253 253 254  252 253 253  253 253 254  253 254 254  253 254 254
++254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  251 251 252
++227 227 227  187 187 188  176 177 177  222 221 221  13 13 13  0 0 0
++12 15 14  73 79 79  36 40 40  0 0 0  0 0 0  0 0 0
++0 0 0  1 1 1  90 87 86  17 18 18  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  7 7 7  78 81 81  12 12 12  23 31 30  52 58 58
++0 0 0  209 210 210  253 253 253  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
++251 251 252  150 151 151  103 103 103  129 130 130  196 196 197  250 250 251
++252 252 253  254 254 254  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  240 240 240  193 193 194  196 196 197  229 229 230  0 0 0
++0 0 0  4 10 10  30 40 40  0 3 3  0 0 0  0 0 0
++0 0 0  0 0 0  47 47 47  53 54 54  3 3 3  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  23 23 23  81 81 82  0 0 0  52 58 58  36 40 40
++42 42 43  250 250 251  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
++227 227 227  7 7 7  7 7 7  7 7 7  7 7 7  44 44 45
++156 155 156  249 250 251  253 253 253  254 254 254  255 255 255  255 255 255
++255 255 255  255 255 255  247 247 246  222 221 221  239 239 240  0 0 0
++30 40 40  44 50 50  23 31 30  29 33 34  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  90 87 86  16 16 16  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++2 2 2  50 51 51  42 42 43  29 33 34  52 58 58  0 0 0
++232 232 233  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
++250 251 252  44 44 44  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  56 56 56  209 210 210  252 252 253  254 254 254  255 255 255
++255 255 255  255 255 255  255 255 255  254 253 253  249 250 251  146 146 147
++36 40 40  44 50 50  36 40 40  67 70 70  61 65 66  0 0 0
++0 0 0  0 0 0  0 0 0  55 55 55  44 44 45  1 1 1
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++10 10 10  81 81 82  1 1 1  52 58 58  44 50 50  52 53 53
++251 251 252  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
++253 253 253  187 187 188  8 8 8  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  19 19 19  178 178 179  252 252 253  254 254 254
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  237 237 238
++10 16 16  30 40 40  0 3 3  23 31 30  84 89 89  0 0 0
++0 0 0  0 0 0  0 0 0  3 3 3  81 81 82  9 9 9
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++29 29 30  72 71 71  10 16 16  52 58 58  0 0 0  222 221 221
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++254 254 254  251 251 252  95 97 97  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  10 10 10  161 161 162  251 252 252
++254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  248 248 249
++0 0 0  0 0 0  0 0 0  0 0 0  84 89 89  0 3 3
++0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  26 27 27
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  4 4 4
++65 64 64  20 20 20  20 25 25  30 40 40  0 0 0  247 247 246
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  253 253 254  222 221 221  9 9 9  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  8 8 8  149 149 150
++252 252 253  254 254 254  255 255 255  255 255 255  255 255 255  252 252 252
++0 0 0  0 0 0  0 0 0  0 0 0  73 79 79  12 15 14
++0 0 0  0 0 0  0 0 0  0 0 0  36 36 36  58 58 58
++3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  20 20 20
++74 74 74  0 0 0  4 10 10  4 10 10  36 36 36  252 252 252
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  227 227 227  253 253 253  255 255 255
++255 255 255  254 254 254  250 251 252  65 64 64  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  8 8 8
++146 146 147  251 252 252  254 254 254  255 255 255  255 255 255  253 254 254
++0 0 0  0 0 0  0 0 0  0 0 0  52 58 58  10 16 16
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  82 82 81
++9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  4 6 6  65 64 64
++25 25 25  0 3 3  30 40 40  0 0 0  187 187 188  254 254 254
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  193 193 194  253 252 252  255 255 255
++255 255 255  255 255 255  252 253 253  129 130 130  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++8 8 8  149 149 150  252 252 253  254 254 254  255 255 255  254 254 254
++52 53 53  0 0 0  0 0 0  0 0 0  20 25 25  2 5 4
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  81 81 82
++20 20 20  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  26 26 27  81 81 82
++0 0 0  18 21 21  73 79 79  0 0 0  237 237 238  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  182 183 184  255 255 255  255 255 255
++255 255 255  255 255 255  253 253 253  176 177 177  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  8 8 8  153 154 155  251 252 252  254 254 254  255 255 255
++150 151 151  0 0 0  0 0 0  0 0 0  20 25 25  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  65 64 64
++33 33 34  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  6 6 6  67 70 70  20 20 20
++0 0 0  23 31 30  82 85 86  0 0 0  247 247 246  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  182 183 184  255 255 255  255 255 255
++255 255 255  255 255 255  253 254 254  214 214 215  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  8 8 8  156 155 156  252 252 253  254 254 254
++167 168 167  0 0 0  0 0 0  0 0 0  67 70 70  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  47 47 47
++44 44 44  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  21 21 22  75 75 76  0 0 0
++0 0 0  29 33 34  84 89 89  0 0 0  248 248 249  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  248 248 249  181 181 181  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  240 240 240  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  8 8 8  161 161 162  251 252 252
++185 185 184  4 4 4  0 0 0  10 11 11  100 103 103  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 36 36
++55 55 55  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  33 33 34  50 51 51  0 0 0
++0 0 0  9 11 11  82 85 86  10 16 16  248 248 249  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  245 244 245  179 180 181  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  251 252 252  20 20 20  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  10 10 10  161 161 162
++205 205 205  17 18 18  0 0 0  95 97 97  78 81 81  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 36 36
++53 54 54  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  31 31 31  58 58 58  0 0 0
++0 0 0  0 0 0  67 70 70  78 81 81  248 248 249  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  234 234 234  179 180 181  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  251 252 252  23 23 23  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++10 11 11  84 84 84  161 161 162  209 210 210  229 229 230  237 237 238
++202 202 203  26 26 27  9 11 11  44 50 50  0 0 0  4 6 6
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  52 53 53
++39 39 39  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  23 23 23  78 81 81  213 157 40
++243 206 27  243 206 27  54 42 32  73 79 79  222 221 221  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  238 238 236  178 178 179  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  251 252 253  36 36 36  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  84 84 84
++222 221 221  251 252 252  252 253 253  253 253 253  253 254 254  252 252 253
++146 146 147  140 142 143  156 155 156  110 114 114  26 27 27  82 85 86
++84 89 89  95 97 97  36 40 40  0 0 0  0 0 0  74 74 74
++23 23 23  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  14 14 14
++24 24 24  26 26 27  26 26 27  26 26 27  25 25 26  21 21 22
++7 7 7  0 0 0  1 1 1  34 34 35  238 192 33  244 210 23
++244 212 23  244 212 23  244 210 23  88 79 47  200 200 197  254 254 254
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  244 245 245  179 180 181  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  252 252 253  36 36 36  7 7 7
++7 7 7  7 7 7  7 7 7  8 8 8  149 149 150  251 251 252
++252 252 253  253 253 253  253 253 253  250 248 249  239 223 156  239 223 156
++120 121 122  182 183 184  176 177 177  120 121 122  33 33 34  3 3 3
++0 0 0  67 70 70  146 146 147  20 25 25  1 1 1  82 82 81
++9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  19 19 19  89 90 91
++146 146 147  150 151 151  150 151 151  150 151 151  150 151 151  129 130 130
++58 58 58  6 6 6  14 14 14  201 147 55  245 211 23  245 213 29
++245 214 35  245 215 41  245 213 29  244 210 23  142 83 36  232 232 233
++254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  185 185 184  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  251 252 252  50 51 51  7 7 7
++7 7 7  7 7 7  7 7 7  146 146 147  251 252 252  252 253 253
++251 252 253  239 239 240  171 168 154  129 130 130  137 136 134  175 173 165
++221 218 200  65 64 64  22 22 22  186 186 187  114 115 115  26 26 27
++2 2 2  0 0 0  61 65 66  31 33 27  238 192 33  108 96 91
++9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  2 2 2  52 53 53  178 178 179
++21 21 22  7 7 7  7 7 7  7 7 7  7 7 7  118 118 118
++137 136 134  36 36 36  65 64 64  243 206 27  244 212 23  245 215 41
++245 215 41  245 215 41  245 215 41  244 209 25  244 209 25  1 1 1
++219 219 219  253 253 253  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  214 214 215  255 255 255  255 255 255
++255 255 255  255 255 255  254 254 254  252 252 253  50 51 51  7 7 7
++7 7 7  7 7 7  84 84 84  250 251 252  252 253 253  251 251 252
++167 168 167  22 22 22  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  34 34 35  187 187 188  103 103 103
++29 29 30  3 3 3  7 9 9  238 204 29  245 215 41  245 214 35
++28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  7 7 7  90 87 86  178 178 179
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  16 16 16
++193 193 194  133 133 133  187 166 103  245 218 76  245 218 76  245 216 51
++245 216 51  245 218 76  246 224 96  245 218 76  245 218 76  245 218 76
++25 25 25  186 186 187  252 252 252  254 254 254  254 254 254  253 254 254
++254 254 254  254 254 254  254 254 254  246 247 248  254 254 254  253 254 254
++254 254 254  254 254 254  253 254 254  251 252 252  36 36 36  7 7 7
++7 7 7  20 20 20  229 229 230  253 253 253  252 253 253  178 178 179
++10 10 10  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  42 42 43  196 196 197
++118 118 118  33 33 34  238 204 29  245 215 41  245 215 41  245 215 41
++49 50 50  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  17 18 18  120 121 122  137 136 134
++7 7 7  7 7 7  34 34 35  20 20 20  7 7 7  7 7 7
++202 202 203  209 206 202  193 187 162  193 187 162  248 234 156  245 218 76
++245 218 76  248 234 156  193 187 162  193 187 162  193 187 162  214 196 166
++240 219 129  95 97 97  196 196 197  186 186 187  187 187 188  196 196 197
++252 252 253  251 252 253  212 211 212  187 187 188  196 196 197  251 252 252
++218 217 217  187 187 188  191 190 190  250 251 252  24 24 24  7 7 7
++7 7 7  110 114 114  252 252 253  253 254 254  250 251 252  89 90 91
++89 90 91  129 130 130  127 127 126  44 44 44  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  49 50 50
++202 202 203  214 196 166  245 216 51  245 214 38  245 214 35  245 214 38
++58 58 58  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  31 31 31  156 155 156  82 82 81
++7 7 7  10 10 10  237 237 238  66 66 66  7 7 7  25 25 25
++247 248 249  81 81 82  7 7 7  31 31 31  247 237 174  245 218 76
++246 226 108  200 200 197  7 7 7  7 7 7  7 7 7  137 136 134
++247 237 174  193 193 194  72 71 71  7 7 7  7 7 7  8 8 8
++196 196 197  250 251 252  67 70 70  7 7 7  84 84 84  244 245 245
++47 47 47  7 7 7  118 118 118  249 250 251  12 12 12  7 7 7
++9 9 9  218 217 217  253 253 253  254 254 254  252 253 253  251 251 252
++249 250 251  237 237 238  95 97 97  9 9 9  15 15 15  95 97 97
++47 47 47  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++66 66 66  240 230 197  246 226 108  245 214 38  245 211 23  244 212 23
++65 64 64  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  2 2 2  52 53 53  185 185 184  25 25 25
++7 7 7  60 60 60  240 240 240  14 14 14  7 7 7  84 84 84
++247 248 249  23 23 23  7 7 7  94 91 88  248 234 156  245 218 76
++248 234 156  127 127 126  7 7 7  7 7 7  7 7 7  167 168 167
++251 248 240  65 64 64  7 7 7  7 7 7  7 7 7  7 7 7
++84 84 84  243 243 243  15 15 15  7 7 7  140 142 143  146 146 147
++7 7 7  33 33 34  237 237 238  243 243 243  21 21 22  120 121 122
++218 217 217  252 252 253  254 254 254  253 253 254  252 253 253  251 252 252
++247 248 249  72 71 71  7 7 7  58 58 58  222 221 221  248 248 249
++75 75 76  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  82 82 81  246 239 193  246 226 108  245 216 51  245 214 38
++238 192 33  21 21 22  1 1 1  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  8 8 8  90 87 86  182 183 184  7 7 7
++7 7 7  120 121 122  187 187 188  7 7 7  7 7 7  146 146 147
++205 205 205  7 7 7  7 7 7  153 153 148  240 219 129  246 224 96
++246 239 193  39 39 39  60 60 60  108 110 110  7 7 7  202 202 203
++227 227 227  7 7 7  7 7 7  205 205 205  89 90 91  7 7 7
++120 121 122  193 193 194  7 7 7  7 7 7  186 186 187  25 25 25
++7 7 7  167 168 167  251 251 252  243 243 243  214 214 215  250 251 252
++251 252 253  254 254 254  253 253 253  219 219 219  140 140 139  140 140 139
++118 118 118  7 7 7  52 53 53  237 237 238  247 247 246  176 177 177
++8 8 8  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  95 97 97  246 239 193  246 226 108  245 216 51
++245 214 38  201 147 55  31 31 31  103 103 103  103 103 103  72 71 71
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  17 18 18  127 127 126  140 140 139  7 7 7
++7 7 7  17 18 18  17 18 18  7 7 7  95 97 97  244 245 245
++146 146 147  7 7 7  7 7 7  200 200 197  246 226 108  240 219 129
++194 194 184  7 7 7  140 140 139  89 90 91  7 7 7  232 232 233
++165 165 165  7 7 7  31 31 31  249 250 251  39 39 39  7 7 7
++176 177 177  133 133 133  7 7 7  22 22 22  108 110 110  7 7 7
++72 71 71  251 252 252  252 253 253  250 251 252  247 248 249  205 205 205
++251 252 253  254 254 254  252 252 253  84 84 84  7 7 7  7 7 7
++7 7 7  7 7 7  140 142 143  247 248 249  140 140 139  14 14 14
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  16 16 16
++14 14 14  7 7 7  7 7 7  114 115 115  246 239 193  246 224 96
++245 216 51  245 216 51  243 235 220  176 177 177  185 185 184  229 229 230
++47 47 47  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  31 31 31  156 155 156  90 87 86  7 7 7
++7 7 7  7 7 7  7 7 7  31 31 31  243 243 241  247 247 246
++84 84 84  7 7 7  26 27 27  246 239 193  246 226 108  248 234 156
++108 110 110  7 7 7  212 211 212  44 44 44  22 22 22  249 250 251
++108 107 107  7 7 7  89 90 91  238 238 236  114 115 115  118 118 118
++231 231 231  75 75 76  7 7 7  34 34 35  10 11 11  12 12 12
++214 214 215  253 253 253  253 253 253  200 200 197  31 31 31  103 103 103
++252 252 253  252 253 253  218 217 217  9 9 9  7 7 7  7 7 7
++7 7 7  7 7 7  25 25 25  39 39 39  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  103 103 103  234 234 234
++181 181 181  7 7 7  7 7 7  7 7 7  133 133 133  247 237 174
++246 224 96  246 226 108  185 185 184  177 177 174  153 154 155  181 181 181
++140 140 139  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  1 1 1  49 50 50  186 186 187  28 28 28  7 7 7
++12 12 12  22 22 22  7 7 7  7 7 7  108 107 107  247 247 246
++25 25 25  7 7 7  90 87 86  247 237 174  246 226 108  246 239 193
++28 28 28  44 44 44  237 237 238  9 9 9  53 54 54  249 250 251
++49 50 50  7 7 7  153 153 148  249 241 199  214 196 166  185 185 184
++229 229 230  19 19 19  7 7 7  7 7 7  7 7 7  103 103 103
++251 252 253  254 254 254  253 253 253  150 151 151  7 7 7  187 187 188
++252 252 253  251 251 252  103 103 103  7 7 7  7 7 7  7 7 7
++7 7 7  23 23 23  17 18 18  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  12 12 12  153 153 148  246 239 193  249 241 199
++161 161 162  9 9 9  84 84 84  108 110 110  25 25 25  153 153 148
++247 237 174  246 224 96  218 217 217  165 165 165  182 183 184  193 193 194
++114 115 115  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  4 4 4  74 74 74  181 181 181  7 7 7  7 7 7
++110 114 114  200 200 197  7 7 7  7 7 7  60 60 60  209 210 210
++7 7 7  7 7 7  146 146 147  248 234 156  248 234 156  177 177 174
++7 7 7  118 118 118  193 193 194  7 7 7  84 84 84  232 232 233
++8 8 8  7 7 7  209 210 210  221 218 200  193 187 162  219 219 219
++200 200 197  7 7 7  7 7 7  7 7 7  7 7 7  95 97 97
++251 252 252  254 254 254  252 253 253  118 118 118  29 29 30  247 248 249
++252 252 253  227 227 227  16 16 16  7 7 7  7 7 7  7 7 7
++100 103 103  218 217 217  219 218 214  7 7 7  7 7 7  7 7 7
++7 7 7  21 21 22  185 185 184  246 239 193  248 234 156  240 230 197
++60 60 60  194 194 184  246 239 193  249 241 199  137 136 134  10 10 10
++171 168 154  248 234 156  248 234 156  226 226 219  209 210 210  249 241 199
++28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  13 13 13  108 110 110  146 146 147  7 7 7  7 7 7
++167 168 167  140 140 139  7 7 7  7 7 7  120 121 122  146 146 147
++7 7 7  7 7 7  194 194 184  240 219 129  247 237 174  95 97 97
++7 7 7  95 97 97  90 87 86  7 7 7  118 118 118  176 177 177
++7 7 7  28 28 28  248 248 249  44 44 45  7 7 7  167 168 167
++140 140 139  7 7 7  36 36 36  74 74 74  7 7 7  65 64 64
++251 252 253  254 254 254  251 252 252  81 81 82  108 110 110  251 252 252
++251 251 252  127 127 126  7 7 7  7 7 7  8 8 8  140 140 139
++181 181 181  140 140 139  221 218 200  7 7 7  7 7 7  7 7 7
++34 34 35  209 210 210  231 231 231  246 239 193  247 237 174  194 194 184
++227 227 227  249 241 199  240 219 129  248 234 156  153 153 148  7 7 7
++13 13 13  185 185 184  248 234 156  245 218 76  245 216 51  245 214 38
++31 31 31  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  31 31 31  153 154 155  89 90 91  7 7 7  8 8 8
++232 232 233  82 82 81  7 7 7  7 7 7  179 180 181  89 90 91
++7 7 7  24 24 24  243 235 220  248 234 156  240 230 197  20 20 20
++7 7 7  7 7 7  7 7 7  7 7 7  149 149 150  118 118 118
++7 7 7  90 87 86  229 229 230  7 7 7  7 7 7  229 229 230
++82 82 81  7 7 7  95 97 97  100 103 103  7 7 7  34 34 35
++251 252 252  253 253 254  251 251 252  47 47 47  193 193 194  251 252 252
++239 239 240  23 23 23  7 7 7  13 13 13  165 165 165  234 234 234
++149 149 150  146 114 101  200 200 197  7 7 7  7 7 7  52 53 53
++227 227 227  167 168 167  16 16 16  214 196 166  248 234 156  243 235 220
++219 219 219  156 155 156  247 237 174  246 239 193  75 75 76  7 7 7
++60 60 60  227 227 227  243 235 220  240 219 129  245 218 76  245 213 29
++16 16 16  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++1 1 1  49 50 50  185 185 184  33 33 34  7 7 7  10 11 11
++56 56 56  16 16 16  7 7 7  10 10 10  237 237 238  26 27 27
++7 7 7  55 55 55  185 185 184  221 218 200  167 168 167  7 7 7
++20 20 20  39 39 39  10 11 11  7 7 7  181 181 181  58 58 58
++7 7 7  103 103 103  133 133 133  7 7 7  44 44 44  247 248 249
++24 24 24  7 7 7  156 155 156  129 130 130  7 7 7  9 9 9
++244 245 245  252 253 253  237 237 238  34 34 35  248 248 249  251 251 252
++161 161 162  7 7 7  24 24 24  187 187 188  212 211 212  67 70 70
++187 187 188  173 170 143  209 206 202  10 10 10  95 97 97  237 237 238
++129 130 130  8 8 8  89 90 91  246 239 193  247 237 174  177 177 174
++17 18 18  137 136 134  249 241 199  219 218 214  10 10 10  95 97 97
++243 243 243  150 151 151  31 31 31  221 218 200  240 219 129  53 54 54
++3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++4 4 4  72 71 71  182 183 184  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  12 12 12  161 161 162  209 210 210  7 7 7
++7 7 7  7 7 7  7 7 7  187 187 188  82 82 81  7 7 7
++146 146 147  247 248 249  17 18 18  7 7 7  212 211 212  47 47 47
++7 7 7  7 7 7  7 7 7  8 8 8  146 146 147  205 205 205
++7 7 7  7 7 7  214 214 215  156 155 156  7 7 7  7 7 7
++218 217 217  251 252 252  186 186 187  110 114 114  249 250 251  248 248 249
++75 75 76  34 34 35  205 205 205  129 130 130  16 16 16  7 7 7
++156 155 156  214 196 166  240 230 197  243 243 241  227 227 227  74 74 74
++7 7 7  29 29 30  226 226 219  249 241 199  175 173 165  14 14 14
++9 9 9  221 218 200  246 239 193  153 153 148  146 146 147  246 247 248
++110 114 114  7 7 7  7 7 7  42 42 43  193 193 194  95 97 97
++19 19 19  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++6 6 6  84 84 84  140 142 143  7 7 7  7 7 7  7 7 7
++7 7 7  20 20 20  177 177 174  249 241 199  149 149 150  7 7 7
++7 7 7  7 7 7  10 11 11  226 226 219  13 13 13  8 8 8
++219 218 214  219 218 214  7 7 7  8 8 8  238 238 236  200 200 197
++13 13 13  7 7 7  13 13 13  161 161 162  243 235 220  146 146 147
++7 7 7  29 29 30  232 232 233  176 177 177  7 7 7  7 7 7
++182 183 184  237 237 238  129 130 130  167 168 167  176 177 177  202 202 203
++10 11 11  95 97 97  44 44 45  7 7 7  7 7 7  7 7 7
++75 75 76  226 226 219  243 235 220  156 155 156  24 24 24  7 7 7
++7 7 7  176 177 177  247 247 246  200 200 197  17 18 18  7 7 7
++49 50 50  246 239 193  248 234 156  251 248 240  239 239 240  84 84 84
++7 7 7  7 7 7  7 7 7  7 7 7  60 60 60  187 187 188
++84 84 84  14 14 14  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++4 4 4  53 54 54  137 136 134  156 155 156  161 161 162  161 161 162
++167 168 167  239 223 156  240 219 129  246 226 108  239 223 156  239 223 156
++239 223 156  239 223 156  214 196 166  239 223 156  193 187 162  193 187 162
++248 234 156  239 223 156  193 187 162  193 187 162  248 234 156  248 234 156
++214 196 166  193 187 162  214 196 166  248 234 156  240 219 129  214 196 166
++193 187 162  193 187 162  171 168 154  146 146 147  137 136 134  137 136 134
++161 161 162  209 210 210  65 64 64  202 202 203  179 180 181  140 140 139
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  60 60 60  39 39 39  7 7 7  7 7 7  7 7 7
++66 66 66  249 250 251  202 202 203  16 16 16  7 7 7  7 7 7
++23 23 23  243 235 220  246 239 193  226 226 219  52 53 53  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  75 75 76
++176 177 177  66 66 66  9 9 9  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  10 10 10  28 28 29  34 34 35  36 36 36  36 36 36
++44 44 45  146 114 101  241 207 50  241 207 50  241 207 50  241 211 63
++241 211 63  241 211 63  241 211 63  241 211 63  241 211 63  245 216 51
++245 216 51  245 216 51  241 211 63  241 211 63  245 216 51  241 211 63
++245 218 76  245 218 76  245 216 51  245 215 41  245 214 38  241 207 50
++241 211 63  201 147 55  88 79 47  29 29 30  34 34 35  42 42 43
++103 103 103  191 190 190  75 75 76  196 196 197  200 200 197  65 64 64
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++90 87 86  146 146 147  19 19 19  7 7 7  7 7 7  7 7 7
++7 7 7  90 87 86  140 140 139  31 31 31  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++103 103 103  161 161 162  53 54 54  7 7 7  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  12 12 12  50 51 51  146 114 101  180 121 62  199 129 48
++201 147 55  213 157 40  213 157 40  230 165 41  226 179 40  226 179 40
++238 192 33  241 205 27  244 209 25  244 210 23  244 212 23  245 211 23
++245 211 23  245 211 23  245 211 23  244 209 25  238 204 29  226 179 40
++213 157 40  199 129 48  54 42 32  0 0 0  4 6 6  44 44 45
++150 151 151  129 130 130  137 136 134  205 205 205  202 202 203  8 8 8
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  129 130 130  146 146 147  47 47 47  4 4 4  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  2 2 2  12 12 12  28 28 29  49 50 50
++74 74 74  108 96 91  180 121 62  180 121 62  199 129 48  201 147 55
++213 157 40  230 165 41  226 179 40  238 192 33  241 205 27  241 205 27
++243 206 27  243 206 27  241 205 27  238 204 29  226 179 40  213 157 40
++199 129 48  199 129 48  21 19 17  65 64 64  103 103 103  167 168 167
++202 202 203  24 24 24  193 193 194  229 229 230  140 140 139  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  8 8 8  156 155 156  133 133 133  36 36 36  3 3 3
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
++4 4 4  10 11 11  21 21 22  39 39 39  60 60 60  108 96 91
++180 121 62  199 129 48  199 129 48  213 157 40  230 165 41  226 179 40
++226 179 40  226 179 40  226 179 40  226 179 40  213 157 40  199 129 48
++180 121 62  99 91 79  72 71 71  56 56 56  129 130 130  167 168 167
++21 21 22  17 18 18  231 231 231  229 229 230  52 53 53  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  13 13 13  176 177 177  120 121 122  33 33 34
++2 2 2  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  8 8 8
++21 21 22  47 47 47  99 91 79  180 121 62  199 129 48  199 129 48
++201 147 55  213 157 40  213 157 40  201 147 55  199 129 48  180 121 62
++99 91 79  26 26 27  9 9 9  60 60 60  186 186 187  31 31 31
++7 7 7  60 60 60  243 243 243  209 210 210  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
++7 7 7  7 7 7  7 7 7  26 27 27  193 193 194  108 110 110
++22 22 22  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  1 1 1  8 8 8  24 24 24  58 58 58  108 96 91
++180 121 62  180 121 62  180 121 62  180 121 62  180 121 62  72 71 71
++15 15 15  0 0 0  4 6 6  75 75 76  156 155 156  24 24 24
++24 24 24  108 107 107  232 232 233  137 136 134  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
++24 24 24  24 24 24  24 24 24  24 24 24  58 58 58  176 177 177
++60 60 60  3 3 3
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  12 12 12
++26 27 27  44 44 44  55 55 55  50 51 51  29 29 30  8 8 8
++0 0 0  0 0 0  3 3 3  47 47 47  127 127 126  150 151 151
++150 151 151  140 142 143  129 130 130  140 142 143  150 151 151  150 151 151
++150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
++150 151 151  150 151 151  153 154 155  161 161 162  165 165 165  167 168 167
++177 177 174  167 168 167  161 161 162  156 155 156  150 151 151  150 151 151
++150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
++150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
++150 151 151  150 151 151  150 151 151  150 151 151  149 149 150  127 127 126
++44 44 45  2 2 2
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  2 2 2  1 1 1  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  7 7 7  21 21 22  25 25 26
++25 25 26  24 24 24  20 20 20  23 23 24  25 25 26  26 26 27
++26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
++26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 27 27
++28 28 29  26 27 27  26 26 27  26 26 27  26 26 27  26 26 27
++26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
++26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
++26 26 27  26 26 27  26 26 27  26 26 27  25 25 26  21 21 22
++7 7 7  0 0 0
+diff --git a/drivers/video/logo/logo_blackfin_vga16.ppm b/drivers/video/logo/logo_blackfin_vga16.ppm
+new file mode 100644
+index 0000000..1352b02
+--- /dev/null
++++ b/drivers/video/logo/logo_blackfin_vga16.ppm
+@@ -0,0 +1,1127 @@
++P3
++# This was generated by the GIMP & Netpbm tools
++# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm)
++# ppmquant -mapfile clut_vga16.ppm linux_bf.ppm | pnmnoraw > logo_blackfin_vga16.ppm
++#
++80 80
++255
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++170 170 170  85 85 85  85 85 85  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  170 170 170  170 170 170  170 170 170  85 85 85  85 85 85
++0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  255 255 255
++255 255 255  255 255 255  170 170 170  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
++0 0 0  0 0 0  0 0 0  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++255 255 255  170 170 170  85 85 85  170 170 170  255 255 255  255 255 255
++0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  85 85 85
++85 85 85  170 170 170  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++255 255 255  85 85 85  170 170 170  170 170 170  255 255 255  255 255 255
++85 85 85  85 85 85  170 170 170  255 255 255  170 170 170  0 0 0
++170 170 170  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++255 255 255  0 0 0  85 85 85  170 170 170  170 170 170  255 255 255
++0 0 0  85 85 85  85 85 85  255 255 255  85 85 85  0 0 0
++0 0 0  85 85 85  170 170 170  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++255 255 255  85 85 85  0 0 0  0 0 0  255 85 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  85 85 85  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 170 170  255 255 255  0 0 0  255 85 85  170 85 0  170 85 0
++255 255 85  255 255 85  170 85 0  255 255 85  255 255 85  255 255 85
++0 0 0  85 85 85  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  255 255 255  255 85 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  255 85 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 85 0  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  170 85 0  85 85 85  255 255 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++255 85 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++170 85 0  85 85 85  255 255 85  255 255 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 85 0  170 85 0  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  170 85 0
++170 85 0  255 255 85  255 255 85  255 85 85  0 0 0  0 0 0
++85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++85 85 85  170 85 0  170 85 0  170 85 0  255 255 85  255 255 85
++255 255 85  255 85 85  170 85 0  170 85 0  170 85 0  255 255 85
++255 255 85  255 255 85  255 85 85  170 170 170  0 0 0  0 0 0
++85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++85 85 85  170 170 170  170 85 0  170 85 0  170 85 0  170 85 0
++170 85 0  170 85 0  170 85 0  255 255 85  255 255 85  255 255 85
++255 85 85  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 170 170  170 170 170  170 170 170  170 85 0  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 85 85  170 170 170
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++170 170 170  255 255 255  255 255 255  170 170 170  170 85 0  255 85 85
++255 85 85  255 85 85  255 85 85  255 85 85  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++170 170 170  255 255 255  255 255 255  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
++255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
++170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++85 85 85  0 0 0  0 0 0  85 85 85  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  170 170 170  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  255 255 255  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
++170 170 170  170 170 170  170 170 170  255 255 255  0 0 0  85 85 85
++85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  170 170 170  170 170 170  255 255 255  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
++0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  170 170 170  85 85 85  170 170 170  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  170 170 170  170 170 170  255 255 255  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
++0 0 0  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
++0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  85 85 85
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
++170 170 170  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  170 170 170  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 85 0
++255 255 85  255 255 85  0 0 0  85 85 85  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++170 170 170  170 170 170  170 170 170  85 85 85  0 0 0  85 85 85
++85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  85 85 85  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 85  170 170 170
++85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++85 85 85  0 0 0  0 0 0  170 85 0  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
++255 255 255  85 85 85  0 0 0  170 170 170  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  0 0 0  255 255 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++170 170 170  0 0 0  85 85 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  0 0 0
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  85 85 85  255 255 255  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0  0 0 0  255 255 85  255 255 85  255 255 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
++0 0 0  0 0 0  255 255 255  255 255 255  255 255 255  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
++85 85 85  0 0 0  255 255 85  255 255 85  255 255 85  255 255 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++170 170 170  170 170 170  170 170 170  170 170 170  255 255 85  255 255 85
++255 255 85  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
++255 255 85  85 85 85  170 170 170  170 170 170  170 170 170  170 170 170
++255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  255 255 255
++255 255 255  170 170 170  170 170 170  255 255 255  0 0 0  0 0 0
++0 0 0  85 85 85  255 255 255  255 255 255  255 255 255  85 85 85
++85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0  255 255 255  85 85 85  0 0 0  0 0 0
++255 255 255  85 85 85  0 0 0  0 0 0  255 255 255  255 255 85
++255 255 85  170 170 170  0 0 0  0 0 0  0 0 0  170 170 170
++255 255 255  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
++170 170 170  255 255 255  85 85 85  0 0 0  85 85 85  255 255 255
++85 85 85  0 0 0  85 85 85  255 255 255  0 0 0  0 0 0
++0 0 0  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  85 85 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  255 255 255  255 255 85  255 255 85  255 255 85  255 255 85
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
++0 0 0  85 85 85  255 255 255  0 0 0  0 0 0  85 85 85
++255 255 255  0 0 0  0 0 0  85 85 85  255 255 85  255 255 85
++255 255 85  85 85 85  0 0 0  0 0 0  0 0 0  170 170 170
++255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  255 255 255  0 0 0  0 0 0  170 170 170  170 170 170
++0 0 0  0 0 0  255 255 255  255 255 255  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  85 85 85  0 0 0  85 85 85  255 255 255  255 255 255
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  255 255 255  255 255 85  255 255 85  255 255 85
++255 255 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  170 170 170
++170 170 170  0 0 0  0 0 0  170 170 170  255 255 85  255 255 85
++255 255 255  0 0 0  85 85 85  85 85 85  0 0 0  170 170 170
++255 255 255  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
++85 85 85  170 170 170  0 0 0  0 0 0  170 170 170  0 0 0
++0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
++255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
++85 85 85  0 0 0  85 85 85  255 255 255  255 255 255  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  255 255 255  255 255 85  255 255 85
++255 255 85  170 85 0  0 0 0  85 85 85  85 85 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
++170 170 170  0 0 0  0 0 0  170 170 170  255 255 85  255 255 85
++170 170 170  0 0 0  170 170 170  85 85 85  0 0 0  255 255 255
++170 170 170  0 0 0  0 0 0  255 255 255  0 0 0  0 0 0
++170 170 170  170 170 170  0 0 0  0 0 0  85 85 85  0 0 0
++85 85 85  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
++255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  255 255 255  255 255 85
++255 255 85  255 255 85  255 255 255  170 170 170  170 170 170  255 255 255
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  255 255 255  255 255 255
++85 85 85  0 0 0  0 0 0  255 255 255  255 255 85  255 255 85
++85 85 85  0 0 0  255 255 255  85 85 85  0 0 0  255 255 255
++85 85 85  0 0 0  85 85 85  255 255 255  85 85 85  85 85 85
++255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++255 255 85  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
++0 0 0  0 0 0  85 85 85  255 255 85  255 255 85  255 255 255
++0 0 0  85 85 85  255 255 255  0 0 0  85 85 85  255 255 255
++85 85 85  0 0 0  170 170 170  255 255 255  170 170 170  170 170 170
++255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  170 170 170
++255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
++170 170 170  0 0 0  85 85 85  85 85 85  0 0 0  170 170 170
++255 255 85  255 255 85  255 255 255  170 170 170  170 170 170  170 170 170
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
++85 85 85  170 170 170  0 0 0  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  170 170 170  255 255 85  255 255 85  170 170 170
++0 0 0  85 85 85  170 170 170  0 0 0  85 85 85  255 255 255
++0 0 0  0 0 0  170 170 170  170 170 170  170 170 170  255 255 255
++170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  255 255 255
++255 255 255  255 255 255  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  255 255 85  255 255 255
++85 85 85  170 170 170  255 255 255  255 255 255  170 170 170  0 0 0
++170 170 170  255 255 85  255 255 85  255 255 255  170 170 170  255 255 255
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
++170 170 170  170 170 170  0 0 0  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  170 170 170  255 255 85  255 255 255  85 85 85
++0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  170 170 170
++0 0 0  0 0 0  255 255 255  85 85 85  0 0 0  170 170 170
++170 170 170  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
++255 255 255  255 255 255  255 255 255  85 85 85  85 85 85  255 255 255
++255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  170 170 170
++170 170 170  170 170 170  255 255 255  0 0 0  0 0 0  0 0 0
++0 0 0  170 170 170  255 255 255  255 255 255  255 255 85  170 170 170
++255 255 255  255 255 255  255 255 85  255 255 85  170 170 170  0 0 0
++0 0 0  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  85 85 85  0 0 0  0 0 0
++255 255 255  85 85 85  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0  255 255 255  255 255 85  255 255 255  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  85 85 85  255 255 255  0 0 0  0 0 0  255 255 255
++85 85 85  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
++255 255 255  255 255 255  255 255 255  85 85 85  170 170 170  255 255 255
++255 255 255  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
++170 170 170  85 85 85  170 170 170  0 0 0  0 0 0  85 85 85
++255 255 255  170 170 170  0 0 0  170 170 170  255 255 85  255 255 255
++255 255 255  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
++85 85 85  255 255 255  255 255 255  255 255 85  255 255 85  255 255 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
++85 85 85  0 0 0  0 0 0  0 0 0  255 255 255  0 0 0
++0 0 0  85 85 85  170 170 170  255 255 255  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  85 85 85  170 170 170  0 0 0  85 85 85  255 255 255
++0 0 0  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
++255 255 255  255 255 255  255 255 255  0 0 0  255 255 255  255 255 255
++170 170 170  0 0 0  0 0 0  170 170 170  255 255 255  85 85 85
++170 170 170  170 170 170  170 170 170  0 0 0  85 85 85  255 255 255
++170 170 170  0 0 0  85 85 85  255 255 255  255 255 85  170 170 170
++0 0 0  170 170 170  255 255 255  255 255 255  0 0 0  85 85 85
++255 255 255  170 170 170  0 0 0  170 170 170  255 255 85  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
++170 170 170  255 255 255  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
++0 0 0  0 0 0  255 255 255  170 170 170  0 0 0  0 0 0
++255 255 255  255 255 255  170 170 170  85 85 85  255 255 255  255 255 255
++85 85 85  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
++170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  85 85 85
++0 0 0  0 0 0  255 255 255  255 255 255  170 170 170  0 0 0
++0 0 0  170 170 170  255 255 255  170 170 170  170 170 170  255 255 255
++85 85 85  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  255 255 255  0 0 0  0 0 0
++255 255 255  255 255 255  0 0 0  0 0 0  255 255 255  170 170 170
++0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  170 170 170
++0 0 0  0 0 0  255 255 255  170 170 170  0 0 0  0 0 0
++170 170 170  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
++0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++85 85 85  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  170 170 170  255 255 255  170 170 170  0 0 0  0 0 0
++85 85 85  255 255 255  255 255 85  255 255 255  255 255 255  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++255 255 85  170 170 170  170 170 170  170 170 170  255 255 85  255 255 85
++170 170 170  170 170 170  170 170 170  255 255 85  255 255 85  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  85 85 85  170 170 170  170 170 170  170 170 170
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  255 255 255  170 170 170  0 0 0  0 0 0  0 0 0
++0 0 0  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  85 85 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 85 85  85 85 85  0 0 0  0 0 0  0 0 0
++85 85 85  170 170 170  85 85 85  170 170 170  170 170 170  85 85 85
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++85 85 85  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  85 85 85  85 85 85  170 85 0  170 85 0
++170 85 0  255 85 85  255 85 85  255 85 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 85 85  170 85 0  85 85 85  0 0 0  0 0 0  85 85 85
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
++85 85 85  85 85 85  170 85 0  170 85 0  170 85 0  170 85 0
++255 85 85  255 85 85  255 255 85  255 255 85  255 255 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 85 85
++170 85 0  170 85 0  0 0 0  85 85 85  85 85 85  170 170 170
++170 170 170  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
++170 85 0  170 85 0  170 85 0  255 85 85  255 85 85  255 255 85
++255 255 85  255 255 85  255 255 85  255 255 85  255 85 85  170 85 0
++170 85 0  85 85 85  85 85 85  85 85 85  170 170 170  170 170 170
++0 0 0  0 0 0  255 255 255  255 255 255  85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  170 85 0  170 85 0  170 85 0
++170 85 0  255 85 85  255 85 85  255 85 85  170 85 0  170 85 0
++85 85 85  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
++0 0 0  85 85 85  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
++0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
++170 85 0  170 85 0  170 85 0  170 85 0  170 85 0  85 85 85
++0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
++0 0 0  85 85 85  255 255 255  170 170 170  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
++85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
++170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  85 85 85
++85 85 85  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
++0 0 0  0 0 0
+diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
+index 685761a..4db6b48 100644
+--- a/drivers/video/pnx4008/pnxrgbfb.c
++++ b/drivers/video/pnx4008/pnxrgbfb.c
+@@ -100,7 +100,6 @@ static int rgbfb_remove(struct platform_device *pdev)
+ 		fb_dealloc_cmap(&info->cmap);
+ 		framebuffer_release(info);
+ 		platform_set_drvdata(pdev, NULL);
+-		kfree(info);
+ 	}
+ 
+ 	pnx4008_free_dum_channel(channel_owned, pdev->id);
+@@ -168,23 +167,21 @@ static int __devinit rgbfb_probe(struct platform_device *pdev)
+ 
+ 	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ 	if (ret < 0)
+-		goto err2;
++		goto err1;
+ 
+ 	ret = register_framebuffer(info);
+ 	if (ret < 0)
+-		goto err3;
++		goto err2;
+ 	platform_set_drvdata(pdev, info);
+ 
+ 	return 0;
+ 
+-err3:
+-	fb_dealloc_cmap(&info->cmap);
+ err2:
+-	framebuffer_release(info);
++	fb_dealloc_cmap(&info->cmap);
+ err1:
+ 	pnx4008_free_dum_channel(channel_owned, pdev->id);
+ err0:
+-	kfree(info);
++	framebuffer_release(info);
+ err:
+ 	return ret;
+ }
+diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
+index bd54cd0..beefab2 100644
+--- a/drivers/video/tridentfb.c
++++ b/drivers/video/tridentfb.c
+@@ -27,7 +27,6 @@
+ #define VERSION		"0.7.8-NEWAPI"
+ 
+ struct tridentfb_par {
+-	int vclk;		/* in MHz */
+ 	void __iomem *io_virt;	/* iospace virtual memory address */
+ };
+ 
+@@ -669,27 +668,26 @@ static void set_screen_start(int base)
+ 		 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
+ }
+ 
+-/* Use 20.12 fixed-point for NTSC value and frequency calculation */
+-#define calc_freq(n, m, k)  ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
+-
+ /* Set dotclock frequency */
+-static void set_vclk(int freq)
++static void set_vclk(unsigned long freq)
+ {
+ 	int m, n, k;
+-	int f, fi, d, di;
++	unsigned long f, fi, d, di;
+ 	unsigned char lo = 0, hi = 0;
+ 
+-	d = 20;
++	d = 20000;
+ 	for (k = 2; k >= 0; k--)
+ 		for (m = 0; m < 63; m++)
+ 			for (n = 0; n < 128; n++) {
+-				fi = calc_freq(n, m, k);
++				fi = ((14318l * (n + 8)) / (m + 2)) >> k;
+ 				if ((di = abs(fi - freq)) < d) {
+ 					d = di;
+ 					f = fi;
+ 					lo = n;
+ 					hi = (k << 6) | m;
+ 				}
++				if (fi > freq)
++					break;
+ 			}
+ 	if (chip3D) {
+ 		write3C4(ClockHigh, hi);
+@@ -888,6 +886,8 @@ static int tridentfb_set_par(struct fb_info *info)
+ 	struct fb_var_screeninfo *var = &info->var;
+ 	int bpp = var->bits_per_pixel;
+ 	unsigned char tmp;
++	unsigned long vclk;
++
+ 	debug("enter\n");
+ 	hdispend = var->xres / 8 - 1;
+ 	hsyncstart = (var->xres + var->right_margin) / 8;
+@@ -905,7 +905,6 @@ static int tridentfb_set_par(struct fb_info *info)
+ 	vblankstart = var->yres;
+ 	vblankend = vtotal + 2;
+ 
+-	enable_mmio();
+ 	crtc_unlock();
+ 	write3CE(CyberControl, 8);
+ 
+@@ -1015,11 +1014,11 @@ static int tridentfb_set_par(struct fb_info *info)
+ 	write3X4(Performance, 0x92);
+ 	write3X4(PCIReg, 0x07);		/* MMIO & PCI read and write burst enable */
+ 
+-	/* convert from picoseconds to MHz */
+-	par->vclk = 1000000 / info->var.pixclock;
++	/* convert from picoseconds to kHz */
++	vclk = PICOS2KHZ(info->var.pixclock);
+ 	if (bpp == 32)
+-		par->vclk *= 2;
+-	set_vclk(par->vclk);
++		vclk *= 2;
++	set_vclk(vclk);
+ 
+ 	write3C4(0, 3);
+ 	write3C4(1, 1);		/* set char clock 8 dots wide */
+diff --git a/fs/9p/fid.h b/fs/9p/fid.h
+index 26e07df..c3bbd6a 100644
+--- a/fs/9p/fid.h
++++ b/fs/9p/fid.h
+@@ -22,6 +22,21 @@
+ 
+ #include <linux/list.h>
+ 
++/**
++ * struct v9fs_dentry - 9p private data stored in dentry d_fsdata
++ * @lock: protects the fidlist
++ * @fidlist: list of FIDs currently associated with this dentry
++ *
++ * This structure defines the 9p private data associated with
++ * a particular dentry.  In particular, this private data is used
++ * to lookup which 9P FID handle should be used for a particular VFS
++ * operation.  FID handles are associated with dentries instead of
++ * inodes in order to more closely map functionality to the Plan 9
++ * expected behavior for FID reclaimation and tracking.
++ *
++ * See Also: Mapping FIDs to Linux VFS model in
++ * Design and Implementation of the Linux 9P File System documentation
++ */
+ struct v9fs_dentry {
+ 	spinlock_t lock; /* protect fidlist */
+ 	struct list_head fidlist;
+diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
+index 9b0f022..047c791 100644
+--- a/fs/9p/v9fs.c
++++ b/fs/9p/v9fs.c
+@@ -71,19 +71,19 @@ static match_table_t tokens = {
+ 
+ /**
+  * v9fs_parse_options - parse mount options into session structure
+- * @options: options string passed from mount
+  * @v9ses: existing v9fs session information
+  *
++ * Return 0 upon success, -ERRNO upon failure.
+  */
+ 
+-static void v9fs_parse_options(struct v9fs_session_info *v9ses)
++static int v9fs_parse_options(struct v9fs_session_info *v9ses)
+ {
+ 	char *options;
+ 	substring_t args[MAX_OPT_ARGS];
+ 	char *p;
+ 	int option = 0;
+ 	char *s, *e;
+-	int ret;
++	int ret = 0;
+ 
+ 	/* setup defaults */
+ 	v9ses->afid = ~0;
+@@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
+ 	v9ses->cache = 0;
+ 
+ 	if (!v9ses->options)
+-		return;
++		return 0;
+ 
+ 	options = kstrdup(v9ses->options, GFP_KERNEL);
++	if (!options) {
++		P9_DPRINTK(P9_DEBUG_ERROR,
++			   "failed to allocate copy of option string\n");
++		return -ENOMEM;
++	}
++
+ 	while ((p = strsep(&options, ",")) != NULL) {
+ 		int token;
+ 		if (!*p)
+ 			continue;
+ 		token = match_token(p, tokens, args);
+ 		if (token < Opt_uname) {
+-			ret = match_int(&args[0], &option);
+-			if (ret < 0) {
++			int r = match_int(&args[0], &option);
++			if (r < 0) {
+ 				P9_DPRINTK(P9_DEBUG_ERROR,
+ 					"integer field, but no integer?\n");
++				ret = r;
+ 				continue;
+ 			}
+ 		}
+@@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
+ 			v9ses->afid = option;
+ 			break;
+ 		case Opt_uname:
+-			match_strcpy(v9ses->uname, &args[0]);
++			match_strlcpy(v9ses->uname, &args[0], PATH_MAX);
+ 			break;
+ 		case Opt_remotename:
+-			match_strcpy(v9ses->aname, &args[0]);
++			match_strlcpy(v9ses->aname, &args[0], PATH_MAX);
+ 			break;
+ 		case Opt_nodevmap:
+ 			v9ses->nodev = 1;
+@@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
+ 
+ 		case Opt_access:
+ 			s = match_strdup(&args[0]);
++			if (!s) {
++				P9_DPRINTK(P9_DEBUG_ERROR,
++					   "failed to allocate copy"
++					   " of option argument\n");
++				ret = -ENOMEM;
++				break;
++			}
+ 			v9ses->flags &= ~V9FS_ACCESS_MASK;
+ 			if (strcmp(s, "user") == 0)
+ 				v9ses->flags |= V9FS_ACCESS_USER;
+@@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
+ 		}
+ 	}
+ 	kfree(options);
++	return ret;
+ }
+ 
+ /**
+@@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
+ {
+ 	int retval = -EINVAL;
+ 	struct p9_fid *fid;
++	int rc;
+ 
+ 	v9ses->uname = __getname();
+ 	if (!v9ses->uname)
+@@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
+ 	v9ses->uid = ~0;
+ 	v9ses->dfltuid = V9FS_DEFUID;
+ 	v9ses->dfltgid = V9FS_DEFGID;
+-	v9ses->options = kstrdup(data, GFP_KERNEL);
+-	v9fs_parse_options(v9ses);
++	if (data) {
++		v9ses->options = kstrdup(data, GFP_KERNEL);
++		if (!v9ses->options) {
++			P9_DPRINTK(P9_DEBUG_ERROR,
++			   "failed to allocate copy of option string\n");
++			retval = -ENOMEM;
++			goto error;
++		}
++	}
++
++	rc = v9fs_parse_options(v9ses);
++	if (rc < 0) {
++		retval = rc;
++		goto error;
++	}
+ 
+ 	v9ses->clnt = p9_client_create(dev_name, v9ses->options);
+ 
+@@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
+ 	return fid;
+ 
+ error:
+-	v9fs_session_close(v9ses);
+ 	return ERR_PTR(retval);
+ }
+ 
+@@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
+ }
+ 
+ /**
+- * v9fs_session_cancel - mark transport as disconnected
+- * 	and cancel all pending requests.
++ * v9fs_session_cancel - terminate a session
++ * @v9ses: session to terminate
++ *
++ * mark transport as disconnected and cancel all pending requests.
+  */
++
+ void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
+ 	P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
+ 	p9_client_disconnect(v9ses->clnt);
+diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
+index 7d3a101..a7d5671 100644
+--- a/fs/9p/v9fs.h
++++ b/fs/9p/v9fs.h
+@@ -21,18 +21,69 @@
+  *
+  */
+ 
+-/*
+-  * Session structure provides information for an opened session
+-  *
+-  */
++/**
++ * enum p9_session_flags - option flags for each 9P session
++ * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
++ * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
++ * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
++ * @V9FS_ACCESS_ANY: use a single attach for all users
++ * @V9FS_ACCESS_MASK: bit mask of different ACCESS options
++ *
++ * Session flags reflect options selected by users at mount time
++ */
++enum p9_session_flags {
++	V9FS_EXTENDED		= 0x01,
++	V9FS_ACCESS_SINGLE	= 0x02,
++	V9FS_ACCESS_USER	= 0x04,
++	V9FS_ACCESS_ANY		= 0x06,
++	V9FS_ACCESS_MASK	= 0x06,
++};
++
++/* possible values of ->cache */
++/**
++ * enum p9_cache_modes - user specified cache preferences
++ * @CACHE_NONE: do not cache data, dentries, or directory contents (default)
++ * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
++ *
++ * eventually support loose, tight, time, session, default always none
++ */
++
++enum p9_cache_modes {
++	CACHE_NONE,
++	CACHE_LOOSE,
++};
++
++/**
++ * struct v9fs_session_info - per-instance session information
++ * @flags: session options of type &p9_session_flags
++ * @nodev: set to 1 to disable device mapping
++ * @debug: debug level
++ * @afid: authentication handle
++ * @cache: cache mode of type &p9_cache_modes
++ * @options: copy of options string given by user
++ * @uname: string user name to mount hierarchy as
++ * @aname: mount specifier for remote hierarchy
++ * @maxdata: maximum data to be sent/recvd per protocol message
++ * @dfltuid: default numeric userid to mount hierarchy as
++ * @dfltgid: default numeric groupid to mount hierarchy as
++ * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
++ * @clnt: reference to 9P network client instantiated for this session
++ * @debugfs_dir: reference to debugfs_dir which can be used for add'l debug
++ *
++ * This structure holds state for each session instance established during
++ * a sys_mount() .
++ *
++ * Bugs: there seems to be a lot of state which could be condensed and/or
++ * removed.
++ */
+ 
+ struct v9fs_session_info {
+ 	/* options */
+-	unsigned char flags;	/* session flags */
+-	unsigned char nodev;	/* set to 1 if no disable device mapping */
+-	unsigned short debug;	/* debug level */
+-	unsigned int afid;	/* authentication fid */
+-	unsigned int cache;	/* cache mode */
++	unsigned char flags;
++	unsigned char nodev;
++	unsigned short debug;
++	unsigned int afid;
++	unsigned int cache;
+ 
+ 	char *options;		/* copy of mount options */
+ 	char *uname;		/* user name to mount as */
+@@ -45,22 +96,6 @@ struct v9fs_session_info {
+ 	struct dentry *debugfs_dir;
+ };
+ 
+-/* session flags */
+-enum {
+-	V9FS_EXTENDED		= 0x01,	/* 9P2000.u */
+-	V9FS_ACCESS_MASK	= 0x06,	/* access mask */
+-	V9FS_ACCESS_SINGLE	= 0x02,	/* only one user can access the files */
+-	V9FS_ACCESS_USER	= 0x04,	/* attache per user */
+-	V9FS_ACCESS_ANY		= 0x06,	/* use the same attach for all users */
+-};
+-
+-/* possible values of ->cache */
+-/* eventually support loose, tight, time, session, default always none */
+-enum {
+-	CACHE_NONE,		/* default */
+-	CACHE_LOOSE,		/* no consistency */
+-};
+-
+ extern struct dentry *v9fs_debugfs_root;
+ 
+ struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
+diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
+index 6248f0e..97d3aed 100644
+--- a/fs/9p/vfs_addr.c
++++ b/fs/9p/vfs_addr.c
+@@ -43,7 +43,7 @@
+ /**
+  * v9fs_vfs_readpage - read an entire page in from 9P
+  *
+- * @file: file being read
++ * @filp: file being read
+  * @page: structure to page
+  *
+  */
+diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
+index 0924d44..88e3787 100644
+--- a/fs/9p/vfs_dir.c
++++ b/fs/9p/vfs_dir.c
+@@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat)
+ 
+ /**
+  * v9fs_dir_readdir - read a directory
+- * @filep: opened file structure
++ * @filp: opened file structure
+  * @dirent: directory structure ???
+  * @filldir: function to populate directory structure ???
+  *
+diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
+index a616fff..0d55aff 100644
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -90,10 +90,11 @@ int v9fs_file_open(struct inode *inode, struct file *file)
+ 
+ /**
+  * v9fs_file_lock - lock a file (or directory)
+- * @inode: inode to be opened
+- * @file: file being opened
++ * @filp: file to be locked
++ * @cmd: lock command
++ * @fl: file lock structure
+  *
+- * XXX - this looks like a local only lock, we should extend into 9P
++ * Bugs: this looks like a local only lock, we should extend into 9P
+  *       by using open exclusive
+  */
+ 
+@@ -118,7 +119,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
+ 
+ /**
+  * v9fs_file_read - read from a file
+- * @filep: file pointer to read
++ * @filp: file pointer to read
+  * @data: data buffer to read data into
+  * @count: size of buffer
+  * @offset: offset at which to read data
+@@ -142,7 +143,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
+ 
+ /**
+  * v9fs_file_write - write to a file
+- * @filep: file pointer to write
++ * @filp: file pointer to write
+  * @data: data buffer to write data from
+  * @count: size of buffer
+  * @offset: offset at which to write data
+diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
+index 6a28842..40fa807 100644
+--- a/fs/9p/vfs_inode.c
++++ b/fs/9p/vfs_inode.c
+@@ -129,6 +129,12 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
+ 	return res;
+ }
+ 
++/**
++ * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
++ * @uflags: flags to convert
++ *
++ */
++
+ int v9fs_uflags2omode(int uflags)
+ {
+ 	int ret;
+@@ -312,6 +318,14 @@ error:
+ }
+ */
+ 
++/**
++ * v9fs_inode_from_fid - populate an inode by issuing a attribute request
++ * @v9ses: session information
++ * @fid: fid to issue attribute request for
++ * @sb: superblock on which to create inode
++ *
++ */
++
+ static struct inode *
+ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ 	struct super_block *sb)
+@@ -384,9 +398,12 @@ v9fs_open_created(struct inode *inode, struct file *file)
+ 
+ /**
+  * v9fs_create - Create a file
++ * @v9ses: session information
++ * @dir: directory that dentry is being created in
+  * @dentry:  dentry that is being created
+  * @perm: create permissions
+  * @mode: open mode
++ * @extension: 9p2000.u extension string to support devices, etc.
+  *
+  */
+ static struct p9_fid *
+@@ -461,7 +478,7 @@ error:
+ 
+ /**
+  * v9fs_vfs_create - VFS hook to create files
+- * @inode: directory inode that is being created
++ * @dir: directory inode that is being created
+  * @dentry:  dentry that is being deleted
+  * @mode: create permissions
+  * @nd: path information
+@@ -519,7 +536,7 @@ error:
+ 
+ /**
+  * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
+- * @inode:  inode that is being unlinked
++ * @dir:  inode that is being unlinked
+  * @dentry: dentry that is being unlinked
+  * @mode: mode for new directory
+  *
+@@ -703,9 +720,9 @@ done:
+ 
+ /**
+  * v9fs_vfs_getattr - retrieve file metadata
+- * @mnt - mount information
+- * @dentry - file to get attributes on
+- * @stat - metadata structure to populate
++ * @mnt: mount information
++ * @dentry: file to get attributes on
++ * @stat: metadata structure to populate
+  *
+  */
+ 
+@@ -928,7 +945,7 @@ done:
+ /**
+  * v9fs_vfs_readlink - read a symlink's location
+  * @dentry: dentry for symlink
+- * @buf: buffer to load symlink location into
++ * @buffer: buffer to load symlink location into
+  * @buflen: length of buffer
+  *
+  */
+@@ -996,10 +1013,12 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+  * v9fs_vfs_put_link - release a symlink path
+  * @dentry: dentry for symlink
+  * @nd: nameidata
++ * @p: unused
+  *
+  */
+ 
+-static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
++static void
++v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
+ {
+ 	char *s = nd_get_link(nd);
+ 
+@@ -1008,6 +1027,15 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
+ 		__putname(s);
+ }
+ 
++/**
++ * v9fs_vfs_mkspecial - create a special file
++ * @dir: inode to create special file in
++ * @dentry: dentry to create
++ * @mode: mode to create special file
++ * @extension: 9p2000.u format extension string representing special file
++ *
++ */
++
+ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
+ 	int mode, const char *extension)
+ {
+@@ -1037,7 +1065,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
+  * @dentry: dentry for symlink
+  * @symname: symlink data
+  *
+- * See 9P2000.u RFC for more information
++ * See Also: 9P2000.u RFC for more information
+  *
+  */
+ 
+@@ -1058,10 +1086,6 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+  *
+  */
+ 
+-/* XXX - lots of code dup'd from symlink and creates,
+- * figure out a better reuse strategy
+- */
+-
+ static int
+ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
+ 	      struct dentry *dentry)
+@@ -1098,7 +1122,7 @@ clunk_fid:
+  * @dir: inode destination for new link
+  * @dentry: dentry for file
+  * @mode: mode for creation
+- * @dev_t: device associated with special file
++ * @rdev: device associated with special file
+  *
+  */
+ 
+diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
+index a452ac6..bf59c39 100644
+--- a/fs/9p/vfs_super.c
++++ b/fs/9p/vfs_super.c
+@@ -75,6 +75,7 @@ static int v9fs_set_super(struct super_block *s, void *data)
+  * v9fs_fill_super - populate superblock with info
+  * @sb: superblock
+  * @v9ses: session information
++ * @flags: flags propagated from v9fs_get_sb()
+  *
+  */
+ 
+@@ -127,29 +128,26 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
+ 	fid = v9fs_session_init(v9ses, dev_name, data);
+ 	if (IS_ERR(fid)) {
+ 		retval = PTR_ERR(fid);
+-		fid = NULL;
+-		kfree(v9ses);
+-		v9ses = NULL;
+-		goto error;
++		goto close_session;
+ 	}
+ 
+ 	st = p9_client_stat(fid);
+ 	if (IS_ERR(st)) {
+ 		retval = PTR_ERR(st);
+-		goto error;
++		goto clunk_fid;
+ 	}
+ 
+ 	sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
+ 	if (IS_ERR(sb)) {
+ 		retval = PTR_ERR(sb);
+-		goto error;
++		goto free_stat;
+ 	}
+ 	v9fs_fill_super(sb, v9ses, flags);
+ 
+ 	inode = v9fs_get_inode(sb, S_IFDIR | mode);
+ 	if (IS_ERR(inode)) {
+ 		retval = PTR_ERR(inode);
+-		goto error;
++		goto release_sb;
+ 	}
+ 
+ 	inode->i_uid = uid;
+@@ -158,7 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
+ 	root = d_alloc_root(inode);
+ 	if (!root) {
+ 		retval = -ENOMEM;
+-		goto error;
++		goto release_sb;
+ 	}
+ 
+ 	sb->s_root = root;
+@@ -169,21 +167,22 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
+ 
+ 	return simple_set_mnt(mnt, sb);
+ 
+-error:
+-	kfree(st);
+-	if (fid)
+-		p9_client_clunk(fid);
+-
+-	if (v9ses) {
+-		v9fs_session_close(v9ses);
+-		kfree(v9ses);
+-	}
+-
++release_sb:
+ 	if (sb) {
+ 		up_write(&sb->s_umount);
+ 		deactivate_super(sb);
+ 	}
+ 
++free_stat:
++	kfree(st);
++
++clunk_fid:
++	p9_client_clunk(fid);
++
++close_session:
++	v9fs_session_close(v9ses);
++	kfree(v9ses);
++
+ 	return retval;
+ }
+ 
+diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
+index a0d26b5..c43bf4b 100644
+--- a/fs/cifs/cifspdu.h
++++ b/fs/cifs/cifspdu.h
+@@ -340,6 +340,7 @@
+ #define OPEN_NO_RECALL          0x00400000
+ #define OPEN_FREE_SPACE_QUERY   0x00800000	/* should be zero */
+ #define CREATE_OPTIONS_MASK     0x007FFFFF
++#define CREATE_OPTION_READONLY	0x10000000
+ #define CREATE_OPTION_SPECIAL   0x20000000   /* system. NB not sent over wire */
+ 
+ /* ImpersonationLevel flags */
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index cfd9750..95fbba4 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -1224,11 +1224,8 @@ OldOpenRetry:
+ 	else /* BB FIXME BB */
+ 		pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
+ 
+-	/* if ((omode & S_IWUGO) == 0)
+-		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
+-	/*  Above line causes problems due to vfs splitting create into two
+-	    pieces - need to set mode after file created not while it is
+-	    being created */
++	if (create_options & CREATE_OPTION_READONLY)
++		pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
+ 
+ 	/* BB FIXME BB */
+ /*	pSMB->CreateOptions = cpu_to_le32(create_options &
+@@ -1331,17 +1328,16 @@ openRetry:
+ 		pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
+ 	else
+ 		pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
++
+ 	/* XP does not handle ATTR_POSIX_SEMANTICS */
+ 	/* but it helps speed up case sensitive checks for other
+ 	servers such as Samba */
+ 	if (tcon->ses->capabilities & CAP_UNIX)
+ 		pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
+ 
+-	/* if ((omode & S_IWUGO) == 0)
+-		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
+-	/*  Above line causes problems due to vfs splitting create into two
+-		pieces - need to set mode after file created not while it is
+-		being created */
++	if (create_options & CREATE_OPTION_READONLY)
++		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
++
+ 	pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
+ 	pSMB->CreateDisposition = cpu_to_le32(openDisposition);
+ 	pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 791ca5c..f428bf3 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -348,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
+ 	int reconnect;
+ 
+ 	current->flags |= PF_MEMALLOC;
+-	server->tsk = current;	/* save process info to wake at shutdown */
+ 	cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
+ 	write_lock(&GlobalSMBSeslock);
+ 	atomic_inc(&tcpSesAllocCount);
+@@ -651,10 +650,20 @@ multi_t2_fnd:
+ 
+ 	spin_lock(&GlobalMid_Lock);
+ 	server->tcpStatus = CifsExiting;
+-	server->tsk = NULL;
++	spin_unlock(&GlobalMid_Lock);
++
++	/* don't exit until kthread_stop is called */
++	set_current_state(TASK_UNINTERRUPTIBLE);
++	while (!kthread_should_stop()) {
++		schedule();
++		set_current_state(TASK_UNINTERRUPTIBLE);
++	}
++	set_current_state(TASK_RUNNING);
++
+ 	/* check if we have blocked requests that need to free */
+ 	/* Note that cifs_max_pending is normally 50, but
+ 	can be set at module install time to as little as two */
++	spin_lock(&GlobalMid_Lock);
+ 	if (atomic_read(&server->inFlight) >= cifs_max_pending)
+ 		atomic_set(&server->inFlight, cifs_max_pending - 1);
+ 	/* We do not want to set the max_pending too low or we
+@@ -1318,42 +1327,43 @@ cifs_parse_mount_options(char *options, const char *devname,
+ 
+ static struct cifsSesInfo *
+ cifs_find_tcp_session(struct in_addr *target_ip_addr,
+-		struct in6_addr *target_ip6_addr,
+-		 char *userName, struct TCP_Server_Info **psrvTcp)
++		      struct in6_addr *target_ip6_addr,
++		      char *userName, struct TCP_Server_Info **psrvTcp)
+ {
+ 	struct list_head *tmp;
+ 	struct cifsSesInfo *ses;
++
+ 	*psrvTcp = NULL;
+-	read_lock(&GlobalSMBSeslock);
+ 
++	read_lock(&GlobalSMBSeslock);
+ 	list_for_each(tmp, &GlobalSMBSessionList) {
+ 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
+-		if (ses->server) {
+-			if ((target_ip_addr &&
+-				(ses->server->addr.sockAddr.sin_addr.s_addr
+-				  == target_ip_addr->s_addr)) || (target_ip6_addr
+-				&& memcmp(&ses->server->addr.sockAddr6.sin6_addr,
+-					target_ip6_addr, sizeof(*target_ip6_addr)))) {
+-				/* BB lock server and tcp session and increment
+-				      use count here?? */
+-
+-				/* found a match on the TCP session */
+-				*psrvTcp = ses->server;
+-
+-				/* BB check if reconnection needed */
+-				if (strncmp
+-				    (ses->userName, userName,
+-				     MAX_USERNAME_SIZE) == 0){
+-					read_unlock(&GlobalSMBSeslock);
+-					/* Found exact match on both TCP and
+-					   SMB sessions */
+-					return ses;
+-				}
+-			}
++		if (!ses->server)
++			continue;
++
++		if (target_ip_addr &&
++		    ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
++				continue;
++		else if (target_ip6_addr &&
++			 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
++				target_ip6_addr, sizeof(*target_ip6_addr)))
++				continue;
++		/* BB lock server and tcp session; increment use count here?? */
++
++		/* found a match on the TCP session */
++		*psrvTcp = ses->server;
++
++		/* BB check if reconnection needed */
++		if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
++			read_unlock(&GlobalSMBSeslock);
++			/* Found exact match on both TCP and
++			   SMB sessions */
++			return ses;
+ 		}
+ 		/* else tcp and smb sessions need reconnection */
+ 	}
+ 	read_unlock(&GlobalSMBSeslock);
++
+ 	return NULL;
+ }
+ 
+@@ -2186,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ 			srvTcp->tcpStatus = CifsExiting;
+ 			spin_unlock(&GlobalMid_Lock);
+ 			if (srvTcp->tsk) {
+-				struct task_struct *tsk;
+ 				/* If we could verify that kthread_stop would
+ 				   always wake up processes blocked in
+ 				   tcp in recv_mesg then we could remove the
+ 				   send_sig call */
+ 				force_sig(SIGKILL, srvTcp->tsk);
+-				tsk = srvTcp->tsk;
+-				if (tsk)
+-					kthread_stop(tsk);
++				kthread_stop(srvTcp->tsk);
+ 			}
+ 		}
+ 		 /* If find_unc succeeded then rc == 0 so we can not end */
+@@ -2210,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
+ 					if ((temp_rc == -ESHUTDOWN) &&
+ 					    (pSesInfo->server) &&
+ 					    (pSesInfo->server->tsk)) {
+-						struct task_struct *tsk;
+ 						force_sig(SIGKILL,
+ 							pSesInfo->server->tsk);
+-						tsk = pSesInfo->server->tsk;
+-						if (tsk)
+-							kthread_stop(tsk);
++						kthread_stop(pSesInfo->server->tsk);
+ 					}
+ 				} else {
+ 					cFYI(1, ("No session or bad tcon"));
+ 					if ((pSesInfo->server) &&
+ 					    (pSesInfo->server->tsk)) {
+-						struct task_struct *tsk;
+ 						force_sig(SIGKILL,
+ 							pSesInfo->server->tsk);
+-						tsk = pSesInfo->server->tsk;
+-						if (tsk)
+-							kthread_stop(tsk);
++						kthread_stop(pSesInfo->server->tsk);
+ 					}
+ 				}
+ 				sesInfoFree(pSesInfo);
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 6ed7759..e4e0078 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
+ {
+ 	int rc = -ENOENT;
+ 	int xid;
++	int create_options = CREATE_NOT_DIR;
+ 	int oplock = 0;
+ 	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
+ 	__u16 fileHandle;
+@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
+ 		FreeXid(xid);
+ 		return -ENOMEM;
+ 	}
++
++	mode &= ~current->fs->umask;
++
++	/*
++	 * if we're not using unix extensions, see if we need to set
++	 * ATTR_READONLY on the create call
++	 */
++	if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
++		create_options |= CREATE_OPTION_READONLY;
++
+ 	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
+ 		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
+-			 desiredAccess, CREATE_NOT_DIR,
++			 desiredAccess, create_options,
+ 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
+ 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ 	else
+@@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
+ 	if (rc == -EIO) {
+ 		/* old server, retry the open legacy style */
+ 		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
+-			desiredAccess, CREATE_NOT_DIR,
++			desiredAccess, create_options,
+ 			&fileHandle, &oplock, buf, cifs_sb->local_nls,
+ 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ 	}
+@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
+ 		/* If Open reported that we actually created a file
+ 		then we now have to set the mode if possible */
+ 		if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
+-			mode &= ~current->fs->umask;
+ 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
+ 					(__u64)current->fsuid,
+diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
+index 0d9d2e6..fcbdbb6 100644
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -974,8 +974,8 @@ mkdir_get_info:
+ 		  * failed to get it from the server or was set bogus */
+ 		if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
+ 				direntry->d_inode->i_nlink = 2;
++		mode &= ~current->fs->umask;
+ 		if (pTcon->unix_ext) {
+-			mode &= ~current->fs->umask;
+ 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+ 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
+ 						    mode,
+@@ -994,9 +994,16 @@ mkdir_get_info:
+ 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
+ 			}
+ 		} else {
+-			/* BB to be implemented via Windows secrty descriptors
+-			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
+-						 -1, -1, local_nls); */
++			if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
++			    (mode & S_IWUGO) == 0) {
++				FILE_BASIC_INFO pInfo;
++				memset(&pInfo, 0, sizeof(pInfo));
++				pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
++				CIFSSMBSetTimes(xid, pTcon, full_path,
++						&pInfo, cifs_sb->local_nls,
++						cifs_sb->mnt_cifs_flags &
++						CIFS_MOUNT_MAP_SPECIAL_CHR);
++			}
+ 			if (direntry->d_inode) {
+ 				direntry->d_inode->i_mode = mode;
+ 				direntry->d_inode->i_mode |= S_IFDIR;
+@@ -1408,18 +1415,19 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
+ 	__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
+ 	struct cifsInodeInfo *cifsInode;
++	struct inode *inode = direntry->d_inode;
+ 
+ 	xid = GetXid();
+ 
+ 	cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
+ 		 direntry->d_name.name, attrs->ia_valid));
+ 
+-	cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
++	cifs_sb = CIFS_SB(inode->i_sb);
+ 	pTcon = cifs_sb->tcon;
+ 
+ 	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
+ 		/* check if we have permission to change attrs */
+-		rc = inode_change_ok(direntry->d_inode, attrs);
++		rc = inode_change_ok(inode, attrs);
+ 		if (rc < 0) {
+ 			FreeXid(xid);
+ 			return rc;
+@@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 		FreeXid(xid);
+ 		return -ENOMEM;
+ 	}
+-	cifsInode = CIFS_I(direntry->d_inode);
++	cifsInode = CIFS_I(inode);
+ 
+ 	if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
+ 		/*
+@@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 		   will be truncated anyway? Also, should we error out here if
+ 		   the flush returns error?
+ 		 */
+-		rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
++		rc = filemap_write_and_wait(inode->i_mapping);
+ 		if (rc != 0) {
+-			CIFS_I(direntry->d_inode)->write_behind_rc = rc;
++			cifsInode->write_behind_rc = rc;
+ 			rc = 0;
+ 		}
+ 	}
+@@ -1521,9 +1529,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 		   */
+ 
+ 		if (rc == 0) {
+-			rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
+-			cifs_truncate_page(direntry->d_inode->i_mapping,
+-					   direntry->d_inode->i_size);
++			rc = cifs_vmtruncate(inode, attrs->ia_size);
++			cifs_truncate_page(inode->i_mapping, inode->i_size);
+ 		} else
+ 			goto cifs_setattr_exit;
+ 	}
+@@ -1557,7 +1564,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 		rc = 0;
+ #ifdef CONFIG_CIFS_EXPERIMENTAL
+ 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
+-			rc = mode_to_acl(direntry->d_inode, full_path, mode);
++			rc = mode_to_acl(inode, full_path, mode);
+ 		else if ((mode & S_IWUGO) == 0) {
+ #else
+ 		if ((mode & S_IWUGO) == 0) {
+@@ -1665,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
+ 	/* do not need local check to inode_check_ok since the server does
+ 	   that */
+ 	if (!rc)
+-		rc = inode_setattr(direntry->d_inode, attrs);
++		rc = inode_setattr(inode, attrs);
+ cifs_setattr_exit:
+ 	kfree(full_path);
+ 	FreeXid(xid);
+diff --git a/fs/dquot.c b/fs/dquot.c
+index dfba162..5ac77da 100644
+--- a/fs/dquot.c
++++ b/fs/dquot.c
+@@ -1491,6 +1491,16 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
+ 
+ 	/* We need to serialize quota_off() for device */
+ 	mutex_lock(&dqopt->dqonoff_mutex);
++
++	/*
++	 * Skip everything if there's nothing to do. We have to do this because
++	 * sometimes we are called when fill_super() failed and calling
++	 * sync_fs() in such cases does no good.
++	 */
++	if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) {
++		mutex_unlock(&dqopt->dqonoff_mutex);
++		return 0;
++	}
+ 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ 		toputinode[cnt] = NULL;
+ 		if (type != -1 && cnt != type)
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 0a13973..c92cc1c 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -37,17 +37,11 @@ static struct dentry *lock_parent(struct dentry *dentry)
+ {
+ 	struct dentry *dir;
+ 
+-	dir = dget(dentry->d_parent);
++	dir = dget_parent(dentry);
+ 	mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
+ 	return dir;
+ }
+ 
+-static void unlock_parent(struct dentry *dentry)
+-{
+-	mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
+-	dput(dentry->d_parent);
+-}
+-
+ static void unlock_dir(struct dentry *dir)
+ {
+ 	mutex_unlock(&dir->d_inode->i_mutex);
+@@ -426,8 +420,9 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+ 	int rc = 0;
+ 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ 	struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
++	struct dentry *lower_dir_dentry;
+ 
+-	lock_parent(lower_dentry);
++	lower_dir_dentry = lock_parent(lower_dentry);
+ 	rc = vfs_unlink(lower_dir_inode, lower_dentry);
+ 	if (rc) {
+ 		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
+@@ -439,7 +434,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+ 	dentry->d_inode->i_ctime = dir->i_ctime;
+ 	d_drop(dentry);
+ out_unlock:
+-	unlock_parent(lower_dentry);
++	unlock_dir(lower_dir_dentry);
+ 	return rc;
+ }
+ 
+diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
+index 788995e..6560da1 100644
+--- a/fs/ecryptfs/miscdev.c
++++ b/fs/ecryptfs/miscdev.c
+@@ -257,12 +257,14 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
+ 	mutex_lock(&daemon->mux);
+ 	if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
+ 		rc = 0;
++		mutex_unlock(&ecryptfs_daemon_hash_mux);
+ 		printk(KERN_WARNING "%s: Attempt to read from zombified "
+ 		       "daemon\n", __func__);
+ 		goto out_unlock_daemon;
+ 	}
+ 	if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) {
+ 		rc = 0;
++		mutex_unlock(&ecryptfs_daemon_hash_mux);
+ 		goto out_unlock_daemon;
+ 	}
+ 	/* This daemon will not go away so long as this flag is set */
+diff --git a/fs/exec.c b/fs/exec.c
+index aeaa979..1f8a24a 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -736,7 +736,7 @@ static int exec_mmap(struct mm_struct *mm)
+ 	tsk->active_mm = mm;
+ 	activate_mm(active_mm, mm);
+ 	task_unlock(tsk);
+-	mm_update_next_owner(mm);
++	mm_update_next_owner(old_mm);
+ 	arch_pick_mmap_layout(mm);
+ 	if (old_mm) {
+ 		up_read(&old_mm->mmap_sem);
+diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
+index d4a4f0e..175414a 100644
+--- a/fs/ext3/xattr.c
++++ b/fs/ext3/xattr.c
+@@ -1000,6 +1000,11 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ 			i.value = NULL;
+ 			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+ 		} else if (error == -ENOSPC) {
++			if (EXT3_I(inode)->i_file_acl && !bs.s.base) {
++				error = ext3_xattr_block_find(inode, &i, &bs);
++				if (error)
++					goto cleanup;
++			}
+ 			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+ 			if (error)
+ 				goto cleanup;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index fbec2ef..b128bdc 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2639,8 +2639,7 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb)
+ 	struct proc_dir_entry *proc;
+ 	char devname[64];
+ 
+-	snprintf(devname, sizeof(devname) - 1, "%s",
+-		bdevname(sb->s_bdev, devname));
++	bdevname(sb->s_bdev, devname);
+ 	sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
+ 
+ 	MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
+@@ -2674,8 +2673,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
+ 	if (sbi->s_mb_proc == NULL)
+ 		return -EINVAL;
+ 
+-	snprintf(devname, sizeof(devname) - 1, "%s",
+-		bdevname(sb->s_bdev, devname));
++	bdevname(sb->s_bdev, devname);
+ 	remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
+ 	remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
+ 	remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 3fbc2c6..ff08633 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1009,6 +1009,11 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ 			i.value = NULL;
+ 			error = ext4_xattr_block_set(handle, inode, &i, &bs);
+ 		} else if (error == -ENOSPC) {
++			if (EXT4_I(inode)->i_file_acl && !bs.s.base) {
++				error = ext4_xattr_block_find(inode, &i, &bs);
++				if (error)
++					goto cleanup;
++			}
+ 			error = ext4_xattr_block_set(handle, inode, &i, &bs);
+ 			if (error)
+ 				goto cleanup;
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index f28cf8b..8092f0d 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -804,6 +804,8 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
+ 		if (offset == PAGE_CACHE_SIZE)
+ 			offset = 0;
+ 
++		if (!fc->big_writes)
++			break;
+ 	} while (iov_iter_count(ii) && count < fc->max_write &&
+ 		 req->num_pages < FUSE_MAX_PAGES_PER_REQ && offset == 0);
+ 
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index dadffa2..bae9486 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -404,6 +404,9 @@ struct fuse_conn {
+ 	/** Is bmap not implemented by fs? */
+ 	unsigned no_bmap : 1;
+ 
++	/** Do multi-page cached writes */
++	unsigned big_writes : 1;
++
+ 	/** The number of requests waiting for completion */
+ 	atomic_t num_waiting;
+ 
+diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
+index 79b6158..fb77e09 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -576,6 +576,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
+ 				fc->no_lock = 1;
+ 			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+ 				fc->atomic_o_trunc = 1;
++			if (arg->flags & FUSE_BIG_WRITES)
++				fc->big_writes = 1;
+ 		} else {
+ 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
+ 			fc->no_lock = 1;
+@@ -599,7 +601,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
+ 	arg->major = FUSE_KERNEL_VERSION;
+ 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
+ 	arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
+-	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC;
++	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
++		FUSE_BIG_WRITES;
+ 	req->in.h.opcode = FUSE_INIT;
+ 	req->in.numargs = 1;
+ 	req->in.args[0].size = sizeof(*arg);
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+index d53b2af..67e1c8b 100644
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -65,6 +65,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask)
+ 		BUG();
+ 		return 0;
+ 	}
++	if (!tree)
++		return 0;
+ 	if (tree->node_size >= PAGE_CACHE_SIZE) {
+ 		nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
+ 		spin_lock(&tree->hash_lock);
+diff --git a/fs/hppfs/Makefile b/fs/hppfs/Makefile
+index 6890433..8a1f503 100644
+--- a/fs/hppfs/Makefile
++++ b/fs/hppfs/Makefile
+@@ -1,9 +1,9 @@
+ #
+-# Copyright (C) 2002, 2003 Jeff Dike (jdike at karaya.com)
++# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ # Licensed under the GPL
+ #
+ 
+-hppfs-objs := hppfs_kern.o
++hppfs-objs := hppfs.o
+ 
+ obj-y =
+-obj-$(CONFIG_HPPFS) += hppfs.o
++obj-$(CONFIG_HPPFS) += $(hppfs-objs)
+diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
+new file mode 100644
+index 0000000..65077aa
+--- /dev/null
++++ b/fs/hppfs/hppfs.c
+@@ -0,0 +1,771 @@
++/*
++ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
++ * Licensed under the GPL
++ */
++
++#include <linux/ctype.h>
++#include <linux/dcache.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/mount.h>
++#include <linux/slab.h>
++#include <linux/statfs.h>
++#include <linux/types.h>
++#include <asm/uaccess.h>
++#include "os.h"
++
++static struct inode *get_inode(struct super_block *, struct dentry *);
++
++struct hppfs_data {
++	struct list_head list;
++	char contents[PAGE_SIZE - sizeof(struct list_head)];
++};
++
++struct hppfs_private {
++	struct file *proc_file;
++	int host_fd;
++	loff_t len;
++	struct hppfs_data *contents;
++};
++
++struct hppfs_inode_info {
++	struct dentry *proc_dentry;
++	struct inode vfs_inode;
++};
++
++static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
++{
++	return container_of(inode, struct hppfs_inode_info, vfs_inode);
++}
++
++#define HPPFS_SUPER_MAGIC 0xb00000ee
++
++static const struct super_operations hppfs_sbops;
++
++static int is_pid(struct dentry *dentry)
++{
++	struct super_block *sb;
++	int i;
++
++	sb = dentry->d_sb;
++	if (dentry->d_parent != sb->s_root)
++		return 0;
++
++	for (i = 0; i < dentry->d_name.len; i++) {
++		if (!isdigit(dentry->d_name.name[i]))
++			return 0;
++	}
++	return 1;
++}
++
++static char *dentry_name(struct dentry *dentry, int extra)
++{
++	struct dentry *parent;
++	char *root, *name;
++	const char *seg_name;
++	int len, seg_len;
++
++	len = 0;
++	parent = dentry;
++	while (parent->d_parent != parent) {
++		if (is_pid(parent))
++			len += strlen("pid") + 1;
++		else len += parent->d_name.len + 1;
++		parent = parent->d_parent;
++	}
++
++	root = "proc";
++	len += strlen(root);
++	name = kmalloc(len + extra + 1, GFP_KERNEL);
++	if (name == NULL)
++		return NULL;
++
++	name[len] = '\0';
++	parent = dentry;
++	while (parent->d_parent != parent) {
++		if (is_pid(parent)) {
++			seg_name = "pid";
++			seg_len = strlen("pid");
++		}
++		else {
++			seg_name = parent->d_name.name;
++			seg_len = parent->d_name.len;
++		}
++
++		len -= seg_len + 1;
++		name[len] = '/';
++		strncpy(&name[len + 1], seg_name, seg_len);
++		parent = parent->d_parent;
++	}
++	strncpy(name, root, strlen(root));
++	return name;
++}
++
++static int file_removed(struct dentry *dentry, const char *file)
++{
++	char *host_file;
++	int extra, fd;
++
++	extra = 0;
++	if (file != NULL)
++		extra += strlen(file) + 1;
++
++	host_file = dentry_name(dentry, extra + strlen("/remove"));
++	if (host_file == NULL) {
++		printk(KERN_ERR "file_removed : allocation failed\n");
++		return -ENOMEM;
++	}
++
++	if (file != NULL) {
++		strcat(host_file, "/");
++		strcat(host_file, file);
++	}
++	strcat(host_file, "/remove");
++
++	fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
++	kfree(host_file);
++	if (fd > 0) {
++		os_close_file(fd);
++		return 1;
++	}
++	return 0;
++}
++
++static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
++				   struct nameidata *nd)
++{
++	struct dentry *proc_dentry, *new, *parent;
++	struct inode *inode;
++	int err, deleted;
++
++	deleted = file_removed(dentry, NULL);
++	if (deleted < 0)
++		return ERR_PTR(deleted);
++	else if (deleted)
++		return ERR_PTR(-ENOENT);
++
++	err = -ENOMEM;
++	parent = HPPFS_I(ino)->proc_dentry;
++	mutex_lock(&parent->d_inode->i_mutex);
++	proc_dentry = d_lookup(parent, &dentry->d_name);
++	if (proc_dentry == NULL) {
++		proc_dentry = d_alloc(parent, &dentry->d_name);
++		if (proc_dentry == NULL) {
++			mutex_unlock(&parent->d_inode->i_mutex);
++			goto out;
++		}
++		new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
++						       proc_dentry, NULL);
++		if (new) {
++			dput(proc_dentry);
++			proc_dentry = new;
++		}
++	}
++	mutex_unlock(&parent->d_inode->i_mutex);
++
++	if (IS_ERR(proc_dentry))
++		return proc_dentry;
++
++	err = -ENOMEM;
++	inode = get_inode(ino->i_sb, proc_dentry);
++	if (!inode)
++		goto out_dput;
++
++ 	d_add(dentry, inode);
++	return NULL;
++
++ out_dput:
++	dput(proc_dentry);
++ out:
++	return ERR_PTR(err);
++}
++
++static const struct inode_operations hppfs_file_iops = {
++};
++
++static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
++			 loff_t *ppos, int is_user)
++{
++	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
++	ssize_t n;
++
++	read = file->f_path.dentry->d_inode->i_fop->read;
++
++	if (!is_user)
++		set_fs(KERNEL_DS);
++
++	n = (*read)(file, buf, count, &file->f_pos);
++
++	if (!is_user)
++		set_fs(USER_DS);
++
++	if (ppos)
++		*ppos = file->f_pos;
++	return n;
++}
++
++static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
++{
++	ssize_t n;
++	int cur, err;
++	char *new_buf;
++
++	n = -ENOMEM;
++	new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
++	if (new_buf == NULL) {
++		printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
++		goto out;
++	}
++	n = 0;
++	while (count > 0) {
++		cur = min_t(ssize_t, count, PAGE_SIZE);
++		err = os_read_file(fd, new_buf, cur);
++		if (err < 0) {
++			printk(KERN_ERR "hppfs_read : read failed, "
++			       "errno = %d\n", err);
++			n = err;
++			goto out_free;
++		} else if (err == 0)
++			break;
++
++		if (copy_to_user(buf, new_buf, err)) {
++			n = -EFAULT;
++			goto out_free;
++		}
++		n += err;
++		count -= err;
++	}
++ out_free:
++	kfree(new_buf);
++ out:
++	return n;
++}
++
++static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
++			  loff_t *ppos)
++{
++	struct hppfs_private *hppfs = file->private_data;
++	struct hppfs_data *data;
++	loff_t off;
++	int err;
++
++	if (hppfs->contents != NULL) {
++		int rem;
++
++		if (*ppos >= hppfs->len)
++			return 0;
++
++		data = hppfs->contents;
++		off = *ppos;
++		while (off >= sizeof(data->contents)) {
++			data = list_entry(data->list.next, struct hppfs_data,
++					  list);
++			off -= sizeof(data->contents);
++		}
++
++		if (off + count > hppfs->len)
++			count = hppfs->len - off;
++		rem = copy_to_user(buf, &data->contents[off], count);
++		*ppos += count - rem;
++		if (rem > 0)
++			return -EFAULT;
++	} else if (hppfs->host_fd != -1) {
++		err = os_seek_file(hppfs->host_fd, *ppos);
++		if (err) {
++			printk(KERN_ERR "hppfs_read : seek failed, "
++			       "errno = %d\n", err);
++			return err;
++		}
++		count = hppfs_read_file(hppfs->host_fd, buf, count);
++		if (count > 0)
++			*ppos += count;
++	}
++	else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
++
++	return count;
++}
++
++static ssize_t hppfs_write(struct file *file, const char __user *buf,
++			   size_t len, loff_t *ppos)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = data->proc_file;
++	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
++
++	write = proc_file->f_path.dentry->d_inode->i_fop->write;
++	return (*write)(proc_file, buf, len, ppos);
++}
++
++static int open_host_sock(char *host_file, int *filter_out)
++{
++	char *end;
++	int fd;
++
++	end = &host_file[strlen(host_file)];
++	strcpy(end, "/rw");
++	*filter_out = 1;
++	fd = os_connect_socket(host_file);
++	if (fd > 0)
++		return fd;
++
++	strcpy(end, "/r");
++	*filter_out = 0;
++	fd = os_connect_socket(host_file);
++	return fd;
++}
++
++static void free_contents(struct hppfs_data *head)
++{
++	struct hppfs_data *data;
++	struct list_head *ele, *next;
++
++	if (head == NULL)
++		return;
++
++	list_for_each_safe(ele, next, &head->list) {
++		data = list_entry(ele, struct hppfs_data, list);
++		kfree(data);
++	}
++	kfree(head);
++}
++
++static struct hppfs_data *hppfs_get_data(int fd, int filter,
++					 struct file *proc_file,
++					 struct file *hppfs_file,
++					 loff_t *size_out)
++{
++	struct hppfs_data *data, *new, *head;
++	int n, err;
++
++	err = -ENOMEM;
++	data = kmalloc(sizeof(*data), GFP_KERNEL);
++	if (data == NULL) {
++		printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
++		goto failed;
++	}
++
++	INIT_LIST_HEAD(&data->list);
++
++	head = data;
++	*size_out = 0;
++
++	if (filter) {
++		while ((n = read_proc(proc_file, data->contents,
++				      sizeof(data->contents), NULL, 0)) > 0)
++			os_write_file(fd, data->contents, n);
++		err = os_shutdown_socket(fd, 0, 1);
++		if (err) {
++			printk(KERN_ERR "hppfs_get_data : failed to shut down "
++			       "socket\n");
++			goto failed_free;
++		}
++	}
++	while (1) {
++		n = os_read_file(fd, data->contents, sizeof(data->contents));
++		if (n < 0) {
++			err = n;
++			printk(KERN_ERR "hppfs_get_data : read failed, "
++			       "errno = %d\n", err);
++			goto failed_free;
++		} else if (n == 0)
++			break;
++
++		*size_out += n;
++
++		if (n < sizeof(data->contents))
++			break;
++
++		new = kmalloc(sizeof(*data), GFP_KERNEL);
++		if (new == 0) {
++			printk(KERN_ERR "hppfs_get_data : data allocation "
++			       "failed\n");
++			err = -ENOMEM;
++			goto failed_free;
++		}
++
++		INIT_LIST_HEAD(&new->list);
++		list_add(&new->list, &data->list);
++		data = new;
++	}
++	return head;
++
++ failed_free:
++	free_contents(head);
++ failed:
++	return ERR_PTR(err);
++}
++
++static struct hppfs_private *hppfs_data(void)
++{
++	struct hppfs_private *data;
++
++	data = kmalloc(sizeof(*data), GFP_KERNEL);
++	if (data == NULL)
++		return data;
++
++	*data = ((struct hppfs_private ) { .host_fd  		= -1,
++					   .len  		= -1,
++					   .contents 		= NULL } );
++	return data;
++}
++
++static int file_mode(int fmode)
++{
++	if (fmode == (FMODE_READ | FMODE_WRITE))
++		return O_RDWR;
++	if (fmode == FMODE_READ)
++		return O_RDONLY;
++	if (fmode == FMODE_WRITE)
++		return O_WRONLY;
++	return 0;
++}
++
++static int hppfs_open(struct inode *inode, struct file *file)
++{
++	struct hppfs_private *data;
++	struct vfsmount *proc_mnt;
++	struct dentry *proc_dentry;
++	char *host_file;
++	int err, fd, type, filter;
++
++	err = -ENOMEM;
++	data = hppfs_data();
++	if (data == NULL)
++		goto out;
++
++	host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
++	if (host_file == NULL)
++		goto out_free2;
++
++	proc_dentry = HPPFS_I(inode)->proc_dentry;
++	proc_mnt = inode->i_sb->s_fs_info;
++
++	/* XXX This isn't closed anywhere */
++	data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
++				      file_mode(file->f_mode));
++	err = PTR_ERR(data->proc_file);
++	if (IS_ERR(data->proc_file))
++		goto out_free1;
++
++	type = os_file_type(host_file);
++	if (type == OS_TYPE_FILE) {
++		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
++		if (fd >= 0)
++			data->host_fd = fd;
++		else
++			printk(KERN_ERR "hppfs_open : failed to open '%s', "
++			       "errno = %d\n", host_file, -fd);
++
++		data->contents = NULL;
++	} else if (type == OS_TYPE_DIR) {
++		fd = open_host_sock(host_file, &filter);
++		if (fd > 0) {
++			data->contents = hppfs_get_data(fd, filter,
++							data->proc_file,
++							file, &data->len);
++			if (!IS_ERR(data->contents))
++				data->host_fd = fd;
++		} else
++			printk(KERN_ERR "hppfs_open : failed to open a socket "
++			       "in '%s', errno = %d\n", host_file, -fd);
++	}
++	kfree(host_file);
++
++	file->private_data = data;
++	return 0;
++
++ out_free1:
++	kfree(host_file);
++ out_free2:
++	free_contents(data->contents);
++	kfree(data);
++ out:
++	return err;
++}
++
++static int hppfs_dir_open(struct inode *inode, struct file *file)
++{
++	struct hppfs_private *data;
++	struct vfsmount *proc_mnt;
++	struct dentry *proc_dentry;
++	int err;
++
++	err = -ENOMEM;
++	data = hppfs_data();
++	if (data == NULL)
++		goto out;
++
++	proc_dentry = HPPFS_I(inode)->proc_dentry;
++	proc_mnt = inode->i_sb->s_fs_info;
++	data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
++				      file_mode(file->f_mode));
++	err = PTR_ERR(data->proc_file);
++	if (IS_ERR(data->proc_file))
++		goto out_free;
++
++	file->private_data = data;
++	return 0;
++
++ out_free:
++	kfree(data);
++ out:
++	return err;
++}
++
++static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = data->proc_file;
++	loff_t (*llseek)(struct file *, loff_t, int);
++	loff_t ret;
++
++	llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek;
++	if (llseek != NULL) {
++		ret = (*llseek)(proc_file, off, where);
++		if (ret < 0)
++			return ret;
++	}
++
++	return default_llseek(file, off, where);
++}
++
++static const struct file_operations hppfs_file_fops = {
++	.owner		= NULL,
++	.llseek		= hppfs_llseek,
++	.read		= hppfs_read,
++	.write		= hppfs_write,
++	.open		= hppfs_open,
++};
++
++struct hppfs_dirent {
++	void *vfs_dirent;
++	filldir_t filldir;
++	struct dentry *dentry;
++};
++
++static int hppfs_filldir(void *d, const char *name, int size,
++			 loff_t offset, u64 inode, unsigned int type)
++{
++	struct hppfs_dirent *dirent = d;
++
++	if (file_removed(dirent->dentry, name))
++		return 0;
++
++	return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
++				  inode, type);
++}
++
++static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
++{
++	struct hppfs_private *data = file->private_data;
++	struct file *proc_file = data->proc_file;
++	int (*readdir)(struct file *, void *, filldir_t);
++	struct hppfs_dirent dirent = ((struct hppfs_dirent)
++		                      { .vfs_dirent  	= ent,
++					.filldir 	= filldir,
++					.dentry  	= file->f_path.dentry
++				      });
++	int err;
++
++	readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir;
++
++	proc_file->f_pos = file->f_pos;
++	err = (*readdir)(proc_file, &dirent, hppfs_filldir);
++	file->f_pos = proc_file->f_pos;
++
++	return err;
++}
++
++static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
++{
++	return 0;
++}
++
++static const struct file_operations hppfs_dir_fops = {
++	.owner		= NULL,
++	.readdir	= hppfs_readdir,
++	.open		= hppfs_dir_open,
++	.fsync		= hppfs_fsync,
++};
++
++static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
++{
++	sf->f_blocks = 0;
++	sf->f_bfree = 0;
++	sf->f_bavail = 0;
++	sf->f_files = 0;
++	sf->f_ffree = 0;
++	sf->f_type = HPPFS_SUPER_MAGIC;
++	return 0;
++}
++
++static struct inode *hppfs_alloc_inode(struct super_block *sb)
++{
++	struct hppfs_inode_info *hi;
++
++	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
++	if (!hi)
++		return NULL;
++
++	hi->proc_dentry = NULL;
++	inode_init_once(&hi->vfs_inode);
++	return &hi->vfs_inode;
++}
++
++void hppfs_delete_inode(struct inode *ino)
++{
++	dput(HPPFS_I(ino)->proc_dentry);
++	mntput(ino->i_sb->s_fs_info);
++
++	clear_inode(ino);
++}
++
++static void hppfs_destroy_inode(struct inode *inode)
++{
++	kfree(HPPFS_I(inode));
++}
++
++static const struct super_operations hppfs_sbops = {
++	.alloc_inode	= hppfs_alloc_inode,
++	.destroy_inode	= hppfs_destroy_inode,
++	.delete_inode	= hppfs_delete_inode,
++	.statfs		= hppfs_statfs,
++};
++
++static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
++			  int buflen)
++{
++	struct dentry *proc_dentry;
++
++	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
++	return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer,
++						    buflen);
++}
++
++static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++	struct dentry *proc_dentry;
++
++	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
++
++	return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
++}
++
++int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd)
++{
++	return generic_permission(inode, mask, NULL);
++}
++
++static const struct inode_operations hppfs_dir_iops = {
++	.lookup		= hppfs_lookup,
++	.permission	= hppfs_permission,
++};
++
++static const struct inode_operations hppfs_link_iops = {
++	.readlink	= hppfs_readlink,
++	.follow_link	= hppfs_follow_link,
++	.permission	= hppfs_permission,
++};
++
++static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
++{
++	struct inode *proc_ino = dentry->d_inode;
++	struct inode *inode = new_inode(sb);
++
++	if (!inode)
++		return ERR_PTR(-ENOMEM);
++
++	if (S_ISDIR(dentry->d_inode->i_mode)) {
++		inode->i_op = &hppfs_dir_iops;
++		inode->i_fop = &hppfs_dir_fops;
++	} else if (S_ISLNK(dentry->d_inode->i_mode)) {
++		inode->i_op = &hppfs_link_iops;
++		inode->i_fop = &hppfs_file_fops;
++	} else {
++		inode->i_op = &hppfs_file_iops;
++		inode->i_fop = &hppfs_file_fops;
++	}
++
++	HPPFS_I(inode)->proc_dentry = dget(dentry);
++
++	inode->i_uid = proc_ino->i_uid;
++	inode->i_gid = proc_ino->i_gid;
++	inode->i_atime = proc_ino->i_atime;
++	inode->i_mtime = proc_ino->i_mtime;
++	inode->i_ctime = proc_ino->i_ctime;
++	inode->i_ino = proc_ino->i_ino;
++	inode->i_mode = proc_ino->i_mode;
++	inode->i_nlink = proc_ino->i_nlink;
++	inode->i_size = proc_ino->i_size;
++	inode->i_blocks = proc_ino->i_blocks;
++
++	return inode;
++}
++
++static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
++{
++	struct inode *root_inode;
++	struct vfsmount *proc_mnt;
++	int err = -ENOENT;
++
++	proc_mnt = do_kern_mount("proc", 0, "proc", NULL);
++	if (IS_ERR(proc_mnt))
++		goto out;
++
++	sb->s_blocksize = 1024;
++	sb->s_blocksize_bits = 10;
++	sb->s_magic = HPPFS_SUPER_MAGIC;
++	sb->s_op = &hppfs_sbops;
++	sb->s_fs_info = proc_mnt;
++
++	err = -ENOMEM;
++	root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root);
++	if (!root_inode)
++		goto out_mntput;
++
++	sb->s_root = d_alloc_root(root_inode);
++	if (!sb->s_root)
++		goto out_iput;
++
++	return 0;
++
++ out_iput:
++	iput(root_inode);
++ out_mntput:
++	mntput(proc_mnt);
++ out:
++	return(err);
++}
++
++static int hppfs_read_super(struct file_system_type *type,
++			    int flags, const char *dev_name,
++			    void *data, struct vfsmount *mnt)
++{
++	return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
++}
++
++static struct file_system_type hppfs_type = {
++	.owner 		= THIS_MODULE,
++	.name 		= "hppfs",
++	.get_sb 	= hppfs_read_super,
++	.kill_sb	= kill_anon_super,
++	.fs_flags 	= 0,
++};
++
++static int __init init_hppfs(void)
++{
++	return register_filesystem(&hppfs_type);
++}
++
++static void __exit exit_hppfs(void)
++{
++	unregister_filesystem(&hppfs_type);
++}
++
++module_init(init_hppfs)
++module_exit(exit_hppfs)
++MODULE_LICENSE("GPL");
+diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
+deleted file mode 100644
+index 8601d8e..0000000
+--- a/fs/hppfs/hppfs_kern.c
++++ /dev/null
+@@ -1,793 +0,0 @@
+-/*
+- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+- * Licensed under the GPL
+- */
+-
+-#include <linux/ctype.h>
+-#include <linux/dcache.h>
+-#include <linux/file.h>
+-#include <linux/fs.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/list.h>
+-#include <linux/module.h>
+-#include <linux/mount.h>
+-#include <linux/slab.h>
+-#include <linux/statfs.h>
+-#include <linux/types.h>
+-#include <asm/uaccess.h>
+-#include "os.h"
+-
+-static struct inode *get_inode(struct super_block *, struct dentry *);
+-
+-struct hppfs_data {
+-	struct list_head list;
+-	char contents[PAGE_SIZE - sizeof(struct list_head)];
+-};
+-
+-struct hppfs_private {
+-	struct file *proc_file;
+-	int host_fd;
+-	loff_t len;
+-	struct hppfs_data *contents;
+-};
+-
+-struct hppfs_inode_info {
+-        struct dentry *proc_dentry;
+-	struct inode vfs_inode;
+-};
+-
+-static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
+-{
+-	return container_of(inode, struct hppfs_inode_info, vfs_inode);
+-}
+-
+-#define HPPFS_SUPER_MAGIC 0xb00000ee
+-
+-static const struct super_operations hppfs_sbops;
+-
+-static int is_pid(struct dentry *dentry)
+-{
+-	struct super_block *sb;
+-	int i;
+-
+-	sb = dentry->d_sb;
+-	if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
+-		return 0;
+-
+-	for (i = 0; i < dentry->d_name.len; i++) {
+-		if (!isdigit(dentry->d_name.name[i]))
+-			return 0;
+-	}
+-	return 1;
+-}
+-
+-static char *dentry_name(struct dentry *dentry, int extra)
+-{
+-	struct dentry *parent;
+-	char *root, *name;
+-	const char *seg_name;
+-	int len, seg_len;
+-
+-	len = 0;
+-	parent = dentry;
+-	while (parent->d_parent != parent) {
+-		if (is_pid(parent))
+-			len += strlen("pid") + 1;
+-		else len += parent->d_name.len + 1;
+-		parent = parent->d_parent;
+-	}
+-
+-	root = "proc";
+-	len += strlen(root);
+-	name = kmalloc(len + extra + 1, GFP_KERNEL);
+-	if (name == NULL)
+-		return NULL;
+-
+-	name[len] = '\0';
+-	parent = dentry;
+-	while (parent->d_parent != parent) {
+-		if (is_pid(parent)) {
+-			seg_name = "pid";
+-			seg_len = strlen("pid");
+-		}
+-		else {
+-			seg_name = parent->d_name.name;
+-			seg_len = parent->d_name.len;
+-		}
+-
+-		len -= seg_len + 1;
+-		name[len] = '/';
+-		strncpy(&name[len + 1], seg_name, seg_len);
+-		parent = parent->d_parent;
+-	}
+-	strncpy(name, root, strlen(root));
+-	return name;
+-}
+-
+-static int file_removed(struct dentry *dentry, const char *file)
+-{
+-	char *host_file;
+-	int extra, fd;
+-
+-	extra = 0;
+-	if (file != NULL)
+-		extra += strlen(file) + 1;
+-
+-	host_file = dentry_name(dentry, extra + strlen("/remove"));
+-	if (host_file == NULL) {
+-		printk(KERN_ERR "file_removed : allocation failed\n");
+-		return -ENOMEM;
+-	}
+-
+-	if (file != NULL) {
+-		strcat(host_file, "/");
+-		strcat(host_file, file);
+-	}
+-	strcat(host_file, "/remove");
+-
+-	fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
+-	kfree(host_file);
+-	if (fd > 0) {
+-		os_close_file(fd);
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
+-                                  struct nameidata *nd)
+-{
+-	struct dentry *proc_dentry, *new, *parent;
+-	struct inode *inode;
+-	int err, deleted;
+-
+-	deleted = file_removed(dentry, NULL);
+-	if (deleted < 0)
+-		return ERR_PTR(deleted);
+-	else if (deleted)
+-		return ERR_PTR(-ENOENT);
+-
+-	err = -ENOMEM;
+-	parent = HPPFS_I(ino)->proc_dentry;
+-	mutex_lock(&parent->d_inode->i_mutex);
+-	proc_dentry = d_lookup(parent, &dentry->d_name);
+-	if (proc_dentry == NULL) {
+-		proc_dentry = d_alloc(parent, &dentry->d_name);
+-		if (proc_dentry == NULL) {
+-			mutex_unlock(&parent->d_inode->i_mutex);
+-			goto out;
+-		}
+-		new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
+-						       proc_dentry, NULL);
+-		if (new) {
+-			dput(proc_dentry);
+-			proc_dentry = new;
+-		}
+-	}
+-	mutex_unlock(&parent->d_inode->i_mutex);
+-
+-	if (IS_ERR(proc_dentry))
+-		return proc_dentry;
+-
+-	err = -ENOMEM;
+-	inode = get_inode(ino->i_sb, proc_dentry);
+-	if (!inode)
+-		goto out_dput;
+-
+- 	d_add(dentry, inode);
+-	return NULL;
+-
+- out_dput:
+-	dput(proc_dentry);
+- out:
+-	return ERR_PTR(err);
+-}
+-
+-static const struct inode_operations hppfs_file_iops = {
+-};
+-
+-static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
+-			 loff_t *ppos, int is_user)
+-{
+-	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
+-	ssize_t n;
+-
+-	read = file->f_path.dentry->d_inode->i_fop->read;
+-
+-	if (!is_user)
+-		set_fs(KERNEL_DS);
+-
+-	n = (*read)(file, buf, count, &file->f_pos);
+-
+-	if (!is_user)
+-		set_fs(USER_DS);
+-
+-	if (ppos)
+-		*ppos = file->f_pos;
+-	return n;
+-}
+-
+-static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
+-{
+-	ssize_t n;
+-	int cur, err;
+-	char *new_buf;
+-
+-	n = -ENOMEM;
+-	new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+-	if (new_buf == NULL) {
+-		printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
+-		goto out;
+-	}
+-	n = 0;
+-	while (count > 0) {
+-		cur = min_t(ssize_t, count, PAGE_SIZE);
+-		err = os_read_file(fd, new_buf, cur);
+-		if (err < 0) {
+-			printk(KERN_ERR "hppfs_read : read failed, "
+-			       "errno = %d\n", err);
+-			n = err;
+-			goto out_free;
+-		} else if (err == 0)
+-			break;
+-
+-		if (copy_to_user(buf, new_buf, err)) {
+-			n = -EFAULT;
+-			goto out_free;
+-		}
+-		n += err;
+-		count -= err;
+-	}
+- out_free:
+-	kfree(new_buf);
+- out:
+-	return n;
+-}
+-
+-static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
+-			  loff_t *ppos)
+-{
+-	struct hppfs_private *hppfs = file->private_data;
+-	struct hppfs_data *data;
+-	loff_t off;
+-	int err;
+-
+-	if (hppfs->contents != NULL) {
+-		if (*ppos >= hppfs->len)
+-			return 0;
+-
+-		data = hppfs->contents;
+-		off = *ppos;
+-		while (off >= sizeof(data->contents)) {
+-			data = list_entry(data->list.next, struct hppfs_data,
+-					  list);
+-			off -= sizeof(data->contents);
+-		}
+-
+-		if (off + count > hppfs->len)
+-			count = hppfs->len - off;
+-		copy_to_user(buf, &data->contents[off], count);
+-		*ppos += count;
+-	} else if (hppfs->host_fd != -1) {
+-		err = os_seek_file(hppfs->host_fd, *ppos);
+-		if (err) {
+-			printk(KERN_ERR "hppfs_read : seek failed, "
+-			       "errno = %d\n", err);
+-			return err;
+-		}
+-		count = hppfs_read_file(hppfs->host_fd, buf, count);
+-		if (count > 0)
+-			*ppos += count;
+-	}
+-	else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
+-
+-	return count;
+-}
+-
+-static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
+-			   loff_t *ppos)
+-{
+-	struct hppfs_private *data = file->private_data;
+-	struct file *proc_file = data->proc_file;
+-	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
+-	int err;
+-
+-	write = proc_file->f_path.dentry->d_inode->i_fop->write;
+-
+-	proc_file->f_pos = file->f_pos;
+-	err = (*write)(proc_file, buf, len, &proc_file->f_pos);
+-	file->f_pos = proc_file->f_pos;
+-
+-	return err;
+-}
+-
+-static int open_host_sock(char *host_file, int *filter_out)
+-{
+-	char *end;
+-	int fd;
+-
+-	end = &host_file[strlen(host_file)];
+-	strcpy(end, "/rw");
+-	*filter_out = 1;
+-	fd = os_connect_socket(host_file);
+-	if (fd > 0)
+-		return fd;
+-
+-	strcpy(end, "/r");
+-	*filter_out = 0;
+-	fd = os_connect_socket(host_file);
+-	return fd;
+-}
+-
+-static void free_contents(struct hppfs_data *head)
+-{
+-	struct hppfs_data *data;
+-	struct list_head *ele, *next;
+-
+-	if (head == NULL)
+-		return;
+-
+-	list_for_each_safe(ele, next, &head->list) {
+-		data = list_entry(ele, struct hppfs_data, list);
+-		kfree(data);
+-	}
+-	kfree(head);
+-}
+-
+-static struct hppfs_data *hppfs_get_data(int fd, int filter,
+-					 struct file *proc_file,
+-					 struct file *hppfs_file,
+-					 loff_t *size_out)
+-{
+-	struct hppfs_data *data, *new, *head;
+-	int n, err;
+-
+-	err = -ENOMEM;
+-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+-	if (data == NULL) {
+-		printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
+-		goto failed;
+-	}
+-
+-	INIT_LIST_HEAD(&data->list);
+-
+-	head = data;
+-	*size_out = 0;
+-
+-	if (filter) {
+-		while ((n = read_proc(proc_file, data->contents,
+-				     sizeof(data->contents), NULL, 0)) > 0)
+-			os_write_file(fd, data->contents, n);
+-		err = os_shutdown_socket(fd, 0, 1);
+-		if (err) {
+-			printk(KERN_ERR "hppfs_get_data : failed to shut down "
+-			       "socket\n");
+-			goto failed_free;
+-		}
+-	}
+-	while (1) {
+-		n = os_read_file(fd, data->contents, sizeof(data->contents));
+-		if (n < 0) {
+-			err = n;
+-			printk(KERN_ERR "hppfs_get_data : read failed, "
+-			       "errno = %d\n", err);
+-			goto failed_free;
+-		} else if (n == 0)
+-			break;
+-
+-		*size_out += n;
+-
+-		if (n < sizeof(data->contents))
+-			break;
+-
+-		new = kmalloc(sizeof(*data), GFP_KERNEL);
+-		if (new == 0) {
+-			printk(KERN_ERR "hppfs_get_data : data allocation "
+-			       "failed\n");
+-			err = -ENOMEM;
+-			goto failed_free;
+-		}
+-
+-		INIT_LIST_HEAD(&new->list);
+-		list_add(&new->list, &data->list);
+-		data = new;
+-	}
+-	return head;
+-
+- failed_free:
+-	free_contents(head);
+- failed:
+-	return ERR_PTR(err);
+-}
+-
+-static struct hppfs_private *hppfs_data(void)
+-{
+-	struct hppfs_private *data;
+-
+-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+-	if (data == NULL)
+-		return data;
+-
+-	*data = ((struct hppfs_private ) { .host_fd  		= -1,
+-					   .len  		= -1,
+-					   .contents 		= NULL } );
+-	return data;
+-}
+-
+-static int file_mode(int fmode)
+-{
+-	if (fmode == (FMODE_READ | FMODE_WRITE))
+-		return O_RDWR;
+-	if (fmode == FMODE_READ)
+-		return O_RDONLY;
+-	if (fmode == FMODE_WRITE)
+-		return O_WRONLY;
+-	return 0;
+-}
+-
+-static int hppfs_open(struct inode *inode, struct file *file)
+-{
+-	struct hppfs_private *data;
+-	struct dentry *proc_dentry;
+-	struct vfsmount *proc_mnt;
+-	char *host_file;
+-	int err, fd, type, filter;
+-
+-	err = -ENOMEM;
+-	data = hppfs_data();
+-	if (data == NULL)
+-		goto out;
+-
+-	host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
+-	if (host_file == NULL)
+-		goto out_free2;
+-
+-	proc_dentry = HPPFS_I(inode)->proc_dentry;
+-	proc_mnt = inode->i_sb->s_fs_info;
+-
+-	/* XXX This isn't closed anywhere */
+-	data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
+-				      file_mode(file->f_mode));
+-	err = PTR_ERR(data->proc_file);
+-	if (IS_ERR(data->proc_file))
+-		goto out_free1;
+-
+-	type = os_file_type(host_file);
+-	if (type == OS_TYPE_FILE) {
+-		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
+-		if (fd >= 0)
+-			data->host_fd = fd;
+-		else
+-			printk(KERN_ERR "hppfs_open : failed to open '%s', "
+-			       "errno = %d\n", host_file, -fd);
+-
+-		data->contents = NULL;
+-	} else if (type == OS_TYPE_DIR) {
+-		fd = open_host_sock(host_file, &filter);
+-		if (fd > 0) {
+-			data->contents = hppfs_get_data(fd, filter,
+-							data->proc_file,
+-							file, &data->len);
+-			if (!IS_ERR(data->contents))
+-				data->host_fd = fd;
+-		} else
+-			printk(KERN_ERR "hppfs_open : failed to open a socket "
+-			       "in '%s', errno = %d\n", host_file, -fd);
+-	}
+-	kfree(host_file);
+-
+-	file->private_data = data;
+-	return 0;
+-
+- out_free1:
+-	kfree(host_file);
+- out_free2:
+-	free_contents(data->contents);
+-	kfree(data);
+- out:
+-	return err;
+-}
+-
+-static int hppfs_dir_open(struct inode *inode, struct file *file)
+-{
+-	struct hppfs_private *data;
+-	struct dentry *proc_dentry;
+-	struct vfsmount *proc_mnt;
+-	int err;
+-
+-	err = -ENOMEM;
+-	data = hppfs_data();
+-	if (data == NULL)
+-		goto out;
+-
+-	proc_dentry = HPPFS_I(inode)->proc_dentry;
+-	proc_mnt = inode->i_sb->s_fs_info;
+-	data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
+-				      file_mode(file->f_mode));
+-	err = PTR_ERR(data->proc_file);
+-	if (IS_ERR(data->proc_file))
+-		goto out_free;
+-
+-	file->private_data = data;
+-	return 0;
+-
+- out_free:
+-	kfree(data);
+- out:
+-	return err;
+-}
+-
+-static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
+-{
+-	struct hppfs_private *data = file->private_data;
+-	struct file *proc_file = data->proc_file;
+-	loff_t (*llseek)(struct file *, loff_t, int);
+-	loff_t ret;
+-
+-	llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek;
+-	if (llseek != NULL) {
+-		ret = (*llseek)(proc_file, off, where);
+-		if (ret < 0)
+-			return ret;
+-	}
+-
+-	return default_llseek(file, off, where);
+-}
+-
+-static const struct file_operations hppfs_file_fops = {
+-	.owner		= NULL,
+-	.llseek		= hppfs_llseek,
+-	.read		= hppfs_read,
+-	.write		= hppfs_write,
+-	.open		= hppfs_open,
+-};
+-
+-struct hppfs_dirent {
+-	void *vfs_dirent;
+-	filldir_t filldir;
+-	struct dentry *dentry;
+-};
+-
+-static int hppfs_filldir(void *d, const char *name, int size,
+-			 loff_t offset, u64 inode, unsigned int type)
+-{
+-	struct hppfs_dirent *dirent = d;
+-
+-	if (file_removed(dirent->dentry, name))
+-		return 0;
+-
+-	return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
+-				  inode, type);
+-}
+-
+-static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
+-{
+-	struct hppfs_private *data = file->private_data;
+-	struct file *proc_file = data->proc_file;
+-	int (*readdir)(struct file *, void *, filldir_t);
+-	struct hppfs_dirent dirent = ((struct hppfs_dirent)
+-		                      { .vfs_dirent  	= ent,
+-					.filldir 	= filldir,
+-					.dentry  	= file->f_path.dentry
+-				      });
+-	int err;
+-
+-	readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir;
+-
+-	proc_file->f_pos = file->f_pos;
+-	err = (*readdir)(proc_file, &dirent, hppfs_filldir);
+-	file->f_pos = proc_file->f_pos;
+-
+-	return err;
+-}
+-
+-static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+-{
+-	return 0;
+-}
+-
+-static const struct file_operations hppfs_dir_fops = {
+-	.owner		= NULL,
+-	.readdir	= hppfs_readdir,
+-	.open		= hppfs_dir_open,
+-	.fsync		= hppfs_fsync,
+-};
+-
+-static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
+-{
+-	sf->f_blocks = 0;
+-	sf->f_bfree = 0;
+-	sf->f_bavail = 0;
+-	sf->f_files = 0;
+-	sf->f_ffree = 0;
+-	sf->f_type = HPPFS_SUPER_MAGIC;
+-	return 0;
+-}
+-
+-static struct inode *hppfs_alloc_inode(struct super_block *sb)
+-{
+-	struct hppfs_inode_info *hi;
+-
+-	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
+-	if (!hi)
+-		return NULL;
+-
+-	hi->proc_dentry = NULL;
+-	inode_init_once(&hi->vfs_inode);
+-	return &hi->vfs_inode;
+-}
+-
+-void hppfs_delete_inode(struct inode *ino)
+-{
+-	clear_inode(ino);
+-}
+-
+-static void hppfs_destroy_inode(struct inode *inode)
+-{
+-	kfree(HPPFS_I(inode));
+-}
+-
+-static void hppfs_put_super(struct super_block *sb)
+-{
+-	mntput(sb->s_fs_info);
+-}
+-
+-static const struct super_operations hppfs_sbops = {
+-	.alloc_inode	= hppfs_alloc_inode,
+-	.destroy_inode	= hppfs_destroy_inode,
+-	.delete_inode	= hppfs_delete_inode,
+-	.statfs		= hppfs_statfs,
+-	.put_super	= hppfs_put_super,
+-};
+-
+-static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
+-			  int buflen)
+-{
+-	struct file *proc_file;
+-	struct dentry *proc_dentry;
+-	struct vfsmount *proc_mnt;
+-	int ret;
+-
+-	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
+-	proc_mnt = dentry->d_sb->s_fs_info;
+-
+-	proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
+-	if (IS_ERR(proc_file))
+-		return PTR_ERR(proc_file);
+-
+-	ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
+-
+-	fput(proc_file);
+-
+-	return ret;
+-}
+-
+-static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+-{
+-	struct file *proc_file;
+-	struct dentry *proc_dentry;
+-	struct vfsmount *proc_mnt;
+-	void *ret;
+-
+-	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
+-	proc_mnt = dentry->d_sb->s_fs_info;
+-
+-	proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
+-	if (IS_ERR(proc_file))
+-		return proc_file;
+-
+-	ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
+-
+-	fput(proc_file);
+-
+-	return ret;
+-}
+-
+-static const struct inode_operations hppfs_dir_iops = {
+-	.lookup		= hppfs_lookup,
+-};
+-
+-static const struct inode_operations hppfs_link_iops = {
+-	.readlink	= hppfs_readlink,
+-	.follow_link	= hppfs_follow_link,
+-};
+-
+-static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
+-{
+-	struct inode *proc_ino = dentry->d_inode;
+-	struct inode *inode = new_inode(sb);
+-
+-	if (!inode)
+-		return ERR_PTR(-ENOMEM);
+-
+-	if (S_ISDIR(dentry->d_inode->i_mode)) {
+-		inode->i_op = &hppfs_dir_iops;
+-		inode->i_fop = &hppfs_dir_fops;
+-	} else if (S_ISLNK(dentry->d_inode->i_mode)) {
+-		inode->i_op = &hppfs_link_iops;
+-		inode->i_fop = &hppfs_file_fops;
+-	} else {
+-		inode->i_op = &hppfs_file_iops;
+-		inode->i_fop = &hppfs_file_fops;
+-	}
+-
+-	HPPFS_I(inode)->proc_dentry = dentry;
+-
+-	inode->i_uid = proc_ino->i_uid;
+-	inode->i_gid = proc_ino->i_gid;
+-	inode->i_atime = proc_ino->i_atime;
+-	inode->i_mtime = proc_ino->i_mtime;
+-	inode->i_ctime = proc_ino->i_ctime;
+-	inode->i_ino = proc_ino->i_ino;
+-	inode->i_mode = proc_ino->i_mode;
+-	inode->i_nlink = proc_ino->i_nlink;
+-	inode->i_size = proc_ino->i_size;
+-	inode->i_blocks = proc_ino->i_blocks;
+-
+-	return 0;
+-}
+-
+-static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
+-{
+-	struct inode *root_inode;
+-	struct vfsmount *proc_mnt;
+-	int err = -ENOENT;
+-
+-	proc_mnt = do_kern_mount("proc", 0, "proc", NULL);
+-	if (IS_ERR(proc_mnt))
+-		goto out;
+-
+-	sb->s_blocksize = 1024;
+-	sb->s_blocksize_bits = 10;
+-	sb->s_magic = HPPFS_SUPER_MAGIC;
+-	sb->s_op = &hppfs_sbops;
+-	sb->s_fs_info = proc_mnt;
+-
+-	err = -ENOMEM;
+-	root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root);
+-	if (!root_inode)
+-		goto out_mntput;
+-
+-	sb->s_root = d_alloc_root(root_inode);
+-	if (!sb->s_root)
+-		goto out_iput;
+-
+-	return 0;
+-
+- out_iput:
+-	iput(root_inode);
+- out_mntput:
+-	mntput(proc_mnt);
+- out:
+-	return(err);
+-}
+-
+-static int hppfs_read_super(struct file_system_type *type,
+-			    int flags, const char *dev_name,
+-			    void *data, struct vfsmount *mnt)
+-{
+-	return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
+-}
+-
+-static struct file_system_type hppfs_type = {
+-	.owner 		= THIS_MODULE,
+-	.name 		= "hppfs",
+-	.get_sb 	= hppfs_read_super,
+-	.kill_sb	= kill_anon_super,
+-	.fs_flags 	= 0,
+-};
+-
+-static int __init init_hppfs(void)
+-{
+-	return register_filesystem(&hppfs_type);
+-}
+-
+-static void __exit exit_hppfs(void)
+-{
+-	unregister_filesystem(&hppfs_type);
+-}
+-
+-module_init(init_hppfs)
+-module_exit(exit_hppfs)
+-MODULE_LICENSE("GPL");
+diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
+index cd931ef..5a8ca61 100644
+--- a/fs/jbd/commit.c
++++ b/fs/jbd/commit.c
+@@ -470,7 +470,9 @@ void journal_commit_transaction(journal_t *journal)
+ 	 * transaction!  Now comes the tricky part: we need to write out
+ 	 * metadata.  Loop over the transaction's entire buffer list:
+ 	 */
++	spin_lock(&journal->j_state_lock);
+ 	commit_transaction->t_state = T_COMMIT;
++	spin_unlock(&journal->j_state_lock);
+ 
+ 	J_ASSERT(commit_transaction->t_nr_buffers <=
+ 		 commit_transaction->t_outstanding_credits);
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 53632e3..2e24567 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -901,7 +901,7 @@ static void jbd2_stats_proc_init(journal_t *journal)
+ {
+ 	char name[BDEVNAME_SIZE];
+ 
+-	snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
++	bdevname(journal->j_dev, name);
+ 	journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
+ 	if (journal->j_proc_entry) {
+ 		proc_create_data("history", S_IRUGO, journal->j_proc_entry,
+@@ -915,7 +915,7 @@ static void jbd2_stats_proc_exit(journal_t *journal)
+ {
+ 	char name[BDEVNAME_SIZE];
+ 
+-	snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
++	bdevname(journal->j_dev, name);
+ 	remove_proc_entry("info", journal->j_proc_entry);
+ 	remove_proc_entry("history", journal->j_proc_entry);
+ 	remove_proc_entry(name, proc_jbd2_stats);
+diff --git a/fs/proc/array.c b/fs/proc/array.c
+index dca997a..9e3b8c3 100644
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -298,6 +298,7 @@ static inline void task_cap(struct seq_file *m, struct task_struct *p)
+ 	render_cap_t(m, "CapInh:\t", &p->cap_inheritable);
+ 	render_cap_t(m, "CapPrm:\t", &p->cap_permitted);
+ 	render_cap_t(m, "CapEff:\t", &p->cap_effective);
++	render_cap_t(m, "CapBnd:\t", &p->cap_bset);
+ }
+ 
+ static inline void task_context_switch_counts(struct seq_file *m,
+diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
+index 244a1aa..11c0351 100644
+--- a/fs/ufs/ufs.h
++++ b/fs/ufs/ufs.h
+@@ -107,7 +107,6 @@ extern struct inode * ufs_new_inode (struct inode *, int);
+ 
+ /* inode.c */
+ extern struct inode *ufs_iget(struct super_block *, unsigned long);
+-extern void ufs_put_inode (struct inode *);
+ extern int ufs_write_inode (struct inode *, int);
+ extern int ufs_sync_inode (struct inode *);
+ extern void ufs_delete_inode (struct inode *);
+diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
+index 384dc08..ac78eba 100644
+--- a/include/asm-alpha/barrier.h
++++ b/include/asm-alpha/barrier.h
+@@ -24,7 +24,7 @@ __asm__ __volatile__("mb": : :"memory")
+ #define smp_mb()	barrier()
+ #define smp_rmb()	barrier()
+ #define smp_wmb()	barrier()
+-#define smp_read_barrier_depends()	barrier()
++#define smp_read_barrier_depends()	do { } while (0)
+ #endif
+ 
+ #define set_mb(var, value) \
+diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h
+index 0982f1d..e691ecf 100644
+--- a/include/asm-alpha/param.h
++++ b/include/asm-alpha/param.h
+@@ -5,8 +5,12 @@
+    hardware ignores reprogramming.  We also need userland buy-in to the 
+    change in HZ, since this is visible in the wait4 resources etc.  */
+ 
++#ifdef __KERNEL__
+ #define HZ		CONFIG_HZ
+ #define USER_HZ		HZ
++#else
++#define HZ		1024
++#endif
+ 
+ #define EXEC_PAGESIZE	8192
+ 
+diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
+index 05ce5fb..3f0c59f 100644
+--- a/include/asm-alpha/pgtable.h
++++ b/include/asm-alpha/pgtable.h
+@@ -287,17 +287,34 @@ extern inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
+ #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ #define pgd_offset(mm, address)	((mm)->pgd+pgd_index(address))
+ 
++/*
++ * The smp_read_barrier_depends() in the following functions are required to
++ * order the load of *dir (the pointer in the top level page table) with any
++ * subsequent load of the returned pmd_t *ret (ret is data dependent on *dir).
++ *
++ * If this ordering is not enforced, the CPU might load an older value of
++ * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for
++ * more details.
++ *
++ * Note that we never change the mm->pgd pointer after the task is running, so
++ * pgd_offset does not require such a barrier.
++ */
++
+ /* Find an entry in the second-level page table.. */
+ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+ {
+-	return (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
++	pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
++	smp_read_barrier_depends(); /* see above */
++	return ret;
+ }
+ 
+ /* Find an entry in the third-level page table.. */
+ extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
+ {
+-	return (pte_t *) pmd_page_vaddr(*dir)
++	pte_t *ret = (pte_t *) pmd_page_vaddr(*dir)
+ 		+ ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1));
++	smp_read_barrier_depends(); /* see above */
++	return ret;
+ }
+ 
+ #define pte_offset_map(dir,addr)	pte_offset_kernel((dir),(addr))
+diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
+index cb307f8..d3a12a9 100644
+--- a/include/asm-frv/system.h
++++ b/include/asm-frv/system.h
+@@ -179,7 +179,7 @@ do {							\
+ #define mb()			asm volatile ("membar" : : :"memory")
+ #define rmb()			asm volatile ("membar" : : :"memory")
+ #define wmb()			asm volatile ("membar" : : :"memory")
+-#define read_barrier_depends()	barrier()
++#define read_barrier_depends()	do { } while (0)
+ 
+ #ifdef CONFIG_SMP
+ #define smp_mb()			mb()
+diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h
+index 04f64f1..1c72fb8 100644
+--- a/include/asm-h8300/param.h
++++ b/include/asm-h8300/param.h
+@@ -1,14 +1,12 @@
+ #ifndef _H8300_PARAM_H
+ #define _H8300_PARAM_H
+ 
+-
+-#ifndef HZ
+-#define HZ CONFIG_HZ
+-#endif
+-
+ #ifdef __KERNEL__
++#define HZ		CONFIG_HZ
+ #define	USER_HZ		HZ
+ #define	CLOCKS_PER_SEC	(USER_HZ)
++#else
++#define HZ		100
+ #endif
+ 
+ #define EXEC_PAGESIZE	4096
+diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
+index c2bd126..6427247 100644
+--- a/include/asm-mips/bitops.h
++++ b/include/asm-mips/bitops.h
+@@ -558,11 +558,13 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *
+ 	__clear_bit(nr, addr);
+ }
+ 
++#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
++
+ /*
+  * Return the bit position (0..63) of the most significant 1 bit in a word
+  * Returns -1 if no 1 bit exists
+  */
+-static inline int __ilog2(unsigned long x)
++static inline unsigned long __fls(unsigned long x)
+ {
+ 	int lz;
+ 
+@@ -591,13 +593,6 @@ static inline int __ilog2(unsigned long x)
+ 	return 63 - lz;
+ }
+ 
+-static inline unsigned long __fls(unsigned long x)
+-{
+-	return __ilog2(x);
+-}
+-
+-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+-
+ /*
+  * __ffs - find first bit in word.
+  * @word: The word to search
+@@ -607,7 +602,7 @@ static inline unsigned long __fls(unsigned long x)
+  */
+ static inline unsigned long __ffs(unsigned long word)
+ {
+-	return __ilog2(word & -word);
++	return __fls(word & -word);
+ }
+ 
+ /*
+@@ -654,6 +649,7 @@ static inline int ffs(int word)
+ #else
+ 
+ #include <asm-generic/bitops/__ffs.h>
++#include <asm-generic/bitops/__fls.h>
+ #include <asm-generic/bitops/ffs.h>
+ #include <asm-generic/bitops/fls.h>
+ #include <asm-generic/bitops/fls64.h>
+diff --git a/include/asm-mips/compiler.h b/include/asm-mips/compiler.h
+index aa6b876..71f5c5c 100644
+--- a/include/asm-mips/compiler.h
++++ b/include/asm-mips/compiler.h
+@@ -9,10 +9,10 @@
+ #define _ASM_COMPILER_H
+ 
+ #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+-#define GCC_IMM_ASM "n"
++#define GCC_IMM_ASM() "n"
+ #define GCC_REG_ACCUM "$0"
+ #else
+-#define GCC_IMM_ASM "rn"
++#define GCC_IMM_ASM() "rn"
+ #define GCC_REG_ACCUM "accum"
+ #endif
+ 
+diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
+index a055551..363a14e 100644
+--- a/include/asm-mips/mach-au1x00/au1000.h
++++ b/include/asm-mips/mach-au1x00/au1000.h
+@@ -40,8 +40,8 @@
+ #include <linux/delay.h>
+ #include <linux/types.h>
+ 
+-#include <asm/io.h>
+-#include <asm/irq.h>
++#include <linux/io.h>
++#include <linux/irq.h>
+ 
+ /* cpu pipeline flush */
+ void static inline au_sync(void)
+@@ -63,32 +63,32 @@ void static inline au_sync_delay(int ms)
+ 
+ void static inline au_writeb(u8 val, unsigned long reg)
+ {
+-	*(volatile u8 *)(reg) = val;
++	*(volatile u8 *)reg = val;
+ }
+ 
+ void static inline au_writew(u16 val, unsigned long reg)
+ {
+-	*(volatile u16 *)(reg) = val;
++	*(volatile u16 *)reg = val;
+ }
+ 
+ void static inline au_writel(u32 val, unsigned long reg)
+ {
+-	*(volatile u32 *)(reg) = val;
++	*(volatile u32 *)reg = val;
+ }
+ 
+ static inline u8 au_readb(unsigned long reg)
+ {
+-	return (*(volatile u8 *)reg);
++	return *(volatile u8 *)reg;
+ }
+ 
+ static inline u16 au_readw(unsigned long reg)
+ {
+-	return (*(volatile u16 *)reg);
++	return *(volatile u16 *)reg;
+ }
+ 
+ static inline u32 au_readl(unsigned long reg)
+ {
+-	return (*(volatile u32 *)reg);
++	return *(volatile u32 *)reg;
+ }
+ 
+ 
+@@ -117,76 +117,77 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #endif /* !defined (_LANGUAGE_ASSEMBLY) */
+ 
+ /*
+- * SDRAM Register Offsets
++ * SDRAM register offsets
+  */
+-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
+-#define MEM_SDMODE0		(0x0000)
+-#define MEM_SDMODE1		(0x0004)
+-#define MEM_SDMODE2		(0x0008)
+-#define MEM_SDADDR0		(0x000C)
+-#define MEM_SDADDR1		(0x0010)
+-#define MEM_SDADDR2		(0x0014)
+-#define MEM_SDREFCFG	(0x0018)
+-#define MEM_SDPRECMD	(0x001C)
+-#define MEM_SDAUTOREF	(0x0020)
+-#define MEM_SDWRMD0		(0x0024)
+-#define MEM_SDWRMD1		(0x0028)
+-#define MEM_SDWRMD2		(0x002C)
+-#define MEM_SDSLEEP		(0x0030)
+-#define MEM_SDSMCKE		(0x0034)
++#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
++    defined(CONFIG_SOC_AU1100)
++#define MEM_SDMODE0		0x0000
++#define MEM_SDMODE1		0x0004
++#define MEM_SDMODE2		0x0008
++#define MEM_SDADDR0		0x000C
++#define MEM_SDADDR1		0x0010
++#define MEM_SDADDR2		0x0014
++#define MEM_SDREFCFG		0x0018
++#define MEM_SDPRECMD		0x001C
++#define MEM_SDAUTOREF		0x0020
++#define MEM_SDWRMD0		0x0024
++#define MEM_SDWRMD1		0x0028
++#define MEM_SDWRMD2		0x002C
++#define MEM_SDSLEEP		0x0030
++#define MEM_SDSMCKE		0x0034
+ 
+ /*
+  * MEM_SDMODE register content definitions
+  */
+-#define MEM_SDMODE_F		(1<<22)
+-#define MEM_SDMODE_SR		(1<<21)
+-#define MEM_SDMODE_BS		(1<<20)
+-#define MEM_SDMODE_RS		(3<<18)
+-#define MEM_SDMODE_CS		(7<<15)
+-#define MEM_SDMODE_TRAS		(15<<11)
+-#define MEM_SDMODE_TMRD		(3<<9)
+-#define MEM_SDMODE_TWR		(3<<7)
+-#define MEM_SDMODE_TRP		(3<<5)
+-#define MEM_SDMODE_TRCD		(3<<3)
+-#define MEM_SDMODE_TCL		(7<<0)
+-
+-#define MEM_SDMODE_BS_2Bank	(0<<20)
+-#define MEM_SDMODE_BS_4Bank	(1<<20)
+-#define MEM_SDMODE_RS_11Row	(0<<18)
+-#define MEM_SDMODE_RS_12Row	(1<<18)
+-#define MEM_SDMODE_RS_13Row	(2<<18)
+-#define MEM_SDMODE_RS_N(N)	((N)<<18)
+-#define MEM_SDMODE_CS_7Col	(0<<15)
+-#define MEM_SDMODE_CS_8Col	(1<<15)
+-#define MEM_SDMODE_CS_9Col	(2<<15)
+-#define MEM_SDMODE_CS_10Col	(3<<15)
+-#define MEM_SDMODE_CS_11Col	(4<<15)
+-#define MEM_SDMODE_CS_N(N)		((N)<<15)
+-#define MEM_SDMODE_TRAS_N(N)	((N)<<11)
+-#define MEM_SDMODE_TMRD_N(N)	((N)<<9)
+-#define MEM_SDMODE_TWR_N(N)		((N)<<7)
+-#define MEM_SDMODE_TRP_N(N)		((N)<<5)
+-#define MEM_SDMODE_TRCD_N(N)	((N)<<3)
+-#define MEM_SDMODE_TCL_N(N)		((N)<<0)
++#define MEM_SDMODE_F		(1 << 22)
++#define MEM_SDMODE_SR		(1 << 21)
++#define MEM_SDMODE_BS		(1 << 20)
++#define MEM_SDMODE_RS		(3 << 18)
++#define MEM_SDMODE_CS		(7 << 15)
++#define MEM_SDMODE_TRAS 	(15 << 11)
++#define MEM_SDMODE_TMRD 	(3 << 9)
++#define MEM_SDMODE_TWR		(3 << 7)
++#define MEM_SDMODE_TRP		(3 << 5)
++#define MEM_SDMODE_TRCD 	(3 << 3)
++#define MEM_SDMODE_TCL		(7 << 0)
++
++#define MEM_SDMODE_BS_2Bank	(0 << 20)
++#define MEM_SDMODE_BS_4Bank	(1 << 20)
++#define MEM_SDMODE_RS_11Row	(0 << 18)
++#define MEM_SDMODE_RS_12Row	(1 << 18)
++#define MEM_SDMODE_RS_13Row	(2 << 18)
++#define MEM_SDMODE_RS_N(N)	((N) << 18)
++#define MEM_SDMODE_CS_7Col	(0 << 15)
++#define MEM_SDMODE_CS_8Col	(1 << 15)
++#define MEM_SDMODE_CS_9Col	(2 << 15)
++#define MEM_SDMODE_CS_10Col	(3 << 15)
++#define MEM_SDMODE_CS_11Col	(4 << 15)
++#define MEM_SDMODE_CS_N(N)	((N) << 15)
++#define MEM_SDMODE_TRAS_N(N)	((N) << 11)
++#define MEM_SDMODE_TMRD_N(N)	((N) << 9)
++#define MEM_SDMODE_TWR_N(N)	((N) << 7)
++#define MEM_SDMODE_TRP_N(N)	((N) << 5)
++#define MEM_SDMODE_TRCD_N(N)	((N) << 3)
++#define MEM_SDMODE_TCL_N(N)	((N) << 0)
+ 
+ /*
+  * MEM_SDADDR register contents definitions
+  */
+-#define MEM_SDADDR_E			(1<<20)
+-#define MEM_SDADDR_CSBA			(0x03FF<<10)
+-#define MEM_SDADDR_CSMASK		(0x03FF<<0)
+-#define MEM_SDADDR_CSBA_N(N)	((N)&(0x03FF<<22)>>12)
+-#define MEM_SDADDR_CSMASK_N(N)	((N)&(0x03FF<<22)>>22)
++#define MEM_SDADDR_E		(1 << 20)
++#define MEM_SDADDR_CSBA 	(0x03FF << 10)
++#define MEM_SDADDR_CSMASK	(0x03FF << 0)
++#define MEM_SDADDR_CSBA_N(N)	((N) & (0x03FF << 22) >> 12)
++#define MEM_SDADDR_CSMASK_N(N)	((N)&(0x03FF << 22) >> 22)
+ 
+ /*
+  * MEM_SDREFCFG register content definitions
+  */
+-#define MEM_SDREFCFG_TRC		(15<<28)
+-#define MEM_SDREFCFG_TRPM		(3<<26)
+-#define MEM_SDREFCFG_E			(1<<25)
+-#define MEM_SDREFCFG_RE			(0x1ffffff<<0)
+-#define MEM_SDREFCFG_TRC_N(N)	((N)<<MEM_SDREFCFG_TRC)
+-#define MEM_SDREFCFG_TRPM_N(N)	((N)<<MEM_SDREFCFG_TRPM)
++#define MEM_SDREFCFG_TRC	(15 << 28)
++#define MEM_SDREFCFG_TRPM	(3 << 26)
++#define MEM_SDREFCFG_E		(1 << 25)
++#define MEM_SDREFCFG_RE 	(0x1ffffff << 0)
++#define MEM_SDREFCFG_TRC_N(N)	((N) << MEM_SDREFCFG_TRC)
++#define MEM_SDREFCFG_TRPM_N(N)	((N) << MEM_SDREFCFG_TRPM)
+ #define MEM_SDREFCFG_REF_N(N)	(N)
+ #endif
+ 
+@@ -199,25 +200,25 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ /***********************************************************************/
+ 
+ #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+-#define MEM_SDMODE0		(0x0800)
+-#define MEM_SDMODE1		(0x0808)
+-#define MEM_SDMODE2		(0x0810)
+-#define MEM_SDADDR0		(0x0820)
+-#define MEM_SDADDR1		(0x0828)
+-#define MEM_SDADDR2		(0x0830)
+-#define MEM_SDCONFIGA	(0x0840)
+-#define MEM_SDCONFIGB	(0x0848)
+-#define MEM_SDSTAT		(0x0850)
+-#define MEM_SDERRADDR	(0x0858)
+-#define MEM_SDSTRIDE0	(0x0860)
+-#define MEM_SDSTRIDE1	(0x0868)
+-#define MEM_SDSTRIDE2	(0x0870)
+-#define MEM_SDWRMD0		(0x0880)
+-#define MEM_SDWRMD1		(0x0888)
+-#define MEM_SDWRMD2		(0x0890)
+-#define MEM_SDPRECMD	(0x08C0)
+-#define MEM_SDAUTOREF	(0x08C8)
+-#define MEM_SDSREF		(0x08D0)
++#define MEM_SDMODE0		0x0800
++#define MEM_SDMODE1		0x0808
++#define MEM_SDMODE2		0x0810
++#define MEM_SDADDR0		0x0820
++#define MEM_SDADDR1		0x0828
++#define MEM_SDADDR2		0x0830
++#define MEM_SDCONFIGA		0x0840
++#define MEM_SDCONFIGB		0x0848
++#define MEM_SDSTAT		0x0850
++#define MEM_SDERRADDR		0x0858
++#define MEM_SDSTRIDE0		0x0860
++#define MEM_SDSTRIDE1		0x0868
++#define MEM_SDSTRIDE2		0x0870
++#define MEM_SDWRMD0		0x0880
++#define MEM_SDWRMD1		0x0888
++#define MEM_SDWRMD2		0x0890
++#define MEM_SDPRECMD		0x08C0
++#define MEM_SDAUTOREF		0x08C8
++#define MEM_SDSREF		0x08D0
+ #define MEM_SDSLEEP		MEM_SDSREF
+ 
+ #endif
+@@ -256,9 +257,9 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #define	SSI0_PHYS_ADDR		0x11600000
+ #define	SSI1_PHYS_ADDR		0x11680000
+ #define	SYS_PHYS_ADDR		0x11900000
+-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
+-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
+ #endif
+ 
+ /********************************************************************/
+@@ -290,13 +291,13 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #define	UART3_PHYS_ADDR		0x11400000
+ #define GPIO2_PHYS_ADDR		0x11700000
+ #define	SYS_PHYS_ADDR		0x11900000
+-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
+-#define PCI_IO_PHYS_ADDR      0x500000000ULL
+-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
+-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#define PCI_MEM_PHYS_ADDR	0x400000000ULL
++#define PCI_IO_PHYS_ADDR	0x500000000ULL
++#define PCI_CONFIG0_PHYS_ADDR	0x600000000ULL
++#define PCI_CONFIG1_PHYS_ADDR	0x680000000ULL
++#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
+ #endif
+ 
+ /********************************************************************/
+@@ -333,9 +334,9 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #define GPIO2_PHYS_ADDR		0x11700000
+ #define	SYS_PHYS_ADDR		0x11900000
+ #define LCD_PHYS_ADDR		0x15000000
+-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
+-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
+ #endif
+ 
+ /***********************************************************************/
+@@ -360,17 +361,17 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #define	SYS_PHYS_ADDR		0x11900000
+ #define	DDMA_PHYS_ADDR		0x14002000
+ #define PE_PHYS_ADDR		0x14008000
+-#define PSC0_PHYS_ADDR	 	0x11A00000
+-#define PSC1_PHYS_ADDR	 	0x11B00000
+-#define PSC2_PHYS_ADDR	 	0x10A00000
+-#define PSC3_PHYS_ADDR	 	0x10B00000
+-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
+-#define PCI_IO_PHYS_ADDR      0x500000000ULL
+-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
+-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#define PSC0_PHYS_ADDR		0x11A00000
++#define PSC1_PHYS_ADDR		0x11B00000
++#define PSC2_PHYS_ADDR		0x10A00000
++#define PSC3_PHYS_ADDR		0x10B00000
++#define PCI_MEM_PHYS_ADDR	0x400000000ULL
++#define PCI_IO_PHYS_ADDR	0x500000000ULL
++#define PCI_CONFIG0_PHYS_ADDR	0x600000000ULL
++#define PCI_CONFIG1_PHYS_ADDR	0x680000000ULL
++#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
+ #endif
+ 
+ /***********************************************************************/
+@@ -397,122 +398,121 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ #define SWCNT_PHYS_ADDR		0x1110010C
+ #define MAEFE_PHYS_ADDR		0x14012000
+ #define MAEBE_PHYS_ADDR		0x14010000
+-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
+-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
++#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
++#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
++#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
+ #endif
+ 
+-
+ /* Static Bus Controller */
+-#define MEM_STCFG0                 0xB4001000
+-#define MEM_STTIME0                0xB4001004
+-#define MEM_STADDR0                0xB4001008
++#define MEM_STCFG0		0xB4001000
++#define MEM_STTIME0		0xB4001004
++#define MEM_STADDR0		0xB4001008
+ 
+-#define MEM_STCFG1                 0xB4001010
+-#define MEM_STTIME1                0xB4001014
+-#define MEM_STADDR1                0xB4001018
++#define MEM_STCFG1		0xB4001010
++#define MEM_STTIME1		0xB4001014
++#define MEM_STADDR1		0xB4001018
+ 
+-#define MEM_STCFG2                 0xB4001020
+-#define MEM_STTIME2                0xB4001024
+-#define MEM_STADDR2                0xB4001028
++#define MEM_STCFG2		0xB4001020
++#define MEM_STTIME2		0xB4001024
++#define MEM_STADDR2		0xB4001028
+ 
+-#define MEM_STCFG3                 0xB4001030
+-#define MEM_STTIME3                0xB4001034
+-#define MEM_STADDR3                0xB4001038
++#define MEM_STCFG3		0xB4001030
++#define MEM_STTIME3		0xB4001034
++#define MEM_STADDR3		0xB4001038
+ 
+ #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+-#define MEM_STNDCTL                0xB4001100
+-#define MEM_STSTAT                 0xB4001104
++#define MEM_STNDCTL		0xB4001100
++#define MEM_STSTAT		0xB4001104
+ 
+-#define MEM_STNAND_CMD                  (0x0)
+-#define MEM_STNAND_ADDR                 (0x4)
+-#define MEM_STNAND_DATA                (0x20)
++#define MEM_STNAND_CMD		0x0
++#define MEM_STNAND_ADDR 	0x4
++#define MEM_STNAND_DATA 	0x20
+ #endif
+ 
+ /* Interrupt Controller 0 */
+-#define IC0_CFG0RD                 0xB0400040
+-#define IC0_CFG0SET                0xB0400040
+-#define IC0_CFG0CLR                0xB0400044
++#define IC0_CFG0RD		0xB0400040
++#define IC0_CFG0SET		0xB0400040
++#define IC0_CFG0CLR		0xB0400044
+ 
+-#define IC0_CFG1RD                 0xB0400048
+-#define IC0_CFG1SET                0xB0400048
+-#define IC0_CFG1CLR                0xB040004C
++#define IC0_CFG1RD		0xB0400048
++#define IC0_CFG1SET		0xB0400048
++#define IC0_CFG1CLR		0xB040004C
+ 
+-#define IC0_CFG2RD                 0xB0400050
+-#define IC0_CFG2SET                0xB0400050
+-#define IC0_CFG2CLR                0xB0400054
++#define IC0_CFG2RD		0xB0400050
++#define IC0_CFG2SET		0xB0400050
++#define IC0_CFG2CLR		0xB0400054
+ 
+-#define IC0_REQ0INT                0xB0400054
+-#define IC0_SRCRD                  0xB0400058
+-#define IC0_SRCSET                 0xB0400058
+-#define IC0_SRCCLR                 0xB040005C
+-#define IC0_REQ1INT                0xB040005C
++#define IC0_REQ0INT		0xB0400054
++#define IC0_SRCRD		0xB0400058
++#define IC0_SRCSET		0xB0400058
++#define IC0_SRCCLR		0xB040005C
++#define IC0_REQ1INT		0xB040005C
+ 
+-#define IC0_ASSIGNRD               0xB0400060
+-#define IC0_ASSIGNSET              0xB0400060
+-#define IC0_ASSIGNCLR              0xB0400064
++#define IC0_ASSIGNRD		0xB0400060
++#define IC0_ASSIGNSET		0xB0400060
++#define IC0_ASSIGNCLR		0xB0400064
+ 
+-#define IC0_WAKERD                 0xB0400068
+-#define IC0_WAKESET                0xB0400068
+-#define IC0_WAKECLR                0xB040006C
++#define IC0_WAKERD		0xB0400068
++#define IC0_WAKESET		0xB0400068
++#define IC0_WAKECLR		0xB040006C
+ 
+-#define IC0_MASKRD                 0xB0400070
+-#define IC0_MASKSET                0xB0400070
+-#define IC0_MASKCLR                0xB0400074
++#define IC0_MASKRD		0xB0400070
++#define IC0_MASKSET		0xB0400070
++#define IC0_MASKCLR		0xB0400074
+ 
+-#define IC0_RISINGRD               0xB0400078
+-#define IC0_RISINGCLR              0xB0400078
+-#define IC0_FALLINGRD              0xB040007C
+-#define IC0_FALLINGCLR             0xB040007C
++#define IC0_RISINGRD		0xB0400078
++#define IC0_RISINGCLR		0xB0400078
++#define IC0_FALLINGRD		0xB040007C
++#define IC0_FALLINGCLR		0xB040007C
+ 
+-#define IC0_TESTBIT                0xB0400080
++#define IC0_TESTBIT		0xB0400080
+ 
+ /* Interrupt Controller 1 */
+-#define IC1_CFG0RD                 0xB1800040
+-#define IC1_CFG0SET                0xB1800040
+-#define IC1_CFG0CLR                0xB1800044
++#define IC1_CFG0RD		0xB1800040
++#define IC1_CFG0SET		0xB1800040
++#define IC1_CFG0CLR		0xB1800044
+ 
+-#define IC1_CFG1RD                 0xB1800048
+-#define IC1_CFG1SET                0xB1800048
+-#define IC1_CFG1CLR                0xB180004C
++#define IC1_CFG1RD		0xB1800048
++#define IC1_CFG1SET		0xB1800048
++#define IC1_CFG1CLR		0xB180004C
+ 
+-#define IC1_CFG2RD                 0xB1800050
+-#define IC1_CFG2SET                0xB1800050
+-#define IC1_CFG2CLR                0xB1800054
++#define IC1_CFG2RD		0xB1800050
++#define IC1_CFG2SET		0xB1800050
++#define IC1_CFG2CLR		0xB1800054
+ 
+-#define IC1_REQ0INT                0xB1800054
+-#define IC1_SRCRD                  0xB1800058
+-#define IC1_SRCSET                 0xB1800058
+-#define IC1_SRCCLR                 0xB180005C
+-#define IC1_REQ1INT                0xB180005C
++#define IC1_REQ0INT		0xB1800054
++#define IC1_SRCRD		0xB1800058
++#define IC1_SRCSET		0xB1800058
++#define IC1_SRCCLR		0xB180005C
++#define IC1_REQ1INT		0xB180005C
+ 
+-#define IC1_ASSIGNRD               0xB1800060
+-#define IC1_ASSIGNSET              0xB1800060
+-#define IC1_ASSIGNCLR              0xB1800064
++#define IC1_ASSIGNRD            0xB1800060
++#define IC1_ASSIGNSET           0xB1800060
++#define IC1_ASSIGNCLR           0xB1800064
+ 
+-#define IC1_WAKERD                 0xB1800068
+-#define IC1_WAKESET                0xB1800068
+-#define IC1_WAKECLR                0xB180006C
++#define IC1_WAKERD		0xB1800068
++#define IC1_WAKESET		0xB1800068
++#define IC1_WAKECLR		0xB180006C
+ 
+-#define IC1_MASKRD                 0xB1800070
+-#define IC1_MASKSET                0xB1800070
+-#define IC1_MASKCLR                0xB1800074
++#define IC1_MASKRD		0xB1800070
++#define IC1_MASKSET		0xB1800070
++#define IC1_MASKCLR		0xB1800074
+ 
+-#define IC1_RISINGRD               0xB1800078
+-#define IC1_RISINGCLR              0xB1800078
+-#define IC1_FALLINGRD              0xB180007C
+-#define IC1_FALLINGCLR             0xB180007C
++#define IC1_RISINGRD		0xB1800078
++#define IC1_RISINGCLR		0xB1800078
++#define IC1_FALLINGRD		0xB180007C
++#define IC1_FALLINGCLR		0xB180007C
+ 
+-#define IC1_TESTBIT                0xB1800080
++#define IC1_TESTBIT		0xB1800080
+ 
+ /* Interrupt Configuration Modes */
+-#define INTC_INT_DISABLED                0
+-#define INTC_INT_RISE_EDGE             0x1
+-#define INTC_INT_FALL_EDGE             0x2
+-#define INTC_INT_RISE_AND_FALL_EDGE    0x3
+-#define INTC_INT_HIGH_LEVEL            0x5
+-#define INTC_INT_LOW_LEVEL             0x6
+-#define INTC_INT_HIGH_AND_LOW_LEVEL    0x7
++#define INTC_INT_DISABLED		0x0
++#define INTC_INT_RISE_EDGE		0x1
++#define INTC_INT_FALL_EDGE		0x2
++#define INTC_INT_RISE_AND_FALL_EDGE	0x3
++#define INTC_INT_HIGH_LEVEL		0x5
++#define INTC_INT_LOW_LEVEL		0x6
++#define INTC_INT_HIGH_AND_LOW_LEVEL	0x7
+ 
+ /* Interrupt Numbers */
+ /* Au1000 */
+@@ -579,18 +579,18 @@ enum soc_au1000_ints {
+ 	AU1000_GPIO_31,
+ };
+ 
+-#define UART0_ADDR                0xB1100000
+-#define UART1_ADDR                0xB1200000
+-#define UART2_ADDR                0xB1300000
+-#define UART3_ADDR                0xB1400000
++#define UART0_ADDR		0xB1100000
++#define UART1_ADDR		0xB1200000
++#define UART2_ADDR		0xB1300000
++#define UART3_ADDR		0xB1400000
+ 
+-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+-#define USB_HOST_CONFIG           0xB017fffc
++#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
++#define USB_HOST_CONFIG 	0xB017FFFC
+ 
+-#define AU1000_ETH0_BASE      0xB0500000
+-#define AU1000_ETH1_BASE      0xB0510000
+-#define AU1000_MAC0_ENABLE       0xB0520000
+-#define AU1000_MAC1_ENABLE       0xB0520004
++#define AU1000_ETH0_BASE	0xB0500000
++#define AU1000_ETH1_BASE	0xB0510000
++#define AU1000_MAC0_ENABLE	0xB0520000
++#define AU1000_MAC1_ENABLE	0xB0520004
+ #define NUM_ETH_INTERFACES 2
+ #endif /* CONFIG_SOC_AU1000 */
+ 
+@@ -662,16 +662,16 @@ enum soc_au1500_ints {
+ #define INTC AU1000_PCI_INTC
+ #define INTD AU1000_PCI_INTD
+ 
+-#define UART0_ADDR                0xB1100000
+-#define UART3_ADDR                0xB1400000
++#define UART0_ADDR		0xB1100000
++#define UART3_ADDR		0xB1400000
+ 
+-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+-#define USB_HOST_CONFIG           0xB017fffc
++#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
++#define USB_HOST_CONFIG 	0xB017fffc
+ 
+-#define AU1500_ETH0_BASE	  0xB1500000
+-#define AU1500_ETH1_BASE	  0xB1510000
+-#define AU1500_MAC0_ENABLE       0xB1520000
+-#define AU1500_MAC1_ENABLE       0xB1520004
++#define AU1500_ETH0_BASE	0xB1500000
++#define AU1500_ETH1_BASE	0xB1510000
++#define AU1500_MAC0_ENABLE	0xB1520000
++#define AU1500_MAC1_ENABLE	0xB1520004
+ #define NUM_ETH_INTERFACES 2
+ #endif /* CONFIG_SOC_AU1500 */
+ 
+@@ -739,15 +739,15 @@ enum soc_au1100_ints {
+ 	AU1000_GPIO_31,
+ };
+ 
+-#define UART0_ADDR                0xB1100000
+-#define UART1_ADDR                0xB1200000
+-#define UART3_ADDR                0xB1400000
++#define UART0_ADDR		0xB1100000
++#define UART1_ADDR		0xB1200000
++#define UART3_ADDR		0xB1400000
+ 
+-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+-#define USB_HOST_CONFIG           0xB017fffc
++#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
++#define USB_HOST_CONFIG 	0xB017FFFC
+ 
+-#define AU1100_ETH0_BASE	  0xB0500000
+-#define AU1100_MAC0_ENABLE       0xB0520000
++#define AU1100_ETH0_BASE	0xB0500000
++#define AU1100_MAC0_ENABLE	0xB0520000
+ #define NUM_ETH_INTERFACES 1
+ #endif /* CONFIG_SOC_AU1100 */
+ 
+@@ -826,18 +826,18 @@ enum soc_au1550_ints {
+ #define INTC AU1550_PCI_INTC
+ #define INTD AU1550_PCI_INTD
+ 
+-#define UART0_ADDR                0xB1100000
+-#define UART1_ADDR                0xB1200000
+-#define UART3_ADDR                0xB1400000
++#define UART0_ADDR		0xB1100000
++#define UART1_ADDR		0xB1200000
++#define UART3_ADDR		0xB1400000
+ 
+-#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
+-#define USB_OHCI_LEN              0x00060000
+-#define USB_HOST_CONFIG           0xB4027ffc
++#define USB_OHCI_BASE		0x14020000	/* phys addr for ioremap */
++#define USB_OHCI_LEN		0x00060000
++#define USB_HOST_CONFIG 	0xB4027ffc
+ 
+-#define AU1550_ETH0_BASE      0xB0500000
+-#define AU1550_ETH1_BASE      0xB0510000
+-#define AU1550_MAC0_ENABLE       0xB0520000
+-#define AU1550_MAC1_ENABLE       0xB0520004
++#define AU1550_ETH0_BASE	0xB0500000
++#define AU1550_ETH1_BASE	0xB0510000
++#define AU1550_MAC0_ENABLE	0xB0520000
++#define AU1550_MAC1_ENABLE	0xB0520004
+ #define NUM_ETH_INTERFACES 2
+ #endif /* CONFIG_SOC_AU1550 */
+ 
+@@ -911,32 +911,32 @@ enum soc_au1200_ints {
+ 	AU1000_GPIO_31,
+ };
+ 
+-#define UART0_ADDR                0xB1100000
+-#define UART1_ADDR                0xB1200000
+-
+-#define USB_UOC_BASE              0x14020020
+-#define USB_UOC_LEN               0x20
+-#define USB_OHCI_BASE             0x14020100
+-#define USB_OHCI_LEN              0x100
+-#define USB_EHCI_BASE             0x14020200
+-#define USB_EHCI_LEN              0x100
+-#define USB_UDC_BASE              0x14022000
+-#define USB_UDC_LEN               0x2000
+-#define USB_MSR_BASE			  0xB4020000
+-#define USB_MSR_MCFG              4
+-#define USBMSRMCFG_OMEMEN         0
+-#define USBMSRMCFG_OBMEN          1
+-#define USBMSRMCFG_EMEMEN         2
+-#define USBMSRMCFG_EBMEN          3
+-#define USBMSRMCFG_DMEMEN         4
+-#define USBMSRMCFG_DBMEN          5
+-#define USBMSRMCFG_GMEMEN         6
+-#define USBMSRMCFG_OHCCLKEN       16
+-#define USBMSRMCFG_EHCCLKEN       17
+-#define USBMSRMCFG_UDCCLKEN       18
+-#define USBMSRMCFG_PHYPLLEN       19
+-#define USBMSRMCFG_RDCOMB         30
+-#define USBMSRMCFG_PFEN           31
++#define UART0_ADDR		0xB1100000
++#define UART1_ADDR		0xB1200000
++
++#define USB_UOC_BASE		0x14020020
++#define USB_UOC_LEN		0x20
++#define USB_OHCI_BASE		0x14020100
++#define USB_OHCI_LEN		0x100
++#define USB_EHCI_BASE		0x14020200
++#define USB_EHCI_LEN		0x100
++#define USB_UDC_BASE		0x14022000
++#define USB_UDC_LEN		0x2000
++#define USB_MSR_BASE		0xB4020000
++#define USB_MSR_MCFG		4
++#define USBMSRMCFG_OMEMEN	0
++#define USBMSRMCFG_OBMEN	1
++#define USBMSRMCFG_EMEMEN	2
++#define USBMSRMCFG_EBMEN	3
++#define USBMSRMCFG_DMEMEN	4
++#define USBMSRMCFG_DBMEN	5
++#define USBMSRMCFG_GMEMEN	6
++#define USBMSRMCFG_OHCCLKEN	16
++#define USBMSRMCFG_EHCCLKEN	17
++#define USBMSRMCFG_UDCCLKEN	18
++#define USBMSRMCFG_PHYPLLEN	19
++#define USBMSRMCFG_RDCOMB	30
++#define USBMSRMCFG_PFEN 	31
+ 
+ #endif /* CONFIG_SOC_AU1200 */
+ 
+@@ -949,259 +949,258 @@ enum soc_au1200_ints {
+ #define INTX			0xFF			/* not valid */
+ 
+ /* Programmable Counters 0 and 1 */
+-#define SYS_BASE                   0xB1900000
+-#define SYS_COUNTER_CNTRL          (SYS_BASE + 0x14)
+-#  define SYS_CNTRL_E1S            (1<<23)
+-#  define SYS_CNTRL_T1S            (1<<20)
+-#  define SYS_CNTRL_M21            (1<<19)
+-#  define SYS_CNTRL_M11            (1<<18)
+-#  define SYS_CNTRL_M01            (1<<17)
+-#  define SYS_CNTRL_C1S            (1<<16)
+-#  define SYS_CNTRL_BP             (1<<14)
+-#  define SYS_CNTRL_EN1            (1<<13)
+-#  define SYS_CNTRL_BT1            (1<<12)
+-#  define SYS_CNTRL_EN0            (1<<11)
+-#  define SYS_CNTRL_BT0            (1<<10)
+-#  define SYS_CNTRL_E0             (1<<8)
+-#  define SYS_CNTRL_E0S            (1<<7)
+-#  define SYS_CNTRL_32S            (1<<5)
+-#  define SYS_CNTRL_T0S            (1<<4)
+-#  define SYS_CNTRL_M20            (1<<3)
+-#  define SYS_CNTRL_M10            (1<<2)
+-#  define SYS_CNTRL_M00            (1<<1)
+-#  define SYS_CNTRL_C0S            (1<<0)
++#define SYS_BASE		0xB1900000
++#define SYS_COUNTER_CNTRL	(SYS_BASE + 0x14)
++#  define SYS_CNTRL_E1S 	(1 << 23)
++#  define SYS_CNTRL_T1S 	(1 << 20)
++#  define SYS_CNTRL_M21 	(1 << 19)
++#  define SYS_CNTRL_M11 	(1 << 18)
++#  define SYS_CNTRL_M01 	(1 << 17)
++#  define SYS_CNTRL_C1S 	(1 << 16)
++#  define SYS_CNTRL_BP		(1 << 14)
++#  define SYS_CNTRL_EN1 	(1 << 13)
++#  define SYS_CNTRL_BT1 	(1 << 12)
++#  define SYS_CNTRL_EN0 	(1 << 11)
++#  define SYS_CNTRL_BT0 	(1 << 10)
++#  define SYS_CNTRL_E0		(1 << 8)
++#  define SYS_CNTRL_E0S 	(1 << 7)
++#  define SYS_CNTRL_32S 	(1 << 5)
++#  define SYS_CNTRL_T0S 	(1 << 4)
++#  define SYS_CNTRL_M20 	(1 << 3)
++#  define SYS_CNTRL_M10 	(1 << 2)
++#  define SYS_CNTRL_M00 	(1 << 1)
++#  define SYS_CNTRL_C0S 	(1 << 0)
+ 
+ /* Programmable Counter 0 Registers */
+-#define SYS_TOYTRIM                 (SYS_BASE + 0)
+-#define SYS_TOYWRITE                (SYS_BASE + 4)
+-#define SYS_TOYMATCH0               (SYS_BASE + 8)
+-#define SYS_TOYMATCH1               (SYS_BASE + 0xC)
+-#define SYS_TOYMATCH2               (SYS_BASE + 0x10)
+-#define SYS_TOYREAD                 (SYS_BASE + 0x40)
++#define SYS_TOYTRIM		(SYS_BASE + 0)
++#define SYS_TOYWRITE		(SYS_BASE + 4)
++#define SYS_TOYMATCH0		(SYS_BASE + 8)
++#define SYS_TOYMATCH1		(SYS_BASE + 0xC)
++#define SYS_TOYMATCH2		(SYS_BASE + 0x10)
++#define SYS_TOYREAD		(SYS_BASE + 0x40)
+ 
+ /* Programmable Counter 1 Registers */
+-#define SYS_RTCTRIM                 (SYS_BASE + 0x44)
+-#define SYS_RTCWRITE                (SYS_BASE + 0x48)
+-#define SYS_RTCMATCH0               (SYS_BASE + 0x4C)
+-#define SYS_RTCMATCH1               (SYS_BASE + 0x50)
+-#define SYS_RTCMATCH2               (SYS_BASE + 0x54)
+-#define SYS_RTCREAD                 (SYS_BASE + 0x58)
++#define SYS_RTCTRIM		(SYS_BASE + 0x44)
++#define SYS_RTCWRITE		(SYS_BASE + 0x48)
++#define SYS_RTCMATCH0		(SYS_BASE + 0x4C)
++#define SYS_RTCMATCH1		(SYS_BASE + 0x50)
++#define SYS_RTCMATCH2		(SYS_BASE + 0x54)
++#define SYS_RTCREAD		(SYS_BASE + 0x58)
+ 
+ /* I2S Controller */
+-#define I2S_DATA                    0xB1000000
+-#  define I2S_DATA_MASK        (0xffffff)
+-#define I2S_CONFIG                0xB1000004
+-#  define I2S_CONFIG_XU        (1<<25)
+-#  define I2S_CONFIG_XO        (1<<24)
+-#  define I2S_CONFIG_RU        (1<<23)
+-#  define I2S_CONFIG_RO        (1<<22)
+-#  define I2S_CONFIG_TR        (1<<21)
+-#  define I2S_CONFIG_TE        (1<<20)
+-#  define I2S_CONFIG_TF        (1<<19)
+-#  define I2S_CONFIG_RR        (1<<18)
+-#  define I2S_CONFIG_RE        (1<<17)
+-#  define I2S_CONFIG_RF        (1<<16)
+-#  define I2S_CONFIG_PD        (1<<11)
+-#  define I2S_CONFIG_LB        (1<<10)
+-#  define I2S_CONFIG_IC        (1<<9)
+-#  define I2S_CONFIG_FM_BIT    7
+-#  define I2S_CONFIG_FM_MASK     (0x3 << I2S_CONFIG_FM_BIT)
+-#    define I2S_CONFIG_FM_I2S    (0x0 << I2S_CONFIG_FM_BIT)
+-#    define I2S_CONFIG_FM_LJ     (0x1 << I2S_CONFIG_FM_BIT)
+-#    define I2S_CONFIG_FM_RJ     (0x2 << I2S_CONFIG_FM_BIT)
+-#  define I2S_CONFIG_TN        (1<<6)
+-#  define I2S_CONFIG_RN        (1<<5)
+-#  define I2S_CONFIG_SZ_BIT    0
+-#  define I2S_CONFIG_SZ_MASK     (0x1F << I2S_CONFIG_SZ_BIT)
+-
+-#define I2S_CONTROL                0xB1000008
+-#  define I2S_CONTROL_D         (1<<1)
+-#  define I2S_CONTROL_CE        (1<<0)
++#define I2S_DATA		0xB1000000
++#  define I2S_DATA_MASK 	0xffffff
++#define I2S_CONFIG		0xB1000004
++#  define I2S_CONFIG_XU 	(1 << 25)
++#  define I2S_CONFIG_XO 	(1 << 24)
++#  define I2S_CONFIG_RU 	(1 << 23)
++#  define I2S_CONFIG_RO 	(1 << 22)
++#  define I2S_CONFIG_TR 	(1 << 21)
++#  define I2S_CONFIG_TE 	(1 << 20)
++#  define I2S_CONFIG_TF 	(1 << 19)
++#  define I2S_CONFIG_RR 	(1 << 18)
++#  define I2S_CONFIG_RE 	(1 << 17)
++#  define I2S_CONFIG_RF 	(1 << 16)
++#  define I2S_CONFIG_PD 	(1 << 11)
++#  define I2S_CONFIG_LB 	(1 << 10)
++#  define I2S_CONFIG_IC 	(1 << 9)
++#  define I2S_CONFIG_FM_BIT	7
++#  define I2S_CONFIG_FM_MASK	(0x3 << I2S_CONFIG_FM_BIT)
++#    define I2S_CONFIG_FM_I2S	(0x0 << I2S_CONFIG_FM_BIT)
++#    define I2S_CONFIG_FM_LJ	(0x1 << I2S_CONFIG_FM_BIT)
++#    define I2S_CONFIG_FM_RJ	(0x2 << I2S_CONFIG_FM_BIT)
++#  define I2S_CONFIG_TN 	(1 << 6)
++#  define I2S_CONFIG_RN 	(1 << 5)
++#  define I2S_CONFIG_SZ_BIT	0
++#  define I2S_CONFIG_SZ_MASK	(0x1F << I2S_CONFIG_SZ_BIT)
++
++#define I2S_CONTROL		0xB1000008
++#  define I2S_CONTROL_D 	(1 << 1)
++#  define I2S_CONTROL_CE	(1 << 0)
+ 
+ /* USB Host Controller */
+ #ifndef USB_OHCI_LEN
+-#define USB_OHCI_LEN              0x00100000
++#define USB_OHCI_LEN		0x00100000
+ #endif
+ 
+ #ifndef CONFIG_SOC_AU1200
+ 
+ /* USB Device Controller */
+-#define USBD_EP0RD                0xB0200000
+-#define USBD_EP0WR                0xB0200004
+-#define USBD_EP2WR                0xB0200008
+-#define USBD_EP3WR                0xB020000C
+-#define USBD_EP4RD                0xB0200010
+-#define USBD_EP5RD                0xB0200014
+-#define USBD_INTEN                0xB0200018
+-#define USBD_INTSTAT              0xB020001C
+-#  define USBDEV_INT_SOF       (1<<12)
+-#  define USBDEV_INT_HF_BIT    6
+-#  define USBDEV_INT_HF_MASK   (0x3f << USBDEV_INT_HF_BIT)
+-#  define USBDEV_INT_CMPLT_BIT  0
++#define USBD_EP0RD		0xB0200000
++#define USBD_EP0WR		0xB0200004
++#define USBD_EP2WR		0xB0200008
++#define USBD_EP3WR		0xB020000C
++#define USBD_EP4RD		0xB0200010
++#define USBD_EP5RD		0xB0200014
++#define USBD_INTEN		0xB0200018
++#define USBD_INTSTAT		0xB020001C
++#  define USBDEV_INT_SOF	(1 << 12)
++#  define USBDEV_INT_HF_BIT	6
++#  define USBDEV_INT_HF_MASK	0x3f << USBDEV_INT_HF_BIT)
++#  define USBDEV_INT_CMPLT_BIT	0
+ #  define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
+-#define USBD_CONFIG               0xB0200020
+-#define USBD_EP0CS                0xB0200024
+-#define USBD_EP2CS                0xB0200028
+-#define USBD_EP3CS                0xB020002C
+-#define USBD_EP4CS                0xB0200030
+-#define USBD_EP5CS                0xB0200034
+-#  define USBDEV_CS_SU         (1<<14)
+-#  define USBDEV_CS_NAK        (1<<13)
+-#  define USBDEV_CS_ACK        (1<<12)
+-#  define USBDEV_CS_BUSY       (1<<11)
+-#  define USBDEV_CS_TSIZE_BIT  1
+-#  define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
+-#  define USBDEV_CS_STALL      (1<<0)
+-#define USBD_EP0RDSTAT            0xB0200040
+-#define USBD_EP0WRSTAT            0xB0200044
+-#define USBD_EP2WRSTAT            0xB0200048
+-#define USBD_EP3WRSTAT            0xB020004C
+-#define USBD_EP4RDSTAT            0xB0200050
+-#define USBD_EP5RDSTAT            0xB0200054
+-#  define USBDEV_FSTAT_FLUSH     (1<<6)
+-#  define USBDEV_FSTAT_UF        (1<<5)
+-#  define USBDEV_FSTAT_OF        (1<<4)
+-#  define USBDEV_FSTAT_FCNT_BIT  0
++#define USBD_CONFIG		0xB0200020
++#define USBD_EP0CS		0xB0200024
++#define USBD_EP2CS		0xB0200028
++#define USBD_EP3CS		0xB020002C
++#define USBD_EP4CS		0xB0200030
++#define USBD_EP5CS		0xB0200034
++#  define USBDEV_CS_SU		(1 << 14)
++#  define USBDEV_CS_NAK 	(1 << 13)
++#  define USBDEV_CS_ACK 	(1 << 12)
++#  define USBDEV_CS_BUSY	(1 << 11)
++#  define USBDEV_CS_TSIZE_BIT	1
++#  define USBDEV_CS_TSIZE_MASK	(0x3ff << USBDEV_CS_TSIZE_BIT)
++#  define USBDEV_CS_STALL	(1 << 0)
++#define USBD_EP0RDSTAT		0xB0200040
++#define USBD_EP0WRSTAT		0xB0200044
++#define USBD_EP2WRSTAT		0xB0200048
++#define USBD_EP3WRSTAT		0xB020004C
++#define USBD_EP4RDSTAT		0xB0200050
++#define USBD_EP5RDSTAT		0xB0200054
++#  define USBDEV_FSTAT_FLUSH	(1 << 6)
++#  define USBDEV_FSTAT_UF	(1 << 5)
++#  define USBDEV_FSTAT_OF	(1 << 4)
++#  define USBDEV_FSTAT_FCNT_BIT 0
+ #  define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
+-#define USBD_ENABLE               0xB0200058
+-#  define USBDEV_ENABLE (1<<1)
+-#  define USBDEV_CE     (1<<0)
++#define USBD_ENABLE		0xB0200058
++#  define USBDEV_ENABLE 	(1 << 1)
++#  define USBDEV_CE		(1 << 0)
+ 
+ #endif /* !CONFIG_SOC_AU1200 */
+ 
+ /* Ethernet Controllers  */
+ 
+ /* 4 byte offsets from AU1000_ETH_BASE */
+-#define MAC_CONTROL                     0x0
+-#  define MAC_RX_ENABLE               (1<<2)
+-#  define MAC_TX_ENABLE               (1<<3)
+-#  define MAC_DEF_CHECK               (1<<5)
+-#  define MAC_SET_BL(X)       (((X)&0x3)<<6)
+-#  define MAC_AUTO_PAD                (1<<8)
+-#  define MAC_DISABLE_RETRY          (1<<10)
+-#  define MAC_DISABLE_BCAST          (1<<11)
+-#  define MAC_LATE_COL               (1<<12)
+-#  define MAC_HASH_MODE              (1<<13)
+-#  define MAC_HASH_ONLY              (1<<15)
+-#  define MAC_PASS_ALL               (1<<16)
+-#  define MAC_INVERSE_FILTER         (1<<17)
+-#  define MAC_PROMISCUOUS            (1<<18)
+-#  define MAC_PASS_ALL_MULTI         (1<<19)
+-#  define MAC_FULL_DUPLEX            (1<<20)
+-#  define MAC_NORMAL_MODE                 0
+-#  define MAC_INT_LOOPBACK           (1<<21)
+-#  define MAC_EXT_LOOPBACK           (1<<22)
+-#  define MAC_DISABLE_RX_OWN         (1<<23)
+-#  define MAC_BIG_ENDIAN             (1<<30)
+-#  define MAC_RX_ALL                 (1<<31)
+-#define MAC_ADDRESS_HIGH                0x4
+-#define MAC_ADDRESS_LOW                 0x8
+-#define MAC_MCAST_HIGH                  0xC
+-#define MAC_MCAST_LOW                  0x10
+-#define MAC_MII_CNTRL                  0x14
+-#  define MAC_MII_BUSY                (1<<0)
+-#  define MAC_MII_READ                     0
+-#  define MAC_MII_WRITE               (1<<1)
+-#  define MAC_SET_MII_SELECT_REG(X)   (((X)&0x1f)<<6)
+-#  define MAC_SET_MII_SELECT_PHY(X)   (((X)&0x1f)<<11)
+-#define MAC_MII_DATA                   0x18
+-#define MAC_FLOW_CNTRL                 0x1C
+-#  define MAC_FLOW_CNTRL_BUSY         (1<<0)
+-#  define MAC_FLOW_CNTRL_ENABLE       (1<<1)
+-#  define MAC_PASS_CONTROL            (1<<2)
+-#  define MAC_SET_PAUSE(X)        (((X)&0xffff)<<16)
+-#define MAC_VLAN1_TAG                  0x20
+-#define MAC_VLAN2_TAG                  0x24
++#define MAC_CONTROL		0x0
++#  define MAC_RX_ENABLE 	(1 << 2)
++#  define MAC_TX_ENABLE 	(1 << 3)
++#  define MAC_DEF_CHECK 	(1 << 5)
++#  define MAC_SET_BL(X) 	(((X) & 0x3) << 6)
++#  define MAC_AUTO_PAD		(1 << 8)
++#  define MAC_DISABLE_RETRY	(1 << 10)
++#  define MAC_DISABLE_BCAST	(1 << 11)
++#  define MAC_LATE_COL		(1 << 12)
++#  define MAC_HASH_MODE 	(1 << 13)
++#  define MAC_HASH_ONLY 	(1 << 15)
++#  define MAC_PASS_ALL		(1 << 16)
++#  define MAC_INVERSE_FILTER	(1 << 17)
++#  define MAC_PROMISCUOUS	(1 << 18)
++#  define MAC_PASS_ALL_MULTI	(1 << 19)
++#  define MAC_FULL_DUPLEX	(1 << 20)
++#  define MAC_NORMAL_MODE	0
++#  define MAC_INT_LOOPBACK	(1 << 21)
++#  define MAC_EXT_LOOPBACK	(1 << 22)
++#  define MAC_DISABLE_RX_OWN	(1 << 23)
++#  define MAC_BIG_ENDIAN	(1 << 30)
++#  define MAC_RX_ALL		(1 << 31)
++#define MAC_ADDRESS_HIGH	0x4
++#define MAC_ADDRESS_LOW		0x8
++#define MAC_MCAST_HIGH		0xC
++#define MAC_MCAST_LOW		0x10
++#define MAC_MII_CNTRL		0x14
++#  define MAC_MII_BUSY		(1 << 0)
++#  define MAC_MII_READ		0
++#  define MAC_MII_WRITE		(1 << 1)
++#  define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6)
++#  define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11)
++#define MAC_MII_DATA		0x18
++#define MAC_FLOW_CNTRL		0x1C
++#  define MAC_FLOW_CNTRL_BUSY	(1 << 0)
++#  define MAC_FLOW_CNTRL_ENABLE (1 << 1)
++#  define MAC_PASS_CONTROL	(1 << 2)
++#  define MAC_SET_PAUSE(X)	(((X) & 0xffff) << 16)
++#define MAC_VLAN1_TAG		0x20
++#define MAC_VLAN2_TAG		0x24
+ 
+ /* Ethernet Controller Enable */
+ 
+-#  define MAC_EN_CLOCK_ENABLE         (1<<0)
+-#  define MAC_EN_RESET0               (1<<1)
+-#  define MAC_EN_TOSS                 (0<<2)
+-#  define MAC_EN_CACHEABLE            (1<<3)
+-#  define MAC_EN_RESET1               (1<<4)
+-#  define MAC_EN_RESET2               (1<<5)
+-#  define MAC_DMA_RESET               (1<<6)
++#  define MAC_EN_CLOCK_ENABLE	(1 << 0)
++#  define MAC_EN_RESET0		(1 << 1)
++#  define MAC_EN_TOSS		(0 << 2)
++#  define MAC_EN_CACHEABLE	(1 << 3)
++#  define MAC_EN_RESET1 	(1 << 4)
++#  define MAC_EN_RESET2 	(1 << 5)
++#  define MAC_DMA_RESET 	(1 << 6)
+ 
+ /* Ethernet Controller DMA Channels */
+ 
+-#define MAC0_TX_DMA_ADDR         0xB4004000
+-#define MAC1_TX_DMA_ADDR         0xB4004200
++#define MAC0_TX_DMA_ADDR	0xB4004000
++#define MAC1_TX_DMA_ADDR	0xB4004200
+ /* offsets from MAC_TX_RING_ADDR address */
+-#define MAC_TX_BUFF0_STATUS             0x0
+-#  define TX_FRAME_ABORTED            (1<<0)
+-#  define TX_JAB_TIMEOUT              (1<<1)
+-#  define TX_NO_CARRIER               (1<<2)
+-#  define TX_LOSS_CARRIER             (1<<3)
+-#  define TX_EXC_DEF                  (1<<4)
+-#  define TX_LATE_COLL_ABORT          (1<<5)
+-#  define TX_EXC_COLL                 (1<<6)
+-#  define TX_UNDERRUN                 (1<<7)
+-#  define TX_DEFERRED                 (1<<8)
+-#  define TX_LATE_COLL                (1<<9)
+-#  define TX_COLL_CNT_MASK         (0xF<<10)
+-#  define TX_PKT_RETRY               (1<<31)
+-#define MAC_TX_BUFF0_ADDR                0x4
+-#  define TX_DMA_ENABLE               (1<<0)
+-#  define TX_T_DONE                   (1<<1)
+-#  define TX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
+-#define MAC_TX_BUFF0_LEN                 0x8
+-#define MAC_TX_BUFF1_STATUS             0x10
+-#define MAC_TX_BUFF1_ADDR               0x14
+-#define MAC_TX_BUFF1_LEN                0x18
+-#define MAC_TX_BUFF2_STATUS             0x20
+-#define MAC_TX_BUFF2_ADDR               0x24
+-#define MAC_TX_BUFF2_LEN                0x28
+-#define MAC_TX_BUFF3_STATUS             0x30
+-#define MAC_TX_BUFF3_ADDR               0x34
+-#define MAC_TX_BUFF3_LEN                0x38
+-
+-#define MAC0_RX_DMA_ADDR         0xB4004100
+-#define MAC1_RX_DMA_ADDR         0xB4004300
++#define MAC_TX_BUFF0_STATUS	0x0
++#  define TX_FRAME_ABORTED	(1 << 0)
++#  define TX_JAB_TIMEOUT	(1 << 1)
++#  define TX_NO_CARRIER 	(1 << 2)
++#  define TX_LOSS_CARRIER	(1 << 3)
++#  define TX_EXC_DEF		(1 << 4)
++#  define TX_LATE_COLL_ABORT	(1 << 5)
++#  define TX_EXC_COLL		(1 << 6)
++#  define TX_UNDERRUN		(1 << 7)
++#  define TX_DEFERRED		(1 << 8)
++#  define TX_LATE_COLL		(1 << 9)
++#  define TX_COLL_CNT_MASK	(0xF << 10)
++#  define TX_PKT_RETRY		(1 << 31)
++#define MAC_TX_BUFF0_ADDR	0x4
++#  define TX_DMA_ENABLE 	(1 << 0)
++#  define TX_T_DONE		(1 << 1)
++#  define TX_GET_DMA_BUFFER(X)	(((X) >> 2) & 0x3)
++#define MAC_TX_BUFF0_LEN	0x8
++#define MAC_TX_BUFF1_STATUS	0x10
++#define MAC_TX_BUFF1_ADDR	0x14
++#define MAC_TX_BUFF1_LEN	0x18
++#define MAC_TX_BUFF2_STATUS	0x20
++#define MAC_TX_BUFF2_ADDR	0x24
++#define MAC_TX_BUFF2_LEN	0x28
++#define MAC_TX_BUFF3_STATUS	0x30
++#define MAC_TX_BUFF3_ADDR	0x34
++#define MAC_TX_BUFF3_LEN	0x38
++
++#define MAC0_RX_DMA_ADDR	0xB4004100
++#define MAC1_RX_DMA_ADDR	0xB4004300
+ /* offsets from MAC_RX_RING_ADDR */
+-#define MAC_RX_BUFF0_STATUS              0x0
+-#  define RX_FRAME_LEN_MASK           0x3fff
+-#  define RX_WDOG_TIMER              (1<<14)
+-#  define RX_RUNT                    (1<<15)
+-#  define RX_OVERLEN                 (1<<16)
+-#  define RX_COLL                    (1<<17)
+-#  define RX_ETHER                   (1<<18)
+-#  define RX_MII_ERROR               (1<<19)
+-#  define RX_DRIBBLING               (1<<20)
+-#  define RX_CRC_ERROR               (1<<21)
+-#  define RX_VLAN1                   (1<<22)
+-#  define RX_VLAN2                   (1<<23)
+-#  define RX_LEN_ERROR               (1<<24)
+-#  define RX_CNTRL_FRAME             (1<<25)
+-#  define RX_U_CNTRL_FRAME           (1<<26)
+-#  define RX_MCAST_FRAME             (1<<27)
+-#  define RX_BCAST_FRAME             (1<<28)
+-#  define RX_FILTER_FAIL             (1<<29)
+-#  define RX_PACKET_FILTER           (1<<30)
+-#  define RX_MISSED_FRAME            (1<<31)
++#define MAC_RX_BUFF0_STATUS	0x0
++#  define RX_FRAME_LEN_MASK	0x3fff
++#  define RX_WDOG_TIMER 	(1 << 14)
++#  define RX_RUNT		(1 << 15)
++#  define RX_OVERLEN		(1 << 16)
++#  define RX_COLL		(1 << 17)
++#  define RX_ETHER		(1 << 18)
++#  define RX_MII_ERROR		(1 << 19)
++#  define RX_DRIBBLING		(1 << 20)
++#  define RX_CRC_ERROR		(1 << 21)
++#  define RX_VLAN1		(1 << 22)
++#  define RX_VLAN2		(1 << 23)
++#  define RX_LEN_ERROR		(1 << 24)
++#  define RX_CNTRL_FRAME	(1 << 25)
++#  define RX_U_CNTRL_FRAME	(1 << 26)
++#  define RX_MCAST_FRAME	(1 << 27)
++#  define RX_BCAST_FRAME	(1 << 28)
++#  define RX_FILTER_FAIL	(1 << 29)
++#  define RX_PACKET_FILTER	(1 << 30)
++#  define RX_MISSED_FRAME	(1 << 31)
+ 
+ #  define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN |  \
+-                    RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
+-                    RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
+-#define MAC_RX_BUFF0_ADDR                0x4
+-#  define RX_DMA_ENABLE               (1<<0)
+-#  define RX_T_DONE                   (1<<1)
+-#  define RX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
+-#  define RX_SET_BUFF_ADDR(X)     ((X)&0xffffffc0)
+-#define MAC_RX_BUFF1_STATUS              0x10
+-#define MAC_RX_BUFF1_ADDR                0x14
+-#define MAC_RX_BUFF2_STATUS              0x20
+-#define MAC_RX_BUFF2_ADDR                0x24
+-#define MAC_RX_BUFF3_STATUS              0x30
+-#define MAC_RX_BUFF3_ADDR                0x34
+-
++		    RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
++		    RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
++#define MAC_RX_BUFF0_ADDR	0x4
++#  define RX_DMA_ENABLE 	(1 << 0)
++#  define RX_T_DONE		(1 << 1)
++#  define RX_GET_DMA_BUFFER(X)	(((X) >> 2) & 0x3)
++#  define RX_SET_BUFF_ADDR(X)	((X) & 0xffffffc0)
++#define MAC_RX_BUFF1_STATUS	0x10
++#define MAC_RX_BUFF1_ADDR	0x14
++#define MAC_RX_BUFF2_STATUS	0x20
++#define MAC_RX_BUFF2_ADDR	0x24
++#define MAC_RX_BUFF3_STATUS	0x30
++#define MAC_RX_BUFF3_ADDR	0x34
+ 
+ /* UARTS 0-3 */
+-#define UART_BASE                 UART0_ADDR
++#define UART_BASE		UART0_ADDR
+ #ifdef	CONFIG_SOC_AU1200
+-#define UART_DEBUG_BASE           UART1_ADDR
++#define UART_DEBUG_BASE 	UART1_ADDR
+ #else
+-#define UART_DEBUG_BASE           UART3_ADDR
++#define UART_DEBUG_BASE 	UART3_ADDR
+ #endif
+ 
+ #define UART_RX		0	/* Receive buffer */
+@@ -1294,341 +1293,337 @@ enum soc_au1200_ints {
+ #define UART_MSR_DCTS	0x01	/* Delta CTS */
+ #define UART_MSR_ANY_DELTA 0x0F	/* Any of the delta bits! */
+ 
+-
+-
+ /* SSIO */
+-#define SSI0_STATUS                0xB1600000
+-#  define SSI_STATUS_BF              (1<<4)
+-#  define SSI_STATUS_OF              (1<<3)
+-#  define SSI_STATUS_UF              (1<<2)
+-#  define SSI_STATUS_D               (1<<1)
+-#  define SSI_STATUS_B               (1<<0)
+-#define SSI0_INT                   0xB1600004
+-#  define SSI_INT_OI                 (1<<3)
+-#  define SSI_INT_UI                 (1<<2)
+-#  define SSI_INT_DI                 (1<<1)
+-#define SSI0_INT_ENABLE            0xB1600008
+-#  define SSI_INTE_OIE               (1<<3)
+-#  define SSI_INTE_UIE               (1<<2)
+-#  define SSI_INTE_DIE               (1<<1)
+-#define SSI0_CONFIG                0xB1600020
+-#  define SSI_CONFIG_AO              (1<<24)
+-#  define SSI_CONFIG_DO              (1<<23)
+-#  define SSI_CONFIG_ALEN_BIT        20
+-#    define SSI_CONFIG_ALEN_MASK       (0x7<<20)
+-#  define SSI_CONFIG_DLEN_BIT        16
+-#    define SSI_CONFIG_DLEN_MASK       (0x7<<16)
+-#  define SSI_CONFIG_DD              (1<<11)
+-#  define SSI_CONFIG_AD              (1<<10)
+-#  define SSI_CONFIG_BM_BIT          8
+-#    define SSI_CONFIG_BM_MASK         (0x3<<8)
+-#  define SSI_CONFIG_CE              (1<<7)
+-#  define SSI_CONFIG_DP              (1<<6)
+-#  define SSI_CONFIG_DL              (1<<5)
+-#  define SSI_CONFIG_EP              (1<<4)
+-#define SSI0_ADATA                 0xB1600024
+-#  define SSI_AD_D                   (1<<24)
+-#  define SSI_AD_ADDR_BIT            16
+-#    define SSI_AD_ADDR_MASK           (0xff<<16)
+-#  define SSI_AD_DATA_BIT            0
+-#    define SSI_AD_DATA_MASK           (0xfff<<0)
+-#define SSI0_CLKDIV                0xB1600028
+-#define SSI0_CONTROL               0xB1600100
+-#  define SSI_CONTROL_CD             (1<<1)
+-#  define SSI_CONTROL_E              (1<<0)
++#define SSI0_STATUS		0xB1600000
++#  define SSI_STATUS_BF 	(1 << 4)
++#  define SSI_STATUS_OF 	(1 << 3)
++#  define SSI_STATUS_UF 	(1 << 2)
++#  define SSI_STATUS_D		(1 << 1)
++#  define SSI_STATUS_B		(1 << 0)
++#define SSI0_INT		0xB1600004
++#  define SSI_INT_OI		(1 << 3)
++#  define SSI_INT_UI		(1 << 2)
++#  define SSI_INT_DI		(1 << 1)
++#define SSI0_INT_ENABLE 	0xB1600008
++#  define SSI_INTE_OIE		(1 << 3)
++#  define SSI_INTE_UIE		(1 << 2)
++#  define SSI_INTE_DIE		(1 << 1)
++#define SSI0_CONFIG		0xB1600020
++#  define SSI_CONFIG_AO 	(1 << 24)
++#  define SSI_CONFIG_DO 	(1 << 23)
++#  define SSI_CONFIG_ALEN_BIT	20
++#  define SSI_CONFIG_ALEN_MASK	(0x7 << 20)
++#  define SSI_CONFIG_DLEN_BIT	16
++#  define SSI_CONFIG_DLEN_MASK	(0x7 << 16)
++#  define SSI_CONFIG_DD 	(1 << 11)
++#  define SSI_CONFIG_AD 	(1 << 10)
++#  define SSI_CONFIG_BM_BIT	8
++#  define SSI_CONFIG_BM_MASK	(0x3 << 8)
++#  define SSI_CONFIG_CE 	(1 << 7)
++#  define SSI_CONFIG_DP 	(1 << 6)
++#  define SSI_CONFIG_DL 	(1 << 5)
++#  define SSI_CONFIG_EP 	(1 << 4)
++#define SSI0_ADATA		0xB1600024
++#  define SSI_AD_D		(1 << 24)
++#  define SSI_AD_ADDR_BIT	16
++#  define SSI_AD_ADDR_MASK	(0xff << 16)
++#  define SSI_AD_DATA_BIT	0
++#  define SSI_AD_DATA_MASK	(0xfff << 0)
++#define SSI0_CLKDIV		0xB1600028
++#define SSI0_CONTROL		0xB1600100
++#  define SSI_CONTROL_CD	(1 << 1)
++#  define SSI_CONTROL_E 	(1 << 0)
+ 
+ /* SSI1 */
+-#define SSI1_STATUS                0xB1680000
+-#define SSI1_INT                   0xB1680004
+-#define SSI1_INT_ENABLE            0xB1680008
+-#define SSI1_CONFIG                0xB1680020
+-#define SSI1_ADATA                 0xB1680024
+-#define SSI1_CLKDIV                0xB1680028
+-#define SSI1_ENABLE                0xB1680100
++#define SSI1_STATUS		0xB1680000
++#define SSI1_INT		0xB1680004
++#define SSI1_INT_ENABLE 	0xB1680008
++#define SSI1_CONFIG		0xB1680020
++#define SSI1_ADATA		0xB1680024
++#define SSI1_CLKDIV		0xB1680028
++#define SSI1_ENABLE		0xB1680100
+ 
+ /*
+  * Register content definitions
+  */
+-#define SSI_STATUS_BF				(1<<4)
+-#define SSI_STATUS_OF				(1<<3)
+-#define SSI_STATUS_UF				(1<<2)
+-#define SSI_STATUS_D				(1<<1)
+-#define SSI_STATUS_B				(1<<0)
++#define SSI_STATUS_BF		(1 << 4)
++#define SSI_STATUS_OF		(1 << 3)
++#define SSI_STATUS_UF		(1 << 2)
++#define SSI_STATUS_D		(1 << 1)
++#define SSI_STATUS_B		(1 << 0)
+ 
+ /* SSI_INT */
+-#define SSI_INT_OI					(1<<3)
+-#define SSI_INT_UI					(1<<2)
+-#define SSI_INT_DI					(1<<1)
++#define SSI_INT_OI		(1 << 3)
++#define SSI_INT_UI		(1 << 2)
++#define SSI_INT_DI		(1 << 1)
+ 
+ /* SSI_INTEN */
+-#define SSI_INTEN_OIE				(1<<3)
+-#define SSI_INTEN_UIE				(1<<2)
+-#define SSI_INTEN_DIE				(1<<1)
+-
+-#define SSI_CONFIG_AO				(1<<24)
+-#define SSI_CONFIG_DO				(1<<23)
+-#define SSI_CONFIG_ALEN				(7<<20)
+-#define SSI_CONFIG_DLEN				(15<<16)
+-#define SSI_CONFIG_DD				(1<<11)
+-#define SSI_CONFIG_AD				(1<<10)
+-#define SSI_CONFIG_BM				(3<<8)
+-#define SSI_CONFIG_CE				(1<<7)
+-#define SSI_CONFIG_DP				(1<<6)
+-#define SSI_CONFIG_DL				(1<<5)
+-#define SSI_CONFIG_EP				(1<<4)
+-#define SSI_CONFIG_ALEN_N(N)		((N-1)<<20)
+-#define SSI_CONFIG_DLEN_N(N)		((N-1)<<16)
+-#define SSI_CONFIG_BM_HI			(0<<8)
+-#define SSI_CONFIG_BM_LO			(1<<8)
+-#define SSI_CONFIG_BM_CY			(2<<8)
+-
+-#define SSI_ADATA_D					(1<<24)
+-#define SSI_ADATA_ADDR				(0xFF<<16)
+-#define SSI_ADATA_DATA				(0x0FFF)
+-#define SSI_ADATA_ADDR_N(N)			(N<<16)
+-
+-#define SSI_ENABLE_CD				(1<<1)
+-#define SSI_ENABLE_E				(1<<0)
+-
++#define SSI_INTEN_OIE		(1 << 3)
++#define SSI_INTEN_UIE		(1 << 2)
++#define SSI_INTEN_DIE		(1 << 1)
++
++#define SSI_CONFIG_AO		(1 << 24)
++#define SSI_CONFIG_DO		(1 << 23)
++#define SSI_CONFIG_ALEN 	(7 << 20)
++#define SSI_CONFIG_DLEN 	(15 << 16)
++#define SSI_CONFIG_DD		(1 << 11)
++#define SSI_CONFIG_AD		(1 << 10)
++#define SSI_CONFIG_BM		(3 << 8)
++#define SSI_CONFIG_CE		(1 << 7)
++#define SSI_CONFIG_DP		(1 << 6)
++#define SSI_CONFIG_DL		(1 << 5)
++#define SSI_CONFIG_EP		(1 << 4)
++#define SSI_CONFIG_ALEN_N(N)	((N-1) << 20)
++#define SSI_CONFIG_DLEN_N(N)	((N-1) << 16)
++#define SSI_CONFIG_BM_HI	(0 << 8)
++#define SSI_CONFIG_BM_LO	(1 << 8)
++#define SSI_CONFIG_BM_CY	(2 << 8)
++
++#define SSI_ADATA_D		(1 << 24)
++#define SSI_ADATA_ADDR		(0xFF << 16)
++#define SSI_ADATA_DATA		0x0FFF
++#define SSI_ADATA_ADDR_N(N)	(N << 16)
++
++#define SSI_ENABLE_CD		(1 << 1)
++#define SSI_ENABLE_E		(1 << 0)
+ 
+ /* IrDA Controller */
+-#define IRDA_BASE                 0xB0300000
+-#define IR_RING_PTR_STATUS        (IRDA_BASE+0x00)
+-#define IR_RING_BASE_ADDR_H       (IRDA_BASE+0x04)
+-#define IR_RING_BASE_ADDR_L       (IRDA_BASE+0x08)
+-#define IR_RING_SIZE              (IRDA_BASE+0x0C)
+-#define IR_RING_PROMPT            (IRDA_BASE+0x10)
+-#define IR_RING_ADDR_CMPR         (IRDA_BASE+0x14)
+-#define IR_INT_CLEAR              (IRDA_BASE+0x18)
+-#define IR_CONFIG_1               (IRDA_BASE+0x20)
+-#  define IR_RX_INVERT_LED        (1<<0)
+-#  define IR_TX_INVERT_LED        (1<<1)
+-#  define IR_ST                   (1<<2)
+-#  define IR_SF                   (1<<3)
+-#  define IR_SIR                  (1<<4)
+-#  define IR_MIR                  (1<<5)
+-#  define IR_FIR                  (1<<6)
+-#  define IR_16CRC                (1<<7)
+-#  define IR_TD                   (1<<8)
+-#  define IR_RX_ALL               (1<<9)
+-#  define IR_DMA_ENABLE           (1<<10)
+-#  define IR_RX_ENABLE            (1<<11)
+-#  define IR_TX_ENABLE            (1<<12)
+-#  define IR_LOOPBACK             (1<<14)
+-#  define IR_SIR_MODE	          (IR_SIR | IR_DMA_ENABLE | \
+-		                   IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
+-#define IR_SIR_FLAGS              (IRDA_BASE+0x24)
+-#define IR_ENABLE                 (IRDA_BASE+0x28)
+-#  define IR_RX_STATUS            (1<<9)
+-#  define IR_TX_STATUS            (1<<10)
+-#define IR_READ_PHY_CONFIG        (IRDA_BASE+0x2C)
+-#define IR_WRITE_PHY_CONFIG       (IRDA_BASE+0x30)
+-#define IR_MAX_PKT_LEN            (IRDA_BASE+0x34)
+-#define IR_RX_BYTE_CNT            (IRDA_BASE+0x38)
+-#define IR_CONFIG_2               (IRDA_BASE+0x3C)
+-#  define IR_MODE_INV             (1<<0)
+-#  define IR_ONE_PIN              (1<<1)
+-#define IR_INTERFACE_CONFIG       (IRDA_BASE+0x40)
++#define IRDA_BASE		0xB0300000
++#define IR_RING_PTR_STATUS	(IRDA_BASE + 0x00)
++#define IR_RING_BASE_ADDR_H	(IRDA_BASE + 0x04)
++#define IR_RING_BASE_ADDR_L	(IRDA_BASE + 0x08)
++#define IR_RING_SIZE		(IRDA_BASE + 0x0C)
++#define IR_RING_PROMPT		(IRDA_BASE + 0x10)
++#define IR_RING_ADDR_CMPR	(IRDA_BASE + 0x14)
++#define IR_INT_CLEAR		(IRDA_BASE + 0x18)
++#define IR_CONFIG_1		(IRDA_BASE + 0x20)
++#  define IR_RX_INVERT_LED	(1 << 0)
++#  define IR_TX_INVERT_LED	(1 << 1)
++#  define IR_ST 		(1 << 2)
++#  define IR_SF 		(1 << 3)
++#  define IR_SIR		(1 << 4)
++#  define IR_MIR		(1 << 5)
++#  define IR_FIR		(1 << 6)
++#  define IR_16CRC		(1 << 7)
++#  define IR_TD 		(1 << 8)
++#  define IR_RX_ALL		(1 << 9)
++#  define IR_DMA_ENABLE 	(1 << 10)
++#  define IR_RX_ENABLE		(1 << 11)
++#  define IR_TX_ENABLE		(1 << 12)
++#  define IR_LOOPBACK		(1 << 14)
++#  define IR_SIR_MODE		(IR_SIR | IR_DMA_ENABLE | \
++				 IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
++#define IR_SIR_FLAGS		(IRDA_BASE + 0x24)
++#define IR_ENABLE		(IRDA_BASE + 0x28)
++#  define IR_RX_STATUS		(1 << 9)
++#  define IR_TX_STATUS		(1 << 10)
++#define IR_READ_PHY_CONFIG	(IRDA_BASE + 0x2C)
++#define IR_WRITE_PHY_CONFIG	(IRDA_BASE + 0x30)
++#define IR_MAX_PKT_LEN		(IRDA_BASE + 0x34)
++#define IR_RX_BYTE_CNT		(IRDA_BASE + 0x38)
++#define IR_CONFIG_2		(IRDA_BASE + 0x3C)
++#  define IR_MODE_INV		(1 << 0)
++#  define IR_ONE_PIN		(1 << 1)
++#define IR_INTERFACE_CONFIG	(IRDA_BASE + 0x40)
+ 
+ /* GPIO */
+-#define SYS_PINFUNC               0xB190002C
+-#  define SYS_PF_USB			(1<<15)	/* 2nd USB device/host */
+-#  define SYS_PF_U3			(1<<14)	/* GPIO23/U3TXD */
+-#  define SYS_PF_U2			(1<<13) /* GPIO22/U2TXD */
+-#  define SYS_PF_U1			(1<<12) /* GPIO21/U1TXD */
+-#  define SYS_PF_SRC			(1<<11)	/* GPIO6/SROMCKE */
+-#  define SYS_PF_CK5			(1<<10)	/* GPIO3/CLK5 */
+-#  define SYS_PF_CK4			(1<<9)	/* GPIO2/CLK4 */
+-#  define SYS_PF_IRF			(1<<8)	/* GPIO15/IRFIRSEL */
+-#  define SYS_PF_UR3			(1<<7)	/* GPIO[14:9]/UART3 */
+-#  define SYS_PF_I2D			(1<<6)	/* GPIO8/I2SDI */
+-#  define SYS_PF_I2S			(1<<5)	/* I2S/GPIO[29:31] */
+-#  define SYS_PF_NI2			(1<<4)	/* NI2/GPIO[24:28] */
+-#  define SYS_PF_U0			(1<<3)	/* U0TXD/GPIO20 */
+-#  define SYS_PF_RD			(1<<2)	/* IRTXD/GPIO19 */
+-#  define SYS_PF_A97			(1<<1)	/* AC97/SSL1 */
+-#  define SYS_PF_S0			(1<<0)	/* SSI_0/GPIO[16:18] */
+-
+-/* Au1100 Only */
+-#  define SYS_PF_PC			(1<<18)	/* PCMCIA/GPIO[207:204] */
+-#  define SYS_PF_LCD			(1<<17)	/* extern lcd/GPIO[203:200] */
+-#  define SYS_PF_CS			(1<<16)	/* EXTCLK0/32khz to gpio2 */
+-#  define SYS_PF_EX0			(1<<9)	/* gpio2/clock */
+-
+-/* Au1550 Only.  Redefines lots of pins */
+-#  define SYS_PF_PSC2_MASK		(7 << 17)
+-#  define SYS_PF_PSC2_AC97		(0)
+-#  define SYS_PF_PSC2_SPI		(0)
+-#  define SYS_PF_PSC2_I2S		(1 << 17)
+-#  define SYS_PF_PSC2_SMBUS		(3 << 17)
+-#  define SYS_PF_PSC2_GPIO		(7 << 17)
+-#  define SYS_PF_PSC3_MASK		(7 << 20)
+-#  define SYS_PF_PSC3_AC97		(0)
+-#  define SYS_PF_PSC3_SPI		(0)
+-#  define SYS_PF_PSC3_I2S		(1 << 20)
+-#  define SYS_PF_PSC3_SMBUS		(3 << 20)
+-#  define SYS_PF_PSC3_GPIO		(7 << 20)
+-#  define SYS_PF_PSC1_S1		(1 << 1)
+-#  define SYS_PF_MUST_BE_SET		((1 << 5) | (1 << 2))
+-
+-/* Au1200 Only */
++#define SYS_PINFUNC		0xB190002C
++#  define SYS_PF_USB		(1 << 15)	/* 2nd USB device/host */
++#  define SYS_PF_U3		(1 << 14)	/* GPIO23/U3TXD */
++#  define SYS_PF_U2		(1 << 13)	/* GPIO22/U2TXD */
++#  define SYS_PF_U1		(1 << 12)	/* GPIO21/U1TXD */
++#  define SYS_PF_SRC		(1 << 11)	/* GPIO6/SROMCKE */
++#  define SYS_PF_CK5		(1 << 10)	/* GPIO3/CLK5 */
++#  define SYS_PF_CK4		(1 << 9)	/* GPIO2/CLK4 */
++#  define SYS_PF_IRF		(1 << 8)	/* GPIO15/IRFIRSEL */
++#  define SYS_PF_UR3		(1 << 7)	/* GPIO[14:9]/UART3 */
++#  define SYS_PF_I2D		(1 << 6)	/* GPIO8/I2SDI */
++#  define SYS_PF_I2S		(1 << 5)	/* I2S/GPIO[29:31] */
++#  define SYS_PF_NI2		(1 << 4)	/* NI2/GPIO[24:28] */
++#  define SYS_PF_U0		(1 << 3)	/* U0TXD/GPIO20 */
++#  define SYS_PF_RD		(1 << 2)	/* IRTXD/GPIO19 */
++#  define SYS_PF_A97		(1 << 1)	/* AC97/SSL1 */
++#  define SYS_PF_S0		(1 << 0)	/* SSI_0/GPIO[16:18] */
++
++/* Au1100 only */
++#  define SYS_PF_PC		(1 << 18)	/* PCMCIA/GPIO[207:204] */
++#  define SYS_PF_LCD		(1 << 17)	/* extern lcd/GPIO[203:200] */
++#  define SYS_PF_CS		(1 << 16)	/* EXTCLK0/32KHz to gpio2 */
++#  define SYS_PF_EX0		(1 << 9)	/* GPIO2/clock */
++
++/* Au1550 only.  Redefines lots of pins */
++#  define SYS_PF_PSC2_MASK	(7 << 17)
++#  define SYS_PF_PSC2_AC97	0
++#  define SYS_PF_PSC2_SPI	0
++#  define SYS_PF_PSC2_I2S	(1 << 17)
++#  define SYS_PF_PSC2_SMBUS	(3 << 17)
++#  define SYS_PF_PSC2_GPIO	(7 << 17)
++#  define SYS_PF_PSC3_MASK	(7 << 20)
++#  define SYS_PF_PSC3_AC97	0
++#  define SYS_PF_PSC3_SPI	0
++#  define SYS_PF_PSC3_I2S	(1 << 20)
++#  define SYS_PF_PSC3_SMBUS	(3 << 20)
++#  define SYS_PF_PSC3_GPIO	(7 << 20)
++#  define SYS_PF_PSC1_S1	(1 << 1)
++#  define SYS_PF_MUST_BE_SET	((1 << 5) | (1 << 2))
++
++/* Au1200 only */
+ #ifdef CONFIG_SOC_AU1200
+-#define SYS_PINFUNC_DMA		(1<<31)
+-#define SYS_PINFUNC_S0A		(1<<30)
+-#define SYS_PINFUNC_S1A		(1<<29)
+-#define SYS_PINFUNC_LP0		(1<<28)
+-#define SYS_PINFUNC_LP1		(1<<27)
+-#define SYS_PINFUNC_LD16	(1<<26)
+-#define SYS_PINFUNC_LD8		(1<<25)
+-#define SYS_PINFUNC_LD1		(1<<24)
+-#define SYS_PINFUNC_LD0		(1<<23)
+-#define SYS_PINFUNC_P1A		(3<<21)
+-#define SYS_PINFUNC_P1B		(1<<20)
+-#define SYS_PINFUNC_FS3		(1<<19)
+-#define SYS_PINFUNC_P0A		(3<<17)
+-#define SYS_PINFUNC_CS		(1<<16)
+-#define SYS_PINFUNC_CIM		(1<<15)
+-#define SYS_PINFUNC_P1C		(1<<14)
+-#define SYS_PINFUNC_U1T		(1<<12)
+-#define SYS_PINFUNC_U1R		(1<<11)
+-#define SYS_PINFUNC_EX1		(1<<10)
+-#define SYS_PINFUNC_EX0		(1<<9)
+-#define SYS_PINFUNC_U0R		(1<<8)
+-#define SYS_PINFUNC_MC		(1<<7)
+-#define SYS_PINFUNC_S0B		(1<<6)
+-#define SYS_PINFUNC_S0C		(1<<5)
+-#define SYS_PINFUNC_P0B		(1<<4)
+-#define SYS_PINFUNC_U0T		(1<<3)
+-#define SYS_PINFUNC_S1B		(1<<2)
++#define SYS_PINFUNC_DMA 	(1 << 31)
++#define SYS_PINFUNC_S0A 	(1 << 30)
++#define SYS_PINFUNC_S1A 	(1 << 29)
++#define SYS_PINFUNC_LP0 	(1 << 28)
++#define SYS_PINFUNC_LP1 	(1 << 27)
++#define SYS_PINFUNC_LD16 	(1 << 26)
++#define SYS_PINFUNC_LD8 	(1 << 25)
++#define SYS_PINFUNC_LD1 	(1 << 24)
++#define SYS_PINFUNC_LD0 	(1 << 23)
++#define SYS_PINFUNC_P1A 	(3 << 21)
++#define SYS_PINFUNC_P1B 	(1 << 20)
++#define SYS_PINFUNC_FS3 	(1 << 19)
++#define SYS_PINFUNC_P0A 	(3 << 17)
++#define SYS_PINFUNC_CS		(1 << 16)
++#define SYS_PINFUNC_CIM 	(1 << 15)
++#define SYS_PINFUNC_P1C 	(1 << 14)
++#define SYS_PINFUNC_U1T 	(1 << 12)
++#define SYS_PINFUNC_U1R 	(1 << 11)
++#define SYS_PINFUNC_EX1 	(1 << 10)
++#define SYS_PINFUNC_EX0 	(1 << 9)
++#define SYS_PINFUNC_U0R 	(1 << 8)
++#define SYS_PINFUNC_MC		(1 << 7)
++#define SYS_PINFUNC_S0B 	(1 << 6)
++#define SYS_PINFUNC_S0C 	(1 << 5)
++#define SYS_PINFUNC_P0B 	(1 << 4)
++#define SYS_PINFUNC_U0T 	(1 << 3)
++#define SYS_PINFUNC_S1B 	(1 << 2)
+ #endif
+ 
+-#define SYS_TRIOUTRD              0xB1900100
+-#define SYS_TRIOUTCLR             0xB1900100
+-#define SYS_OUTPUTRD              0xB1900108
+-#define SYS_OUTPUTSET             0xB1900108
+-#define SYS_OUTPUTCLR             0xB190010C
+-#define SYS_PINSTATERD            0xB1900110
+-#define SYS_PININPUTEN            0xB1900110
++#define SYS_TRIOUTRD		0xB1900100
++#define SYS_TRIOUTCLR		0xB1900100
++#define SYS_OUTPUTRD		0xB1900108
++#define SYS_OUTPUTSET		0xB1900108
++#define SYS_OUTPUTCLR		0xB190010C
++#define SYS_PINSTATERD		0xB1900110
++#define SYS_PININPUTEN		0xB1900110
+ 
+ /* GPIO2, Au1500, Au1550 only */
+-#define GPIO2_BASE                0xB1700000
+-#define GPIO2_DIR                 (GPIO2_BASE + 0)
+-#define GPIO2_OUTPUT              (GPIO2_BASE + 8)
+-#define GPIO2_PINSTATE            (GPIO2_BASE + 0xC)
+-#define GPIO2_INTENABLE           (GPIO2_BASE + 0x10)
+-#define GPIO2_ENABLE              (GPIO2_BASE + 0x14)
++#define GPIO2_BASE		0xB1700000
++#define GPIO2_DIR		(GPIO2_BASE + 0)
++#define GPIO2_OUTPUT		(GPIO2_BASE + 8)
++#define GPIO2_PINSTATE		(GPIO2_BASE + 0xC)
++#define GPIO2_INTENABLE 	(GPIO2_BASE + 0x10)
++#define GPIO2_ENABLE		(GPIO2_BASE + 0x14)
+ 
+ /* Power Management */
+-#define SYS_SCRATCH0              0xB1900018
+-#define SYS_SCRATCH1              0xB190001C
+-#define SYS_WAKEMSK               0xB1900034
+-#define SYS_ENDIAN                0xB1900038
+-#define SYS_POWERCTRL             0xB190003C
+-#define SYS_WAKESRC               0xB190005C
+-#define SYS_SLPPWR                0xB1900078
+-#define SYS_SLEEP                 0xB190007C
++#define SYS_SCRATCH0		0xB1900018
++#define SYS_SCRATCH1		0xB190001C
++#define SYS_WAKEMSK		0xB1900034
++#define SYS_ENDIAN		0xB1900038
++#define SYS_POWERCTRL		0xB190003C
++#define SYS_WAKESRC		0xB190005C
++#define SYS_SLPPWR		0xB1900078
++#define SYS_SLEEP		0xB190007C
+ 
+ /* Clock Controller */
+-#define SYS_FREQCTRL0             0xB1900020
+-#  define SYS_FC_FRDIV2_BIT         22
+-#  define SYS_FC_FRDIV2_MASK        (0xff << SYS_FC_FRDIV2_BIT)
+-#  define SYS_FC_FE2                (1<<21)
+-#  define SYS_FC_FS2                (1<<20)
+-#  define SYS_FC_FRDIV1_BIT         12
+-#  define SYS_FC_FRDIV1_MASK        (0xff << SYS_FC_FRDIV1_BIT)
+-#  define SYS_FC_FE1                (1<<11)
+-#  define SYS_FC_FS1                (1<<10)
+-#  define SYS_FC_FRDIV0_BIT         2
+-#  define SYS_FC_FRDIV0_MASK        (0xff << SYS_FC_FRDIV0_BIT)
+-#  define SYS_FC_FE0                (1<<1)
+-#  define SYS_FC_FS0                (1<<0)
+-#define SYS_FREQCTRL1             0xB1900024
+-#  define SYS_FC_FRDIV5_BIT         22
+-#  define SYS_FC_FRDIV5_MASK        (0xff << SYS_FC_FRDIV5_BIT)
+-#  define SYS_FC_FE5                (1<<21)
+-#  define SYS_FC_FS5                (1<<20)
+-#  define SYS_FC_FRDIV4_BIT         12
+-#  define SYS_FC_FRDIV4_MASK        (0xff << SYS_FC_FRDIV4_BIT)
+-#  define SYS_FC_FE4                (1<<11)
+-#  define SYS_FC_FS4                (1<<10)
+-#  define SYS_FC_FRDIV3_BIT         2
+-#  define SYS_FC_FRDIV3_MASK        (0xff << SYS_FC_FRDIV3_BIT)
+-#  define SYS_FC_FE3                (1<<1)
+-#  define SYS_FC_FS3                (1<<0)
+-#define SYS_CLKSRC                0xB1900028
+-#  define SYS_CS_ME1_BIT            27
+-#  define SYS_CS_ME1_MASK           (0x7<<SYS_CS_ME1_BIT)
+-#  define SYS_CS_DE1                (1<<26)
+-#  define SYS_CS_CE1                (1<<25)
+-#  define SYS_CS_ME0_BIT            22
+-#  define SYS_CS_ME0_MASK           (0x7<<SYS_CS_ME0_BIT)
+-#  define SYS_CS_DE0                (1<<21)
+-#  define SYS_CS_CE0                (1<<20)
+-#  define SYS_CS_MI2_BIT            17
+-#  define SYS_CS_MI2_MASK           (0x7<<SYS_CS_MI2_BIT)
+-#  define SYS_CS_DI2                (1<<16)
+-#  define SYS_CS_CI2                (1<<15)
++#define SYS_FREQCTRL0		0xB1900020
++#  define SYS_FC_FRDIV2_BIT	22
++#  define SYS_FC_FRDIV2_MASK	(0xff << SYS_FC_FRDIV2_BIT)
++#  define SYS_FC_FE2		(1 << 21)
++#  define SYS_FC_FS2		(1 << 20)
++#  define SYS_FC_FRDIV1_BIT	12
++#  define SYS_FC_FRDIV1_MASK	(0xff << SYS_FC_FRDIV1_BIT)
++#  define SYS_FC_FE1		(1 << 11)
++#  define SYS_FC_FS1		(1 << 10)
++#  define SYS_FC_FRDIV0_BIT	2
++#  define SYS_FC_FRDIV0_MASK	(0xff << SYS_FC_FRDIV0_BIT)
++#  define SYS_FC_FE0		(1 << 1)
++#  define SYS_FC_FS0		(1 << 0)
++#define SYS_FREQCTRL1		0xB1900024
++#  define SYS_FC_FRDIV5_BIT	22
++#  define SYS_FC_FRDIV5_MASK	(0xff << SYS_FC_FRDIV5_BIT)
++#  define SYS_FC_FE5		(1 << 21)
++#  define SYS_FC_FS5		(1 << 20)
++#  define SYS_FC_FRDIV4_BIT	12
++#  define SYS_FC_FRDIV4_MASK	(0xff << SYS_FC_FRDIV4_BIT)
++#  define SYS_FC_FE4		(1 << 11)
++#  define SYS_FC_FS4		(1 << 10)
++#  define SYS_FC_FRDIV3_BIT	2
++#  define SYS_FC_FRDIV3_MASK	(0xff << SYS_FC_FRDIV3_BIT)
++#  define SYS_FC_FE3		(1 << 1)
++#  define SYS_FC_FS3		(1 << 0)
++#define SYS_CLKSRC		0xB1900028
++#  define SYS_CS_ME1_BIT	27
++#  define SYS_CS_ME1_MASK	(0x7 << SYS_CS_ME1_BIT)
++#  define SYS_CS_DE1		(1 << 26)
++#  define SYS_CS_CE1		(1 << 25)
++#  define SYS_CS_ME0_BIT	22
++#  define SYS_CS_ME0_MASK	(0x7 << SYS_CS_ME0_BIT)
++#  define SYS_CS_DE0		(1 << 21)
++#  define SYS_CS_CE0		(1 << 20)
++#  define SYS_CS_MI2_BIT	17
++#  define SYS_CS_MI2_MASK	(0x7 << SYS_CS_MI2_BIT)
++#  define SYS_CS_DI2		(1 << 16)
++#  define SYS_CS_CI2		(1 << 15)
+ #ifdef CONFIG_SOC_AU1100
+-#  define SYS_CS_ML_BIT             7
+-#  define SYS_CS_ML_MASK            (0x7<<SYS_CS_ML_BIT)
+-#  define SYS_CS_DL                 (1<<6)
+-#  define SYS_CS_CL                 (1<<5)
++#  define SYS_CS_ML_BIT 	7
++#  define SYS_CS_ML_MASK	(0x7 << SYS_CS_ML_BIT)
++#  define SYS_CS_DL		(1 << 6)
++#  define SYS_CS_CL		(1 << 5)
+ #else
+-#  define SYS_CS_MUH_BIT            12
+-#  define SYS_CS_MUH_MASK           (0x7<<SYS_CS_MUH_BIT)
+-#  define SYS_CS_DUH                (1<<11)
+-#  define SYS_CS_CUH                (1<<10)
+-#  define SYS_CS_MUD_BIT            7
+-#  define SYS_CS_MUD_MASK           (0x7<<SYS_CS_MUD_BIT)
+-#  define SYS_CS_DUD                (1<<6)
+-#  define SYS_CS_CUD                (1<<5)
++#  define SYS_CS_MUH_BIT	12
++#  define SYS_CS_MUH_MASK	(0x7 << SYS_CS_MUH_BIT)
++#  define SYS_CS_DUH		(1 << 11)
++#  define SYS_CS_CUH		(1 << 10)
++#  define SYS_CS_MUD_BIT	7
++#  define SYS_CS_MUD_MASK	(0x7 << SYS_CS_MUD_BIT)
++#  define SYS_CS_DUD		(1 << 6)
++#  define SYS_CS_CUD		(1 << 5)
+ #endif
+-#  define SYS_CS_MIR_BIT            2
+-#  define SYS_CS_MIR_MASK           (0x7<<SYS_CS_MIR_BIT)
+-#  define SYS_CS_DIR                (1<<1)
+-#  define SYS_CS_CIR                (1<<0)
+-
+-#  define SYS_CS_MUX_AUX            0x1
+-#  define SYS_CS_MUX_FQ0            0x2
+-#  define SYS_CS_MUX_FQ1            0x3
+-#  define SYS_CS_MUX_FQ2            0x4
+-#  define SYS_CS_MUX_FQ3            0x5
+-#  define SYS_CS_MUX_FQ4            0x6
+-#  define SYS_CS_MUX_FQ5            0x7
+-#define SYS_CPUPLL                0xB1900060
+-#define SYS_AUXPLL                0xB1900064
++#  define SYS_CS_MIR_BIT	2
++#  define SYS_CS_MIR_MASK	(0x7 << SYS_CS_MIR_BIT)
++#  define SYS_CS_DIR		(1 << 1)
++#  define SYS_CS_CIR		(1 << 0)
++
++#  define SYS_CS_MUX_AUX	0x1
++#  define SYS_CS_MUX_FQ0	0x2
++#  define SYS_CS_MUX_FQ1	0x3
++#  define SYS_CS_MUX_FQ2	0x4
++#  define SYS_CS_MUX_FQ3	0x5
++#  define SYS_CS_MUX_FQ4	0x6
++#  define SYS_CS_MUX_FQ5	0x7
++#define SYS_CPUPLL		0xB1900060
++#define SYS_AUXPLL		0xB1900064
+ 
+ /* AC97 Controller */
+-#define AC97C_CONFIG              0xB0000000
+-#  define AC97C_RECV_SLOTS_BIT  13
++#define AC97C_CONFIG		0xB0000000
++#  define AC97C_RECV_SLOTS_BIT	13
+ #  define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
+-#  define AC97C_XMIT_SLOTS_BIT  3
++#  define AC97C_XMIT_SLOTS_BIT	3
+ #  define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT)
+-#  define AC97C_SG              (1<<2)
+-#  define AC97C_SYNC            (1<<1)
+-#  define AC97C_RESET           (1<<0)
+-#define AC97C_STATUS              0xB0000004
+-#  define AC97C_XU              (1<<11)
+-#  define AC97C_XO              (1<<10)
+-#  define AC97C_RU              (1<<9)
+-#  define AC97C_RO              (1<<8)
+-#  define AC97C_READY           (1<<7)
+-#  define AC97C_CP              (1<<6)
+-#  define AC97C_TR              (1<<5)
+-#  define AC97C_TE              (1<<4)
+-#  define AC97C_TF              (1<<3)
+-#  define AC97C_RR              (1<<2)
+-#  define AC97C_RE              (1<<1)
+-#  define AC97C_RF              (1<<0)
+-#define AC97C_DATA                0xB0000008
+-#define AC97C_CMD                 0xB000000C
+-#  define AC97C_WD_BIT          16
+-#  define AC97C_READ            (1<<7)
+-#  define AC97C_INDEX_MASK      0x7f
+-#define AC97C_CNTRL               0xB0000010
+-#  define AC97C_RS              (1<<1)
+-#  define AC97C_CE              (1<<0)
+-
++#  define AC97C_SG		(1 << 2)
++#  define AC97C_SYNC		(1 << 1)
++#  define AC97C_RESET		(1 << 0)
++#define AC97C_STATUS		0xB0000004
++#  define AC97C_XU		(1 << 11)
++#  define AC97C_XO		(1 << 10)
++#  define AC97C_RU		(1 << 9)
++#  define AC97C_RO		(1 << 8)
++#  define AC97C_READY		(1 << 7)
++#  define AC97C_CP		(1 << 6)
++#  define AC97C_TR		(1 << 5)
++#  define AC97C_TE		(1 << 4)
++#  define AC97C_TF		(1 << 3)
++#  define AC97C_RR		(1 << 2)
++#  define AC97C_RE		(1 << 1)
++#  define AC97C_RF		(1 << 0)
++#define AC97C_DATA		0xB0000008
++#define AC97C_CMD		0xB000000C
++#  define AC97C_WD_BIT		16
++#  define AC97C_READ		(1 << 7)
++#  define AC97C_INDEX_MASK	0x7f
++#define AC97C_CNTRL		0xB0000010
++#  define AC97C_RS		(1 << 1)
++#  define AC97C_CE		(1 << 0)
+ 
+ /* Secure Digital (SD) Controller */
+ #define SD0_XMIT_FIFO	0xB0600000
+@@ -1638,73 +1633,74 @@ enum soc_au1200_ints {
+ 
+ #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+ /* Au1500 PCI Controller */
+-#define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
+-#define Au1500_PCI_CMEM           (Au1500_CFG_BASE + 0)
+-#define Au1500_PCI_CFG            (Au1500_CFG_BASE + 4)
+-#  define PCI_ERROR ((1<<22) | (1<<23) | (1<<24) | (1<<25) | (1<<26) | (1<<27))
+-#define Au1500_PCI_B2BMASK_CCH    (Au1500_CFG_BASE + 8)
+-#define Au1500_PCI_B2B0_VID       (Au1500_CFG_BASE + 0xC)
+-#define Au1500_PCI_B2B1_ID        (Au1500_CFG_BASE + 0x10)
+-#define Au1500_PCI_MWMASK_DEV     (Au1500_CFG_BASE + 0x14)
++#define Au1500_CFG_BASE 	0xB4005000	/* virtual, KSEG1 addr */
++#define Au1500_PCI_CMEM 	(Au1500_CFG_BASE + 0)
++#define Au1500_PCI_CFG		(Au1500_CFG_BASE + 4)
++#  define PCI_ERROR		((1 << 22) | (1 << 23) | (1 << 24) | \
++				 (1 << 25) | (1 << 26) | (1 << 27))
++#define Au1500_PCI_B2BMASK_CCH	(Au1500_CFG_BASE + 8)
++#define Au1500_PCI_B2B0_VID	(Au1500_CFG_BASE + 0xC)
++#define Au1500_PCI_B2B1_ID	(Au1500_CFG_BASE + 0x10)
++#define Au1500_PCI_MWMASK_DEV	(Au1500_CFG_BASE + 0x14)
+ #define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
+-#define Au1500_PCI_ERR_ADDR       (Au1500_CFG_BASE + 0x1C)
+-#define Au1500_PCI_SPEC_INTACK    (Au1500_CFG_BASE + 0x20)
+-#define Au1500_PCI_ID             (Au1500_CFG_BASE + 0x100)
+-#define Au1500_PCI_STATCMD        (Au1500_CFG_BASE + 0x104)
+-#define Au1500_PCI_CLASSREV       (Au1500_CFG_BASE + 0x108)
+-#define Au1500_PCI_HDRTYPE        (Au1500_CFG_BASE + 0x10C)
+-#define Au1500_PCI_MBAR           (Au1500_CFG_BASE + 0x110)
++#define Au1500_PCI_ERR_ADDR	(Au1500_CFG_BASE + 0x1C)
++#define Au1500_PCI_SPEC_INTACK	(Au1500_CFG_BASE + 0x20)
++#define Au1500_PCI_ID		(Au1500_CFG_BASE + 0x100)
++#define Au1500_PCI_STATCMD	(Au1500_CFG_BASE + 0x104)
++#define Au1500_PCI_CLASSREV	(Au1500_CFG_BASE + 0x108)
++#define Au1500_PCI_HDRTYPE	(Au1500_CFG_BASE + 0x10C)
++#define Au1500_PCI_MBAR 	(Au1500_CFG_BASE + 0x110)
+ 
+-#define Au1500_PCI_HDR            0xB4005100 // virtual, kseg0 addr
++#define Au1500_PCI_HDR		0xB4005100	/* virtual, KSEG1 addr */
+ 
+-/* All of our structures, like pci resource, have 32 bit members.
++/*
++ * All of our structures, like PCI resource, have 32-bit members.
+  * Drivers are expected to do an ioremap on the PCI MEM resource, but it's
+- * hard to store 0x4 0000 0000 in a 32 bit type.  We require a small patch
++ * hard to store 0x4 0000 0000 in a 32-bit type.  We require a small patch
+  * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
+- * (u32)Au1500_PCI_MEM_END and change those to the full 36 bit PCI MEM
+- * addresses.  For PCI IO, it's simpler because we get to do the ioremap
++ * (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM
++ * addresses.  For PCI I/O, it's simpler because we get to do the ioremap
+  * ourselves and then adjust the device's resources.
+  */
+-#define Au1500_EXT_CFG            0x600000000ULL
+-#define Au1500_EXT_CFG_TYPE1      0x680000000ULL
+-#define Au1500_PCI_IO_START       0x500000000ULL
+-#define Au1500_PCI_IO_END         0x5000FFFFFULL
+-#define Au1500_PCI_MEM_START      0x440000000ULL
+-#define Au1500_PCI_MEM_END        0x44FFFFFFFULL
++#define Au1500_EXT_CFG		0x600000000ULL
++#define Au1500_EXT_CFG_TYPE1	0x680000000ULL
++#define Au1500_PCI_IO_START	0x500000000ULL
++#define Au1500_PCI_IO_END	0x5000FFFFFULL
++#define Au1500_PCI_MEM_START	0x440000000ULL
++#define Au1500_PCI_MEM_END	0x44FFFFFFFULL
+ 
+ #define PCI_IO_START	0x00001000
+ #define PCI_IO_END	0x000FFFFF
+ #define PCI_MEM_START	0x40000000
+ #define PCI_MEM_END	0x4FFFFFFF
+ 
+-#define PCI_FIRST_DEVFN (0<<3)
+-#define PCI_LAST_DEVFN  (19<<3)
++#define PCI_FIRST_DEVFN (0 << 3)
++#define PCI_LAST_DEVFN	(19 << 3)
+ 
+-#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */
+-#define IOPORT_RESOURCE_END   0xffffffff
+-#define IOMEM_RESOURCE_START  0x10000000
+-#define IOMEM_RESOURCE_END    0xffffffff
++#define IOPORT_RESOURCE_START	0x00001000	/* skip legacy probing */
++#define IOPORT_RESOURCE_END	0xffffffff
++#define IOMEM_RESOURCE_START	0x10000000
++#define IOMEM_RESOURCE_END	0xffffffff
+ 
+ #else /* Au1000 and Au1100 and Au1200 */
+ 
+-/* don't allow any legacy ports probing */
+-#define IOPORT_RESOURCE_START 0x10000000
+-#define IOPORT_RESOURCE_END   0xffffffff
+-#define IOMEM_RESOURCE_START  0x10000000
+-#define IOMEM_RESOURCE_END    0xffffffff
++/* Don't allow any legacy ports probing */
++#define IOPORT_RESOURCE_START	0x10000000
++#define IOPORT_RESOURCE_END	0xffffffff
++#define IOMEM_RESOURCE_START	0x10000000
++#define IOMEM_RESOURCE_END	0xffffffff
+ 
+-#define PCI_IO_START    0
+-#define PCI_IO_END      0
+-#define PCI_MEM_START   0
+-#define PCI_MEM_END     0
++#define PCI_IO_START	0
++#define PCI_IO_END	0
++#define PCI_MEM_START	0
++#define PCI_MEM_END	0
+ #define PCI_FIRST_DEVFN 0
+-#define PCI_LAST_DEVFN  0
++#define PCI_LAST_DEVFN	0
+ 
+ #endif
+ 
+ #ifndef _LANGUAGE_ASSEMBLY
+-typedef volatile struct
+-{
++typedef volatile struct {
+ 	/* 0x0000 */ u32 toytrim;
+ 	/* 0x0004 */ u32 toywrite;
+ 	/* 0x0008 */ u32 toymatch0;
+@@ -1746,13 +1742,14 @@ typedef volatile struct
+ 	/* 0x010C */ u32 outputclr;
+ 	/* 0x0110 */ u32 pinstaterd;
+ #define pininputen pinstaterd
+-
+ } AU1X00_SYS;
+ 
+-static AU1X00_SYS* const sys  = (AU1X00_SYS *)SYS_BASE;
++static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
+ 
+ #endif
+-/* Processor information base on prid.
++
++/*
++ * Processor information based on PRID.
+  * Copied from PowerPC.
+  */
+ #ifndef _LANGUAGE_ASSEMBLY
+@@ -1767,9 +1764,8 @@ struct cpu_spec {
+ 	unsigned char	cpu_pll_wo;	/* sys_cpupll reg. write-only */
+ };
+ 
+-extern struct cpu_spec		cpu_specs[];
+-extern struct cpu_spec		*cur_cpu_spec[];
++extern struct cpu_spec	cpu_specs[];
++extern struct cpu_spec	*cur_cpu_spec[];
+ #endif
+ 
+ #endif
+-
+diff --git a/include/asm-mips/mach-au1x00/au1000_dma.h b/include/asm-mips/mach-au1x00/au1000_dma.h
+index 9f29520..c333b4e 100644
+--- a/include/asm-mips/mach-au1x00/au1000_dma.h
++++ b/include/asm-mips/mach-au1x00/au1000_dma.h
+@@ -1,11 +1,10 @@
+ /*
+  * BRIEF MODULE DESCRIPTION
+- *	Defines for using and allocating dma channels on the Alchemy
+- *      Au1000 mips processor.
++ *	Defines for using and allocating DMA channels on the Alchemy
++ *      Au1x00 MIPS processors.
+  *
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	stevel at mvista.com or source at mvista.com
++ * Copyright 2000, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -31,7 +30,7 @@
+ #ifndef __ASM_AU1000_DMA_H
+ #define __ASM_AU1000_DMA_H
+ 
+-#include <asm/io.h>		/* need byte IO */
++#include <linux/io.h>		/* need byte IO */
+ #include <linux/spinlock.h>	/* And spinlocks */
+ #include <linux/delay.h>
+ #include <asm/system.h>
+@@ -50,36 +49,36 @@
+ #define DMA_DAH_MASK		(0x0f << 20)
+ #define DMA_DID_BIT		16
+ #define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
+-#define DMA_DS			(1<<15)
+-#define DMA_BE			(1<<13)
+-#define DMA_DR			(1<<12)
+-#define DMA_TS8			(1<<11)
++#define DMA_DS			(1 << 15)
++#define DMA_BE			(1 << 13)
++#define DMA_DR			(1 << 12)
++#define DMA_TS8 		(1 << 11)
+ #define DMA_DW_BIT		9
+ #define DMA_DW_MASK		(0x03 << DMA_DW_BIT)
+ #define DMA_DW8			(0 << DMA_DW_BIT)
+ #define DMA_DW16		(1 << DMA_DW_BIT)
+ #define DMA_DW32		(2 << DMA_DW_BIT)
+-#define DMA_NC			(1<<8)
+-#define DMA_IE			(1<<7)
+-#define DMA_HALT		(1<<6)
+-#define DMA_GO			(1<<5)
+-#define DMA_AB			(1<<4)
+-#define DMA_D1			(1<<3)
+-#define DMA_BE1			(1<<2)
+-#define DMA_D0			(1<<1)
+-#define DMA_BE0			(1<<0)
+-
+-#define DMA_PERIPHERAL_ADDR       0x00000008
+-#define DMA_BUFFER0_START         0x0000000C
+-#define DMA_BUFFER1_START         0x00000014
+-#define DMA_BUFFER0_COUNT         0x00000010
+-#define DMA_BUFFER1_COUNT         0x00000018
+-#define DMA_BAH_BIT 16
+-#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
+-#define DMA_COUNT_BIT 0
+-#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
+-
+-/* DMA Device ID's follow */
++#define DMA_NC			(1 << 8)
++#define DMA_IE			(1 << 7)
++#define DMA_HALT		(1 << 6)
++#define DMA_GO			(1 << 5)
++#define DMA_AB			(1 << 4)
++#define DMA_D1			(1 << 3)
++#define DMA_BE1 		(1 << 2)
++#define DMA_D0			(1 << 1)
++#define DMA_BE0 		(1 << 0)
++
++#define DMA_PERIPHERAL_ADDR	0x00000008
++#define DMA_BUFFER0_START	0x0000000C
++#define DMA_BUFFER1_START	0x00000014
++#define DMA_BUFFER0_COUNT	0x00000010
++#define DMA_BUFFER1_COUNT	0x00000018
++#define DMA_BAH_BIT	16
++#define DMA_BAH_MASK	(0x0f << DMA_BAH_BIT)
++#define DMA_COUNT_BIT	0
++#define DMA_COUNT_MASK	(0xffff << DMA_COUNT_BIT)
++
++/* DMA Device IDs follow */
+ enum {
+ 	DMA_ID_UART0_TX = 0,
+ 	DMA_ID_UART0_RX,
+@@ -110,7 +109,8 @@ enum {
+ };
+ 
+ struct dma_chan {
+-	int dev_id;		// this channel is allocated if >=0, free otherwise
++	int dev_id;		/* this channel is allocated if >= 0, */
++				/* free otherwise */
+ 	unsigned int io;
+ 	const char *dev_str;
+ 	int irq;
+@@ -132,23 +132,23 @@ extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+ extern void dump_au1000_dma_channel(unsigned int dmanr);
+ extern spinlock_t au1000_dma_spin_lock;
+ 
+-
+-static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
++static inline struct dma_chan *get_dma_chan(unsigned int dmanr)
+ {
+-	if (dmanr >= NUM_AU1000_DMA_CHANNELS
+-	    || au1000_dma_table[dmanr].dev_id < 0)
++	if (dmanr >= NUM_AU1000_DMA_CHANNELS ||
++	    au1000_dma_table[dmanr].dev_id < 0)
+ 		return NULL;
+ 	return &au1000_dma_table[dmanr];
+ }
+ 
+-static __inline__ unsigned long claim_dma_lock(void)
++static inline unsigned long claim_dma_lock(void)
+ {
+ 	unsigned long flags;
++
+ 	spin_lock_irqsave(&au1000_dma_spin_lock, flags);
+ 	return flags;
+ }
+ 
+-static __inline__ void release_dma_lock(unsigned long flags)
++static inline void release_dma_lock(unsigned long flags)
+ {
+ 	spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
+ }
+@@ -156,48 +156,53 @@ static __inline__ void release_dma_lock(unsigned long flags)
+ /*
+  * Set the DMA buffer enable bits in the mode register.
+  */
+-static __inline__ void enable_dma_buffer0(unsigned int dmanr)
++static inline void enable_dma_buffer0(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
+ }
+-static __inline__ void enable_dma_buffer1(unsigned int dmanr)
++
++static inline void enable_dma_buffer1(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
+ }
+-static __inline__ void enable_dma_buffers(unsigned int dmanr)
++static inline void enable_dma_buffers(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
+ }
+ 
+-static __inline__ void start_dma(unsigned int dmanr)
++static inline void start_dma(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+-
+ 	au_writel(DMA_GO, chan->io + DMA_MODE_SET);
+ }
+ 
+ #define DMA_HALT_POLL 0x5000
+ 
+-static __inline__ void halt_dma(unsigned int dmanr)
++static inline void halt_dma(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
+ 	int i;
++
+ 	if (!chan)
+ 		return;
+-
+ 	au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
+-	// poll the halt bit
++
++	/* Poll the halt bit */
+ 	for (i = 0; i < DMA_HALT_POLL; i++)
+ 		if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
+ 			break;
+@@ -205,55 +210,57 @@ static __inline__ void halt_dma(unsigned int dmanr)
+ 		printk(KERN_INFO "halt_dma: HALT poll expired!\n");
+ }
+ 
+-
+-static __inline__ void disable_dma(unsigned int dmanr)
++static inline void disable_dma(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 
+ 	halt_dma(dmanr);
+ 
+-	// now we can disable the buffers
++	/* Now we can disable the buffers */
+ 	au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
+ }
+ 
+-static __inline__ int dma_halted(unsigned int dmanr)
++static inline int dma_halted(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return 1;
+ 	return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
+ }
+ 
+-/* initialize a DMA channel */
+-static __inline__ void init_dma(unsigned int dmanr)
++/* Initialize a DMA channel. */
++static inline void init_dma(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
+ 	u32 mode;
++
+ 	if (!chan)
+ 		return;
+ 
+ 	disable_dma(dmanr);
+ 
+-	// set device FIFO address
+-	au_writel(CPHYSADDR(chan->fifo_addr),
+-		  chan->io + DMA_PERIPHERAL_ADDR);
++	/* Set device FIFO address */
++	au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
+ 
+ 	mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
+ 	if (chan->irq)
+ 		mode |= DMA_IE;
+ 
+ 	au_writel(~mode, chan->io + DMA_MODE_CLEAR);
+-	au_writel(mode, chan->io + DMA_MODE_SET);
++	au_writel(mode,  chan->io + DMA_MODE_SET);
+ }
+ 
+ /*
+- * set mode for a specific DMA channel
++ * Set mode for a specific DMA channel
+  */
+-static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
++static inline void set_dma_mode(unsigned int dmanr, unsigned int mode)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	/*
+@@ -266,36 +273,37 @@ static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
+ 	chan->mode |= mode;
+ }
+ 
+-static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
++static inline unsigned int get_dma_mode(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return 0;
+ 	return chan->mode;
+ }
+ 
+-static __inline__ int get_dma_active_buffer(unsigned int dmanr)
++static inline int get_dma_active_buffer(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return -1;
+ 	return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
+ }
+ 
+-
+ /*
+- * set the device FIFO address for a specific DMA channel - only
++ * Set the device FIFO address for a specific DMA channel - only
+  * applicable to GPO4 and GPO5. All the other devices have fixed
+  * FIFO addresses.
+  */
+-static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
+-					 unsigned int a)
++static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 
+-	if (chan->mode & DMA_DS)	/* second bank of device ids */
++	if (chan->mode & DMA_DS)	/* second bank of device IDs */
+ 		return;
+ 
+ 	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
+@@ -307,16 +315,19 @@ static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
+ /*
+  * Clear the DMA buffer done bits in the mode register.
+  */
+-static __inline__ void clear_dma_done0(unsigned int dmanr)
++static inline void clear_dma_done0(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
+ }
+-static __inline__ void clear_dma_done1(unsigned int dmanr)
++
++static inline void clear_dma_done1(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
+@@ -325,16 +336,17 @@ static __inline__ void clear_dma_done1(unsigned int dmanr)
+ /*
+  * This does nothing - not applicable to Au1000 DMA.
+  */
+-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
++static inline void set_dma_page(unsigned int dmanr, char pagenr)
+ {
+ }
+ 
+ /*
+  * Set Buffer 0 transfer address for specific DMA channel.
+  */
+-static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
++static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(a, chan->io + DMA_BUFFER0_START);
+@@ -343,9 +355,10 @@ static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
+ /*
+  * Set Buffer 1 transfer address for specific DMA channel.
+  */
+-static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
++static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	au_writel(a, chan->io + DMA_BUFFER1_START);
+@@ -355,10 +368,10 @@ static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
+ /*
+  * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
+  */
+-static __inline__ void set_dma_count0(unsigned int dmanr,
+-				      unsigned int count)
++static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	count &= DMA_COUNT_MASK;
+@@ -368,10 +381,10 @@ static __inline__ void set_dma_count0(unsigned int dmanr,
+ /*
+  * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
+  */
+-static __inline__ void set_dma_count1(unsigned int dmanr,
+-				      unsigned int count)
++static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	count &= DMA_COUNT_MASK;
+@@ -381,10 +394,10 @@ static __inline__ void set_dma_count1(unsigned int dmanr,
+ /*
+  * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
+  */
+-static __inline__ void set_dma_count(unsigned int dmanr,
+-				     unsigned int count)
++static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return;
+ 	count &= DMA_COUNT_MASK;
+@@ -396,35 +409,36 @@ static __inline__ void set_dma_count(unsigned int dmanr,
+  * Returns which buffer has its done bit set in the mode register.
+  * Returns -1 if neither or both done bits set.
+  */
+-static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr)
++static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return 0;
+-
+-    return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
++	return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
+ }
+ 
+ 
+ /*
+  * Returns the DMA channel's Buffer Done IRQ number.
+  */
+-static __inline__ int get_dma_done_irq(unsigned int dmanr)
++static inline int get_dma_done_irq(unsigned int dmanr)
+ {
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return -1;
+-
+ 	return chan->irq;
+ }
+ 
+ /*
+  * Get DMA residue count. Returns the number of _bytes_ left to transfer.
+  */
+-static __inline__ int get_dma_residue(unsigned int dmanr)
++static inline int get_dma_residue(unsigned int dmanr)
+ {
+ 	int curBufCntReg, count;
+ 	struct dma_chan *chan = get_dma_chan(dmanr);
++
+ 	if (!chan)
+ 		return 0;
+ 
+@@ -442,4 +456,3 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
+ }
+ 
+ #endif /* __ASM_AU1000_DMA_H */
+-
+diff --git a/include/asm-mips/mach-au1x00/au1000_gpio.h b/include/asm-mips/mach-au1x00/au1000_gpio.h
+index 298f920..d8c96fd 100644
+--- a/include/asm-mips/mach-au1x00/au1000_gpio.h
++++ b/include/asm-mips/mach-au1x00/au1000_gpio.h
+@@ -2,12 +2,12 @@
+  * FILE NAME au1000_gpio.h
+  *
+  * BRIEF MODULE DESCRIPTION
+- *	API to Alchemy Au1000 GPIO device.
++ *	API to Alchemy Au1xx0 GPIO device.
+  *
+  *  Author: MontaVista Software, Inc.  <source at mvista.com>
+- *          Steve Longerbeam <stevel at mvista.com>
++ *          Steve Longerbeam
+  *
+- * Copyright 2001 MontaVista Software Inc.
++ * Copyright 2001, 2008 MontaVista Software Inc.
+  *
+  *  This program is free software; you can redistribute  it and/or modify it
+  *  under  the terms of  the GNU General  Public License as published by the
+@@ -37,12 +37,12 @@
+ 
+ #define AU1000GPIO_IOC_MAGIC 'A'
+ 
+-#define AU1000GPIO_IN		_IOR (AU1000GPIO_IOC_MAGIC, 0, int)
+-#define AU1000GPIO_SET		_IOW (AU1000GPIO_IOC_MAGIC, 1, int)
+-#define AU1000GPIO_CLEAR	_IOW (AU1000GPIO_IOC_MAGIC, 2, int)
+-#define AU1000GPIO_OUT		_IOW (AU1000GPIO_IOC_MAGIC, 3, int)
+-#define AU1000GPIO_TRISTATE	_IOW (AU1000GPIO_IOC_MAGIC, 4, int)
+-#define AU1000GPIO_AVAIL_MASK	_IOR (AU1000GPIO_IOC_MAGIC, 5, int)
++#define AU1000GPIO_IN		_IOR(AU1000GPIO_IOC_MAGIC, 0, int)
++#define AU1000GPIO_SET		_IOW(AU1000GPIO_IOC_MAGIC, 1, int)
++#define AU1000GPIO_CLEAR	_IOW(AU1000GPIO_IOC_MAGIC, 2, int)
++#define AU1000GPIO_OUT		_IOW(AU1000GPIO_IOC_MAGIC, 3, int)
++#define AU1000GPIO_TRISTATE	_IOW(AU1000GPIO_IOC_MAGIC, 4, int)
++#define AU1000GPIO_AVAIL_MASK	_IOR(AU1000GPIO_IOC_MAGIC, 5, int)
+ 
+ #ifdef __KERNEL__
+ extern u32 get_au1000_avail_gpio_mask(void);
+diff --git a/include/asm-mips/mach-au1x00/au1550_spi.h b/include/asm-mips/mach-au1x00/au1550_spi.h
+index c2f0466..40e6c48 100644
+--- a/include/asm-mips/mach-au1x00/au1550_spi.h
++++ b/include/asm-mips/mach-au1x00/au1550_spi.h
+@@ -1,5 +1,5 @@
+ /*
+- * au1550_spi.h - au1550 psc spi controller driver - platform data struct
++ * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure
+  */
+ 
+ #ifndef _AU1550_SPI_H_
+diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
+index 9471359..1b36550 100644
+--- a/include/asm-mips/mach-au1x00/au1xxx.h
++++ b/include/asm-mips/mach-au1x00/au1xxx.h
+@@ -23,10 +23,10 @@
+ #ifndef _AU1XXX_H_
+ #define _AU1XXX_H_
+ 
+-
+ #include <asm/mach-au1x00/au1000.h>
+ 
+-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
++#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
++    defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+ #include <asm/mach-db1x00/db1x00.h>
+ 
+ #elif defined(CONFIG_MIPS_PB1550)
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+index 93d507c..ad17d7c 100644
+--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
++++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+@@ -28,17 +28,18 @@
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
+-/* Specifics for the Au1xxx Descriptor-Based DMA Controllers, first
+- * seen in the AU1550 part.
++/*
++ * Specifics for the Au1xxx Descriptor-Based DMA Controller,
++ * first seen in the AU1550 part.
+  */
+ #ifndef _AU1000_DBDMA_H_
+ #define _AU1000_DBDMA_H_
+ 
+-
+ #ifndef _LANGUAGE_ASSEMBLY
+ 
+-/* The DMA base addresses.
+- * The Channels are every 256 bytes (0x0100) from the channel 0 base.
++/*
++ * The DMA base addresses.
++ * The channels are every 256 bytes (0x0100) from the channel 0 base.
+  * Interrupt status/enable is bits 15:0 for channels 15 to zero.
+  */
+ #define DDMA_GLOBAL_BASE	0xb4003000
+@@ -51,16 +52,14 @@ typedef volatile struct dbdma_global {
+ 	u32	ddma_inten;
+ } dbdma_global_t;
+ 
+-/* General Configuration.
+-*/
++/* General Configuration. */
+ #define DDMA_CONFIG_AF		(1 << 2)
+ #define DDMA_CONFIG_AH		(1 << 1)
+ #define DDMA_CONFIG_AL		(1 << 0)
+ 
+ #define DDMA_THROTTLE_EN	(1 << 31)
+ 
+-/* The structure of a DMA Channel.
+-*/
++/* The structure of a DMA Channel. */
+ typedef volatile struct au1xxx_dma_channel {
+ 	u32	ddma_cfg;	/* See below */
+ 	u32	ddma_desptr;	/* 32-byte aligned pointer to descriptor */
+@@ -69,8 +68,7 @@ typedef volatile struct au1xxx_dma_channel {
+ 	u32	ddma_irq;	/* If bit 0 set, interrupt pending */
+ 	u32	ddma_stat;	/* See below */
+ 	u32	ddma_bytecnt;	/* Byte count, valid only when chan idle */
+-	/* Remainder, up to the 256 byte boundary, is reserved.
+-	*/
++	/* Remainder, up to the 256 byte boundary, is reserved. */
+ } au1x_dma_chan_t;
+ 
+ #define DDMA_CFG_SED	(1 << 9)	/* source DMA level/edge detect */
+@@ -84,7 +82,8 @@ typedef volatile struct au1xxx_dma_channel {
+ #define DDMA_CFG_DBE	(1 << 1)	/* Destination big endian */
+ #define DDMA_CFG_EN	(1 << 0)	/* Channel enable */
+ 
+-/* Always set when descriptor processing done, regardless of
++/*
++ * Always set when descriptor processing done, regardless of
+  * interrupt enable state.  Reflected in global intstat, don't
+  * clear this until global intstat is read/used.
+  */
+@@ -94,7 +93,8 @@ typedef volatile struct au1xxx_dma_channel {
+ #define DDMA_STAT_V	(1 << 1)	/* Descriptor valid */
+ #define DDMA_STAT_H	(1 << 0)	/* Channel Halted */
+ 
+-/* "Standard" DDMA Descriptor.
++/*
++ * "Standard" DDMA Descriptor.
+  * Must be 32-byte aligned.
+  */
+ typedef volatile struct au1xxx_ddma_desc {
+@@ -106,8 +106,9 @@ typedef volatile struct au1xxx_ddma_desc {
+ 	u32	dscr_dest1;		/* See below */
+ 	u32	dscr_stat;		/* completion status */
+ 	u32	dscr_nxtptr;		/* Next descriptor pointer (mostly) */
+-	/* First 32bytes are HW specific!!!
+-	   Lets have some SW data following.. make sure its 32bytes
++	/*
++	 * First 32 bytes are HW specific!!!
++	 * Lets have some SW data following -- make sure it's 32 bytes.
+ 	 */
+ 	u32	sw_status;
+ 	u32 	sw_context;
+@@ -130,10 +131,9 @@ typedef volatile struct au1xxx_ddma_desc {
+ #define DSCR_CMD0_CV		(0x1 << 2)	/* Clear Valid when done */
+ #define DSCR_CMD0_ST_MASK	(0x3 << 0)	/* Status instruction */
+ 
+-#define SW_STATUS_INUSE		(1<<0)
++#define SW_STATUS_INUSE 	(1 << 0)
+ 
+-/* Command 0 device IDs.
+-*/
++/* Command 0 device IDs. */
+ #ifdef CONFIG_SOC_AU1550
+ #define DSCR_CMD0_UART0_TX	0
+ #define DSCR_CMD0_UART0_RX	1
+@@ -198,16 +198,15 @@ typedef volatile struct au1xxx_ddma_desc {
+ #define DSCR_CMD0_THROTTLE	30
+ #define DSCR_CMD0_ALWAYS	31
+ #define DSCR_NDEV_IDS		32
+-/* THis macro is used to find/create custom device types */
+-#define DSCR_DEV2CUSTOM_ID(x, d)	(((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
+-#define DSCR_CUSTOM2DEV_ID(x)	((x)&0xFF)
+-
++/* This macro is used to find/create custom device types */
++#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \
++				  ((d) & 0xFF))
++#define DSCR_CUSTOM2DEV_ID(x)	((x) & 0xFF)
+ 
+ #define DSCR_CMD0_SID(x)	(((x) & 0x1f) << 25)
+ #define DSCR_CMD0_DID(x)	(((x) & 0x1f) << 20)
+ 
+-/* Source/Destination transfer width.
+-*/
++/* Source/Destination transfer width. */
+ #define DSCR_CMD0_BYTE		0
+ #define DSCR_CMD0_HALFWORD	1
+ #define DSCR_CMD0_WORD		2
+@@ -215,16 +214,14 @@ typedef volatile struct au1xxx_ddma_desc {
+ #define DSCR_CMD0_SW(x)		(((x) & 0x3) << 18)
+ #define DSCR_CMD0_DW(x)		(((x) & 0x3) << 16)
+ 
+-/* DDMA Descriptor Type.
+-*/
++/* DDMA Descriptor Type. */
+ #define DSCR_CMD0_STANDARD	0
+ #define DSCR_CMD0_LITERAL	1
+ #define DSCR_CMD0_CMP_BRANCH	2
+ 
+ #define DSCR_CMD0_DT(x)		(((x) & 0x3) << 13)
+ 
+-/* Status Instruction.
+-*/
++/* Status Instruction. */
+ #define DSCR_CMD0_ST_NOCHANGE	0	/* Don't change */
+ #define DSCR_CMD0_ST_CURRENT	1	/* Write current status */
+ #define DSCR_CMD0_ST_CMD0	2	/* Write cmd0 with V cleared */
+@@ -232,23 +229,20 @@ typedef volatile struct au1xxx_ddma_desc {
+ 
+ #define DSCR_CMD0_ST(x)		(((x) & 0x3) << 0)
+ 
+-/* Descriptor Command 1
+-*/
++/* Descriptor Command 1. */
+ #define DSCR_CMD1_SUPTR_MASK	(0xf << 28)	/* upper 4 bits of src addr */
+ #define DSCR_CMD1_DUPTR_MASK	(0xf << 24)	/* upper 4 bits of dest addr */
+ #define DSCR_CMD1_FL_MASK	(0x3 << 22)	/* Flag bits */
+ #define DSCR_CMD1_BC_MASK	(0x3fffff)	/* Byte count */
+ 
+-/* Flag description.
+-*/
++/* Flag description. */
+ #define DSCR_CMD1_FL_MEM_STRIDE0	0
+ #define DSCR_CMD1_FL_MEM_STRIDE1	1
+ #define DSCR_CMD1_FL_MEM_STRIDE2	2
+ 
+ #define DSCR_CMD1_FL(x)		(((x) & 0x3) << 22)
+ 
+-/* Source1, 1-dimensional stride.
+-*/
++/* Source1, 1-dimensional stride. */
+ #define DSCR_SRC1_STS_MASK	(3 << 30)	/* Src xfer size */
+ #define DSCR_SRC1_SAM_MASK	(3 << 28)	/* Src xfer movement */
+ #define DSCR_SRC1_SB_MASK	(0x3fff << 14)	/* Block size */
+@@ -256,8 +250,7 @@ typedef volatile struct au1xxx_ddma_desc {
+ #define DSCR_SRC1_SS_MASK	(0x3fff << 0)	/* Stride */
+ #define DSCR_SRC1_SS(x)		(((x) & 0x3fff) << 0)
+ 
+-/* Dest1, 1-dimensional stride.
+-*/
++/* Dest1, 1-dimensional stride. */
+ #define DSCR_DEST1_DTS_MASK	(3 << 30)	/* Dest xfer size */
+ #define DSCR_DEST1_DAM_MASK	(3 << 28)	/* Dest xfer movement */
+ #define DSCR_DEST1_DB_MASK	(0x3fff << 14)	/* Block size */
+@@ -279,29 +272,27 @@ typedef volatile struct au1xxx_ddma_desc {
+ #define DSCR_SRC1_SAM(x)	(((x) & 3) << 28)
+ #define DSCR_DEST1_DAM(x)	(((x) & 3) << 28)
+ 
+-/* The next descriptor pointer.
+-*/
++/* The next descriptor pointer. */
+ #define DSCR_NXTPTR_MASK	(0x07ffffff)
+ #define DSCR_NXTPTR(x)		((x) >> 5)
+ #define DSCR_GET_NXTPTR(x)	((x) << 5)
+ #define DSCR_NXTPTR_MS		(1 << 27)
+ 
+-/* The number of DBDMA channels.
+-*/
++/* The number of DBDMA channels. */
+ #define NUM_DBDMA_CHANS	16
+ 
+ /*
+- * Ddma API definitions
++ * DDMA API definitions
+  * FIXME: may not fit to this header file
+  */
+ typedef struct dbdma_device_table {
+-	u32		dev_id;
+-	u32		dev_flags;
+-	u32		dev_tsize;
+-	u32		dev_devwidth;
+-	u32		dev_physaddr;		/* If FIFO */
+-	u32		dev_intlevel;
+-	u32		dev_intpolarity;
++	u32	dev_id;
++	u32	dev_flags;
++	u32	dev_tsize;
++	u32	dev_devwidth;
++	u32	dev_physaddr;		/* If FIFO */
++	u32	dev_intlevel;
++	u32	dev_intpolarity;
+ } dbdev_tab_t;
+ 
+ 
+@@ -316,44 +307,41 @@ typedef struct dbdma_chan_config {
+ 	au1x_ddma_desc_t	*chan_desc_base;
+ 	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
+ 	void			*chan_callparam;
+-	void (*chan_callback)(int, void *);
++	void			(*chan_callback)(int, void *);
+ } chan_tab_t;
+ 
+ #define DEV_FLAGS_INUSE		(1 << 0)
+ #define DEV_FLAGS_ANYUSE	(1 << 1)
+ #define DEV_FLAGS_OUT		(1 << 2)
+ #define DEV_FLAGS_IN		(1 << 3)
+-#define DEV_FLAGS_BURSTABLE (1 << 4)
++#define DEV_FLAGS_BURSTABLE	(1 << 4)
+ #define DEV_FLAGS_SYNC		(1 << 5)
+-/* end Ddma API definitions */
++/* end DDMA API definitions */
+ 
+-/* External functions for drivers to use.
+-*/
+-/* Use this to allocate a dbdma channel.  The device ids are one of the
+- * DSCR_CMD0 devices IDs, which is usually redefined to a more
+- * meaningful name.  The 'callback' is called during dma completion
++/*
++ * External functions for drivers to use.
++ * Use this to allocate a DBDMA channel.  The device IDs are one of
++ * the DSCR_CMD0 devices IDs, which is usually redefined to a more
++ * meaningful name.  The 'callback' is called during DMA completion
+  * interrupt.
+  */
+ extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+-	void (*callback)(int, void *), void *callparam);
++				   void (*callback)(int, void *),
++				   void *callparam);
+ 
+ #define DBDMA_MEM_CHAN	DSCR_CMD0_ALWAYS
+ 
+-/* Set the device width of a in/out fifo.
+-*/
++/* Set the device width of an in/out FIFO. */
+ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
+ 
+-/* Allocate a ring of descriptors for dbdma.
+-*/
++/* Allocate a ring of descriptors for DBDMA. */
+ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
+ 
+-/* Put buffers on source/destination descriptors.
+-*/
++/* Put buffers on source/destination descriptors. */
+ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
+ u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
+ 
+-/* Get a buffer from the destination descriptor.
+-*/
++/* Get a buffer from the destination descriptor. */
+ u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
+ 
+ void au1xxx_dbdma_stop(u32 chanid);
+@@ -364,29 +352,34 @@ u32 au1xxx_get_dma_residue(u32 chanid);
+ void au1xxx_dbdma_chan_free(u32 chanid);
+ void au1xxx_dbdma_dump(u32 chanid);
+ 
+-u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
++u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
+ 
+-u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
+-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
++u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
++void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+ 
+ /*
+- 	Some compatibilty macros --
+-		Needed to make changes to API without breaking existing drivers
+-*/
+-#define	au1xxx_dbdma_put_source(chanid, buf, nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+-#define	au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+-#define	put_source_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
+-
+-
+-#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+-#define	au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+-#define	put_dest_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
++ * Some compatibilty macros -- needed to make changes to API
++ * without breaking existing drivers.
++ */
++#define au1xxx_dbdma_put_source(chanid, buf, nbytes)			\
++	_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
++#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)	\
++	_au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
++#define put_source_flags(chanid, buf, nbytes, flags)			\
++	au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
++
++#define au1xxx_dbdma_put_dest(chanid, buf, nbytes)			\
++	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
++#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) 	\
++	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
++#define put_dest_flags(chanid, buf, nbytes, flags)			\
++	au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
+ 
+ /*
+  *	Flags for the put_source/put_dest functions.
+  */
+-#define DDMA_FLAGS_IE	(1<<0)
+-#define DDMA_FLAGS_NOIE (1<<1)
++#define DDMA_FLAGS_IE	(1 << 0)
++#define DDMA_FLAGS_NOIE (1 << 1)
+ 
+ #endif /* _LANGUAGE_ASSEMBLY */
+ #endif /* _AU1000_DBDMA_H_ */
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
+index b493a5e..60638b8 100644
+--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
++++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
+@@ -31,167 +31,164 @@
+  */
+ 
+ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+-        #define DMA_WAIT_TIMEOUT        100
+-        #define NUM_DESCRIPTORS         PRD_ENTRIES
++#define DMA_WAIT_TIMEOUT	100
++#define NUM_DESCRIPTORS 	PRD_ENTRIES
+ #else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+-        #define NUM_DESCRIPTORS         2
++#define NUM_DESCRIPTORS 	2
+ #endif
+ 
+ #ifndef AU1XXX_ATA_RQSIZE
+-        #define AU1XXX_ATA_RQSIZE       128
++#define AU1XXX_ATA_RQSIZE	128
+ #endif
+ 
+ /* Disable Burstable-Support for DBDMA */
+ #ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+-        #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON  0
++#define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON	0
+ #endif
+ 
+ #ifdef CONFIG_PM
+ /*
+-* This will enable the device to be powered up when write() or read()
+-* is called. If this is not defined, the driver will return -EBUSY.
+-*/
++ * This will enable the device to be powered up when write() or read()
++ * is called. If this is not defined, the driver will return -EBUSY.
++ */
+ #define WAKE_ON_ACCESS 1
+ 
+-typedef struct
+-{
+-        spinlock_t         lock;       /* Used to block on state transitions */
+-        au1xxx_power_dev_t *dev;       /* Power Managers device structure */
+-        unsigned	   stopped;    /* USed to signaling device is stopped */
++typedef struct {
++	spinlock_t		lock;	/* Used to block on state transitions */
++	au1xxx_power_dev_t	*dev;	/* Power Managers device structure */
++	unsigned		stopped; /* Used to signal device is stopped */
+ } pm_state;
+ #endif
+ 
+-
+-typedef struct
+-{
+-        u32                     tx_dev_id, rx_dev_id, target_dev_id;
+-        u32                     tx_chan, rx_chan;
+-        void                    *tx_desc_head, *rx_desc_head;
+-        ide_hwif_t              *hwif;
++typedef struct {
++	u32			tx_dev_id, rx_dev_id, target_dev_id;
++	u32			tx_chan, rx_chan;
++	void			*tx_desc_head, *rx_desc_head;
++	ide_hwif_t		*hwif;
+ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+-        ide_drive_t             *drive;
+-        struct dbdma_cmd        *dma_table_cpu;
+-        dma_addr_t              dma_table_dma;
++	ide_drive_t		*drive;
++	struct dbdma_cmd	*dma_table_cpu;
++	dma_addr_t		dma_table_dma;
+ #endif
+ 	int			irq;
+ 	u32			regbase;
+ #ifdef CONFIG_PM
+-        pm_state                pm;
++	pm_state		pm;
+ #endif
+ } _auide_hwif;
+ 
+-/*******************************************************************************
+-* PIO Mode timing calculation :                                                *
+-*                                                                              *
+-* Static Bus Spec   ATA Spec                                                   *
+-*      Tcsoe      =   t1                                                       *
+-*      Toecs      =   t9                                                       *
+-*      Twcs       =   t9                                                       *
+-*      Tcsh       =   t2i | t2                                                 *
+-*      Tcsoff     =   t2i | t2                                                 *
+-*      Twp        =   t2                                                       *
+-*      Tcsw       =   t1                                                       *
+-*      Tpm        =   0                                                        *
+-*      Ta         =   t1+t2                                                    *
+-*******************************************************************************/
++/******************************************************************************/
++/* PIO Mode timing calculation :					      */
++/*									      */
++/* Static Bus Spec   ATA Spec						      */
++/*	Tcsoe	   =	t1						      */
++/*	Toecs	   =	t9						      */
++/*	Twcs	   =	t9						      */
++/*	Tcsh	   =	t2i | t2					      */
++/*	Tcsoff	   =	t2i | t2					      */
++/*	Twp	   =	t2						      */
++/*	Tcsw	   =	t1						      */
++/*	Tpm	   =	0						      */
++/*	Ta	   =	t1+t2						      */
++/******************************************************************************/
+ 
+-#define TCSOE_MASK            (0x07<<29)
+-#define TOECS_MASK            (0x07<<26)
+-#define TWCS_MASK             (0x07<<28)
+-#define TCSH_MASK             (0x0F<<24)
+-#define TCSOFF_MASK           (0x07<<20)
+-#define TWP_MASK              (0x3F<<14)
+-#define TCSW_MASK             (0x0F<<10)
+-#define TPM_MASK              (0x0F<<6)
+-#define TA_MASK               (0x3F<<0)
+-#define TS_MASK               (1<<8)
++#define TCSOE_MASK		(0x07 << 29)
++#define TOECS_MASK		(0x07 << 26)
++#define TWCS_MASK		(0x07 << 28)
++#define TCSH_MASK		(0x0F << 24)
++#define TCSOFF_MASK		(0x07 << 20)
++#define TWP_MASK		(0x3F << 14)
++#define TCSW_MASK		(0x0F << 10)
++#define TPM_MASK		(0x0F << 6)
++#define TA_MASK 		(0x3F << 0)
++#define TS_MASK 		(1 << 8)
+ 
+ /* Timing parameters PIO mode 0 */
+-#define SBC_IDE_PIO0_TCSOE    (0x04<<29)
+-#define SBC_IDE_PIO0_TOECS    (0x01<<26)
+-#define SBC_IDE_PIO0_TWCS     (0x02<<28)
+-#define SBC_IDE_PIO0_TCSH     (0x08<<24)
+-#define SBC_IDE_PIO0_TCSOFF   (0x07<<20)
+-#define SBC_IDE_PIO0_TWP      (0x10<<14)
+-#define SBC_IDE_PIO0_TCSW     (0x04<<10)
+-#define SBC_IDE_PIO0_TPM      (0x0<<6)
+-#define SBC_IDE_PIO0_TA       (0x15<<0)
++#define SBC_IDE_PIO0_TCSOE	(0x04 << 29)
++#define SBC_IDE_PIO0_TOECS	(0x01 << 26)
++#define SBC_IDE_PIO0_TWCS	(0x02 << 28)
++#define SBC_IDE_PIO0_TCSH	(0x08 << 24)
++#define SBC_IDE_PIO0_TCSOFF	(0x07 << 20)
++#define SBC_IDE_PIO0_TWP	(0x10 << 14)
++#define SBC_IDE_PIO0_TCSW	(0x04 << 10)
++#define SBC_IDE_PIO0_TPM	(0x00 << 6)
++#define SBC_IDE_PIO0_TA 	(0x15 << 0)
+ /* Timing parameters PIO mode 1 */
+-#define SBC_IDE_PIO1_TCSOE    (0x03<<29)
+-#define SBC_IDE_PIO1_TOECS    (0x01<<26)
+-#define SBC_IDE_PIO1_TWCS     (0x01<<28)
+-#define SBC_IDE_PIO1_TCSH     (0x06<<24)
+-#define SBC_IDE_PIO1_TCSOFF   (0x06<<20)
+-#define SBC_IDE_PIO1_TWP      (0x08<<14)
+-#define SBC_IDE_PIO1_TCSW     (0x03<<10)
+-#define SBC_IDE_PIO1_TPM      (0x00<<6)
+-#define SBC_IDE_PIO1_TA       (0x0B<<0)
++#define SBC_IDE_PIO1_TCSOE	(0x03 << 29)
++#define SBC_IDE_PIO1_TOECS	(0x01 << 26)
++#define SBC_IDE_PIO1_TWCS	(0x01 << 28)
++#define SBC_IDE_PIO1_TCSH	(0x06 << 24)
++#define SBC_IDE_PIO1_TCSOFF	(0x06 << 20)
++#define SBC_IDE_PIO1_TWP	(0x08 << 14)
++#define SBC_IDE_PIO1_TCSW	(0x03 << 10)
++#define SBC_IDE_PIO1_TPM	(0x00 << 6)
++#define SBC_IDE_PIO1_TA 	(0x0B << 0)
+ /* Timing parameters PIO mode 2 */
+-#define SBC_IDE_PIO2_TCSOE    (0x05<<29)
+-#define SBC_IDE_PIO2_TOECS    (0x01<<26)
+-#define SBC_IDE_PIO2_TWCS     (0x01<<28)
+-#define SBC_IDE_PIO2_TCSH     (0x07<<24)
+-#define SBC_IDE_PIO2_TCSOFF   (0x07<<20)
+-#define SBC_IDE_PIO2_TWP      (0x1F<<14)
+-#define SBC_IDE_PIO2_TCSW     (0x05<<10)
+-#define SBC_IDE_PIO2_TPM      (0x00<<6)
+-#define SBC_IDE_PIO2_TA       (0x22<<0)
++#define SBC_IDE_PIO2_TCSOE	(0x05 << 29)
++#define SBC_IDE_PIO2_TOECS	(0x01 << 26)
++#define SBC_IDE_PIO2_TWCS	(0x01 << 28)
++#define SBC_IDE_PIO2_TCSH	(0x07 << 24)
++#define SBC_IDE_PIO2_TCSOFF	(0x07 << 20)
++#define SBC_IDE_PIO2_TWP	(0x1F << 14)
++#define SBC_IDE_PIO2_TCSW	(0x05 << 10)
++#define SBC_IDE_PIO2_TPM	(0x00 << 6)
++#define SBC_IDE_PIO2_TA 	(0x22 << 0)
+ /* Timing parameters PIO mode 3 */
+-#define SBC_IDE_PIO3_TCSOE    (0x05<<29)
+-#define SBC_IDE_PIO3_TOECS    (0x01<<26)
+-#define SBC_IDE_PIO3_TWCS     (0x01<<28)
+-#define SBC_IDE_PIO3_TCSH     (0x0D<<24)
+-#define SBC_IDE_PIO3_TCSOFF   (0x0D<<20)
+-#define SBC_IDE_PIO3_TWP      (0x15<<14)
+-#define SBC_IDE_PIO3_TCSW     (0x05<<10)
+-#define SBC_IDE_PIO3_TPM      (0x00<<6)
+-#define SBC_IDE_PIO3_TA       (0x1A<<0)
++#define SBC_IDE_PIO3_TCSOE	(0x05 << 29)
++#define SBC_IDE_PIO3_TOECS	(0x01 << 26)
++#define SBC_IDE_PIO3_TWCS	(0x01 << 28)
++#define SBC_IDE_PIO3_TCSH	(0x0D << 24)
++#define SBC_IDE_PIO3_TCSOFF	(0x0D << 20)
++#define SBC_IDE_PIO3_TWP	(0x15 << 14)
++#define SBC_IDE_PIO3_TCSW	(0x05 << 10)
++#define SBC_IDE_PIO3_TPM	(0x00 << 6)
++#define SBC_IDE_PIO3_TA 	(0x1A << 0)
+ /* Timing parameters PIO mode 4 */
+-#define SBC_IDE_PIO4_TCSOE    (0x04<<29)
+-#define SBC_IDE_PIO4_TOECS    (0x01<<26)
+-#define SBC_IDE_PIO4_TWCS     (0x01<<28)
+-#define SBC_IDE_PIO4_TCSH     (0x04<<24)
+-#define SBC_IDE_PIO4_TCSOFF   (0x04<<20)
+-#define SBC_IDE_PIO4_TWP      (0x0D<<14)
+-#define SBC_IDE_PIO4_TCSW     (0x03<<10)
+-#define SBC_IDE_PIO4_TPM      (0x00<<6)
+-#define SBC_IDE_PIO4_TA       (0x12<<0)
++#define SBC_IDE_PIO4_TCSOE	(0x04 << 29)
++#define SBC_IDE_PIO4_TOECS	(0x01 << 26)
++#define SBC_IDE_PIO4_TWCS	(0x01 << 28)
++#define SBC_IDE_PIO4_TCSH	(0x04 << 24)
++#define SBC_IDE_PIO4_TCSOFF	(0x04 << 20)
++#define SBC_IDE_PIO4_TWP	(0x0D << 14)
++#define SBC_IDE_PIO4_TCSW	(0x03 << 10)
++#define SBC_IDE_PIO4_TPM	(0x00 << 6)
++#define SBC_IDE_PIO4_TA 	(0x12 << 0)
+ /* Timing parameters MDMA mode 0 */
+-#define SBC_IDE_MDMA0_TCSOE   (0x03<<29)
+-#define SBC_IDE_MDMA0_TOECS   (0x01<<26)
+-#define SBC_IDE_MDMA0_TWCS    (0x01<<28)
+-#define SBC_IDE_MDMA0_TCSH    (0x07<<24)
+-#define SBC_IDE_MDMA0_TCSOFF  (0x07<<20)
+-#define SBC_IDE_MDMA0_TWP     (0x0C<<14)
+-#define SBC_IDE_MDMA0_TCSW    (0x03<<10)
+-#define SBC_IDE_MDMA0_TPM     (0x00<<6)
+-#define SBC_IDE_MDMA0_TA      (0x0F<<0)
++#define SBC_IDE_MDMA0_TCSOE	(0x03 << 29)
++#define SBC_IDE_MDMA0_TOECS	(0x01 << 26)
++#define SBC_IDE_MDMA0_TWCS	(0x01 << 28)
++#define SBC_IDE_MDMA0_TCSH	(0x07 << 24)
++#define SBC_IDE_MDMA0_TCSOFF	(0x07 << 20)
++#define SBC_IDE_MDMA0_TWP	(0x0C << 14)
++#define SBC_IDE_MDMA0_TCSW	(0x03 << 10)
++#define SBC_IDE_MDMA0_TPM	(0x00 << 6)
++#define SBC_IDE_MDMA0_TA	(0x0F << 0)
+ /* Timing parameters MDMA mode 1 */
+-#define SBC_IDE_MDMA1_TCSOE   (0x05<<29)
+-#define SBC_IDE_MDMA1_TOECS   (0x01<<26)
+-#define SBC_IDE_MDMA1_TWCS    (0x01<<28)
+-#define SBC_IDE_MDMA1_TCSH    (0x05<<24)
+-#define SBC_IDE_MDMA1_TCSOFF  (0x05<<20)
+-#define SBC_IDE_MDMA1_TWP     (0x0F<<14)
+-#define SBC_IDE_MDMA1_TCSW    (0x05<<10)
+-#define SBC_IDE_MDMA1_TPM     (0x00<<6)
+-#define SBC_IDE_MDMA1_TA      (0x15<<0)
++#define SBC_IDE_MDMA1_TCSOE	(0x05 << 29)
++#define SBC_IDE_MDMA1_TOECS	(0x01 << 26)
++#define SBC_IDE_MDMA1_TWCS	(0x01 << 28)
++#define SBC_IDE_MDMA1_TCSH	(0x05 << 24)
++#define SBC_IDE_MDMA1_TCSOFF	(0x05 << 20)
++#define SBC_IDE_MDMA1_TWP	(0x0F << 14)
++#define SBC_IDE_MDMA1_TCSW	(0x05 << 10)
++#define SBC_IDE_MDMA1_TPM	(0x00 << 6)
++#define SBC_IDE_MDMA1_TA	(0x15 << 0)
+ /* Timing parameters MDMA mode 2 */
+-#define SBC_IDE_MDMA2_TCSOE   (0x04<<29)
+-#define SBC_IDE_MDMA2_TOECS   (0x01<<26)
+-#define SBC_IDE_MDMA2_TWCS    (0x01<<28)
+-#define SBC_IDE_MDMA2_TCSH    (0x04<<24)
+-#define SBC_IDE_MDMA2_TCSOFF  (0x04<<20)
+-#define SBC_IDE_MDMA2_TWP     (0x0D<<14)
+-#define SBC_IDE_MDMA2_TCSW    (0x04<<10)
+-#define SBC_IDE_MDMA2_TPM     (0x00<<6)
+-#define SBC_IDE_MDMA2_TA      (0x12<<0)
++#define SBC_IDE_MDMA2_TCSOE	(0x04 << 29)
++#define SBC_IDE_MDMA2_TOECS	(0x01 << 26)
++#define SBC_IDE_MDMA2_TWCS	(0x01 << 28)
++#define SBC_IDE_MDMA2_TCSH	(0x04 << 24)
++#define SBC_IDE_MDMA2_TCSOFF	(0x04 << 20)
++#define SBC_IDE_MDMA2_TWP	(0x0D << 14)
++#define SBC_IDE_MDMA2_TCSW	(0x04 << 10)
++#define SBC_IDE_MDMA2_TPM	(0x00 << 6)
++#define SBC_IDE_MDMA2_TA	(0x12 << 0)
+ 
+ #define SBC_IDE_TIMING(mode) \
+-         SBC_IDE_##mode##_TWCS | \
+-         SBC_IDE_##mode##_TCSH | \
+-         SBC_IDE_##mode##_TCSOFF | \
+-         SBC_IDE_##mode##_TWP | \
+-         SBC_IDE_##mode##_TCSW | \
+-         SBC_IDE_##mode##_TPM | \
+-         SBC_IDE_##mode##_TA
++	(SBC_IDE_##mode##_TWCS | \
++	 SBC_IDE_##mode##_TCSH | \
++	 SBC_IDE_##mode##_TCSOFF | \
++	 SBC_IDE_##mode##_TWP | \
++	 SBC_IDE_##mode##_TCSW | \
++	 SBC_IDE_##mode##_TPM | \
++	 SBC_IDE_##mode##_TA)
+diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
+index 1bd4e27..dae4eca 100644
+--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
++++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
+@@ -33,7 +33,6 @@
+ #ifndef _AU1000_PSC_H_
+ #define _AU1000_PSC_H_
+ 
+-
+ /* The PSC base addresses.  */
+ #ifdef CONFIG_SOC_AU1550
+ #define PSC0_BASE_ADDR		0xb1a00000
+@@ -47,8 +46,8 @@
+ #define PSC1_BASE_ADDR		0xb1b00000
+ #endif
+ 
+-/* The PSC select and control registers are common to
+- * all protocols.
++/*
++ * The PSC select and control registers are common to all protocols.
+  */
+ #define PSC_SEL_OFFSET		0x00000000
+ #define PSC_CTRL_OFFSET		0x00000004
+@@ -59,18 +58,17 @@
+ #define PSC_SEL_CLK_SERCLK	(2 << 4)
+ 
+ #define PSC_SEL_PS_MASK		0x00000007
+-#define PSC_SEL_PS_DISABLED	(0)
+-#define PSC_SEL_PS_SPIMODE	(2)
+-#define PSC_SEL_PS_I2SMODE	(3)
+-#define PSC_SEL_PS_AC97MODE	(4)
+-#define PSC_SEL_PS_SMBUSMODE	(5)
+-
+-#define PSC_CTRL_DISABLE	(0)
+-#define PSC_CTRL_SUSPEND	(2)
+-#define PSC_CTRL_ENABLE		(3)
+-
+-/* AC97 Registers.
+-*/
++#define PSC_SEL_PS_DISABLED	0
++#define PSC_SEL_PS_SPIMODE	2
++#define PSC_SEL_PS_I2SMODE	3
++#define PSC_SEL_PS_AC97MODE	4
++#define PSC_SEL_PS_SMBUSMODE	5
++
++#define PSC_CTRL_DISABLE	0
++#define PSC_CTRL_SUSPEND	2
++#define PSC_CTRL_ENABLE 	3
++
++/* AC97 Registers. */
+ #define PSC_AC97CFG_OFFSET	0x00000008
+ #define PSC_AC97MSK_OFFSET	0x0000000c
+ #define PSC_AC97PCR_OFFSET	0x00000010
+@@ -95,8 +93,7 @@
+ #define PSC_AC97GPO		(AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
+ #define PSC_AC97GPI		(AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
+ 
+-/* AC97 Config Register.
+-*/
++/* AC97 Config Register. */
+ #define PSC_AC97CFG_RT_MASK	(3 << 30)
+ #define PSC_AC97CFG_RT_FIFO1	(0 << 30)
+ #define PSC_AC97CFG_RT_FIFO2	(1 << 30)
+@@ -118,20 +115,19 @@
+ #define PSC_AC97CFG_RXSLOT_MASK	(0x3ff << 1)
+ #define PSC_AC97CFG_GE_ENABLE	(1)
+ 
+-/* Enable slots 3-12.
+-*/
++/* Enable slots 3-12. */
+ #define PSC_AC97CFG_TXSLOT_ENA(x)	(1 << (((x) - 3) + 11))
+ #define PSC_AC97CFG_RXSLOT_ENA(x)	(1 << (((x) - 3) + 1))
+ 
+-/* The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
++/*
++ * The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
+  * The only sensible numbers are 7, 9, or possibly 11.  Nah, just do the
+  * arithmetic in the macro.
+  */
+-#define PSC_AC97CFG_SET_LEN(x)	(((((x)-2)/2) & 0xf) << 21)
++#define PSC_AC97CFG_SET_LEN(x)	(((((x) - 2) / 2) & 0xf) << 21)
+ #define PSC_AC97CFG_GET_LEN(x)	(((((x) >> 21) & 0xf) * 2) + 2)
+ 
+-/* AC97 Mask Register.
+-*/
++/* AC97 Mask Register. */
+ #define PSC_AC97MSK_GR		(1 << 25)
+ #define PSC_AC97MSK_CD		(1 << 24)
+ #define PSC_AC97MSK_RR		(1 << 13)
+@@ -148,8 +144,7 @@
+ 				 PSC_AC97MSK_TO | PSC_AC97MSK_TU | \
+ 				 PSC_AC97MSK_RD | PSC_AC97MSK_TD)
+ 
+-/* AC97 Protocol Control Register.
+-*/
++/* AC97 Protocol Control Register. */
+ #define PSC_AC97PCR_RC		(1 << 6)
+ #define PSC_AC97PCR_RP		(1 << 5)
+ #define PSC_AC97PCR_RS		(1 << 4)
+@@ -157,8 +152,7 @@
+ #define PSC_AC97PCR_TP		(1 << 1)
+ #define PSC_AC97PCR_TS		(1 << 0)
+ 
+-/* AC97 Status register (read only).
+-*/
++/* AC97 Status register (read only). */
+ #define PSC_AC97STAT_CB		(1 << 26)
+ #define PSC_AC97STAT_CP		(1 << 25)
+ #define PSC_AC97STAT_CR		(1 << 24)
+@@ -174,8 +168,7 @@
+ #define PSC_AC97STAT_DR		(1 << 1)
+ #define PSC_AC97STAT_SR		(1 << 0)
+ 
+-/* AC97 Event Register.
+-*/
++/* AC97 Event Register. */
+ #define PSC_AC97EVNT_GR		(1 << 25)
+ #define PSC_AC97EVNT_CD		(1 << 24)
+ #define PSC_AC97EVNT_RR		(1 << 13)
+@@ -187,22 +180,18 @@
+ #define PSC_AC97EVNT_RD		(1 << 5)
+ #define PSC_AC97EVNT_TD		(1 << 4)
+ 
+-/* CODEC Command Register.
+-*/
++/* CODEC Command Register. */
+ #define PSC_AC97CDC_RD		(1 << 25)
+ #define PSC_AC97CDC_ID_MASK	(3 << 23)
+ #define PSC_AC97CDC_INDX_MASK	(0x7f << 16)
+-#define PSC_AC97CDC_ID(x)	(((x) & 0x3) << 23)
++#define PSC_AC97CDC_ID(x)	(((x) & 0x03) << 23)
+ #define PSC_AC97CDC_INDX(x)	(((x) & 0x7f) << 16)
+ 
+-/* AC97 Reset Control Register.
+-*/
++/* AC97 Reset Control Register. */
+ #define PSC_AC97RST_RST		(1 << 1)
+ #define PSC_AC97RST_SNC		(1 << 0)
+ 
+-
+-/* PSC in I2S Mode.
+-*/
++/* PSC in I2S Mode. */
+ typedef struct	psc_i2s {
+ 	u32	psc_sel;
+ 	u32	psc_ctrl;
+@@ -215,8 +204,7 @@ typedef struct	psc_i2s {
+ 	u32	psc_i2sudf;
+ } psc_i2s_t;
+ 
+-/* I2S Config Register.
+-*/
++/* I2S Config Register. */
+ #define PSC_I2SCFG_RT_MASK	(3 << 30)
+ #define PSC_I2SCFG_RT_FIFO1	(0 << 30)
+ #define PSC_I2SCFG_RT_FIFO2	(1 << 30)
+@@ -247,8 +235,7 @@ typedef struct	psc_i2s {
+ #define PSC_I2SCFG_MLJ		(1 << 10)
+ #define PSC_I2SCFG_XM		(1 << 9)
+ 
+-/* The word length equation is simply LEN+1.
+- */
++/* The word length equation is simply LEN+1. */
+ #define PSC_I2SCFG_SET_LEN(x)	((((x) - 1) & 0x1f) << 4)
+ #define PSC_I2SCFG_GET_LEN(x)	((((x) >> 4) & 0x1f) + 1)
+ 
+@@ -256,8 +243,7 @@ typedef struct	psc_i2s {
+ #define PSC_I2SCFG_MLF		(1 << 1)
+ #define PSC_I2SCFG_MS		(1 << 0)
+ 
+-/* I2S Mask Register.
+-*/
++/* I2S Mask Register. */
+ #define PSC_I2SMSK_RR		(1 << 13)
+ #define PSC_I2SMSK_RO		(1 << 12)
+ #define PSC_I2SMSK_RU		(1 << 11)
+@@ -271,8 +257,7 @@ typedef struct	psc_i2s {
+ 				 PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
+ 				 PSC_I2SMSK_RD | PSC_I2SMSK_TD)
+ 
+-/* I2S Protocol Control Register.
+-*/
++/* I2S Protocol Control Register. */
+ #define PSC_I2SPCR_RC		(1 << 6)
+ #define PSC_I2SPCR_RP		(1 << 5)
+ #define PSC_I2SPCR_RS		(1 << 4)
+@@ -280,8 +265,7 @@ typedef struct	psc_i2s {
+ #define PSC_I2SPCR_TP		(1 << 1)
+ #define PSC_I2SPCR_TS		(1 << 0)
+ 
+-/* I2S Status register (read only).
+-*/
++/* I2S Status register (read only). */
+ #define PSC_I2SSTAT_RF		(1 << 13)
+ #define PSC_I2SSTAT_RE		(1 << 12)
+ #define PSC_I2SSTAT_RR		(1 << 11)
+@@ -294,8 +278,7 @@ typedef struct	psc_i2s {
+ #define PSC_I2SSTAT_DR		(1 << 1)
+ #define PSC_I2SSTAT_SR		(1 << 0)
+ 
+-/* I2S Event Register.
+-*/
++/* I2S Event Register. */
+ #define PSC_I2SEVNT_RR		(1 << 13)
+ #define PSC_I2SEVNT_RO		(1 << 12)
+ #define PSC_I2SEVNT_RU		(1 << 11)
+@@ -305,8 +288,7 @@ typedef struct	psc_i2s {
+ #define PSC_I2SEVNT_RD		(1 << 5)
+ #define PSC_I2SEVNT_TD		(1 << 4)
+ 
+-/* PSC in SPI Mode.
+-*/
++/* PSC in SPI Mode. */
+ typedef struct	psc_spi {
+ 	u32	psc_sel;
+ 	u32	psc_ctrl;
+@@ -318,8 +300,7 @@ typedef struct	psc_spi {
+ 	u32	psc_spitxrx;
+ } psc_spi_t;
+ 
+-/* SPI Config Register.
+-*/
++/* SPI Config Register. */
+ #define PSC_SPICFG_RT_MASK	(3 << 30)
+ #define PSC_SPICFG_RT_FIFO1	(0 << 30)
+ #define PSC_SPICFG_RT_FIFO2	(1 << 30)
+@@ -355,8 +336,7 @@ typedef struct	psc_spi {
+ #define PSC_SPICFG_MLF		(1 << 1)
+ #define PSC_SPICFG_MO		(1 << 0)
+ 
+-/* SPI Mask Register.
+-*/
++/* SPI Mask Register. */
+ #define PSC_SPIMSK_MM		(1 << 16)
+ #define PSC_SPIMSK_RR		(1 << 13)
+ #define PSC_SPIMSK_RO		(1 << 12)
+@@ -371,16 +351,14 @@ typedef struct	psc_spi {
+ 				 PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
+ 				 PSC_SPIMSK_MD)
+ 
+-/* SPI Protocol Control Register.
+-*/
++/* SPI Protocol Control Register. */
+ #define PSC_SPIPCR_RC		(1 << 6)
+ #define PSC_SPIPCR_SP		(1 << 5)
+ #define PSC_SPIPCR_SS		(1 << 4)
+ #define PSC_SPIPCR_TC		(1 << 2)
+ #define PSC_SPIPCR_MS		(1 << 0)
+ 
+-/* SPI Status register (read only).
+-*/
++/* SPI Status register (read only). */
+ #define PSC_SPISTAT_RF		(1 << 13)
+ #define PSC_SPISTAT_RE		(1 << 12)
+ #define PSC_SPISTAT_RR		(1 << 11)
+@@ -393,8 +371,7 @@ typedef struct	psc_spi {
+ #define PSC_SPISTAT_DR		(1 << 1)
+ #define PSC_SPISTAT_SR		(1 << 0)
+ 
+-/* SPI Event Register.
+-*/
++/* SPI Event Register. */
+ #define PSC_SPIEVNT_MM		(1 << 16)
+ #define PSC_SPIEVNT_RR		(1 << 13)
+ #define PSC_SPIEVNT_RO		(1 << 12)
+@@ -405,13 +382,11 @@ typedef struct	psc_spi {
+ #define PSC_SPIEVNT_SD		(1 << 5)
+ #define PSC_SPIEVNT_MD		(1 << 4)
+ 
+-/* Transmit register control.
+-*/
++/* Transmit register control. */
+ #define PSC_SPITXRX_LC		(1 << 29)
+ #define PSC_SPITXRX_SR		(1 << 28)
+ 
+-/* PSC in SMBus (I2C) Mode.
+-*/
++/* PSC in SMBus (I2C) Mode. */
+ typedef struct	psc_smb {
+ 	u32	psc_sel;
+ 	u32	psc_ctrl;
+@@ -424,8 +399,7 @@ typedef struct	psc_smb {
+ 	u32	psc_smbtmr;
+ } psc_smb_t;
+ 
+-/* SMBus Config Register.
+-*/
++/* SMBus Config Register. */
+ #define PSC_SMBCFG_RT_MASK	(3 << 30)
+ #define PSC_SMBCFG_RT_FIFO1	(0 << 30)
+ #define PSC_SMBCFG_RT_FIFO2	(1 << 30)
+@@ -452,8 +426,7 @@ typedef struct	psc_smb {
+ 
+ #define PSC_SMBCFG_SET_SLV(x)	(((x) & 0x7f) << 1)
+ 
+-/* SMBus Mask Register.
+-*/
++/* SMBus Mask Register. */
+ #define PSC_SMBMSK_DN		(1 << 30)
+ #define PSC_SMBMSK_AN		(1 << 29)
+ #define PSC_SMBMSK_AL		(1 << 28)
+@@ -471,13 +444,11 @@ typedef struct	psc_smb {
+ 				 PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
+ 				 PSC_SMBMSK_MD)
+ 
+-/* SMBus Protocol Control Register.
+-*/
++/* SMBus Protocol Control Register. */
+ #define PSC_SMBPCR_DC		(1 << 2)
+ #define PSC_SMBPCR_MS		(1 << 0)
+ 
+-/* SMBus Status register (read only).
+-*/
++/* SMBus Status register (read only). */
+ #define PSC_SMBSTAT_BB		(1 << 28)
+ #define PSC_SMBSTAT_RF		(1 << 13)
+ #define PSC_SMBSTAT_RE		(1 << 12)
+@@ -491,8 +462,7 @@ typedef struct	psc_smb {
+ #define PSC_SMBSTAT_DR		(1 << 1)
+ #define PSC_SMBSTAT_SR		(1 << 0)
+ 
+-/* SMBus Event Register.
+-*/
++/* SMBus Event Register. */
+ #define PSC_SMBEVNT_DN		(1 << 30)
+ #define PSC_SMBEVNT_AN		(1 << 29)
+ #define PSC_SMBEVNT_AL		(1 << 28)
+@@ -510,15 +480,13 @@ typedef struct	psc_smb {
+ 				 PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
+ 				 PSC_SMBEVNT_MD)
+ 
+-/* Transmit register control.
+-*/
++/* Transmit register control. */
+ #define PSC_SMBTXRX_RSR		(1 << 28)
+ #define PSC_SMBTXRX_STP		(1 << 29)
+-#define PSC_SMBTXRX_DATAMASK	(0xff)
++#define PSC_SMBTXRX_DATAMASK	0xff
+ 
+-/* SMBus protocol timers register.
+-*/
+-#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x3) << 30)
++/* SMBus protocol timers register. */
++#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x03) << 30)
+ #define PSC_SMBTMR_SET_PS(x)	(((x) & 0x1f) << 25)
+ #define PSC_SMBTMR_SET_PU(x)	(((x) & 0x1f) << 20)
+ #define PSC_SMBTMR_SET_SH(x)	(((x) & 0x1f) << 15)
+@@ -526,5 +494,4 @@ typedef struct	psc_smb {
+ #define PSC_SMBTMR_SET_CL(x)	(((x) & 0x1f) << 5)
+ #define PSC_SMBTMR_SET_CH(x)	(((x) & 0x1f) << 0)
+ 
+-
+ #endif /* _AU1000_PSC_H_ */
+diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
+index eedd048..27f2610 100644
+--- a/include/asm-mips/mach-db1x00/db1200.h
++++ b/include/asm-mips/mach-db1x00/db1200.h
+@@ -1,6 +1,6 @@
+ /*
+- * AMD Alchemy DB1200 Referrence Board
+- * Board Registers defines.
++ * AMD Alchemy DBAu1200 Reference Board
++ * Board register defines.
+  *
+  * ########################################################################
+  *
+@@ -27,26 +27,25 @@
+ #include <linux/types.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+ 
+-// This is defined in au1000.h with bogus value
+-#undef AU1X00_EXTERNAL_INT
++#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC1_RX
+ 
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+-
+-/* SPI and SMB are muxed on the Pb1200 board.
+-   Refer to board documentation.
++/*
++ * SPI and SMB are muxed on the DBAu1200 board.
++ * Refer to board documentation.
+  */
+-#define SPI_PSC_BASE        PSC0_BASE_ADDR
+-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
+-/* AC97 and I2S are muxed on the Pb1200 board.
+-   Refer to board documentation.
++#define SPI_PSC_BASE		PSC0_BASE_ADDR
++#define SMBUS_PSC_BASE		PSC0_BASE_ADDR
++/*
++ * AC'97 and I2S are muxed on the DBAu1200 board.
++ * Refer to board documentation.
+  */
+-#define AC97_PSC_BASE       PSC1_BASE_ADDR
++#define AC97_PSC_BASE		PSC1_BASE_ADDR
+ #define I2S_PSC_BASE		PSC1_BASE_ADDR
+ 
+-#define BCSR_KSEG1_ADDR 0xB9800000
++#define BCSR_KSEG1_ADDR 	0xB9800000
+ 
+ typedef volatile struct
+ {
+@@ -102,9 +101,9 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_STATUS_SWAPBOOT	0x0040
+ #define BCSR_STATUS_FLASHBUSY	0x0100
+ #define BCSR_STATUS_IDECBLID	0x0200
+-#define BCSR_STATUS_SD0WP		0x0400
+-#define BCSR_STATUS_U0RXD		0x1000
+-#define BCSR_STATUS_U1RXD		0x2000
++#define BCSR_STATUS_SD0WP	0x0400
++#define BCSR_STATUS_U0RXD	0x1000
++#define BCSR_STATUS_U1RXD	0x2000
+ 
+ #define BCSR_SWITCHES_OCTAL	0x00FF
+ #define BCSR_SWITCHES_DIP_1	0x0080
+@@ -122,8 +121,8 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_RESETS_DC		0x0004
+ #define BCSR_RESETS_IDE		0x0008
+ #define BCSR_RESETS_TV		0x0010
+-/* not resets but in the same register */
+-#define BCSR_RESETS_PWMR1mUX 0x0800
++/* Not resets but in the same register */
++#define BCSR_RESETS_PWMR1MUX	0x0800
+ #define BCSR_RESETS_PCS0MUX	0x1000
+ #define BCSR_RESETS_PCS1MUX	0x2000
+ #define BCSR_RESETS_SPISEL	0x4000
+@@ -160,7 +159,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_INT_PC0STSCHG	0x0008
+ #define BCSR_INT_PC1		0x0010
+ #define BCSR_INT_PC1STSCHG	0x0020
+-#define BCSR_INT_DC			0x0040
++#define BCSR_INT_DC		0x0040
+ #define BCSR_INT_FLASHBUSY	0x0080
+ #define BCSR_INT_PC0INSERT	0x0100
+ #define BCSR_INT_PC0EJECT	0x0200
+@@ -179,10 +178,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define IDE_DDMA_REQ		DSCR_CMD0_DMA_REQ1
+ #define IDE_RQSIZE		128
+ 
+-#define NAND_PHYS_ADDR   0x20000000
++#define NAND_PHYS_ADDR		0x20000000
+ 
+ /*
+- * External Interrupts for Pb1200 as of 8/6/2004.
++ * External Interrupts for DBAu1200 as of 8/6/2004.
+  * Bit positions in the CPLD registers can be calculated by taking
+  * the interrupt define and subtracting the DB1200_INT_BEGIN value.
+  *
+@@ -211,23 +210,21 @@ enum external_pb1200_ints {
+ };
+ 
+ 
+-/* For drivers/pcmcia/au1000_db1x00.c */
+-
+-/* PCMCIA Db1x00 specific defines */
+-
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++/*
++ * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
++ */
++#define PCMCIA_MAX_SOCK  1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+ /* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT)\
+-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
++#define SET_VCC_VPP(VCC, VPP, SLOT) \
++	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+ 
+-#define BOARD_PC0_INT DB1200_PC0_INT
+-#define BOARD_PC1_INT DB1200_PC1_INT
+-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
++#define BOARD_PC0_INT	DB1200_PC0_INT
++#define BOARD_PC1_INT	DB1200_PC1_INT
++#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
+ 
+-/* Nand chip select */
++/* NAND chip select */
+ #define NAND_CS 1
+ 
+ #endif /* __ASM_DB1200_H */
+-
+diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h
+index e7a88ba..612ae90 100644
+--- a/include/asm-mips/mach-db1x00/db1x00.h
++++ b/include/asm-mips/mach-db1x00/db1x00.h
+@@ -1,9 +1,8 @@
+ /*
+- * AMD Alchemy DB1x00 Reference Boards
++ * AMD Alchemy DBAu1x00 Reference Boards
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  * Copyright (C) 2005 Ralf Baechle (ralf at linux-mips.org)
+  *
+  * ########################################################################
+@@ -32,26 +31,26 @@
+ 
+ #ifdef CONFIG_MIPS_DB1550
+ 
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#define DBDMA_I2S_TX_CHAN  DSCR_CMD0_PSC3_TX
+-#define DBDMA_I2S_RX_CHAN  DSCR_CMD0_PSC3_RX
++#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC3_TX
++#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC3_RX
+ 
+-#define SPI_PSC_BASE       PSC0_BASE_ADDR
+-#define AC97_PSC_BASE      PSC1_BASE_ADDR
+-#define SMBUS_PSC_BASE     PSC2_BASE_ADDR
+-#define I2S_PSC_BASE       PSC3_BASE_ADDR
++#define SPI_PSC_BASE		PSC0_BASE_ADDR
++#define AC97_PSC_BASE		PSC1_BASE_ADDR
++#define SMBUS_PSC_BASE		PSC2_BASE_ADDR
++#define I2S_PSC_BASE		PSC3_BASE_ADDR
+ 
+-#define BCSR_KSEG1_ADDR 0xAF000000
+-#define NAND_PHYS_ADDR  0x20000000
++#define BCSR_KSEG1_ADDR 	0xAF000000
++#define NAND_PHYS_ADDR		0x20000000
+ 
+ #else
+ #define BCSR_KSEG1_ADDR 0xAE000000
+ #endif
+ 
+ /*
+- * Overlay data structure of the Db1x00 board registers.
+- * Registers located at physical 0E0000xx, KSEG1 0xAE0000xx
++ * Overlay data structure of the DBAu1x00 board registers.
++ * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx.
+  */
+ typedef volatile struct
+ {
+@@ -138,18 +137,19 @@ typedef volatile struct
+ 
+ #define BCSR_SWRESET_RESET		0x0080
+ 
+-/* PCMCIA Db1x00 specific defines */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++/* PCMCIA DBAu1x00 specific defines */
++#define PCMCIA_MAX_SOCK  1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+ /* VPP/VCC */
+ #define SET_VCC_VPP(VCC, VPP, SLOT)\
+-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
++	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+ 
+-/* SD controller macros */
+ /*
+- * Detect card.
++ * SD controller macros
+  */
++
++/* Detect card. */
+ #define mmc_card_inserted(_n_, _res_) \
+ 	do { \
+ 		BCSR * const bcsr = (BCSR *)0xAE000000; \
+@@ -176,10 +176,10 @@ typedef volatile struct
+ 		unsigned long mmc_pwr, mmc_wp, board_specific; \
+ 		if ((_n_)) { \
+ 			mmc_pwr = BCSR_BOARD_SD1_PWR; \
+-			mmc_wp = BCSR_BOARD_SD1_WP; \
++			mmc_wp	= BCSR_BOARD_SD1_WP; \
+ 		} else { \
+ 			mmc_pwr = BCSR_BOARD_SD0_PWR; \
+-			mmc_wp = BCSR_BOARD_SD0_WP; \
++			mmc_wp	= BCSR_BOARD_SD0_WP; \
+ 		} \
+ 		board_specific = au_readl((unsigned long)(&bcsr->specific)); \
+ 		if (!(board_specific & mmc_wp)) {/* low means card present */ \
+@@ -190,17 +190,19 @@ typedef volatile struct
+ 	} while (0)
+ 
+ 
+-/* NAND defines */
+-/* Timing values as described in databook, * ns value stripped of
++/*
++ * NAND defines
++ *
++ * Timing values as described in databook, * ns value stripped of the
+  * lower 2 bits.
+- * These defines are here rather than an SOC1550 generic file because
++ * These defines are here rather than an Au1550 generic file because
+  * the parts chosen on another board may be different and may require
+  * different timings.
+  */
+-#define NAND_T_H			(18 >> 2)
+-#define NAND_T_PUL			(30 >> 2)
+-#define NAND_T_SU			(30 >> 2)
+-#define NAND_T_WH			(30 >> 2)
++#define NAND_T_H		(18 >> 2)
++#define NAND_T_PUL		(30 >> 2)
++#define NAND_T_SU		(30 >> 2)
++#define NAND_T_WH		(30 >> 2)
+ 
+ /* Bitfield shift amounts */
+ #define NAND_T_H_SHIFT		0
+@@ -208,16 +210,15 @@ typedef volatile struct
+ #define NAND_T_SU_SHIFT		8
+ #define NAND_T_WH_SHIFT		12
+ 
+-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
+-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
+-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
+-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
+-#define NAND_CS 1
++#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
++			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
++			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
++			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
++#define NAND_CS 	1
+ 
+-/* should be done by yamon */
+-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
+-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
+-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
++/* Should be done by YAMON */
++#define NAND_STCFG	0x00400005 /* 8-bit NAND */
++#define NAND_STTIME	0x00007774 /* valid for 396 MHz SD=2 only */
++#define NAND_STADDR	0x12000FFF /* physical address 0x20000000 */
+ 
+ #endif /* __ASM_DB1X00_H */
+-
+diff --git a/include/asm-mips/mach-pb1x00/pb1000.h b/include/asm-mips/mach-pb1x00/pb1000.h
+index b52e0e7..6d1ff90 100644
+--- a/include/asm-mips/mach-pb1x00/pb1000.h
++++ b/include/asm-mips/mach-pb1x00/pb1000.h
+@@ -1,9 +1,8 @@
+ /*
+- * Alchemy Semi PB1000 Referrence Board
++ * Alchemy Semi Pb1000 Referrence Board
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  * ########################################################################
+  *
+@@ -28,145 +27,61 @@
+ #define __ASM_PB1000_H
+ 
+ /* PCMCIA PB1000 specific defines */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+-
+-#define PB1000_PCR     0xBE000000
+-#  define PCR_SLOT_0_VPP0  (1<<0)
+-#  define PCR_SLOT_0_VPP1  (1<<1)
+-#  define PCR_SLOT_0_VCC0  (1<<2)
+-#  define PCR_SLOT_0_VCC1  (1<<3)
+-#  define PCR_SLOT_0_RST   (1<<4)
+-
+-#  define PCR_SLOT_1_VPP0  (1<<8)
+-#  define PCR_SLOT_1_VPP1  (1<<9)
+-#  define PCR_SLOT_1_VCC0  (1<<10)
+-#  define PCR_SLOT_1_VCC1  (1<<11)
+-#  define PCR_SLOT_1_RST   (1<<12)
+-
+-#define PB1000_MDR     0xBE000004
+-#  define MDR_PI        (1<<5)  /* pcmcia int latch  */
+-#  define MDR_EPI      (1<<14)  /* enable pcmcia int */
+-#  define MDR_CPI      (1<<15)  /* clear pcmcia int  */
+-
+-#define PB1000_ACR1    0xBE000008
+-#  define ACR1_SLOT_0_CD1    (1<<0)  /* card detect 1     */
+-#  define ACR1_SLOT_0_CD2    (1<<1)  /* card detect 2     */
+-#  define ACR1_SLOT_0_READY  (1<<2)  /* ready             */
+-#  define ACR1_SLOT_0_STATUS (1<<3)  /* status change     */
+-#  define ACR1_SLOT_0_VS1    (1<<4)  /* voltage sense 1   */
+-#  define ACR1_SLOT_0_VS2    (1<<5)  /* voltage sense 2   */
+-#  define ACR1_SLOT_0_INPACK (1<<6)  /* inpack pin status */
+-#  define ACR1_SLOT_1_CD1    (1<<8)  /* card detect 1     */
+-#  define ACR1_SLOT_1_CD2    (1<<9)  /* card detect 2     */
+-#  define ACR1_SLOT_1_READY  (1<<10) /* ready             */
+-#  define ACR1_SLOT_1_STATUS (1<<11) /* status change     */
+-#  define ACR1_SLOT_1_VS1    (1<<12) /* voltage sense 1   */
+-#  define ACR1_SLOT_1_VS2    (1<<13) /* voltage sense 2   */
+-#  define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */
+-
+-#define CPLD_AUX0      0xBE00000C
+-#define CPLD_AUX1      0xBE000010
+-#define CPLD_AUX2      0xBE000014
++#define PCMCIA_MAX_SOCK  1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
++
++#define PB1000_PCR		0xBE000000
++#  define PCR_SLOT_0_VPP0	(1 << 0)
++#  define PCR_SLOT_0_VPP1	(1 << 1)
++#  define PCR_SLOT_0_VCC0	(1 << 2)
++#  define PCR_SLOT_0_VCC1	(1 << 3)
++#  define PCR_SLOT_0_RST	(1 << 4)
++#  define PCR_SLOT_1_VPP0	(1 << 8)
++#  define PCR_SLOT_1_VPP1	(1 << 9)
++#  define PCR_SLOT_1_VCC0	(1 << 10)
++#  define PCR_SLOT_1_VCC1	(1 << 11)
++#  define PCR_SLOT_1_RST	(1 << 12)
++
++#define PB1000_MDR		0xBE000004
++#  define MDR_PI		(1 << 5)	/* PCMCIA int latch  */
++#  define MDR_EPI		(1 << 14)	/* enable PCMCIA int */
++#  define MDR_CPI		(1 << 15)	/* clear  PCMCIA int  */
++
++#define PB1000_ACR1		0xBE000008
++#  define ACR1_SLOT_0_CD1	(1 << 0)	/* card detect 1	*/
++#  define ACR1_SLOT_0_CD2	(1 << 1)	/* card detect 2	*/
++#  define ACR1_SLOT_0_READY	(1 << 2)	/* ready		*/
++#  define ACR1_SLOT_0_STATUS	(1 << 3)	/* status change	*/
++#  define ACR1_SLOT_0_VS1	(1 << 4)	/* voltage sense 1	*/
++#  define ACR1_SLOT_0_VS2	(1 << 5)	/* voltage sense 2	*/
++#  define ACR1_SLOT_0_INPACK	(1 << 6)	/* inpack pin status	*/
++#  define ACR1_SLOT_1_CD1	(1 << 8)	/* card detect 1	*/
++#  define ACR1_SLOT_1_CD2	(1 << 9)	/* card detect 2	*/
++#  define ACR1_SLOT_1_READY	(1 << 10)	/* ready		*/
++#  define ACR1_SLOT_1_STATUS	(1 << 11)	/* status change	*/
++#  define ACR1_SLOT_1_VS1	(1 << 12)	/* voltage sense 1	*/
++#  define ACR1_SLOT_1_VS2	(1 << 13)	/* voltage sense 2	*/
++#  define ACR1_SLOT_1_INPACK	(1 << 14)	/* inpack pin status	*/
++
++#define CPLD_AUX0		0xBE00000C
++#define CPLD_AUX1		0xBE000010
++#define CPLD_AUX2		0xBE000014
+ 
+ /* Voltage levels */
+ 
+ /* VPPEN1 - VPPEN0 */
+-#define VPP_GND ((0<<1) | (0<<0))
+-#define VPP_5V  ((1<<1) | (0<<0))
+-#define VPP_3V  ((0<<1) | (1<<0))
+-#define VPP_12V ((0<<1) | (1<<0))
+-#define VPP_HIZ ((1<<1) | (1<<0))
++#define VPP_GND ((0 << 1) | (0 << 0))
++#define VPP_5V	((1 << 1) | (0 << 0))
++#define VPP_3V	((0 << 1) | (1 << 0))
++#define VPP_12V ((0 << 1) | (1 << 0))
++#define VPP_HIZ ((1 << 1) | (1 << 0))
+ 
+ /* VCCEN1 - VCCEN0 */
+-#define VCC_3V  ((0<<1) | (1<<0))
+-#define VCC_5V  ((1<<1) | (0<<0))
+-#define VCC_HIZ ((0<<1) | (0<<0))
++#define VCC_3V	((0 << 1) | (1 << 0))
++#define VCC_5V	((1 << 1) | (0 << 0))
++#define VCC_HIZ ((0 << 1) | (0 << 0))
+ 
+ /* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT)\
+-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+-
+-
+-/* PCI PB1000 specific defines */
+-/* The reason these defines are here instead of au1000.h is because
+- * the Au1000 does not have a PCI bus controller so the PCI implementation
+- * on the some of the older Pb1000 boards was very board specific.
+- */
+-#define PCI_CONFIG_BASE   0xBA020000 /* the only external slot */
+-
+-#define SDRAM_DEVID       0xBA010000
+-#define SDRAM_CMD         0xBA010004
+-#define SDRAM_CLASS       0xBA010008
+-#define SDRAM_MISC        0xBA01000C
+-#define SDRAM_MBAR        0xBA010010
+-
+-#define PCI_IO_DATA_PORT  0xBA800000
+-
+-#define PCI_IO_ADDR       0xBE00001C
+-#define PCI_INT_ACK       0xBBC00000
+-#define PCI_IO_READ       0xBBC00020
+-#define PCI_IO_WRITE      0xBBC00030
+-
+-#define PCI_BRIDGE_CONFIG 0xBE000018
+-
+-#define PCI_IO_START      0x10000000
+-#define PCI_IO_END        0x1000ffff
+-#define PCI_MEM_START     0x18000000
+-#define PCI_MEM_END       0x18ffffff
+-
+-#define PCI_FIRST_DEVFN   0
+-#define PCI_LAST_DEVFN    1
+-
+-static inline u8 au_pci_io_readb(u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
+-	return (readl(PCI_IO_DATA_PORT) & 0xff);
+-}
+-
+-static inline u16 au_pci_io_readw(u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
+-	return (readl(PCI_IO_DATA_PORT) & 0xffff);
+-}
+-
+-static inline u32 au_pci_io_readl(u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG);
+-	return readl(PCI_IO_DATA_PORT);
+-}
+-
+-static inline void au_pci_io_writeb(u8 val, u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
+-	writel(val, PCI_IO_DATA_PORT);
+-}
+-
+-static inline void au_pci_io_writew(u16 val, u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
+-	writel(val, PCI_IO_DATA_PORT);
+-}
+-
+-static inline void au_pci_io_writel(u32 val, u32 addr)
+-{
+-	writel(addr, PCI_IO_ADDR);
+-	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG);
+-	writel(val, PCI_IO_DATA_PORT);
+-}
+-
+-static inline void set_sdram_extbyte(void)
+-{
+-	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG);
+-}
+-
+-static inline void set_slot_extbyte(void)
+-{
+-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG);
+-}
++#define SET_VCC_VPP(VCC, VPP, SLOT) \
++	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+ #endif /* __ASM_PB1000_H */
+diff --git a/include/asm-mips/mach-pb1x00/pb1100.h b/include/asm-mips/mach-pb1x00/pb1100.h
+index 63aa392..b1a60f1 100644
+--- a/include/asm-mips/mach-pb1x00/pb1100.h
++++ b/include/asm-mips/mach-pb1x00/pb1100.h
+@@ -1,9 +1,8 @@
+ /*
+- * Alchemy Semi PB1100 Referrence Board
++ * Alchemy Semi Pb1100 Referrence Board
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  * ########################################################################
+  *
+@@ -27,59 +26,60 @@
+ #ifndef __ASM_PB1100_H
+ #define __ASM_PB1100_H
+ 
+-#define PB1100_IDENT          0xAE000000
+-#define BOARD_STATUS_REG      0xAE000004
+-#  define PB1100_ROM_SEL         (1<<15)
+-#  define PB1100_ROM_SIZ         (1<<14)
+-#  define PB1100_SWAP_BOOT       (1<<13)
+-#  define PB1100_FLASH_WP        (1<<12)
+-#  define PB1100_ROM_H_STS       (1<<11)
+-#  define PB1100_ROM_L_STS       (1<<10)
+-#  define PB1100_FLASH_H_STS      (1<<9)
+-#  define PB1100_FLASH_L_STS      (1<<8)
+-#  define PB1100_SRAM_SIZ         (1<<7)
+-#  define PB1100_TSC_BUSY         (1<<6)
+-#  define PB1100_PCMCIA_VS_MASK   (3<<4)
+-#  define PB1100_RS232_CD         (1<<3)
+-#  define PB1100_RS232_CTS        (1<<2)
+-#  define PB1100_RS232_DSR        (1<<1)
+-#  define PB1100_RS232_RI         (1<<0)
++#define PB1100_IDENT		0xAE000000
++#define BOARD_STATUS_REG	0xAE000004
++#  define PB1100_ROM_SEL	(1 << 15)
++#  define PB1100_ROM_SIZ	(1 << 14)
++#  define PB1100_SWAP_BOOT	(1 << 13)
++#  define PB1100_FLASH_WP	(1 << 12)
++#  define PB1100_ROM_H_STS	(1 << 11)
++#  define PB1100_ROM_L_STS	(1 << 10)
++#  define PB1100_FLASH_H_STS	(1 << 9)
++#  define PB1100_FLASH_L_STS	(1 << 8)
++#  define PB1100_SRAM_SIZ	(1 << 7)
++#  define PB1100_TSC_BUSY	(1 << 6)
++#  define PB1100_PCMCIA_VS_MASK (3 << 4)
++#  define PB1100_RS232_CD	(1 << 3)
++#  define PB1100_RS232_CTS	(1 << 2)
++#  define PB1100_RS232_DSR	(1 << 1)
++#  define PB1100_RS232_RI	(1 << 0)
+ 
+-#define PB1100_IRDA_RS232     0xAE00000C
+-#  define PB1100_IRDA_FULL       (0<<14) /* full power */
+-#  define PB1100_IRDA_SHUTDOWN   (1<<14)
+-#  define PB1100_IRDA_TT         (2<<14) /* 2/3 power */
+-#  define PB1100_IRDA_OT         (3<<14) /* 1/3 power */
+-#  define PB1100_IRDA_FIR        (1<<13)
++#define PB1100_IRDA_RS232	0xAE00000C
++#  define PB1100_IRDA_FULL	(0 << 14)	/* full power		*/
++#  define PB1100_IRDA_SHUTDOWN	(1 << 14)
++#  define PB1100_IRDA_TT	(2 << 14)	/* 2/3 power		*/
++#  define PB1100_IRDA_OT	(3 << 14)	/* 1/3 power		*/
++#  define PB1100_IRDA_FIR	(1 << 13)
+ 
+-#define PCMCIA_BOARD_REG     0xAE000010
+-#  define PB1100_SD_WP1_RO       (1<<15) /* read only */
+-#  define PB1100_SD_WP0_RO       (1<<14) /* read only */
+-#  define PB1100_SD_PWR1         (1<<11) /* applies power to SD1 */
+-#  define PB1100_SD_PWR0         (1<<10) /* applies power to SD0 */
+-#  define PB1100_SEL_SD_CONN1     (1<<9)
+-#  define PB1100_SEL_SD_CONN0     (1<<8)
+-#  define PC_DEASSERT_RST         (1<<7)
+-#  define PC_DRV_EN               (1<<4)
++#define PCMCIA_BOARD_REG	0xAE000010
++#  define PB1100_SD_WP1_RO	(1 << 15)	/* read only		*/
++#  define PB1100_SD_WP0_RO	(1 << 14)	/* read only		*/
++#  define PB1100_SD_PWR1	(1 << 11)	/* applies power to SD1 */
++#  define PB1100_SD_PWR0	(1 << 10)	/* applies power to SD0 */
++#  define PB1100_SEL_SD_CONN1	(1 << 9)
++#  define PB1100_SEL_SD_CONN0	(1 << 8)
++#  define PC_DEASSERT_RST	(1 << 7)
++#  define PC_DRV_EN		(1 << 4)
+ 
+-#define PB1100_G_CONTROL      0xAE000014 /* graphics control */
++#define PB1100_G_CONTROL	0xAE000014	/* graphics control	*/
+ 
+-#define PB1100_RST_VDDI       0xAE00001C
+-#  define PB1100_SOFT_RESET      (1<<15) /* clear to reset the board */
+-#  define PB1100_VDDI_MASK        (0x1F)
++#define PB1100_RST_VDDI 	0xAE00001C
++#  define PB1100_SOFT_RESET	(1 << 15)	/* clear to reset the board */
++#  define PB1100_VDDI_MASK	0x1F
+ 
+-#define PB1100_LEDS           0xAE000018
++#define PB1100_LEDS		0xAE000018
+ 
+-/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+- * 7:0 is the LED Display's decimal points.
++/*
++ * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
++ * 7:0  is the LED Display's decimal points.
+  */
+-#define PB1100_HEX_LED        0xAE000018
++#define PB1100_HEX_LED		0xAE000018
+ 
+-/* PCMCIA PB1100 specific defines */
+-#define PCMCIA_MAX_SOCK 0
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++/* PCMCIA Pb1100 specific defines */
++#define PCMCIA_MAX_SOCK  0
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+ /* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
++#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
+ 
+ #endif /* __ASM_PB1100_H */
+diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
+index e2c6bca..c8618df 100644
+--- a/include/asm-mips/mach-pb1x00/pb1200.h
++++ b/include/asm-mips/mach-pb1x00/pb1200.h
+@@ -1,5 +1,5 @@
+ /*
+- * AMD Alchemy PB1200 Referrence Board
++ * AMD Alchemy Pb1200 Referrence Board
+  * Board Registers defines.
+  *
+  * ########################################################################
+@@ -27,21 +27,20 @@
+ #include <linux/types.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+ 
+-// This is defined in au1000.h with bogus value
+-#undef AU1X00_EXTERNAL_INT
++#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC1_RX
+ 
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+-
+-/* SPI and SMB are muxed on the Pb1200 board.
+-   Refer to board documentation.
++/*
++ * SPI and SMB are muxed on the Pb1200 board.
++ * Refer to board documentation.
+  */
+-#define SPI_PSC_BASE        PSC0_BASE_ADDR
+-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
+-/* AC97 and I2S are muxed on the Pb1200 board.
+-   Refer to board documentation.
++#define SPI_PSC_BASE		PSC0_BASE_ADDR
++#define SMBUS_PSC_BASE		PSC0_BASE_ADDR
++/*
++ * AC97 and I2S are muxed on the Pb1200 board.
++ * Refer to board documentation.
+  */
+ #define AC97_PSC_BASE       PSC1_BASE_ADDR
+ #define I2S_PSC_BASE		PSC1_BASE_ADDR
+@@ -102,10 +101,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_STATUS_SWAPBOOT	0x0040
+ #define BCSR_STATUS_FLASHBUSY	0x0100
+ #define BCSR_STATUS_IDECBLID	0x0200
+-#define BCSR_STATUS_SD0WP		0x0400
+-#define BCSR_STATUS_SD1WP		0x0800
+-#define BCSR_STATUS_U0RXD		0x1000
+-#define BCSR_STATUS_U1RXD		0x2000
++#define BCSR_STATUS_SD0WP	0x0400
++#define BCSR_STATUS_SD1WP	0x0800
++#define BCSR_STATUS_U0RXD	0x1000
++#define BCSR_STATUS_U1RXD	0x2000
+ 
+ #define BCSR_SWITCHES_OCTAL	0x00FF
+ #define BCSR_SWITCHES_DIP_1	0x0080
+@@ -123,11 +122,11 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_RESETS_DC		0x0004
+ #define BCSR_RESETS_IDE		0x0008
+ /* not resets but in the same register */
+-#define BCSR_RESETS_WSCFSM  0x0800
++#define BCSR_RESETS_WSCFSM	0x0800
+ #define BCSR_RESETS_PCS0MUX	0x1000
+ #define BCSR_RESETS_PCS1MUX	0x2000
+ #define BCSR_RESETS_SPISEL	0x4000
+-#define BCSR_RESETS_SD1MUX  0x8000
++#define BCSR_RESETS_SD1MUX	0x8000
+ 
+ #define BCSR_PCMCIA_PC0VPP	0x0003
+ #define BCSR_PCMCIA_PC0VCC	0x000C
+@@ -163,7 +162,7 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_INT_PC0STSCHG	0x0008
+ #define BCSR_INT_PC1		0x0010
+ #define BCSR_INT_PC1STSCHG	0x0020
+-#define BCSR_INT_DC			0x0040
++#define BCSR_INT_DC		0x0040
+ #define BCSR_INT_FLASHBUSY	0x0080
+ #define BCSR_INT_PC0INSERT	0x0100
+ #define BCSR_INT_PC0EJECT	0x0200
+@@ -174,14 +173,6 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define BCSR_INT_SD1INSERT	0x4000
+ #define BCSR_INT_SD1EJECT	0x8000
+ 
+-/* PCMCIA Db1x00 specific defines */
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+-
+-/* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT)\
+-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+-
+ #define SMC91C111_PHYS_ADDR	0x0D000300
+ #define SMC91C111_INT		PB1200_ETH_INT
+ 
+@@ -192,18 +183,19 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define IDE_DDMA_REQ		DSCR_CMD0_DMA_REQ1
+ #define IDE_RQSIZE		128
+ 
+-#define NAND_PHYS_ADDR   0x1C000000
++#define NAND_PHYS_ADDR 	0x1C000000
+ 
+-/* Timing values as described in databook, * ns value stripped of
++/*
++ * Timing values as described in databook, * ns value stripped of
+  * lower 2 bits.
+- * These defines are here rather than an SOC1200 generic file because
++ * These defines are here rather than an Au1200 generic file because
+  * the parts chosen on another board may be different and may require
+  * different timings.
+  */
+-#define NAND_T_H			(18 >> 2)
+-#define NAND_T_PUL			(30 >> 2)
+-#define NAND_T_SU			(30 >> 2)
+-#define NAND_T_WH			(30 >> 2)
++#define NAND_T_H		(18 >> 2)
++#define NAND_T_PUL		(30 >> 2)
++#define NAND_T_SU		(30 >> 2)
++#define NAND_T_WH		(30 >> 2)
+ 
+ /* Bitfield shift amounts */
+ #define NAND_T_H_SHIFT		0
+@@ -211,11 +203,10 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+ #define NAND_T_SU_SHIFT		8
+ #define NAND_T_WH_SHIFT		12
+ 
+-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
+-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
+-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
+-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
+-
++#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
++			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
++			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
++			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
+ 
+ /*
+  * External Interrupts for Pb1200 as of 8/6/2004.
+@@ -248,13 +239,21 @@ enum external_pb1200_ints {
+ 	PB1200_INT_END		= PB1200_INT_BEGIN + 15
+ };
+ 
+-/* For drivers/pcmcia/au1000_db1x00.c */
+-#define BOARD_PC0_INT PB1200_PC0_INT
+-#define BOARD_PC1_INT PB1200_PC1_INT
+-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
++/*
++ * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
++ */
++#define PCMCIA_MAX_SOCK  1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+-/* Nand chip select */
++/* VPP/VCC */
++#define SET_VCC_VPP(VCC, VPP, SLOT) \
++	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
++
++#define BOARD_PC0_INT	PB1200_PC0_INT
++#define BOARD_PC1_INT	PB1200_PC1_INT
++#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
++
++/* NAND chip select */
+ #define NAND_CS 1
+ 
+ #endif /* __ASM_PB1200_H */
+-
+diff --git a/include/asm-mips/mach-pb1x00/pb1500.h b/include/asm-mips/mach-pb1x00/pb1500.h
+index ff6d40c..da51a2e 100644
+--- a/include/asm-mips/mach-pb1x00/pb1500.h
++++ b/include/asm-mips/mach-pb1x00/pb1500.h
+@@ -1,9 +1,8 @@
+ /*
+- * Alchemy Semi PB1500 Referrence Board
++ * Alchemy Semi Pb1500 Referrence Board
+  *
+- * Copyright 2001 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ * Copyright 2001, 2008 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. <source at mvista.com>
+  *
+  * ########################################################################
+  *
+@@ -27,25 +26,24 @@
+ #ifndef __ASM_PB1500_H
+ #define __ASM_PB1500_H
+ 
++#define IDENT_BOARD_REG 	0xAE000000
++#define BOARD_STATUS_REG	0xAE000004
++#define PCI_BOARD_REG		0xAE000010
++#define PCMCIA_BOARD_REG	0xAE000010
++#  define PC_DEASSERT_RST	      0x80
++#  define PC_DRV_EN		      0x10
++#define PB1500_G_CONTROL	0xAE000014
++#define PB1500_RST_VDDI 	0xAE00001C
++#define PB1500_LEDS		0xAE000018
+ 
+-#define IDENT_BOARD_REG           0xAE000000
+-#define BOARD_STATUS_REG          0xAE000004
+-#define PCI_BOARD_REG             0xAE000010
+-#define PCMCIA_BOARD_REG          0xAE000010
+-  #define PC_DEASSERT_RST               0x80
+-  #define PC_DRV_EN                     0x10
+-#define PB1500_G_CONTROL          0xAE000014
+-#define PB1500_RST_VDDI           0xAE00001C
+-#define PB1500_LEDS               0xAE000018
++#define PB1500_HEX_LED		0xAF000004
++#define PB1500_HEX_LED_BLANK	0xAF000008
+ 
+-#define PB1500_HEX_LED            0xAF000004
+-#define PB1500_HEX_LED_BLANK      0xAF000008
+-
+-/* PCMCIA PB1500 specific defines */
+-#define PCMCIA_MAX_SOCK 0
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++/* PCMCIA Pb1500 specific defines */
++#define PCMCIA_MAX_SOCK  0
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+ /* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
++#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
+ 
+ #endif /* __ASM_PB1500_H */
+diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h
+index c2ab0e2..6704a11 100644
+--- a/include/asm-mips/mach-pb1x00/pb1550.h
++++ b/include/asm-mips/mach-pb1x00/pb1550.h
+@@ -30,15 +30,15 @@
+ #include <linux/types.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+ 
+-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
+-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
++#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
++#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
++#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC3_TX
++#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC3_RX
+ 
+-#define SPI_PSC_BASE        PSC0_BASE_ADDR
+-#define AC97_PSC_BASE       PSC1_BASE_ADDR
+-#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
+-#define I2S_PSC_BASE        PSC3_BASE_ADDR
++#define SPI_PSC_BASE		PSC0_BASE_ADDR
++#define AC97_PSC_BASE		PSC1_BASE_ADDR
++#define SMBUS_PSC_BASE		PSC2_BASE_ADDR
++#define I2S_PSC_BASE		PSC3_BASE_ADDR
+ 
+ #define BCSR_PHYS_ADDR 0xAF000000
+ 
+@@ -129,12 +129,12 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
+ #define BCSR_SYSTEM_POWEROFF	0x4000
+ #define BCSR_SYSTEM_RESET	0x8000
+ 
+-#define PCMCIA_MAX_SOCK 1
+-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
++#define PCMCIA_MAX_SOCK  1
++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+ 
+ /* VPP/VCC */
+-#define SET_VCC_VPP(VCC, VPP, SLOT)\
+-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
++#define SET_VCC_VPP(VCC, VPP, SLOT) \
++	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+ 
+ #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
+ #define PB1550_BOTH_BANKS
+@@ -144,16 +144,17 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
+ #define PB1550_USER_ONLY
+ #endif
+ 
+-/* Timing values as described in databook, * ns value stripped of
++/*
++ * Timing values as described in databook, * ns value stripped of
+  * lower 2 bits.
+  * These defines are here rather than an SOC1550 generic file because
+  * the parts chosen on another board may be different and may require
+  * different timings.
+  */
+-#define NAND_T_H			(18 >> 2)
+-#define NAND_T_PUL			(30 >> 2)
+-#define NAND_T_SU			(30 >> 2)
+-#define NAND_T_WH			(30 >> 2)
++#define NAND_T_H		(18 >> 2)
++#define NAND_T_PUL		(30 >> 2)
++#define NAND_T_SU		(30 >> 2)
++#define NAND_T_WH		(30 >> 2)
+ 
+ /* Bitfield shift amounts */
+ #define NAND_T_H_SHIFT		0
+@@ -161,16 +162,16 @@ static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
+ #define NAND_T_SU_SHIFT		8
+ #define NAND_T_WH_SHIFT		12
+ 
+-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
+-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
+-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
+-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
++#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
++			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
++			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
++			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
+ 
+ #define NAND_CS 1
+ 
+-/* should be done by yamon */
+-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
+-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
+-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
++/* Should be done by YAMON */
++#define NAND_STCFG	0x00400005 /* 8-bit NAND */
++#define NAND_STTIME	0x00007774 /* valid for 396 MHz SD=2 only */
++#define NAND_STADDR	0x12000FFF /* physical address 0x20000000 */
+ 
+ #endif /* __ASM_PB1550_H */
+diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
+index 65778c8..20b6660 100644
+--- a/include/asm-mips/rtlx.h
++++ b/include/asm-mips/rtlx.h
+@@ -29,13 +29,13 @@ extern unsigned int rtlx_read_poll(int index, int can_sleep);
+ extern unsigned int rtlx_write_poll(int index);
+ 
+ enum rtlx_state {
+-	RTLX_STATE_UNUSED,
++	RTLX_STATE_UNUSED = 0,
+ 	RTLX_STATE_INITIALISED,
+ 	RTLX_STATE_REMOTE_READY,
+ 	RTLX_STATE_OPENED
+ };
+ 
+-#define RTLX_BUFFER_SIZE 1024
++#define RTLX_BUFFER_SIZE 2048
+ 
+ /* each channel supports read and write.
+    linux (vpe0) reads lx_buffer  and writes rt_buffer
+diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
+index 0593cb8..70ebd33 100644
+--- a/include/asm-ppc/system.h
++++ b/include/asm-ppc/system.h
+@@ -178,7 +178,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
+ 
+ }
+ 
+-extern inline void * xchg_ptr(void * m, void * val)
++static inline void * xchg_ptr(void * m, void * val)
+ {
+ 	return (void *) xchg_u32(m, (unsigned long) val);
+ }
+diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h
+index 78dda03..0e959e2 100644
+--- a/include/asm-s390/types.h
++++ b/include/asm-s390/types.h
+@@ -10,9 +10,9 @@
+ #define _S390_TYPES_H
+ 
+ #ifndef __s390x__
+-# include <asm-generic/int-l64.h>
+-#else
+ # include <asm-generic/int-ll64.h>
++#else
++# include <asm-generic/int-l64.h>
+ #endif
+ 
+ #ifndef __ASSEMBLY__
+diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
+index e18be98..3d16b40 100644
+--- a/include/asm-sparc/mman.h
++++ b/include/asm-sparc/mman.h
+@@ -24,9 +24,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc_mmap_check
+-int sparc_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
++int sparc_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 
+diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
+index 6b5e6ce..0afb867 100644
+--- a/include/asm-sparc/ptrace.h
++++ b/include/asm-sparc/ptrace.h
+@@ -10,6 +10,8 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
++#include <linux/types.h>
++
+ struct pt_regs {
+ 	unsigned long psr;
+ 	unsigned long pc;
+diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
+index e584563..625be4d 100644
+--- a/include/asm-sparc64/mman.h
++++ b/include/asm-sparc64/mman.h
+@@ -24,9 +24,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc64_mmap_check
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc64_mmap_check(addr,len)
++int sparc64_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 
+diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
+index 71e42d1..e5873e3 100644
+--- a/include/asm-sparc64/thread_info.h
++++ b/include/asm-sparc64/thread_info.h
+@@ -38,7 +38,7 @@ struct thread_info {
+ 	struct task_struct	*task;
+ 	unsigned long		flags;
+ 	__u8			fpsaved[7];
+-	__u8			pad;
++	__u8			status;
+ 	unsigned long		ksp;
+ 
+ 	/* D$ line 2 */
+@@ -217,7 +217,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
+  *	 nop
+  */
+ #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+-#define TIF_RESTORE_SIGMASK	1	/* restore signal mask in do_signal() */
++/* flags bit 1 is available */
+ #define TIF_SIGPENDING		2	/* signal pending */
+ #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+ #define TIF_PERFCTR		4	/* performance counters active */
+@@ -244,14 +244,34 @@ register struct thread_info *current_thread_info_reg asm("g6");
+ #define _TIF_32BIT		(1<<TIF_32BIT)
+ #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+ #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
+-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+ #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
+ #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+ 
+ #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
+-				 (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \
++				 (_TIF_SIGPENDING | \
+ 				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
+ 
++/*
++ * Thread-synchronous status.
++ *
++ * This is different from the flags in that nobody else
++ * ever touches our thread-synchronous status, so we don't
++ * have to worry about atomic accesses.
++ *
++ * Note that there are only 8 bits available.
++ */
++#define TS_RESTORE_SIGMASK	0x0001	/* restore signal mask in do_signal() */
++
++#ifndef __ASSEMBLY__
++#define HAVE_SET_RESTORE_SIGMASK	1
++static inline void set_restore_sigmask(void)
++{
++	struct thread_info *ti = current_thread_info();
++	ti->status |= TS_RESTORE_SIGMASK;
++	set_bit(TIF_SIGPENDING, &ti->flags);
++}
++#endif	/* !__ASSEMBLY__ */
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _ASM_THREAD_INFO_H */
+diff --git a/include/asm-um/irq.h b/include/asm-um/irq.h
+index de389a4..4a2037f 100644
+--- a/include/asm-um/irq.h
++++ b/include/asm-um/irq.h
+@@ -15,8 +15,9 @@
+ #define SIGIO_WRITE_IRQ 	11
+ #define TELNETD_IRQ 		12
+ #define XTERM_IRQ 		13
++#define RANDOM_IRQ 		14
+ 
+-#define LAST_IRQ XTERM_IRQ
++#define LAST_IRQ RANDOM_IRQ
+ #define NR_IRQS (LAST_IRQ + 1)
+ 
+ #endif
+diff --git a/include/asm-um/keyboard.h b/include/asm-um/keyboard.h
+deleted file mode 100644
+index ee2e230..0000000
+--- a/include/asm-um/keyboard.h
++++ /dev/null
+@@ -1,6 +0,0 @@
+-#ifndef __UM_KEYBOARD_H
+-#define __UM_KEYBOARD_H
+-
+-#include "asm/arch/keyboard.h"
+-
+-#endif
+diff --git a/include/asm-um/page.h b/include/asm-um/page.h
+index 381f96b..916e1a6 100644
+--- a/include/asm-um/page.h
++++ b/include/asm-um/page.h
+@@ -7,16 +7,20 @@
+ #ifndef __UM_PAGE_H
+ #define __UM_PAGE_H
+ 
+-struct page;
+-
+-#include <linux/types.h>
+-#include <asm/vm-flags.h>
++#include <linux/const.h>
+ 
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT	12
+-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
++#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
+ #define PAGE_MASK	(~(PAGE_SIZE-1))
+ 
++#ifndef __ASSEMBLY__
++
++struct page;
++
++#include <linux/types.h>
++#include <asm/vm-flags.h>
++
+ /*
+  * These are used to make use of C type-checking..
+  */
+@@ -120,4 +124,5 @@ extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/page.h>
+ 
+-#endif
++#endif	/* __ASSEMBLY__ */
++#endif	/* __UM_PAGE_H */
+diff --git a/include/asm-um/param.h b/include/asm-um/param.h
+index 4cd4a22..e44f4e6 100644
+--- a/include/asm-um/param.h
++++ b/include/asm-um/param.h
+@@ -13,6 +13,8 @@
+ #define HZ CONFIG_HZ
+ #define USER_HZ	100	   /* .. some user interfaces are in "ticks" */
+ #define CLOCKS_PER_SEC (USER_HZ)  /* frequency at which times() counts */
++#else
++#define HZ 100
+ #endif
+ 
+ #endif
+diff --git a/include/asm-v850/param.h b/include/asm-v850/param.h
+index 2818326..4391f5f 100644
+--- a/include/asm-v850/param.h
++++ b/include/asm-v850/param.h
+@@ -26,6 +26,8 @@
+ # define HZ		CONFIG_HZ
+ # define USER_HZ	100
+ # define CLOCKS_PER_SEC	USER_HZ
++#else
++# define HZ		100
+ #endif
+ 
+ #endif /* __V850_PARAM_H__ */
+diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
+index 801b31f..55c3a0e 100644
+--- a/include/asm-x86/pgtable.h
++++ b/include/asm-x86/pgtable.h
+@@ -57,7 +57,8 @@
+ #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |	\
+ 			 _PAGE_DIRTY)
+ 
+-#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
++#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_PCD | _PAGE_PWT |		\
++			 _PAGE_ACCESSED | _PAGE_DIRTY)
+ 
+ #define _PAGE_CACHE_MASK	(_PAGE_PCD | _PAGE_PWT)
+ #define _PAGE_CACHE_WB		(0)
+@@ -288,12 +289,21 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ 	 * Chop off the NX bit (if present), and add the NX portion of
+ 	 * the newprot (if present):
+ 	 */
+-	val &= _PAGE_CHG_MASK & ~_PAGE_NX;
+-	val |= pgprot_val(newprot) & __supported_pte_mask;
++	val &= _PAGE_CHG_MASK;
++	val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask;
+ 
+ 	return __pte(val);
+ }
+ 
++/* mprotect needs to preserve PAT bits when updating vm_page_prot */
++#define pgprot_modify pgprot_modify
++static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
++{
++	pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
++	pgprotval_t addbits = pgprot_val(newprot);
++	return __pgprot(preservebits | addbits);
++}
++
+ #define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
+ 
+ #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
+diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
+index 82ad34d..ba03d5a 100644
+--- a/include/asm-xtensa/param.h
++++ b/include/asm-xtensa/param.h
+@@ -15,6 +15,8 @@
+ # define HZ		CONFIG_HZ	/* internal timer frequency */
+ # define USER_HZ	100		/* for user interfaces in "ticks" */
+ # define CLOCKS_PER_SEC (USER_HZ)	/* frequnzy at which times() counts */
++#else
++# define HZ		100
+ #endif
+ 
+ #define EXEC_PAGESIZE	4096
+diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
+index 43b406d..1abfe66 100644
+--- a/include/linux/bitmap.h
++++ b/include/linux/bitmap.h
+@@ -110,7 +110,6 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits);
+ 
+ extern int bitmap_scnprintf(char *buf, unsigned int len,
+ 			const unsigned long *src, int nbits);
+-extern int bitmap_scnprintf_len(unsigned int len);
+ extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
+ 			unsigned long *dst, int nbits);
+ extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
+diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
+index 9650806..5df3db5 100644
+--- a/include/linux/cpumask.h
++++ b/include/linux/cpumask.h
+@@ -289,13 +289,6 @@ static inline int __cpumask_scnprintf(char *buf, int len,
+ 	return bitmap_scnprintf(buf, len, srcp->bits, nbits);
+ }
+ 
+-#define cpumask_scnprintf_len(len) \
+-			__cpumask_scnprintf_len((len))
+-static inline int __cpumask_scnprintf_len(int len)
+-{
+-	return bitmap_scnprintf_len(len);
+-}
+-
+ #define cpumask_parse_user(ubuf, ulen, dst) \
+ 			__cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS)
+ static inline int __cpumask_parse_user(const char __user *buf, int len,
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 8c23e3d..15e9fa3 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -183,7 +183,6 @@ struct class {
+ 	struct module		*owner;
+ 
+ 	struct kset		subsys;
+-	struct list_head	children;
+ 	struct list_head	devices;
+ 	struct list_head	interfaces;
+ 	struct kset		class_dirs;
+diff --git a/include/linux/fuse.h b/include/linux/fuse.h
+index 5c86f11..d482821 100644
+--- a/include/linux/fuse.h
++++ b/include/linux/fuse.h
+@@ -109,6 +109,7 @@ struct fuse_file_lock {
+ #define FUSE_POSIX_LOCKS	(1 << 1)
+ #define FUSE_FILE_OPS		(1 << 2)
+ #define FUSE_ATOMIC_O_TRUNC	(1 << 3)
++#define FUSE_BIG_WRITES		(1 << 5)
+ 
+ /**
+  * Release flags
+diff --git a/include/linux/genhd.h b/include/linux/genhd.h
+index e9874e7..ae7aec3 100644
+--- a/include/linux/genhd.h
++++ b/include/linux/genhd.h
+@@ -525,7 +525,7 @@ struct unixware_disklabel {
+ #define ADDPART_FLAG_RAID	1
+ #define ADDPART_FLAG_WHOLEDISK	2
+ 
+-extern dev_t blk_lookup_devt(const char *name);
++extern dev_t blk_lookup_devt(const char *name, int part);
+ extern char *disk_name (struct gendisk *hd, int part, char *buf);
+ 
+ extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
+@@ -553,7 +553,7 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
+ 
+ static inline void printk_all_partitions(void) { }
+ 
+-static inline dev_t blk_lookup_devt(const char *name)
++static inline dev_t blk_lookup_devt(const char *name, int part)
+ {
+ 	dev_t devt = MKDEV(0, 0);
+ 	return devt;
+diff --git a/include/linux/ide.h b/include/linux/ide.h
+index b0135b0..f8f195c 100644
+--- a/include/linux/ide.h
++++ b/include/linux/ide.h
+@@ -965,7 +965,6 @@ typedef struct ide_task_s {
+ void ide_tf_dump(const char *, struct ide_taskfile *);
+ 
+ extern void SELECT_DRIVE(ide_drive_t *);
+-extern void SELECT_MASK(ide_drive_t *, int);
+ 
+ extern int drive_is_ready(ide_drive_t *);
+ 
+@@ -1058,8 +1057,8 @@ enum {
+ 	IDE_HFLAG_NO_SET_MODE		= (1 << 9),
+ 	/* trust BIOS for programming chipset/device for DMA */
+ 	IDE_HFLAG_TRUST_BIOS_FOR_DMA	= (1 << 10),
+-	/* host uses VDMA (tied with IDE_HFLAG_CS5520 for now) */
+-	IDE_HFLAG_VDMA			= (1 << 11),
++	/* host is CS5510/CS5520 */
++	IDE_HFLAG_CS5520		= (1 << 11),
+ 	/* ATAPI DMA is unsupported */
+ 	IDE_HFLAG_NO_ATAPI_DMA		= (1 << 12),
+ 	/* set if host is a "non-bootable" controller */
+@@ -1070,8 +1069,6 @@ enum {
+ 	IDE_HFLAG_NO_AUTODMA		= (1 << 15),
+ 	/* host uses MMIO */
+ 	IDE_HFLAG_MMIO			= (1 << 16),
+-	/* host is CS5510/CS5520 */
+-	IDE_HFLAG_CS5520		= IDE_HFLAG_VDMA,
+ 	/* no LBA48 */
+ 	IDE_HFLAG_NO_LBA48		= (1 << 17),
+ 	/* no LBA48 DMA */
+@@ -1101,6 +1098,8 @@ enum {
+ 	IDE_HFLAG_NO_IO_32BIT		= (1 << 30),
+ 	/* never unmask IRQs */
+ 	IDE_HFLAG_NO_UNMASK_IRQS	= (1 << 31),
++	/* host uses VDMA (disabled for now) */
++	IDE_HFLAG_VDMA			= 0,
+ };
+ 
+ #ifdef CONFIG_BLK_DEV_OFFBOARD
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index 4d46e29..792bf0a 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -276,7 +276,17 @@ extern void print_hex_dump(const char *level, const char *prefix_str,
+ 				const void *buf, size_t len, bool ascii);
+ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
+ 			const void *buf, size_t len);
+-#define hex_asc(x)	"0123456789abcdef"[x]
++
++extern const char hex_asc[];
++#define hex_asc_lo(x)	hex_asc[((x) & 0x0f)]
++#define hex_asc_hi(x)	hex_asc[((x) & 0xf0) >> 4]
++
++static inline char *pack_hex_byte(char *buf, u8 byte)
++{
++	*buf++ = hex_asc_hi(byte);
++	*buf++ = hex_asc_lo(byte);
++	return buf;
++}
+ 
+ #define pr_emerg(fmt, arg...) \
+ 	printk(KERN_EMERG fmt, ##arg)
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index eb7c16c..02a27ae 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -226,8 +226,17 @@ struct mm_struct {
+ 	rwlock_t		ioctx_list_lock;	/* aio lock */
+ 	struct kioctx		*ioctx_list;
+ #ifdef CONFIG_MM_OWNER
+-	struct task_struct *owner;	/* The thread group leader that */
+-					/* owns the mm_struct.		*/
++	/*
++	 * "owner" points to a task that is regarded as the canonical
++	 * user/owner of this mm. All of the following must be true in
++	 * order for it to be changed:
++	 *
++	 * current == mm->owner
++	 * current->mm != mm
++	 * new_owner->mm == mm
++	 * new_owner->alloc_lock is held
++	 */
++	struct task_struct *owner;
+ #endif
+ 
+ #ifdef CONFIG_PROC_FS
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 7c1d446..b11e6e1 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -93,14 +93,16 @@ struct wireless_dev;
+  *	used.
+  */
+  
+-#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
+-#define LL_MAX_HEADER	32
++#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
++# if defined(CONFIG_MAC80211_MESH)
++#  define LL_MAX_HEADER 128
++# else
++#  define LL_MAX_HEADER 96
++# endif
++#elif defined(CONFIG_TR)
++# define LL_MAX_HEADER 48
+ #else
+-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+-#define LL_MAX_HEADER	96
+-#else
+-#define LL_MAX_HEADER	48
+-#endif
++# define LL_MAX_HEADER 32
+ #endif
+ 
+ #if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \
+@@ -244,11 +246,16 @@ struct hh_cache
+  *
+  * We could use other alignment values, but we must maintain the
+  * relationship HH alignment <= LL alignment.
++ *
++ * LL_ALLOCATED_SPACE also takes into account the tailroom the device
++ * may need.
+  */
+ #define LL_RESERVED_SPACE(dev) \
+-	(((dev)->hard_header_len&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
++	((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+ #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
+-	((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
++	((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
++#define LL_ALLOCATED_SPACE(dev) \
++	((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+ 
+ struct header_ops {
+ 	int	(*create) (struct sk_buff *skb, struct net_device *dev,
+@@ -567,6 +574,13 @@ struct net_device
+ 	unsigned short		type;	/* interface hardware type	*/
+ 	unsigned short		hard_header_len;	/* hardware hdr length	*/
+ 
++	/* extra head- and tailroom the hardware may need, but not in all cases
++	 * can this be guaranteed, especially tailroom. Some cases also use
++	 * LL_MAX_HEADER instead to allocate the skb.
++	 */
++	unsigned short		needed_headroom;
++	unsigned short		needed_tailroom;
++
+ 	struct net_device	*master; /* Pointer to master device of a group,
+ 					  * which this device is member of.
+ 					  */
+@@ -715,6 +729,9 @@ struct net_device
+ 	struct net		*nd_net;
+ #endif
+ 
++	/* mid-layer private */
++	void			*ml_priv;
++
+ 	/* bridge stuff */
+ 	struct net_bridge_port	*br_port;
+ 	/* macvlan */
+diff --git a/include/linux/parser.h b/include/linux/parser.h
+index 26b2bdf..7dcd050 100644
+--- a/include/linux/parser.h
++++ b/include/linux/parser.h
+@@ -29,5 +29,5 @@ int match_token(char *, match_table_t table, substring_t args[]);
+ int match_int(substring_t *, int *result);
+ int match_octal(substring_t *, int *result);
+ int match_hex(substring_t *, int *result);
+-void match_strcpy(char *, const substring_t *);
++size_t match_strlcpy(char *, const substring_t *, size_t);
+ char *match_strdup(const substring_t *);
+diff --git a/include/linux/percpu.h b/include/linux/percpu.h
+index d746a2a..4cdd393 100644
+--- a/include/linux/percpu.h
++++ b/include/linux/percpu.h
+@@ -13,8 +13,14 @@
+ 	__attribute__((__section__(".data.percpu")))			\
+ 	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
+ 
++#ifdef MODULE
++#define SHARED_ALIGNED_SECTION ".data.percpu"
++#else
++#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned"
++#endif
++
+ #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)			\
+-	__attribute__((__section__(".data.percpu.shared_aligned")))	\
++	__attribute__((__section__(SHARED_ALIGNED_SECTION)))		\
+ 	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name		\
+ 	____cacheline_aligned_in_smp
+ #else
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 4ab9f32..5395a61 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -2027,7 +2027,7 @@ static inline int fatal_signal_pending(struct task_struct *p)
+ 
+ static inline int need_resched(void)
+ {
+-	return unlikely(test_tsk_need_resched(current));
++	return unlikely(test_thread_flag(TIF_NEED_RESCHED));
+ }
+ 
+ /*
+@@ -2038,7 +2038,7 @@ static inline int need_resched(void)
+  * cond_resched_softirq() will enable bhs before scheduling.
+  */
+ extern int _cond_resched(void);
+-#ifdef CONFIG_PREEMPT
++#ifdef CONFIG_PREEMPT_BKL
+ static inline int cond_resched(void)
+ {
+ 	return 0;
+diff --git a/include/linux/usb/association.h b/include/linux/usb/association.h
+new file mode 100644
+index 0000000..07c5e3c
+--- /dev/null
++++ b/include/linux/usb/association.h
+@@ -0,0 +1,150 @@
++/*
++ * Wireless USB - Cable Based Association
++ *
++ * Copyright (C) 2006 Intel Corporation
++ * Inaky Perez-Gonzalez <inaky.perez-gonzalez at intel.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version
++ * 2 as published by the Free Software Foundation.
++ *
++ */
++#ifndef __LINUX_USB_ASSOCIATION_H
++#define __LINUX_USB_ASSOCIATION_H
++
++
++/*
++ * Association attributes
++ *
++ * Association Models Supplement to WUSB 1.0 T[3-1]
++ *
++ * Each field in the structures has it's ID, it's length and then the
++ * value. This is the actual definition of the field's ID and its
++ * length.
++ */
++struct wusb_am_attr {
++	__u8 id;
++	__u8 len;
++};
++
++/* Different fields defined by the spec */
++#define WUSB_AR_AssociationTypeId	{ .id = 0x0000, .len =  2 }
++#define WUSB_AR_AssociationSubTypeId	{ .id = 0x0001, .len =  2 }
++#define WUSB_AR_Length			{ .id = 0x0002, .len =  4 }
++#define WUSB_AR_AssociationStatus	{ .id = 0x0004, .len =  4 }
++#define WUSB_AR_LangID			{ .id = 0x0008, .len =  2 }
++#define WUSB_AR_DeviceFriendlyName	{ .id = 0x000b, .len = 64 } /* max */
++#define WUSB_AR_HostFriendlyName	{ .id = 0x000c, .len = 64 } /* max */
++#define WUSB_AR_CHID			{ .id = 0x1000, .len = 16 }
++#define WUSB_AR_CDID			{ .id = 0x1001, .len = 16 }
++#define WUSB_AR_ConnectionContext	{ .id = 0x1002, .len = 48 }
++#define WUSB_AR_BandGroups		{ .id = 0x1004, .len =  2 }
++
++/* CBAF Control Requests (AMS1.0[T4-1] */
++enum {
++	CBAF_REQ_GET_ASSOCIATION_INFORMATION = 0x01,
++	CBAF_REQ_GET_ASSOCIATION_REQUEST,
++	CBAF_REQ_SET_ASSOCIATION_RESPONSE
++};
++
++/*
++ * CBAF USB-interface defitions
++ *
++ * No altsettings, one optional interrupt endpoint.
++ */
++enum {
++	CBAF_IFACECLASS    = 0xef,
++	CBAF_IFACESUBCLASS = 0x03,
++	CBAF_IFACEPROTOCOL = 0x01,
++};
++
++/* Association Information (AMS1.0[T4-3]) */
++struct wusb_cbaf_assoc_info {
++	__le16 Length;
++	__u8 NumAssociationRequests;
++	__le16 Flags;
++	__u8 AssociationRequestsArray[];
++} __attribute__((packed));
++
++/* Association Request (AMS1.0[T4-4]) */
++struct wusb_cbaf_assoc_request {
++	__u8 AssociationDataIndex;
++	__u8 Reserved;
++	__le16 AssociationTypeId;
++	__le16 AssociationSubTypeId;
++	__le32 AssociationTypeInfoSize;
++} __attribute__((packed));
++
++enum {
++	AR_TYPE_WUSB                    = 0x0001,
++	AR_TYPE_WUSB_RETRIEVE_HOST_INFO = 0x0000,
++	AR_TYPE_WUSB_ASSOCIATE          = 0x0001,
++};
++
++/* Association Attribute header (AMS1.0[3.8]) */
++struct wusb_cbaf_attr_hdr {
++	__le16 id;
++	__le16 len;
++} __attribute__((packed));
++
++/* Host Info (AMS1.0[T4-7]) (yeah, more headers and fields...) */
++struct wusb_cbaf_host_info {
++	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
++	__le16 AssociationTypeId;
++	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
++	__le16 AssociationSubTypeId;
++	struct wusb_cbaf_attr_hdr CHID_hdr;
++	struct wusb_ckhdid CHID;
++	struct wusb_cbaf_attr_hdr LangID_hdr;
++	__le16 LangID;
++	struct wusb_cbaf_attr_hdr HostFriendlyName_hdr;
++	__u8 HostFriendlyName[];
++} __attribute__((packed));
++
++/* Device Info (AMS1.0[T4-8])
++ *
++ * I still don't get this tag'n'header stuff for each goddamn
++ * field...
++ */
++struct wusb_cbaf_device_info {
++	struct wusb_cbaf_attr_hdr Length_hdr;
++	__le32 Length;
++	struct wusb_cbaf_attr_hdr CDID_hdr;
++	struct wusb_ckhdid CDID;
++	struct wusb_cbaf_attr_hdr BandGroups_hdr;
++	__le16 BandGroups;
++	struct wusb_cbaf_attr_hdr LangID_hdr;
++	__le16 LangID;
++	struct wusb_cbaf_attr_hdr DeviceFriendlyName_hdr;
++	__u8 DeviceFriendlyName[];
++} __attribute__((packed));
++
++/* Connection Context; CC_DATA - Success case (AMS1.0[T4-9]) */
++struct wusb_cbaf_cc_data {
++	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
++	__le16 AssociationTypeId;
++	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
++	__le16 AssociationSubTypeId;
++	struct wusb_cbaf_attr_hdr Length_hdr;
++	__le32 Length;
++	struct wusb_cbaf_attr_hdr ConnectionContext_hdr;
++	struct wusb_ckhdid CHID;
++	struct wusb_ckhdid CDID;
++	struct wusb_ckhdid CK;
++	struct wusb_cbaf_attr_hdr BandGroups_hdr;
++	__le16 BandGroups;
++} __attribute__((packed));
++
++/* CC_DATA - Failure case (AMS1.0[T4-10]) */
++struct wusb_cbaf_cc_data_fail {
++	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
++	__le16 AssociationTypeId;
++	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
++	__le16 AssociationSubTypeId;
++	struct wusb_cbaf_attr_hdr Length_hdr;
++	__le16 Length;
++	struct wusb_cbaf_attr_hdr AssociationStatus_hdr;
++	__u32 AssociationStatus;
++} __attribute__((packed));
++
++#endif	/* __LINUX_USB_ASSOCIATION_H */
+diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
+index 585eb44..b3d3e27 100644
+--- a/include/net/9p/9p.h
++++ b/include/net/9p/9p.h
+@@ -29,14 +29,31 @@
+ 
+ #ifdef CONFIG_NET_9P_DEBUG
+ 
+-#define P9_DEBUG_ERROR		(1<<0)
+-#define P9_DEBUG_9P	        (1<<2)
+-#define P9_DEBUG_VFS	        (1<<3)
+-#define P9_DEBUG_CONV		(1<<4)
+-#define P9_DEBUG_MUX		(1<<5)
+-#define P9_DEBUG_TRANS		(1<<6)
+-#define P9_DEBUG_SLABS	      	(1<<7)
+-#define P9_DEBUG_FCALL		(1<<8)
++/**
++ * enum p9_debug_flags - bits for mount time debug parameter
++ * @P9_DEBUG_ERROR: more verbose error messages including original error string
++ * @P9_DEBUG_9P: 9P protocol tracing
++ * @P9_DEBUG_VFS: VFS API tracing
++ * @P9_DEBUG_CONV: protocol conversion tracing
++ * @P9_DEBUG_MUX: trace management of concurrent transactions
++ * @P9_DEBUG_TRANS: transport tracing
++ * @P9_DEBUG_SLABS: memory management tracing
++ * @P9_DEBUG_FCALL: verbose dump of protocol messages
++ *
++ * These flags are passed at mount time to turn on various levels of
++ * verbosity and tracing which will be output to the system logs.
++ */
++
++enum p9_debug_flags {
++	P9_DEBUG_ERROR = 	(1<<0),
++	P9_DEBUG_9P = 		(1<<2),
++	P9_DEBUG_VFS =		(1<<3),
++	P9_DEBUG_CONV =		(1<<4),
++	P9_DEBUG_MUX =		(1<<5),
++	P9_DEBUG_TRANS =	(1<<6),
++	P9_DEBUG_SLABS =      	(1<<7),
++	P9_DEBUG_FCALL =	(1<<8),
++};
+ 
+ extern unsigned int p9_debug_level;
+ 
+@@ -62,9 +79,47 @@ do { \
+ 		format , __FUNCTION__, task_pid_nr(current), ## arg); \
+ } while (0)
+ 
++/**
++ * enum p9_msg_t - 9P message types
++ * @P9_TVERSION: version handshake request
++ * @P9_RVERSION: version handshake response
++ * @P9_TAUTH: request to establish authentication channel
++ * @P9_RAUTH: response with authentication information
++ * @P9_TATTACH: establish user access to file service
++ * @P9_RATTACH: response with top level handle to file hierarchy
++ * @P9_TERROR: not used
++ * @P9_RERROR: response for any failed request
++ * @P9_TFLUSH: request to abort a previous request
++ * @P9_RFLUSH: response when previous request has been cancelled
++ * @P9_TWALK: descend a directory hierarchy
++ * @P9_RWALK: response with new handle for position within hierarchy
++ * @P9_TOPEN: prepare a handle for I/O on an existing file
++ * @P9_ROPEN: response with file access information
++ * @P9_TCREATE: prepare a handle for I/O on a new file
++ * @P9_RCREATE: response with file access information
++ * @P9_TREAD: request to transfer data from a file or directory
++ * @P9_RREAD: response with data requested
++ * @P9_TWRITE: reuqest to transfer data to a file
++ * @P9_RWRITE: response with out much data was transfered to file
++ * @P9_TCLUNK: forget about a handle to an entity within the file system
++ * @P9_RCLUNK: response when server has forgotten about the handle
++ * @P9_TREMOVE: request to remove an entity from the hierarchy
++ * @P9_RREMOVE: response when server has removed the entity
++ * @P9_TSTAT: request file entity attributes
++ * @P9_RSTAT: response with file entity attributes
++ * @P9_TWSTAT: request to update file entity attributes
++ * @P9_RWSTAT: response when file entity attributes are updated
++ *
++ * There are 14 basic operations in 9P2000, paired as
++ * requests and responses.  The one special case is ERROR
++ * as there is no @P9_TERROR request for clients to transmit to
++ * the server, but the server may respond to any other request
++ * with an @P9_RERROR.
++ *
++ * See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html
++ */
+ 
+-/* Message Types */
+-enum {
++enum p9_msg_t {
+ 	P9_TVERSION = 100,
+ 	P9_RVERSION,
+ 	P9_TAUTH = 102,
+@@ -95,30 +150,71 @@ enum {
+ 	P9_RWSTAT,
+ };
+ 
+-/* open modes */
+-enum {
++/**
++ * enum p9_open_mode_t - 9P open modes
++ * @P9_OREAD: open file for reading only
++ * @P9_OWRITE: open file for writing only
++ * @P9_ORDWR: open file for reading or writing
++ * @P9_OEXEC: open file for execution
++ * @P9_OTRUNC: truncate file to zero-length before opening it
++ * @P9_OREXEC: close the file when an exec(2) system call is made
++ * @P9_ORCLOSE: remove the file when the file is closed
++ * @P9_OAPPEND: open the file and seek to the end
++ * @P9_OEXCL: only create a file, do not open it
++ *
++ * 9P open modes differ slightly from Posix standard modes.
++ * In particular, there are extra modes which specify different
++ * semantic behaviors than may be available on standard Posix
++ * systems.  For example, @P9_OREXEC and @P9_ORCLOSE are modes that
++ * most likely will not be issued from the Linux VFS client, but may
++ * be supported by servers.
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/open
++ */
++
++enum p9_open_mode_t {
+ 	P9_OREAD = 0x00,
+ 	P9_OWRITE = 0x01,
+ 	P9_ORDWR = 0x02,
+ 	P9_OEXEC = 0x03,
+-	P9_OEXCL = 0x04,
+ 	P9_OTRUNC = 0x10,
+ 	P9_OREXEC = 0x20,
+ 	P9_ORCLOSE = 0x40,
+ 	P9_OAPPEND = 0x80,
+-};
+-
+-/* permissions */
+-enum {
++	P9_OEXCL = 0x1000,
++};
++
++/**
++ * enum p9_perm_t - 9P permissions
++ * @P9_DMDIR: mode bite for directories
++ * @P9_DMAPPEND: mode bit for is append-only
++ * @P9_DMEXCL: mode bit for excluse use (only one open handle allowed)
++ * @P9_DMMOUNT: mode bite for mount points
++ * @P9_DMAUTH: mode bit for authentication file
++ * @P9_DMTMP: mode bit for non-backed-up files
++ * @P9_DMSYMLINK: mode bit for symbolic links (9P2000.u)
++ * @P9_DMLINK: mode bit for hard-link (9P2000.u)
++ * @P9_DMDEVICE: mode bit for device files (9P2000.u)
++ * @P9_DMNAMEDPIPE: mode bit for named pipe (9P2000.u)
++ * @P9_DMSOCKET: mode bit for socket (9P2000.u)
++ * @P9_DMSETUID: mode bit for setuid (9P2000.u)
++ * @P9_DMSETGID: mode bit for setgid (9P2000.u)
++ * @P9_DMSETVTX: mode bit for sticky bit (9P2000.u)
++ *
++ * 9P permissions differ slightly from Posix standard modes.
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
++ */
++enum p9_perm_t {
+ 	P9_DMDIR = 0x80000000,
+ 	P9_DMAPPEND = 0x40000000,
+ 	P9_DMEXCL = 0x20000000,
+ 	P9_DMMOUNT = 0x10000000,
+ 	P9_DMAUTH = 0x08000000,
+ 	P9_DMTMP = 0x04000000,
++/* 9P2000.u extensions */
+ 	P9_DMSYMLINK = 0x02000000,
+ 	P9_DMLINK = 0x01000000,
+-	/* 9P2000.u extensions */
+ 	P9_DMDEVICE = 0x00800000,
+ 	P9_DMNAMEDPIPE = 0x00200000,
+ 	P9_DMSOCKET = 0x00100000,
+@@ -127,8 +223,26 @@ enum {
+ 	P9_DMSETVTX = 0x00010000,
+ };
+ 
+-/* qid.types */
+-enum {
++/**
++ * enum p9_qid_t - QID types
++ * @P9_QTDIR: directory
++ * @P9_QTAPPEND: append-only
++ * @P9_QTEXCL: excluse use (only one open handle allowed)
++ * @P9_QTMOUNT: mount points
++ * @P9_QTAUTH: authentication file
++ * @P9_QTTMP: non-backed-up files
++ * @P9_QTSYMLINK: symbolic links (9P2000.u)
++ * @P9_QTLINK: hard-link (9P2000.u)
++ * @P9_QTFILE: normal files
++ *
++ * QID types are a subset of permissions - they are primarily
++ * used to differentiate semantics for a file system entity via
++ * a jump-table.  Their value is also the most signifigant 16 bits
++ * of the permission_t
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
++ */
++enum p9_qid_t {
+ 	P9_QTDIR = 0x80,
+ 	P9_QTAPPEND = 0x40,
+ 	P9_QTEXCL = 0x20,
+@@ -140,6 +254,7 @@ enum {
+ 	P9_QTFILE = 0x00,
+ };
+ 
++/* 9P Magic Numbers */
+ #define P9_NOTAG	(u16)(~0)
+ #define P9_NOFID	(u32)(~0)
+ #define P9_MAXWELEM	16
+@@ -147,19 +262,69 @@ enum {
+ /* ample room for Twrite/Rread header */
+ #define P9_IOHDRSZ	24
+ 
++/**
++ * struct p9_str - length prefixed string type
++ * @len: length of the string
++ * @str: the string
++ *
++ * The protocol uses length prefixed strings for all
++ * string data, so we replicate that for our internal
++ * string members.
++ */
++
+ struct p9_str {
+ 	u16 len;
+ 	char *str;
+ };
+ 
+-/* qids are the unique ID for a file (like an inode */
++/**
++ * struct p9_qid - file system entity information
++ * @type: 8-bit type &p9_qid_t
++ * @version: 16-bit monotonically incrementing version number
++ * @path: 64-bit per-server-unique ID for a file system element
++ *
++ * qids are identifiers used by 9P servers to track file system
++ * entities.  The type is used to differentiate semantics for operations
++ * on the entity (ie. read means something different on a directory than
++ * on a file).  The path provides a server unique index for an entity
++ * (roughly analogous to an inode number), while the version is updated
++ * every time a file is modified and can be used to maintain cache
++ * coherency between clients and serves.
++ * Servers will often differentiate purely synthetic entities by setting
++ * their version to 0, signaling that they should never be cached and
++ * should be accessed synchronously.
++ *
++ * See Also://plan9.bell-labs.com/magic/man2html/2/stat
++ */
++
+ struct p9_qid {
+ 	u8 type;
+ 	u32 version;
+ 	u64 path;
+ };
+ 
+-/* Plan 9 file metadata (stat) structure */
++/**
++ * struct p9_stat - file system metadata information
++ * @size: length prefix for this stat structure instance
++ * @type: the type of the server (equivilent to a major number)
++ * @dev: the sub-type of the server (equivilent to a minor number)
++ * @qid: unique id from the server of type &p9_qid
++ * @mode: Plan 9 format permissions of type &p9_perm_t
++ * @atime: Last access/read time
++ * @mtime: Last modify/write time
++ * @length: file length
++ * @name: last element of path (aka filename) in type &p9_str
++ * @uid: owner name in type &p9_str
++ * @gid: group owner in type &p9_str
++ * @muid: last modifier in type &p9_str
++ * @extension: area used to encode extended UNIX support in type &p9_str
++ * @n_uid: numeric user id of owner (part of 9p2000.u extension)
++ * @n_gid: numeric group id (part of 9p2000.u extension)
++ * @n_muid: numeric user id of laster modifier (part of 9p2000.u extension)
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
++ */
++
+ struct p9_stat {
+ 	u16 size;
+ 	u16 type;
+@@ -179,10 +344,14 @@ struct p9_stat {
+ 	u32 n_muid;			/* 9p2000.u extensions */
+ };
+ 
+-/* file metadata (stat) structure used to create Twstat message
+-   The is similar to p9_stat, but the strings don't point to
+-   the same memory block and should be freed separately
+-*/
++/*
++ * file metadata (stat) structure used to create Twstat message
++ * The is identical to &p9_stat, but the strings don't point to
++ * the same memory block and should be freed separately
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
++ */
++
+ struct p9_wstat {
+ 	u16 size;
+ 	u16 type;
+@@ -335,10 +504,20 @@ struct p9_twstat {
+ struct p9_rwstat {
+ };
+ 
+-/*
+-  * fcall is the primary packet structure
+-  *
+-  */
++/**
++ * struct p9_fcall - primary packet structure
++ * @size: prefixed length of the structure
++ * @id: protocol operating identifier of type &p9_msg_t
++ * @tag: transaction id of the request
++ * @sdata: payload
++ * @params: per-operation parameters
++ *
++ * &p9_fcall represents the structure for all 9P RPC
++ * transactions.  Requests are packaged into fcalls, and reponses
++ * must be extracted from them.
++ *
++ * See Also: http://plan9.bell-labs.com/magic/man2html/2/fcall
++ */
+ 
+ struct p9_fcall {
+ 	u32 size;
+@@ -416,4 +595,5 @@ int p9_idpool_check(int id, struct p9_idpool *p);
+ 
+ int p9_error_init(void);
+ int p9_errstr2errno(char *, int);
++int p9_trans_fd_init(void);
+ #endif /* NET_9P_H */
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index e52f93d..c936dd1 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -26,6 +26,23 @@
+ #ifndef NET_9P_CLIENT_H
+ #define NET_9P_CLIENT_H
+ 
++/**
++ * struct p9_client - per client instance state
++ * @lock: protect @fidlist
++ * @msize: maximum data size negotiated by protocol
++ * @dotu: extension flags negotiated by protocol
++ * @trans_mod: module API instantiated with this client
++ * @trans: tranport instance state and API
++ * @conn: connection state information used by trans_fd
++ * @fidpool: fid handle accounting for session
++ * @fidlist: List of active fid handles
++ *
++ * The client structure is used to keep track of various per-client
++ * state that has been instantiated.
++ *
++ * Bugs: duplicated data and potentially unnecessary elements.
++ */
++
+ struct p9_client {
+ 	spinlock_t lock; /* protect client structure */
+ 	int msize;
+@@ -38,6 +55,24 @@ struct p9_client {
+ 	struct list_head fidlist;
+ };
+ 
++/**
++ * struct p9_fid - file system entity handle
++ * @clnt: back pointer to instantiating &p9_client
++ * @fid: numeric identifier for this handle
++ * @mode: current mode of this fid (enum?)
++ * @qid: the &p9_qid server identifier this handle points to
++ * @iounit: the server reported maximum transaction size for this file
++ * @uid: the numeric uid of the local user who owns this handle
++ * @aux: transport specific information (unused?)
++ * @rdir_fpos: tracks offset of file position when reading directory contents
++ * @rdir_pos: (unused?)
++ * @rdir_fcall: holds response of last directory read request
++ * @flist: per-client-instance fid tracking
++ * @dlist: per-dentry fid tracking
++ *
++ * TODO: This needs lots of explanation.
++ */
++
+ struct p9_fid {
+ 	struct p9_client *clnt;
+ 	u32 fid;
+diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
+index d2209ae..0db3a40 100644
+--- a/include/net/9p/transport.h
++++ b/include/net/9p/transport.h
+@@ -26,12 +26,40 @@
+ #ifndef NET_9P_TRANSPORT_H
+ #define NET_9P_TRANSPORT_H
+ 
++/**
++ * enum p9_trans_status - different states of underlying transports
++ * @Connected: transport is connected and healthy
++ * @Disconnected: transport has been disconnected
++ * @Hung: transport is connected by wedged
++ *
++ * This enumeration details the various states a transport
++ * instatiation can be in.
++ */
++
+ enum p9_trans_status {
+ 	Connected,
+ 	Disconnected,
+ 	Hung,
+ };
+ 
++/**
++ * struct p9_trans - per-transport state and API
++ * @status: transport &p9_trans_status
++ * @msize: negotiated maximum packet size (duplicate from client)
++ * @extended: negotiated protocol extensions (duplicate from client)
++ * @priv: transport private data
++ * @close: member function to disconnect and close the transport
++ * @rpc: member function to issue a request to the transport
++ *
++ * This is the basic API for a transport instance.  It is used as
++ * a handle by the client to issue requests.  This interface is currently
++ * in flux during reorganization.
++ *
++ * Bugs: there is lots of duplicated data here and its not clear that
++ * the member functions need to be per-instance versus per transport
++ * module.
++ */
++
+ struct p9_trans {
+ 	enum p9_trans_status status;
+ 	int msize;
+@@ -42,6 +70,21 @@ struct p9_trans {
+ 							struct p9_fcall **rc);
+ };
+ 
++/**
++ * struct p9_trans_module - transport module interface
++ * @list: used to maintain a list of currently available transports
++ * @name: the human-readable name of the transport
++ * @maxsize: transport provided maximum packet size
++ * @def: set if this transport should be considered the default
++ * @create: member function to create a new connection on this transport
++ *
++ * This is the basic API for a transport module which is registered by the
++ * transport module with the 9P core network module and used by the client
++ * to instantiate a new connection on a transport.
++ *
++ * Bugs: the transport module list isn't protected.
++ */
++
+ struct p9_trans_module {
+ 	struct list_head list;
+ 	char *name;		/* name of transport */
+@@ -53,5 +96,4 @@ struct p9_trans_module {
+ void v9fs_register_trans(struct p9_trans_module *m);
+ struct p9_trans_module *v9fs_match_trans(const substring_t *name);
+ struct p9_trans_module *v9fs_default_trans(void);
+-
+ #endif /* NET_9P_TRANSPORT_H */
+diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h
+index e4efad1..0ce9339 100644
+--- a/include/net/irda/discovery.h
++++ b/include/net/irda/discovery.h
+@@ -57,9 +57,6 @@ typedef union {
+ 	__u8  byte[2];
+ } __u16_host_order;
+ 
+-/* Same purpose, different application */
+-#define u16ho(array) (* ((__u16 *) array))
+-
+ /* Types of discovery */
+ typedef enum {
+ 	DISCOVERY_LOG,		/* What's in our discovery log */
+diff --git a/include/net/syncppp.h b/include/net/syncppp.h
+index 877efa4..e43f407 100644
+--- a/include/net/syncppp.h
++++ b/include/net/syncppp.h
+@@ -59,7 +59,7 @@ struct ppp_device
+ 
+ static inline struct sppp *sppp_of(struct net_device *dev) 
+ {
+-	struct ppp_device **ppp = dev->priv;
++	struct ppp_device **ppp = dev->ml_priv;
+ 	BUG_ON((*ppp)->dev != dev);
+ 	return &(*ppp)->sppp;
+ }
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index e6ea6f7..d3c8c03 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -238,7 +238,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_info *uinfo);
+ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_info *uinfo);
+-#define snd_soc_info_bool_ext		snd_ctl_boolean_mono
++#define snd_soc_info_bool_ext		snd_ctl_boolean_mono_info
+ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
+ 	struct snd_ctl_elem_value *ucontrol);
+ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
+diff --git a/init/do_mounts.c b/init/do_mounts.c
+index 3885e70..660c1e5 100644
+--- a/init/do_mounts.c
++++ b/init/do_mounts.c
+@@ -76,6 +76,7 @@ dev_t name_to_dev_t(char *name)
+ 	char s[32];
+ 	char *p;
+ 	dev_t res = 0;
++	int part;
+ 
+ 	if (strncmp(name, "/dev/", 5) != 0) {
+ 		unsigned maj, min;
+@@ -106,7 +107,31 @@ dev_t name_to_dev_t(char *name)
+ 	for (p = s; *p; p++)
+ 		if (*p == '/')
+ 			*p = '!';
+-	res = blk_lookup_devt(s);
++	res = blk_lookup_devt(s, 0);
++	if (res)
++		goto done;
++
++	/*
++	 * try non-existant, but valid partition, which may only exist
++	 * after revalidating the disk, like partitioned md devices
++	 */
++	while (p > s && isdigit(p[-1]))
++		p--;
++	if (p == s || !*p || *p == '0')
++		goto fail;
++
++	/* try disk name without <part number> */
++	part = simple_strtoul(p, NULL, 10);
++	*p = '\0';
++	res = blk_lookup_devt(s, part);
++	if (res)
++		goto done;
++
++	/* try disk name without p<part number> */
++	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
++		goto fail;
++	p[-1] = '\0';
++	res = blk_lookup_devt(s, part);
+ 	if (res)
+ 		goto done;
+ 
+diff --git a/init/main.c b/init/main.c
+index ddada7a..f406fef 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -702,7 +702,6 @@ static void __init do_initcalls(void)
+ 
+ 	for (call = __initcall_start; call < __initcall_end; call++) {
+ 		ktime_t t0, t1, delta;
+-		char *msg = NULL;
+ 		char msgbuf[40];
+ 		int result;
+ 
+@@ -724,22 +723,23 @@ static void __init do_initcalls(void)
+ 				(unsigned long long) delta.tv64 >> 20);
+ 		}
+ 
+-		if (result && result != -ENODEV && initcall_debug) {
+-			sprintf(msgbuf, "error code %d", result);
+-			msg = msgbuf;
+-		}
++		msgbuf[0] = 0;
++
++		if (result && result != -ENODEV && initcall_debug)
++			sprintf(msgbuf, "error code %d ", result);
++
+ 		if (preempt_count() != count) {
+-			msg = "preemption imbalance";
++			strncat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
+ 			preempt_count() = count;
+ 		}
+ 		if (irqs_disabled()) {
+-			msg = "disabled interrupts";
++			strncat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
+ 			local_irq_enable();
+ 		}
+-		if (msg) {
++		if (msgbuf[0]) {
+ 			print_fn_descriptor_symbol(KERN_WARNING "initcall %s()",
+ 					(unsigned long) *call);
+-			printk(" returned with %s\n", msg);
++			printk(" returned with %s\n", msgbuf);
+ 		}
+ 	}
+ 
+diff --git a/kernel/kgdb.c b/kernel/kgdb.c
+index 39e31a0..14787de 100644
+--- a/kernel/kgdb.c
++++ b/kernel/kgdb.c
+@@ -346,14 +346,6 @@ static void put_packet(char *buffer)
+ 	}
+ }
+ 
+-static char *pack_hex_byte(char *pkt, u8 byte)
+-{
+-	*pkt++ = hexchars[byte >> 4];
+-	*pkt++ = hexchars[byte & 0xf];
+-
+-	return pkt;
+-}
+-
+ /*
+  * Convert the memory pointed to by mem into hex, placing result in buf.
+  * Return a pointer to the last char put in buf (null). May return an error.
+diff --git a/kernel/sched.c b/kernel/sched.c
+index 8841a91..cfa222a 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -8986,7 +8986,7 @@ static u64 cpu_shares_read_u64(struct cgroup *cgrp, struct cftype *cft)
+ #endif
+ 
+ #ifdef CONFIG_RT_GROUP_SCHED
+-static ssize_t cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
++static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
+ 				s64 val)
+ {
+ 	return sched_group_set_rt_runtime(cgroup_tg(cgrp), val);
+diff --git a/lib/bitmap.c b/lib/bitmap.c
+index c4cb48f..482df94 100644
+--- a/lib/bitmap.c
++++ b/lib/bitmap.c
+@@ -316,22 +316,6 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
+ EXPORT_SYMBOL(bitmap_scnprintf);
+ 
+ /**
+- * bitmap_scnprintf_len - return buffer length needed to convert
+- * bitmap to an ASCII hex string.
+- * @len: number of bits to be converted
+- */
+-int bitmap_scnprintf_len(unsigned int len)
+-{
+-	/* we need 9 chars per word for 32 bit words (8 hexdigits + sep/null) */
+-	int bitslen = ALIGN(len, CHUNKSZ);
+-	int wordlen = CHUNKSZ / 4;
+-	int buflen = (bitslen / wordlen) * (wordlen + 1) * sizeof(char);
+-
+-	return buflen;
+-}
+-EXPORT_SYMBOL(bitmap_scnprintf_len);
+-
+-/**
+  * __bitmap_parse - convert an ASCII hex string into a bitmap.
+  * @buf: pointer to buffer containing string.
+  * @buflen: buffer size in bytes.  If string is smaller than this
+diff --git a/lib/hexdump.c b/lib/hexdump.c
+index 3435465..f07c0db 100644
+--- a/lib/hexdump.c
++++ b/lib/hexdump.c
+@@ -12,6 +12,9 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ 
++const char hex_asc[] = "0123456789abcdef";
++EXPORT_SYMBOL(hex_asc);
++
+ /**
+  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
+  * @buf: data blob to dump
+@@ -93,8 +96,8 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
+ 		for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen;
+ 		     j++) {
+ 			ch = ptr[j];
+-			linebuf[lx++] = hex_asc(ch >> 4);
+-			linebuf[lx++] = hex_asc(ch & 0x0f);
++			linebuf[lx++] = hex_asc_hi(ch);
++			linebuf[lx++] = hex_asc_lo(ch);
+ 			linebuf[lx++] = ' ';
+ 		}
+ 		ascii_column = 3 * rowsize + 2;
+diff --git a/lib/lmb.c b/lib/lmb.c
+index 83287d3..867f7b5 100644
+--- a/lib/lmb.c
++++ b/lib/lmb.c
+@@ -19,31 +19,42 @@
+ 
+ struct lmb lmb;
+ 
++static int lmb_debug;
++
++static int __init early_lmb(char *p)
++{
++	if (p && strstr(p, "debug"))
++		lmb_debug = 1;
++	return 0;
++}
++early_param("lmb", early_lmb);
++
+ void lmb_dump_all(void)
+ {
+-#ifdef DEBUG
+ 	unsigned long i;
+ 
+-	pr_debug("lmb_dump_all:\n");
+-	pr_debug("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
+-	pr_debug("    memory.size		  = 0x%llx\n",
++	if (!lmb_debug)
++		return;
++
++	pr_info("lmb_dump_all:\n");
++	pr_info("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
++	pr_info("    memory.size		  = 0x%llx\n",
+ 	    (unsigned long long)lmb.memory.size);
+ 	for (i=0; i < lmb.memory.cnt ;i++) {
+-		pr_debug("    memory.region[0x%x].base       = 0x%llx\n",
++		pr_info("    memory.region[0x%lx].base       = 0x%llx\n",
+ 		    i, (unsigned long long)lmb.memory.region[i].base);
+-		pr_debug("		      .size     = 0x%llx\n",
++		pr_info("		      .size     = 0x%llx\n",
+ 		    (unsigned long long)lmb.memory.region[i].size);
+ 	}
+ 
+-	pr_debug("    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
+-	pr_debug("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
++	pr_info("    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
++	pr_info("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
+ 	for (i=0; i < lmb.reserved.cnt ;i++) {
+-		pr_debug("    reserved.region[0x%x].base       = 0x%llx\n",
++		pr_info("    reserved.region[0x%lx].base       = 0x%llx\n",
+ 		    i, (unsigned long long)lmb.reserved.region[i].base);
+-		pr_debug("		      .size     = 0x%llx\n",
++		pr_info("		      .size     = 0x%llx\n",
+ 		    (unsigned long long)lmb.reserved.region[i].size);
+ 	}
+-#endif /* DEBUG */
+ }
+ 
+ static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2,
+@@ -286,8 +297,7 @@ static u64 __init lmb_alloc_nid_unreserved(u64 start, u64 end,
+ 		j = lmb_overlaps_region(&lmb.reserved, base, size);
+ 		if (j < 0) {
+ 			/* this area isn't reserved, take it */
+-			if (lmb_add_region(&lmb.reserved, base,
+-					   lmb_align_up(size, align)) < 0)
++			if (lmb_add_region(&lmb.reserved, base, size) < 0)
+ 				base = ~(u64)0;
+ 			return base;
+ 		}
+@@ -333,6 +343,10 @@ u64 __init lmb_alloc_nid(u64 size, u64 align, int nid,
+ 	struct lmb_region *mem = &lmb.memory;
+ 	int i;
+ 
++	BUG_ON(0 == size);
++
++	size = lmb_align_up(size, align);
++
+ 	for (i = 0; i < mem->cnt; i++) {
+ 		u64 ret = lmb_alloc_nid_region(&mem->region[i],
+ 					       nid_range,
+@@ -370,6 +384,8 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
+ 
+ 	BUG_ON(0 == size);
+ 
++	size = lmb_align_up(size, align);
++
+ 	/* On some platforms, make sure we allocate lowmem */
+ 	/* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */
+ 	if (max_addr == LMB_ALLOC_ANYWHERE)
+@@ -393,8 +409,7 @@ u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
+ 			j = lmb_overlaps_region(&lmb.reserved, base, size);
+ 			if (j < 0) {
+ 				/* this area isn't reserved, take it */
+-				if (lmb_add_region(&lmb.reserved, base,
+-						   lmb_align_up(size, align)) < 0)
++				if (lmb_add_region(&lmb.reserved, base, size) < 0)
+ 					return 0;
+ 				return base;
+ 			}
+diff --git a/lib/parser.c b/lib/parser.c
+index 703c8c1..4f0cbc0 100644
+--- a/lib/parser.c
++++ b/lib/parser.c
+@@ -182,18 +182,25 @@ int match_hex(substring_t *s, int *result)
+ }
+ 
+ /**
+- * match_strcpy: - copies the characters from a substring_t to a string
+- * @to: string to copy characters to.
+- * @s: &substring_t to copy
++ * match_strlcpy: - Copy the characters from a substring_t to a sized buffer
++ * @dest: where to copy to
++ * @src: &substring_t to copy
++ * @size: size of destination buffer
+  *
+- * Description: Copies the set of characters represented by the given
+- * &substring_t @s to the c-style string @to. Caller guarantees that @to is
+- * large enough to hold the characters of @s.
++ * Description: Copy the characters in &substring_t @src to the
++ * c-style string @dest.  Copy no more than @size - 1 characters, plus
++ * the terminating NUL.  Return length of @src.
+  */
+-void match_strcpy(char *to, const substring_t *s)
++size_t match_strlcpy(char *dest, const substring_t *src, size_t size)
+ {
+-	memcpy(to, s->from, s->to - s->from);
+-	to[s->to - s->from] = '\0';
++	size_t ret = src->to - src->from;
++
++	if (size) {
++		size_t len = ret >= size ? size - 1 : ret;
++		memcpy(dest, src->from, len);
++		dest[len] = '\0';
++	}
++	return ret;
+ }
+ 
+ /**
+@@ -206,9 +213,10 @@ void match_strcpy(char *to, const substring_t *s)
+  */
+ char *match_strdup(const substring_t *s)
+ {
+-	char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
++	size_t sz = s->to - s->from + 1;
++	char *p = kmalloc(sz, GFP_KERNEL);
+ 	if (p)
+-		match_strcpy(p, s);
++		match_strlcpy(p, s, sz);
+ 	return p;
+ }
+ 
+@@ -216,5 +224,5 @@ EXPORT_SYMBOL(match_token);
+ EXPORT_SYMBOL(match_int);
+ EXPORT_SYMBOL(match_octal);
+ EXPORT_SYMBOL(match_hex);
+-EXPORT_SYMBOL(match_strcpy);
++EXPORT_SYMBOL(match_strlcpy);
+ EXPORT_SYMBOL(match_strdup);
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 2dead9a..1e6a7d3 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1461,6 +1461,11 @@ page_not_uptodate:
+ 	 */
+ 	ClearPageError(page);
+ 	error = mapping->a_ops->readpage(file, page);
++	if (!error) {
++		wait_on_page_locked(page);
++		if (!PageUptodate(page))
++			error = -EIO;
++	}
+ 	page_cache_release(page);
+ 
+ 	if (!error || error == AOP_TRUNCATED_PAGE)
+diff --git a/mm/memory.c b/mm/memory.c
+index 48c122d..fb5608a 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -311,6 +311,21 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+ 	if (!new)
+ 		return -ENOMEM;
+ 
++	/*
++	 * Ensure all pte setup (eg. pte page lock and page clearing) are
++	 * visible before the pte is made visible to other CPUs by being
++	 * put into page tables.
++	 *
++	 * The other side of the story is the pointer chasing in the page
++	 * table walking code (when walking the page table without locking;
++	 * ie. most of the time). Fortunately, these data accesses consist
++	 * of a chain of data-dependent loads, meaning most CPUs (alpha
++	 * being the notable exception) will already guarantee loads are
++	 * seen in-order. See the alpha page table accessors for the
++	 * smp_read_barrier_depends() barriers in page table walking code.
++	 */
++	smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */
++
+ 	spin_lock(&mm->page_table_lock);
+ 	if (!pmd_present(*pmd)) {	/* Has another populated it ? */
+ 		mm->nr_ptes++;
+@@ -329,6 +344,8 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+ 	if (!new)
+ 		return -ENOMEM;
+ 
++	smp_wmb(); /* See comment in __pte_alloc */
++
+ 	spin_lock(&init_mm.page_table_lock);
+ 	if (!pmd_present(*pmd)) {	/* Has another populated it ? */
+ 		pmd_populate_kernel(&init_mm, pmd, new);
+@@ -2619,6 +2636,8 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+ 	if (!new)
+ 		return -ENOMEM;
+ 
++	smp_wmb(); /* See comment in __pte_alloc */
++
+ 	spin_lock(&mm->page_table_lock);
+ 	if (pgd_present(*pgd))		/* Another has populated it */
+ 		pud_free(mm, new);
+@@ -2640,6 +2659,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+ 	if (!new)
+ 		return -ENOMEM;
+ 
++	smp_wmb(); /* See comment in __pte_alloc */
++
+ 	spin_lock(&mm->page_table_lock);
+ #ifndef __ARCH_HAS_4LEVEL_HACK
+ 	if (pud_present(*pud))		/* Another has populated it */
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+index b17dca7..833f854 100644
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -159,21 +159,58 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
+ }
+ #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
+ 
++static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
++			   unsigned long end_pfn)
++{
++	unsigned long old_zone_end_pfn;
++
++	zone_span_writelock(zone);
++
++	old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
++	if (start_pfn < zone->zone_start_pfn)
++		zone->zone_start_pfn = start_pfn;
++
++	zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
++				zone->zone_start_pfn;
++
++	zone_span_writeunlock(zone);
++}
++
++static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
++			    unsigned long end_pfn)
++{
++	unsigned long old_pgdat_end_pfn =
++		pgdat->node_start_pfn + pgdat->node_spanned_pages;
++
++	if (start_pfn < pgdat->node_start_pfn)
++		pgdat->node_start_pfn = start_pfn;
++
++	pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
++					pgdat->node_start_pfn;
++}
++
+ static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
+ {
+ 	struct pglist_data *pgdat = zone->zone_pgdat;
+ 	int nr_pages = PAGES_PER_SECTION;
+ 	int nid = pgdat->node_id;
+ 	int zone_type;
++	unsigned long flags;
+ 
+ 	zone_type = zone - pgdat->node_zones;
+ 	if (!zone->wait_table) {
+-		int ret = 0;
++		int ret;
++
+ 		ret = init_currently_empty_zone(zone, phys_start_pfn,
+ 						nr_pages, MEMMAP_HOTPLUG);
+-		if (ret < 0)
++		if (ret)
+ 			return ret;
+ 	}
++	pgdat_resize_lock(zone->zone_pgdat, &flags);
++	grow_zone_span(zone, phys_start_pfn, phys_start_pfn + nr_pages);
++	grow_pgdat_span(zone->zone_pgdat, phys_start_pfn,
++			phys_start_pfn + nr_pages);
++	pgdat_resize_unlock(zone->zone_pgdat, &flags);
+ 	memmap_init_zone(nr_pages, nid, zone_type,
+ 			 phys_start_pfn, MEMMAP_HOTPLUG);
+ 	return 0;
+@@ -299,36 +336,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
+ }
+ EXPORT_SYMBOL_GPL(__remove_pages);
+ 
+-static void grow_zone_span(struct zone *zone,
+-		unsigned long start_pfn, unsigned long end_pfn)
+-{
+-	unsigned long old_zone_end_pfn;
+-
+-	zone_span_writelock(zone);
+-
+-	old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+-	if (start_pfn < zone->zone_start_pfn)
+-		zone->zone_start_pfn = start_pfn;
+-
+-	zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
+-				zone->zone_start_pfn;
+-
+-	zone_span_writeunlock(zone);
+-}
+-
+-static void grow_pgdat_span(struct pglist_data *pgdat,
+-		unsigned long start_pfn, unsigned long end_pfn)
+-{
+-	unsigned long old_pgdat_end_pfn =
+-		pgdat->node_start_pfn + pgdat->node_spanned_pages;
+-
+-	if (start_pfn < pgdat->node_start_pfn)
+-		pgdat->node_start_pfn = start_pfn;
+-
+-	pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
+-					pgdat->node_start_pfn;
+-}
+-
+ void online_page(struct page *page)
+ {
+ 	totalram_pages++;
+@@ -367,7 +374,6 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
+ 
+ int online_pages(unsigned long pfn, unsigned long nr_pages)
+ {
+-	unsigned long flags;
+ 	unsigned long onlined_pages = 0;
+ 	struct zone *zone;
+ 	int need_zonelists_rebuild = 0;
+@@ -395,11 +401,6 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
+ 	 * memory_block->state_mutex.
+ 	 */
+ 	zone = page_zone(pfn_to_page(pfn));
+-	pgdat_resize_lock(zone->zone_pgdat, &flags);
+-	grow_zone_span(zone, pfn, pfn + nr_pages);
+-	grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
+-	pgdat_resize_unlock(zone->zone_pgdat, &flags);
+-
+ 	/*
+ 	 * If this zone is not populated, then it is not in zonelist.
+ 	 * This means the page allocator ignores this zone.
+@@ -408,8 +409,15 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
+ 	if (!populated_zone(zone))
+ 		need_zonelists_rebuild = 1;
+ 
+-	walk_memory_resource(pfn, nr_pages, &onlined_pages,
++	ret = walk_memory_resource(pfn, nr_pages, &onlined_pages,
+ 		online_pages_range);
++	if (ret) {
++		printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
++			nr_pages, pfn);
++		memory_notify(MEM_CANCEL_ONLINE, &arg);
++		return ret;
++	}
++
+ 	zone->present_pages += onlined_pages;
+ 	zone->zone_pgdat->node_present_pages += onlined_pages;
+ 
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index 4de5468..a5bf31c 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -26,6 +26,13 @@
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
+ 
++#ifndef pgprot_modify
++static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
++{
++	return newprot;
++}
++#endif
++
+ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
+ 		unsigned long addr, unsigned long end, pgprot_t newprot,
+ 		int dirty_accountable)
+@@ -192,7 +199,9 @@ success:
+ 	 * held in write mode.
+ 	 */
+ 	vma->vm_flags = newflags;
+-	vma->vm_page_prot = vm_get_page_prot(newflags);
++	vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
++					  vm_get_page_prot(newflags));
++
+ 	if (vma_wants_writenotify(vma)) {
+ 		vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
+ 		dirty_accountable = 1;
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index bdd5c43..6383557 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2862,8 +2862,6 @@ __meminit int init_currently_empty_zone(struct zone *zone,
+ 
+ 	zone->zone_start_pfn = zone_start_pfn;
+ 
+-	memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
+-
+ 	zone_init_free_lists(zone);
+ 
+ 	return 0;
+@@ -3433,6 +3431,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
+ 		ret = init_currently_empty_zone(zone, zone_start_pfn,
+ 						size, MEMMAP_EARLY);
+ 		BUG_ON(ret);
++		memmap_init(size, nid, j, zone_start_pfn);
+ 		zone_start_pfn += size;
+ 	}
+ }
+diff --git a/mm/pdflush.c b/mm/pdflush.c
+index 1c96cfc..9d834aa 100644
+--- a/mm/pdflush.c
++++ b/mm/pdflush.c
+@@ -207,7 +207,6 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
+ 
+ 	spin_lock_irqsave(&pdflush_lock, flags);
+ 	if (list_empty(&pdflush_list)) {
+-		spin_unlock_irqrestore(&pdflush_lock, flags);
+ 		ret = -1;
+ 	} else {
+ 		struct pdflush_work *pdf;
+@@ -219,8 +218,9 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
+ 		pdf->fn = fn;
+ 		pdf->arg0 = arg0;
+ 		wake_up_process(pdf->who);
+-		spin_unlock_irqrestore(&pdflush_lock, flags);
+ 	}
++	spin_unlock_irqrestore(&pdflush_lock, flags);
++
+ 	return ret;
+ }
+ 
+diff --git a/mm/vmstat.c b/mm/vmstat.c
+index 1a32130..db9eabb 100644
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -41,7 +41,9 @@ static void sum_vm_events(unsigned long *ret, cpumask_t *cpumask)
+ */
+ void all_vm_events(unsigned long *ret)
+ {
++	get_online_cpus();
+ 	sum_vm_events(ret, &cpu_online_map);
++	put_online_cpus();
+ }
+ EXPORT_SYMBOL_GPL(all_vm_events);
+ 
+diff --git a/net/9p/Kconfig b/net/9p/Kconfig
+index bafc50c..ff34c5a 100644
+--- a/net/9p/Kconfig
++++ b/net/9p/Kconfig
+@@ -13,16 +13,6 @@ menuconfig NET_9P
+ 
+ 	  If unsure, say N.
+ 
+-config NET_9P_FD
+-	depends on NET_9P
+-	default y if NET_9P
+-	tristate "9P File Descriptor Transports (Experimental)"
+-	help
+-	  This builds support for file descriptor transports for 9p
+-	  which includes support for TCP/IP, named pipes, or passed
+-	  file descriptors.  TCP/IP is the default transport for 9p,
+-	  so if you are going to use 9p, you'll likely want this.
+-
+ config NET_9P_VIRTIO
+ 	depends on NET_9P && EXPERIMENTAL && VIRTIO
+ 	tristate "9P Virtio Transport (Experimental)"
+diff --git a/net/9p/Makefile b/net/9p/Makefile
+index 8a10511..5192194 100644
+--- a/net/9p/Makefile
++++ b/net/9p/Makefile
+@@ -1,5 +1,4 @@
+ obj-$(CONFIG_NET_9P) := 9pnet.o
+-obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
+ 
+ 9pnet-objs := \
+@@ -9,8 +8,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
+ 	error.o \
+ 	fcprint.o \
+ 	util.o \
+-
+-9pnet_fd-objs := \
+ 	trans_fd.o \
+ 
+ 9pnet_virtio-objs := \
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 84e087e..2ffe40c 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -64,21 +64,30 @@ static match_table_t tokens = {
+  * @options: options string passed from mount
+  * @v9ses: existing v9fs session information
+  *
++ * Return 0 upon success, -ERRNO upon failure
+  */
+ 
+-static void parse_opts(char *options, struct p9_client *clnt)
++static int parse_opts(char *opts, struct p9_client *clnt)
+ {
++	char *options;
+ 	char *p;
+ 	substring_t args[MAX_OPT_ARGS];
+ 	int option;
+-	int ret;
++	int ret = 0;
+ 
+ 	clnt->trans_mod = v9fs_default_trans();
+ 	clnt->dotu = 1;
+ 	clnt->msize = 8192;
+ 
+-	if (!options)
+-		return;
++	if (!opts)
++		return 0;
++
++	options = kstrdup(opts, GFP_KERNEL);
++	if (!options) {
++		P9_DPRINTK(P9_DEBUG_ERROR,
++				"failed to allocate copy of option string\n");
++		return -ENOMEM;
++	}
+ 
+ 	while ((p = strsep(&options, ",")) != NULL) {
+ 		int token;
+@@ -86,10 +95,11 @@ static void parse_opts(char *options, struct p9_client *clnt)
+ 			continue;
+ 		token = match_token(p, tokens, args);
+ 		if (token < Opt_trans) {
+-			ret = match_int(&args[0], &option);
+-			if (ret < 0) {
++			int r = match_int(&args[0], &option);
++			if (r < 0) {
+ 				P9_DPRINTK(P9_DEBUG_ERROR,
+ 					"integer field, but no integer?\n");
++				ret = r;
+ 				continue;
+ 			}
+ 		}
+@@ -107,6 +117,8 @@ static void parse_opts(char *options, struct p9_client *clnt)
+ 			continue;
+ 		}
+ 	}
++	kfree(options);
++	return ret;
+ }
+ 
+ 
+@@ -138,16 +150,20 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
+ 	if (!clnt)
+ 		return ERR_PTR(-ENOMEM);
+ 
++	clnt->trans = NULL;
+ 	spin_lock_init(&clnt->lock);
+ 	INIT_LIST_HEAD(&clnt->fidlist);
+ 	clnt->fidpool = p9_idpool_create();
+-	if (!clnt->fidpool) {
++	if (IS_ERR(clnt->fidpool)) {
+ 		err = PTR_ERR(clnt->fidpool);
+ 		clnt->fidpool = NULL;
+ 		goto error;
+ 	}
+ 
+-	parse_opts(options, clnt);
++	err = parse_opts(options, clnt);
++	if (err < 0)
++		goto error;
++
+ 	if (clnt->trans_mod == NULL) {
+ 		err = -EPROTONOSUPPORT;
+ 		P9_DPRINTK(P9_DEBUG_ERROR,
+diff --git a/net/9p/conv.c b/net/9p/conv.c
+index 3fe35d5..4454720 100644
+--- a/net/9p/conv.c
++++ b/net/9p/conv.c
+@@ -197,7 +197,7 @@ static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid)
+ 
+ /**
+  * p9_size_wstat - calculate the size of a variable length stat struct
+- * @stat: metadata (stat) structure
++ * @wstat: metadata (stat) structure
+  * @dotu: non-zero if 9P2000.u
+  *
+  */
+@@ -511,6 +511,12 @@ p9_create_common(struct cbuf *bufp, u32 size, u8 id)
+ 	return fc;
+ }
+ 
++/**
++ * p9_set_tag - set the tag field of an &p9_fcall structure
++ * @fc: fcall structure to set tag within
++ * @tag: tag id to set
++ */
++
+ void p9_set_tag(struct p9_fcall *fc, u16 tag)
+ {
+ 	fc->tag = tag;
+@@ -518,6 +524,12 @@ void p9_set_tag(struct p9_fcall *fc, u16 tag)
+ }
+ EXPORT_SYMBOL(p9_set_tag);
+ 
++/**
++ * p9_create_tversion - allocates and creates a T_VERSION request
++ * @msize: requested maximum data size
++ * @version: version string to negotiate
++ *
++ */
+ struct p9_fcall *p9_create_tversion(u32 msize, char *version)
+ {
+ 	int size;
+@@ -542,6 +554,16 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tversion);
+ 
++/**
++ * p9_create_tauth - allocates and creates a T_AUTH request
++ * @afid: handle to use for authentication protocol
++ * @uname: user name attempting to authenticate
++ * @aname: mount specifier for remote server
++ * @n_uname: numeric id for user attempting to authneticate
++ * @dotu: 9P2000.u extension flag
++ *
++ */
++
+ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
+ 	u32 n_uname, int dotu)
+ {
+@@ -580,6 +602,18 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tauth);
+ 
++/**
++ * p9_create_tattach - allocates and creates a T_ATTACH request
++ * @fid: handle to use for the new mount point
++ * @afid: handle to use for authentication protocol
++ * @uname: user name attempting to attach
++ * @aname: mount specifier for remote server
++ * @n_uname: numeric id for user attempting to attach
++ * @n_uname: numeric id for user attempting to attach
++ * @dotu: 9P2000.u extension flag
++ *
++ */
++
+ struct p9_fcall *
+ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
+ 	u32 n_uname, int dotu)
+@@ -616,6 +650,12 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tattach);
+ 
++/**
++ * p9_create_tflush - allocates and creates a T_FLUSH request
++ * @oldtag: tag id for the transaction we are attempting to cancel
++ *
++ */
++
+ struct p9_fcall *p9_create_tflush(u16 oldtag)
+ {
+ 	int size;
+@@ -639,6 +679,15 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tflush);
+ 
++/**
++ * p9_create_twalk - allocates and creates a T_FLUSH request
++ * @fid: handle we are traversing from
++ * @newfid: a new handle for this transaction
++ * @nwname: number of path elements to traverse
++ * @wnames: array of path elements
++ *
++ */
++
+ struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
+ 				     char **wnames)
+ {
+@@ -677,6 +726,13 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_twalk);
+ 
++/**
++ * p9_create_topen - allocates and creates a T_OPEN request
++ * @fid: handle we are trying to open
++ * @mode: what mode we are trying to open the file in
++ *
++ */
++
+ struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
+ {
+ 	int size;
+@@ -701,6 +757,19 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_topen);
+ 
++/**
++ * p9_create_tcreate - allocates and creates a T_CREATE request
++ * @fid: handle of directory we are trying to create in
++ * @name: name of the file we are trying to create
++ * @perm: permissions for the file we are trying to create
++ * @mode: what mode we are trying to open the file in
++ * @extension: 9p2000.u extension string (for special files)
++ * @dotu: 9p2000.u enabled flag
++ *
++ * Note: Plan 9 create semantics include opening the resulting file
++ * which is why mode is included.
++ */
++
+ struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
+ 	char *extension, int dotu)
+ {
+@@ -736,6 +805,13 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tcreate);
+ 
++/**
++ * p9_create_tread - allocates and creates a T_READ request
++ * @fid: handle of the file we are trying to read
++ * @offset: offset to start reading from
++ * @count: how many bytes to read
++ */
++
+ struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
+ {
+ 	int size;
+@@ -761,6 +837,17 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tread);
+ 
++/**
++ * p9_create_twrite - allocates and creates a T_WRITE request from the kernel
++ * @fid: handle of the file we are trying to write
++ * @offset: offset to start writing at
++ * @count: how many bytes to write
++ * @data: data to write
++ *
++ * This function will create a requst with data buffers from the kernel
++ * such as the page cache.
++ */
++
+ struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
+ 				      const char *data)
+ {
+@@ -794,6 +881,16 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_twrite);
+ 
++/**
++ * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
++ * @fid: handle of the file we are trying to write
++ * @offset: offset to start writing at
++ * @count: how many bytes to write
++ * @data: data to write
++ *
++ * This function will create a request with data buffers from userspace
++ */
++
+ struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
+ 				      const char __user *data)
+ {
+@@ -827,6 +924,14 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_twrite_u);
+ 
++/**
++ * p9_create_tclunk - allocate a request to forget about a file handle
++ * @fid: handle of the file we closing or forgetting about
++ *
++ * clunk is used both to close open files and to discard transient handles
++ * which may be created during meta-data operations and hierarchy traversal.
++ */
++
+ struct p9_fcall *p9_create_tclunk(u32 fid)
+ {
+ 	int size;
+@@ -850,6 +955,12 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tclunk);
+ 
++/**
++ * p9_create_tremove - allocate and create a request to remove a file
++ * @fid: handle of the file or directory we are removing
++ *
++ */
++
+ struct p9_fcall *p9_create_tremove(u32 fid)
+ {
+ 	int size;
+@@ -873,6 +984,12 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tremove);
+ 
++/**
++ * p9_create_tstat - allocate and populate a request for attributes
++ * @fid: handle of the file or directory we are trying to get the attributes of
++ *
++ */
++
+ struct p9_fcall *p9_create_tstat(u32 fid)
+ {
+ 	int size;
+@@ -896,6 +1013,14 @@ error:
+ }
+ EXPORT_SYMBOL(p9_create_tstat);
+ 
++/**
++ * p9_create_tstat - allocate and populate a request to change attributes
++ * @fid: handle of the file or directory we are trying to change
++ * @wstat: &p9_stat structure with attributes we wish to set
++ * @dotu: 9p2000.u enabled flag
++ *
++ */
++
+ struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
+ 				      int dotu)
+ {
+@@ -922,3 +1047,4 @@ error:
+ 	return fc;
+ }
+ EXPORT_SYMBOL(p9_create_twstat);
++
+diff --git a/net/9p/error.c b/net/9p/error.c
+index 64104b9..fdebe43 100644
+--- a/net/9p/error.c
++++ b/net/9p/error.c
+@@ -33,6 +33,13 @@
+ #include <linux/errno.h>
+ #include <net/9p/9p.h>
+ 
++/**
++ * struct errormap - map string errors from Plan 9 to Linux numeric ids
++ * @name: string sent over 9P
++ * @val: numeric id most closely representing @name
++ * @namelen: length of string
++ * @list: hash-table list for string lookup
++ */
+ struct errormap {
+ 	char *name;
+ 	int val;
+@@ -177,8 +184,7 @@ static struct errormap errmap[] = {
+ };
+ 
+ /**
+- * p9_error_init - preload
+- * @errstr: error string
++ * p9_error_init - preload mappings into hash list
+  *
+  */
+ 
+@@ -206,6 +212,7 @@ EXPORT_SYMBOL(p9_error_init);
+ /**
+  * errstr2errno - convert error string to error number
+  * @errstr: error string
++ * @len: length of error string
+  *
+  */
+ 
+@@ -230,8 +237,8 @@ int p9_errstr2errno(char *errstr, int len)
+ 	if (errno == 0) {
+ 		/* TODO: if error isn't found, add it dynamically */
+ 		errstr[len] = 0;
+-		printk(KERN_ERR "%s: errstr :%s: not found\n", __func__,
+-		       errstr);
++		printk(KERN_ERR "%s: server reported unknown error %s\n",
++			__func__, errstr);
+ 		errno = 1;
+ 	}
+ 
+diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c
+index 40244fb..53dd8e2 100644
+--- a/net/9p/fcprint.c
++++ b/net/9p/fcprint.c
+@@ -142,6 +142,14 @@ p9_printdata(char *buf, int buflen, u8 *data, int datalen)
+ 	return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
+ }
+ 
++/**
++ * p9_printfcall - decode and print a protocol structure into a buffer
++ * @buf: buffer to deposit decoded structure into
++ * @buflen: available space in buffer
++ * @fc: protocol rpc structure of type &p9_fcall
++ * @extended: whether or not session is operating with extended protocol
++ */
++
+ int
+ p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
+ {
+diff --git a/net/9p/mod.c b/net/9p/mod.c
+index c285aab..bdee1fb 100644
+--- a/net/9p/mod.c
++++ b/net/9p/mod.c
+@@ -39,9 +39,6 @@ module_param_named(debug, p9_debug_level, uint, 0);
+ MODULE_PARM_DESC(debug, "9P debugging level");
+ #endif
+ 
+-extern int p9_mux_global_init(void);
+-extern void p9_mux_global_exit(void);
+-
+ /*
+  * Dynamic Transport Registration Routines
+  *
+@@ -52,7 +49,7 @@ static struct p9_trans_module *v9fs_default_transport;
+ 
+ /**
+  * v9fs_register_trans - register a new transport with 9p
+- * @m - structure describing the transport module and entry points
++ * @m: structure describing the transport module and entry points
+  *
+  */
+ void v9fs_register_trans(struct p9_trans_module *m)
+@@ -65,7 +62,7 @@ EXPORT_SYMBOL(v9fs_register_trans);
+ 
+ /**
+  * v9fs_match_trans - match transport versus registered transports
+- * @arg: string identifying transport
++ * @name: string identifying transport
+  *
+  */
+ struct p9_trans_module *v9fs_match_trans(const substring_t *name)
+@@ -110,6 +107,7 @@ static int __init init_p9(void)
+ 
+ 	p9_error_init();
+ 	printk(KERN_INFO "Installing 9P2000 support\n");
++	p9_trans_fd_init();
+ 
+ 	return ret;
+ }
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index f624dff..4507f74 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -47,12 +47,29 @@
+ #define SCHED_TIMEOUT	10
+ #define MAXPOLLWADDR	2
+ 
++/**
++ * struct p9_fd_opts - per-transport options
++ * @rfd: file descriptor for reading (trans=fd)
++ * @wfd: file descriptor for writing (trans=fd)
++ * @port: port to connect to (trans=tcp)
++ *
++ */
++
+ struct p9_fd_opts {
+ 	int rfd;
+ 	int wfd;
+ 	u16 port;
+ };
+ 
++
++/**
++ * struct p9_trans_fd - transport state
++ * @rd: reference to file to read from
++ * @wr: reference of file to write to
++ * @conn: connection state reference
++ *
++ */
++
+ struct p9_trans_fd {
+ 	struct file *rd;
+ 	struct file *wr;
+@@ -90,10 +107,24 @@ enum {
+ };
+ 
+ struct p9_req;
+-
+ typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
++
++/**
++ * struct p9_req - fd mux encoding of an rpc transaction
++ * @lock: protects req_list
++ * @tag: numeric tag for rpc transaction
++ * @tcall: request &p9_fcall structure
++ * @rcall: response &p9_fcall structure
++ * @err: error state
++ * @cb: callback for when response is received
++ * @cba: argument to pass to callback
++ * @flush: flag to indicate RPC has been flushed
++ * @req_list: list link for higher level objects to chain requests
++ *
++ */
++
+ struct p9_req {
+-	spinlock_t lock; /* protect request structure */
++	spinlock_t lock;
+ 	int tag;
+ 	struct p9_fcall *tcall;
+ 	struct p9_fcall *rcall;
+@@ -104,7 +135,39 @@ struct p9_req {
+ 	struct list_head req_list;
+ };
+ 
+-struct p9_mux_poll_task;
++struct p9_mux_poll_task {
++	struct task_struct *task;
++	struct list_head mux_list;
++	int muxnum;
++};
++
++/**
++ * struct p9_conn - fd mux connection state information
++ * @lock: protects mux_list (?)
++ * @mux_list: list link for mux to manage multiple connections (?)
++ * @poll_task: task polling on this connection
++ * @msize: maximum size for connection (dup)
++ * @extended: 9p2000.u flag (dup)
++ * @trans: reference to transport instance for this connection
++ * @tagpool: id accounting for transactions
++ * @err: error state
++ * @equeue: event wait_q (?)
++ * @req_list: accounting for requests which have been sent
++ * @unsent_req_list: accounting for requests that haven't been sent
++ * @rcall: current response &p9_fcall structure
++ * @rpos: read position in current frame
++ * @rbuf: current read buffer
++ * @wpos: write position for current frame
++ * @wsize: amount of data to write for current frame
++ * @wbuf: current write buffer
++ * @poll_wait: array of wait_q's for various worker threads
++ * @poll_waddr: ????
++ * @pt: poll state
++ * @rq: current read work
++ * @wq: current write work
++ * @wsched: ????
++ *
++ */
+ 
+ struct p9_conn {
+ 	spinlock_t lock; /* protect lock structure */
+@@ -132,11 +195,16 @@ struct p9_conn {
+ 	unsigned long wsched;
+ };
+ 
+-struct p9_mux_poll_task {
+-	struct task_struct *task;
+-	struct list_head mux_list;
+-	int muxnum;
+-};
++/**
++ * struct p9_mux_rpc - fd mux rpc accounting structure
++ * @m: connection this request was issued on
++ * @err: error state
++ * @tcall: request &p9_fcall
++ * @rcall: response &p9_fcall
++ * @wqueue: wait queue that client is blocked on for this rpc
++ *
++ * Bug: isn't this information duplicated elsewhere like &p9_req
++ */
+ 
+ struct p9_mux_rpc {
+ 	struct p9_conn *m;
+@@ -207,10 +275,12 @@ static void p9_mux_put_tag(struct p9_conn *m, u16 tag)
+ 
+ /**
+  * p9_mux_calc_poll_procs - calculates the number of polling procs
+- * based on the number of mounted v9fs filesystems.
++ * @muxnum: number of mounts
+  *
++ * Calculation is based on the number of mounted v9fs filesystems.
+  * The current implementation returns sqrt of the number of mounts.
+  */
++
+ static int p9_mux_calc_poll_procs(int muxnum)
+ {
+ 	int n;
+@@ -331,12 +401,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
+ 
+ /**
+  * p9_conn_create - allocate and initialize the per-session mux data
+- * Creates the polling task if this is the first session.
++ * @trans: transport structure
+  *
+- * @trans - transport structure
+- * @msize - maximum message size
+- * @extended - extended flag
++ * Note: Creates the polling task if this is the first session.
+  */
++
+ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
+ {
+ 	int i, n;
+@@ -406,7 +475,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
+ 
+ /**
+  * p9_mux_destroy - cancels all pending requests and frees mux resources
++ * @m: mux to destroy
++ *
+  */
++
+ static void p9_conn_destroy(struct p9_conn *m)
+ {
+ 	P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
+@@ -429,9 +501,14 @@ static void p9_conn_destroy(struct p9_conn *m)
+ }
+ 
+ /**
+- * p9_pollwait - called by files poll operation to add v9fs-poll task
+- * 	to files wait queue
++ * p9_pollwait - add poll task to the wait queue
++ * @filp: file pointer being polled
++ * @wait_address: wait_q to block on
++ * @p: poll state
++ *
++ * called by files poll operation to add v9fs-poll task to files wait queue
+  */
++
+ static void
+ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
+ {
+@@ -462,7 +539,10 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
+ 
+ /**
+  * p9_poll_mux - polls a mux and schedules read or write works if necessary
++ * @m: connection to poll
++ *
+  */
++
+ static void p9_poll_mux(struct p9_conn *m)
+ {
+ 	int n;
+@@ -499,9 +579,14 @@ static void p9_poll_mux(struct p9_conn *m)
+ }
+ 
+ /**
+- * p9_poll_proc - polls all v9fs transports for new events and queues
+- * 	the appropriate work to the work queue
++ * p9_poll_proc - poll worker thread
++ * @a: thread state and arguments
++ *
++ * polls all v9fs transports for new events and queues the appropriate
++ * work to the work queue
++ *
+  */
++
+ static int p9_poll_proc(void *a)
+ {
+ 	struct p9_conn *m, *mtmp;
+@@ -527,7 +612,10 @@ static int p9_poll_proc(void *a)
+ 
+ /**
+  * p9_write_work - called when a transport can send some data
++ * @work: container for work to be done
++ *
+  */
++
+ static void p9_write_work(struct work_struct *work)
+ {
+ 	int n, err;
+@@ -638,7 +726,10 @@ static void process_request(struct p9_conn *m, struct p9_req *req)
+ 
+ /**
+  * p9_read_work - called when there is some data to be read from a transport
++ * @work: container of work to be done
++ *
+  */
++
+ static void p9_read_work(struct work_struct *work)
+ {
+ 	int n, err;
+@@ -793,7 +884,9 @@ error:
+  * @tc: request to be sent
+  * @cb: callback function to call when response is received
+  * @cba: parameter to pass to the callback function
++ *
+  */
++
+ static struct p9_req *p9_send_request(struct p9_conn *m,
+ 					  struct p9_fcall *tc,
+ 					  p9_conn_req_callback cb, void *cba)
+@@ -961,10 +1054,12 @@ p9_conn_rpc_cb(struct p9_req *req, void *a)
+ /**
+  * p9_fd_rpc- sends 9P request and waits until a response is available.
+  *	The function can be interrupted.
+- * @m: mux data
++ * @t: transport data
+  * @tc: request to be sent
+  * @rc: pointer where a pointer to the response is stored
++ *
+  */
++
+ int
+ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+ {
+@@ -1041,8 +1136,10 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+  * @m: mux data
+  * @tc: request to be sent
+  * @cb: callback function to be called when response arrives
+- * @cba: value to pass to the callback function
++ * @a: value to pass to the callback function
++ *
+  */
++
+ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
+ 		   p9_conn_req_callback cb, void *a)
+ {
+@@ -1065,7 +1162,9 @@ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
+  * p9_conn_cancel - cancel all pending requests with error
+  * @m: mux data
+  * @err: error code
++ *
+  */
++
+ void p9_conn_cancel(struct p9_conn *m, int err)
+ {
+ 	struct p9_req *req, *rtmp;
+@@ -1097,35 +1196,46 @@ void p9_conn_cancel(struct p9_conn *m, int err)
+ }
+ 
+ /**
+- * v9fs_parse_options - parse mount options into session structure
++ * parse_options - parse mount options into session structure
+  * @options: options string passed from mount
+- * @v9ses: existing v9fs session information
++ * @opts: transport-specific structure to parse options into
+  *
++ * Returns 0 upon success, -ERRNO upon failure
+  */
+ 
+-static void parse_opts(char *options, struct p9_fd_opts *opts)
++static int parse_opts(char *params, struct p9_fd_opts *opts)
+ {
+ 	char *p;
+ 	substring_t args[MAX_OPT_ARGS];
+ 	int option;
++	char *options;
+ 	int ret;
+ 
+ 	opts->port = P9_PORT;
+ 	opts->rfd = ~0;
+ 	opts->wfd = ~0;
+ 
+-	if (!options)
+-		return;
++	if (!params)
++		return 0;
++
++	options = kstrdup(params, GFP_KERNEL);
++	if (!options) {
++		P9_DPRINTK(P9_DEBUG_ERROR,
++				"failed to allocate copy of option string\n");
++		return -ENOMEM;
++	}
+ 
+ 	while ((p = strsep(&options, ",")) != NULL) {
+ 		int token;
++		int r;
+ 		if (!*p)
+ 			continue;
+ 		token = match_token(p, tokens, args);
+-		ret = match_int(&args[0], &option);
+-		if (ret < 0) {
++		r = match_int(&args[0], &option);
++		if (r < 0) {
+ 			P9_DPRINTK(P9_DEBUG_ERROR,
+ 			 "integer field, but no integer?\n");
++			ret = r;
+ 			continue;
+ 		}
+ 		switch (token) {
+@@ -1142,6 +1252,8 @@ static void parse_opts(char *options, struct p9_fd_opts *opts)
+ 			continue;
+ 		}
+ 	}
++	kfree(options);
++	return 0;
+ }
+ 
+ static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
+@@ -1193,11 +1305,12 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
+ 
+ /**
+  * p9_fd_read- read from a fd
+- * @v9ses: session information
++ * @trans: transport instance state
+  * @v: buffer to receive data into
+  * @len: size of receive buffer
+  *
+  */
++
+ static int p9_fd_read(struct p9_trans *trans, void *v, int len)
+ {
+ 	int ret;
+@@ -1220,11 +1333,12 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len)
+ 
+ /**
+  * p9_fd_write - write to a socket
+- * @v9ses: session information
++ * @trans: transport instance state
+  * @v: buffer to send data from
+  * @len: size of send buffer
+  *
+  */
++
+ static int p9_fd_write(struct p9_trans *trans, void *v, int len)
+ {
+ 	int ret;
+@@ -1296,6 +1410,7 @@ end:
+  * @trans: private socket structure
+  *
+  */
++
+ static void p9_fd_close(struct p9_trans *trans)
+ {
+ 	struct p9_trans_fd *ts;
+@@ -1318,6 +1433,23 @@ static void p9_fd_close(struct p9_trans *trans)
+ 	kfree(ts);
+ }
+ 
++/*
++ * stolen from NFS - maybe should be made a generic function?
++ */
++static inline int valid_ipaddr4(const char *buf)
++{
++	int rc, count, in[4];
++
++	rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
++	if (rc != 4)
++		return -EINVAL;
++	for (count = 0; count < 4; count++) {
++		if (in[count] > 255)
++			return -EINVAL;
++	}
++	return 0;
++}
++
+ static struct p9_trans *
+ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
+ {
+@@ -1328,7 +1460,12 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
+ 	struct p9_fd_opts opts;
+ 	struct p9_trans_fd *p;
+ 
+-	parse_opts(args, &opts);
++	err = parse_opts(args, &opts);
++	if (err < 0)
++		return ERR_PTR(err);
++
++	if (valid_ipaddr4(addr) < 0)
++		return ERR_PTR(-EINVAL);
+ 
+ 	csocket = NULL;
+ 	trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+@@ -1508,7 +1645,7 @@ static struct p9_trans_module p9_fd_trans = {
+ 	.create = p9_trans_create_fd,
+ };
+ 
+-static int __init p9_trans_fd_init(void)
++int p9_trans_fd_init(void)
+ {
+ 	int ret = p9_mux_global_init();
+ 	if (ret) {
+@@ -1522,9 +1659,4 @@ static int __init p9_trans_fd_init(void)
+ 
+ 	return 0;
+ }
+-
+-module_init(p9_trans_fd_init);
+-
+-MODULE_AUTHOR("Latchesar Ionkov <lucho at ionkov.net>");
+-MODULE_AUTHOR("Eric Van Hensbergen <ericvh at gmail.com>");
+-MODULE_LICENSE("GPL");
++EXPORT_SYMBOL(p9_trans_fd_init);
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index de7a9f5..42adc05 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -49,29 +49,75 @@
+ #define VIRTQUEUE_NUM	128
+ 
+ /* a single mutex to manage channel initialization and attachment */
+-static DECLARE_MUTEX(virtio_9p_lock);
++static DEFINE_MUTEX(virtio_9p_lock);
+ /* global which tracks highest initialized channel */
+ static int chan_index;
+ 
+ #define P9_INIT_MAXTAG	16
+ 
+-#define REQ_STATUS_IDLE	0
+-#define REQ_STATUS_SENT 1
+-#define REQ_STATUS_RCVD 2
+-#define REQ_STATUS_FLSH 3
++
++/**
++ * enum p9_req_status_t - virtio request status
++ * @REQ_STATUS_IDLE: request slot unused
++ * @REQ_STATUS_SENT: request sent to server
++ * @REQ_STATUS_RCVD: response received from server
++ * @REQ_STATUS_FLSH: request has been flushed
++ *
++ * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
++ * but use is actually tracked by the idpool structure which handles tag
++ * id allocation.
++ *
++ */
++
++enum p9_req_status_t {
++	REQ_STATUS_IDLE,
++	REQ_STATUS_SENT,
++	REQ_STATUS_RCVD,
++	REQ_STATUS_FLSH,
++};
++
++/**
++ * struct p9_req_t - virtio request slots
++ * @status: status of this request slot
++ * @wq: wait_queue for the client to block on for this request
++ *
++ * The virtio transport uses an array to track outstanding requests
++ * instead of a list.  While this may incurr overhead during initial
++ * allocation or expansion, it makes request lookup much easier as the
++ * tag id is a index into an array.  (We use tag+1 so that we can accomodate
++ * the -1 tag for the T_VERSION request).
++ * This also has the nice effect of only having to allocate wait_queues
++ * once, instead of constantly allocating and freeing them.  Its possible
++ * other resources could benefit from this scheme as well.
++ *
++ */
+ 
+ struct p9_req_t {
+ 	int status;
+ 	wait_queue_head_t *wq;
+ };
+ 
+-/* We keep all per-channel information in a structure.
++/**
++ * struct virtio_chan - per-instance transport information
++ * @initialized: whether the channel is initialized
++ * @inuse: whether the channel is in use
++ * @lock: protects multiple elements within this structure
++ * @vdev: virtio dev associated with this channel
++ * @vq: virtio queue associated with this channel
++ * @tagpool: accounting for tag ids (and request slots)
++ * @reqs: array of request slots
++ * @max_tag: current number of request_slots allocated
++ * @sg: scatter gather list which is used to pack a request (protected?)
++ *
++ * We keep all per-channel information in a structure.
+  * This structure is allocated within the devices dev->mem space.
+  * A pointer to the structure will get put in the transport private.
++ *
+  */
++
+ static struct virtio_chan {
+-	bool initialized;		/* channel is initialized */
+-	bool inuse;			/* channel is in use */
++	bool initialized;
++	bool inuse;
+ 
+ 	spinlock_t lock;
+ 
+@@ -86,7 +132,19 @@ static struct virtio_chan {
+ 	struct scatterlist sg[VIRTQUEUE_NUM];
+ } channels[MAX_9P_CHAN];
+ 
+-/* Lookup requests by tag */
++/**
++ * p9_lookup_tag - Lookup requests by tag
++ * @c: virtio channel to lookup tag within
++ * @tag: numeric id for transaction
++ *
++ * this is a simple array lookup, but will grow the
++ * request_slots as necessary to accomodate transaction
++ * ids which did not previously have a slot.
++ *
++ * Bugs: there is currently no upper limit on request slots set
++ * here, but that should be constrained by the id accounting.
++ */
++
+ static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
+ {
+ 	/* This looks up the original request by tag so we know which
+@@ -130,11 +188,20 @@ static unsigned int rest_of_page(void *data)
+ 	return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
+ }
+ 
++/**
++ * p9_virtio_close - reclaim resources of a channel
++ * @trans: transport state
++ *
++ * This reclaims a channel by freeing its resources and
++ * reseting its inuse flag.
++ *
++ */
++
+ static void p9_virtio_close(struct p9_trans *trans)
+ {
+ 	struct virtio_chan *chan = trans->priv;
+ 	int count;
+-	unsigned int flags;
++	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&chan->lock, flags);
+ 	p9_idpool_destroy(chan->tagpool);
+@@ -144,13 +211,26 @@ static void p9_virtio_close(struct p9_trans *trans)
+ 	chan->max_tag = 0;
+ 	spin_unlock_irqrestore(&chan->lock, flags);
+ 
+-	down(&virtio_9p_lock);
++	mutex_lock(&virtio_9p_lock);
+ 	chan->inuse = false;
+-	up(&virtio_9p_lock);
++	mutex_unlock(&virtio_9p_lock);
+ 
+ 	kfree(trans);
+ }
+ 
++/**
++ * req_done - callback which signals activity from the server
++ * @vq: virtio queue activity was received on
++ *
++ * This notifies us that the server has triggered some activity
++ * on the virtio channel - most likely a response to request we
++ * sent.  Figure out which requests now have responses and wake up
++ * those threads.
++ *
++ * Bugs: could do with some additional sanity checking, but appears to work.
++ *
++ */
++
+ static void req_done(struct virtqueue *vq)
+ {
+ 	struct virtio_chan *chan = vq->vdev->priv;
+@@ -169,6 +249,20 @@ static void req_done(struct virtqueue *vq)
+ 	spin_unlock_irqrestore(&chan->lock, flags);
+ }
+ 
++/**
++ * pack_sg_list - pack a scatter gather list from a linear buffer
++ * @sg: scatter/gather list to pack into
++ * @start: which segment of the sg_list to start at
++ * @limit: maximum segment to pack data to
++ * @data: data to pack into scatter/gather list
++ * @count: amount of data to pack into the scatter/gather list
++ *
++ * sg_lists have multiple segments of various sizes.  This will pack
++ * arbitrary data into an existing scatter gather list, segmenting the
++ * data as necessary within constraints.
++ *
++ */
++
+ static int
+ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
+ 								int count)
+@@ -189,6 +283,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
+ 	return index-start;
+ }
+ 
++/**
++ * p9_virtio_rpc - issue a request and wait for a response
++ * @t: transport state
++ * @tc: &p9_fcall request to transmit
++ * @rc: &p9_fcall to put reponse into
++ *
++ */
++
+ static int
+ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+ {
+@@ -263,16 +365,26 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+ 	return 0;
+ }
+ 
++/**
++ * p9_virtio_probe - probe for existence of 9P virtio channels
++ * @vdev: virtio device to probe
++ *
++ * This probes for existing virtio channels.  At present only
++ * a single channel is in use, so in the future more work may need
++ * to be done here.
++ *
++ */
++
+ static int p9_virtio_probe(struct virtio_device *vdev)
+ {
+ 	int err;
+ 	struct virtio_chan *chan;
+ 	int index;
+ 
+-	down(&virtio_9p_lock);
++	mutex_lock(&virtio_9p_lock);
+ 	index = chan_index++;
+ 	chan = &channels[index];
+-	up(&virtio_9p_lock);
++	mutex_unlock(&virtio_9p_lock);
+ 
+ 	if (chan_index > MAX_9P_CHAN) {
+ 		printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
+@@ -301,17 +413,34 @@ static int p9_virtio_probe(struct virtio_device *vdev)
+ out_free_vq:
+ 	vdev->config->del_vq(chan->vq);
+ fail:
+-	down(&virtio_9p_lock);
++	mutex_lock(&virtio_9p_lock);
+ 	chan_index--;
+-	up(&virtio_9p_lock);
++	mutex_unlock(&virtio_9p_lock);
+ 	return err;
+ }
+ 
+-/* This sets up a transport channel for 9p communication.  Right now
++
++/**
++ * p9_virtio_create - allocate a new virtio channel
++ * @devname: string identifying the channel to connect to (unused)
++ * @args: args passed from sys_mount() for per-transport options (unused)
++ * @msize: requested maximum packet size
++ * @extended: 9p2000.u enabled flag
++ *
++ * This sets up a transport channel for 9p communication.  Right now
+  * we only match the first available channel, but eventually we couldlook up
+  * alternate channels by matching devname versus a virtio_config entry.
+  * We use a simple reference count mechanism to ensure that only a single
+- * mount has a channel open at a time. */
++ * mount has a channel open at a time.
++ *
++ * Bugs: doesn't allow identification of a specific channel
++ * to allocate, channels are allocated sequentially. This was
++ * a pragmatic decision to get things rolling, but ideally some
++ * way of identifying the channel to attach to would be nice
++ * if we are going to support multiple channels.
++ *
++ */
++
+ static struct p9_trans *
+ p9_virtio_create(const char *devname, char *args, int msize,
+ 							unsigned char extended)
+@@ -320,7 +449,7 @@ p9_virtio_create(const char *devname, char *args, int msize,
+ 	struct virtio_chan *chan = channels;
+ 	int index = 0;
+ 
+-	down(&virtio_9p_lock);
++	mutex_lock(&virtio_9p_lock);
+ 	while (index < MAX_9P_CHAN) {
+ 		if (chan->initialized && !chan->inuse) {
+ 			chan->inuse = true;
+@@ -330,7 +459,7 @@ p9_virtio_create(const char *devname, char *args, int msize,
+ 			chan = &channels[index];
+ 		}
+ 	}
+-	up(&virtio_9p_lock);
++	mutex_unlock(&virtio_9p_lock);
+ 
+ 	if (index >= MAX_9P_CHAN) {
+ 		printk(KERN_ERR "9p: no channels available\n");
+@@ -360,6 +489,12 @@ p9_virtio_create(const char *devname, char *args, int msize,
+ 	return trans;
+ }
+ 
++/**
++ * p9_virtio_remove - clean up resources associated with a virtio device
++ * @vdev: virtio device to remove
++ *
++ */
++
+ static void p9_virtio_remove(struct virtio_device *vdev)
+ {
+ 	struct virtio_chan *chan = vdev->priv;
+diff --git a/net/9p/util.c b/net/9p/util.c
+index ef72155..958fc58 100644
+--- a/net/9p/util.c
++++ b/net/9p/util.c
+@@ -32,11 +32,23 @@
+ #include <linux/idr.h>
+ #include <net/9p/9p.h>
+ 
++/**
++ * struct p9_idpool - per-connection accounting for tag idpool
++ * @lock: protects the pool
++ * @pool: idr to allocate tag id from
++ *
++ */
++
+ struct p9_idpool {
+ 	spinlock_t lock;
+ 	struct idr pool;
+ };
+ 
++/**
++ * p9_idpool_create - create a new per-connection id pool
++ *
++ */
++
+ struct p9_idpool *p9_idpool_create(void)
+ {
+ 	struct p9_idpool *p;
+@@ -52,6 +64,11 @@ struct p9_idpool *p9_idpool_create(void)
+ }
+ EXPORT_SYMBOL(p9_idpool_create);
+ 
++/**
++ * p9_idpool_destroy - create a new per-connection id pool
++ * @p: idpool to destory
++ */
++
+ void p9_idpool_destroy(struct p9_idpool *p)
+ {
+ 	idr_destroy(&p->pool);
+@@ -61,9 +78,9 @@ EXPORT_SYMBOL(p9_idpool_destroy);
+ 
+ /**
+  * p9_idpool_get - allocate numeric id from pool
+- * @p - pool to allocate from
++ * @p: pool to allocate from
+  *
+- * XXX - This seems to be an awful generic function, should it be in idr.c with
++ * Bugs: This seems to be an awful generic function, should it be in idr.c with
+  *            the lock included in struct idr?
+  */
+ 
+@@ -71,7 +88,7 @@ int p9_idpool_get(struct p9_idpool *p)
+ {
+ 	int i = 0;
+ 	int error;
+-	unsigned int flags;
++	unsigned long flags;
+ 
+ retry:
+ 	if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
+@@ -94,15 +111,16 @@ EXPORT_SYMBOL(p9_idpool_get);
+ 
+ /**
+  * p9_idpool_put - release numeric id from pool
+- * @p - pool to allocate from
++ * @id: numeric id which is being released
++ * @p: pool to release id into
+  *
+- * XXX - This seems to be an awful generic function, should it be in idr.c with
++ * Bugs: This seems to be an awful generic function, should it be in idr.c with
+  *            the lock included in struct idr?
+  */
+ 
+ void p9_idpool_put(int id, struct p9_idpool *p)
+ {
+-	unsigned int flags;
++	unsigned long flags;
+ 	spin_lock_irqsave(&p->lock, flags);
+ 	idr_remove(&p->pool, id);
+ 	spin_unlock_irqrestore(&p->lock, flags);
+@@ -111,11 +129,13 @@ EXPORT_SYMBOL(p9_idpool_put);
+ 
+ /**
+  * p9_idpool_check - check if the specified id is available
+- * @id - id to check
+- * @p - pool
++ * @id: id to check
++ * @p: pool to check
+  */
++
+ int p9_idpool_check(int id, struct p9_idpool *p)
+ {
+ 	return idr_find(&p->pool, id) != NULL;
+ }
+ EXPORT_SYMBOL(p9_idpool_check);
++
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index b04d643..8fb134d 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -419,7 +419,7 @@ static void arp_reply(struct sk_buff *skb)
+ 		return;
+ 
+ 	size = arp_hdr_len(skb->dev);
+-	send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
++	send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
+ 			    LL_RESERVED_SPACE(np->dev));
+ 
+ 	if (!send_skb)
+diff --git a/net/core/sock.c b/net/core/sock.c
+index fa76f04..88094cb 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -270,7 +270,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ 	int err = 0;
+ 	int skb_len;
+ 
+-	/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
++	/* Cast sk->rcvbuf to unsigned... It's pointless, but reduces
+ 	   number of warnings when compiling with -W --ANK
+ 	 */
+ 	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
+diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
+index 68d1544..7c9bb13 100644
+--- a/net/econet/af_econet.c
++++ b/net/econet/af_econet.c
+@@ -340,7 +340,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
+ 
+ 		dev_hold(dev);
+ 
+-		skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
++		skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
+ 					  msg->msg_flags & MSG_DONTWAIT, &err);
+ 		if (skb==NULL)
+ 			goto out_unlock;
+diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
+index 68b72a7..418862f 100644
+--- a/net/ipv4/arp.c
++++ b/net/ipv4/arp.c
+@@ -570,7 +570,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
+ 	 *	Allocate a buffer
+ 	 */
+ 
+-	skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
++	skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
+ 	if (skb == NULL)
+ 		return NULL;
+ 
+diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
+index 05afb57..2c0e457 100644
+--- a/net/ipv4/cipso_ipv4.c
++++ b/net/ipv4/cipso_ipv4.c
+@@ -338,7 +338,7 @@ static int cipso_v4_cache_check(const unsigned char *key,
+ 		return -ENOENT;
+ 
+ 	hash = cipso_v4_map_cache_hash(key, key_len);
+-	bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
++	bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1);
+ 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
+ 	list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
+ 		if (entry->hash == hash &&
+@@ -417,7 +417,7 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
+ 	atomic_inc(&secattr->cache->refcount);
+ 	entry->lsm_data = secattr->cache;
+ 
+-	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
++	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1);
+ 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
+ 	if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
+ 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 6250f42..2769dc4 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -292,7 +292,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
+ 	struct iphdr *pip;
+ 	struct igmpv3_report *pig;
+ 
+-	skb = alloc_skb(size + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
++	skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
+ 	if (skb == NULL)
+ 		return NULL;
+ 
+@@ -653,7 +653,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
+ 		return -1;
+ 	}
+ 
+-	skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
++	skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
+ 	if (skb == NULL) {
+ 		ip_rt_put(rt);
+ 		return -1;
+diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
+index 89dee43..ed45037 100644
+--- a/net/ipv4/ipconfig.c
++++ b/net/ipv4/ipconfig.c
+@@ -710,14 +710,14 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
+ 	struct net_device *dev = d->dev;
+ 	struct sk_buff *skb;
+ 	struct bootp_pkt *b;
+-	int hh_len = LL_RESERVED_SPACE(dev);
+ 	struct iphdr *h;
+ 
+ 	/* Allocate packet */
+-	skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
++	skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
++			GFP_KERNEL);
+ 	if (!skb)
+ 		return;
+-	skb_reserve(skb, hh_len);
++	skb_reserve(skb, LL_RESERVED_SPACE(dev));
+ 	b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
+ 	memset(b, 0, sizeof(struct bootp_pkt));
+ 
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 11d7f75..fead049 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -322,7 +322,6 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
+ 			unsigned int flags)
+ {
+ 	struct inet_sock *inet = inet_sk(sk);
+-	int hh_len;
+ 	struct iphdr *iph;
+ 	struct sk_buff *skb;
+ 	unsigned int iphlen;
+@@ -336,13 +335,12 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
+ 	if (flags&MSG_PROBE)
+ 		goto out;
+ 
+-	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
+-
+-	skb = sock_alloc_send_skb(sk, length+hh_len+15,
+-				  flags&MSG_DONTWAIT, &err);
++	skb = sock_alloc_send_skb(sk,
++				  length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
++				  flags & MSG_DONTWAIT, &err);
+ 	if (skb == NULL)
+ 		goto error;
+-	skb_reserve(skb, hh_len);
++	skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
+ 
+ 	skb->priority = sk->sk_priority;
+ 	skb->mark = sk->sk_mark;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 26c9369..b54d9d3 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -1842,9 +1842,16 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
+ 			TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
+ 		}
+ 
+-		/* Don't lost mark skbs that were fwd transmitted after RTO */
+-		if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) &&
+-		    !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) {
++		/* Marking forward transmissions that were made after RTO lost
++		 * can cause unnecessary retransmissions in some scenarios,
++		 * SACK blocks will mitigate that in some but not in all cases.
++		 * We used to not mark them but it was causing break-ups with
++		 * receivers that do only in-order receival.
++		 *
++		 * TODO: we could detect presence of such receiver and select
++		 * different behavior per flow.
++		 */
++		if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
+ 			TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
+ 			tp->lost_out += tcp_skb_pcount(skb);
+ 		}
+@@ -1860,7 +1867,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
+ 	tp->reordering = min_t(unsigned int, tp->reordering,
+ 			       sysctl_tcp_reordering);
+ 	tcp_set_ca_state(sk, TCP_CA_Loss);
+-	tp->high_seq = tp->frto_highmark;
++	tp->high_seq = tp->snd_nxt;
+ 	TCP_ECN_queue_cwr(tp);
+ 
+ 	tcp_clear_retrans_hints_partial(tp);
+@@ -2482,7 +2489,7 @@ static void tcp_try_to_open(struct sock *sk, int flag)
+ 
+ 	tcp_verify_left_out(tp);
+ 
+-	if (tp->retrans_out == 0)
++	if (!tp->frto_counter && tp->retrans_out == 0)
+ 		tp->retrans_stamp = 0;
+ 
+ 	if (flag & FLAG_ECE)
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 0af2e05..48cdce9 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -780,7 +780,7 @@ slow_path:
+ 		 *	Allocate buffer.
+ 		 */
+ 
+-		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
++		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
+ 			NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
+ 			IP6_INC_STATS(ip6_dst_idev(skb->dst),
+ 				      IPSTATS_MIB_FRAGFAILS);
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 54f91ef..fd632dd 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
+ 		     IPV6_TLV_PADN, 0 };
+ 
+ 	/* we assume size > sizeof(ra) here */
+-	skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err);
++	skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
+ 
+ 	if (!skb)
+ 		return NULL;
+@@ -1790,7 +1790,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
+ 	payload_len = len + sizeof(ra);
+ 	full_len = sizeof(struct ipv6hdr) + payload_len;
+ 
+-	skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
++	skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
+ 
+ 	if (skb == NULL) {
+ 		rcu_read_lock();
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index 2c74885..a55fc05 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -479,7 +479,7 @@ static void __ndisc_send(struct net_device *dev,
+ 
+ 	skb = sock_alloc_send_skb(sk,
+ 				  (MAX_HEADER + sizeof(struct ipv6hdr) +
+-				   len + LL_RESERVED_SPACE(dev)),
++				   len + LL_ALLOCATED_SPACE(dev)),
+ 				  1, &err);
+ 	if (!skb) {
+ 		ND_PRINTK0(KERN_ERR
+@@ -1521,7 +1521,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
+ 
+ 	buff = sock_alloc_send_skb(sk,
+ 				   (MAX_HEADER + sizeof(struct ipv6hdr) +
+-				    len + LL_RESERVED_SPACE(dev)),
++				    len + LL_ALLOCATED_SPACE(dev)),
+ 				   1, &err);
+ 	if (buff == NULL) {
+ 		ND_PRINTK0(KERN_ERR
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 396f0ea..232e0dc 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -609,7 +609,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
+ 	struct ipv6_pinfo *np = inet6_sk(sk);
+ 	struct ipv6hdr *iph;
+ 	struct sk_buff *skb;
+-	unsigned int hh_len;
+ 	int err;
+ 
+ 	if (length > rt->u.dst.dev->mtu) {
+@@ -619,13 +618,12 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
+ 	if (flags&MSG_PROBE)
+ 		goto out;
+ 
+-	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
+-
+-	skb = sock_alloc_send_skb(sk, length+hh_len+15,
+-				  flags&MSG_DONTWAIT, &err);
++	skb = sock_alloc_send_skb(sk,
++				  length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
++				  flags & MSG_DONTWAIT, &err);
+ 	if (skb == NULL)
+ 		goto error;
+-	skb_reserve(skb, hh_len);
++	skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
+ 
+ 	skb->priority = sk->sk_priority;
+ 	skb->mark = sk->sk_mark;
+diff --git a/net/irda/discovery.c b/net/irda/discovery.c
+index bfacef8..a6f99b5 100644
+--- a/net/irda/discovery.c
++++ b/net/irda/discovery.c
+@@ -40,6 +40,8 @@
+ 
+ #include <net/irda/discovery.h>
+ 
++#include <asm/unaligned.h>
++
+ /*
+  * Function irlmp_add_discovery (cachelog, discovery)
+  *
+@@ -87,7 +89,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
+ 			 */
+ 			hashbin_remove_this(cachelog, (irda_queue_t *) node);
+ 			/* Check if hints bits are unchanged */
+-			if(u16ho(node->data.hints) == u16ho(new->data.hints))
++			if (get_unaligned((__u16 *)node->data.hints) == get_unaligned((__u16 *)new->data.hints))
+ 				/* Set time of first discovery for this node */
+ 				new->firststamp = node->firststamp;
+ 			kfree(node);
+@@ -281,9 +283,9 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
+ 		/* Mask out the ones we don't want :
+ 		 * We want to match the discovery mask, and to get only
+ 		 * the most recent one (unless we want old ones) */
+-		if ((u16ho(discovery->data.hints) & mask) &&
++		if ((get_unaligned((__u16 *)discovery->data.hints) & mask) &&
+ 		    ((old_entries) ||
+-		     ((jiffies - discovery->firststamp) < j_timeout)) ) {
++		     ((jiffies - discovery->firststamp) < j_timeout))) {
+ 			/* Create buffer as needed.
+ 			 * As this function get called a lot and most time
+ 			 * we don't have anything to put in the log (we are
+diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
+index 1f81f8e..7bf5b91 100644
+--- a/net/irda/irlmp.c
++++ b/net/irda/irlmp.c
+@@ -1062,7 +1062,8 @@ void irlmp_discovery_expiry(discinfo_t *expiries, int number)
+ 		for(i = 0; i < number; i++) {
+ 			/* Check if we should notify client */
+ 			if ((client->expir_callback) &&
+-			    (client->hint_mask.word & u16ho(expiries[i].hints)
++			    (client->hint_mask.word &
++			     get_unaligned((__u16 *)expiries[i].hints)
+ 			     & 0x7f7f) )
+ 				client->expir_callback(&(expiries[i]),
+ 						       EXPIRY_TIMEOUT,
+@@ -1086,7 +1087,7 @@ discovery_t *irlmp_get_discovery_response(void)
+ 
+ 	IRDA_ASSERT(irlmp != NULL, return NULL;);
+ 
+-	u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
++	put_unaligned(irlmp->hints.word, (__u16 *)irlmp->discovery_rsp.data.hints);
+ 
+ 	/*
+ 	 *  Set character set for device name (we use ASCII), and
+diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
+index 75497e5..cf9a4b5 100644
+--- a/net/irda/irnet/irnet_irda.c
++++ b/net/irda/irnet/irnet_irda.c
+@@ -10,6 +10,7 @@
+ 
+ #include "irnet_irda.h"		/* Private header */
+ #include <linux/seq_file.h>
++#include <asm/unaligned.h>
+ 
+ /*
+  * PPP disconnect work: we need to make sure we're in
+@@ -1673,7 +1674,7 @@ irnet_discovery_indication(discinfo_t *		discovery,
+   /* Notify the control channel */
+   irnet_post_event(NULL, IRNET_DISCOVER,
+ 		   discovery->saddr, discovery->daddr, discovery->info,
+-		   u16ho(discovery->hints));
++		   get_unaligned((__u16 *)discovery->hints));
+ 
+   DEXIT(IRDA_OCB_TRACE, "\n");
+ }
+@@ -1704,7 +1705,7 @@ irnet_expiry_indication(discinfo_t *	expiry,
+   /* Notify the control channel */
+   irnet_post_event(NULL, IRNET_EXPIRE,
+ 		   expiry->saddr, expiry->daddr, expiry->info,
+-		   u16ho(expiry->hints));
++		   get_unaligned((__u16 *)expiry->hints));
+ 
+   DEXIT(IRDA_OCB_TRACE, "\n");
+ }
+diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
+index 879e721..19efc3a 100644
+--- a/net/mac80211/debugfs_key.c
++++ b/net/mac80211/debugfs_key.c
+@@ -255,14 +255,23 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
+ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
+ {
+ 	char buf[50];
++	struct ieee80211_key *key;
+ 
+ 	if (!sdata->debugfsdir)
+ 		return;
+ 
+-	sprintf(buf, "../keys/%d", sdata->default_key->debugfs.cnt);
+-	sdata->debugfs.default_key =
+-		debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
++	/* this is running under the key lock */
++
++	key = sdata->default_key;
++	if (key) {
++		sprintf(buf, "../keys/%d", key->debugfs.cnt);
++		sdata->debugfs.default_key =
++			debugfs_create_symlink("default_key",
++					       sdata->debugfsdir, buf);
++	} else
++		ieee80211_debugfs_key_remove_default(sdata);
+ }
++
+ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
+ {
+ 	if (!sdata)
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 80954a5..06e88a5 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -54,6 +54,15 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
+ 	if (!ndev)
+ 		return -ENOMEM;
+ 
++	ndev->needed_headroom = local->tx_headroom +
++				4*6 /* four MAC addresses */
++				+ 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
++				+ 6 /* mesh */
++				+ 8 /* rfc1042/bridge tunnel */
++				- ETH_HLEN /* ethernet hard_header_len */
++				+ IEEE80211_ENCRYPT_HEADROOM;
++	ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
++
+ 	ret = dev_alloc_name(ndev, ndev->name);
+ 	if (ret < 0)
+ 		goto fail;
+diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
+index f76bc26..697ef67 100644
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -397,7 +397,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
+ 	put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum);
+ 	sdata->u.sta.mesh_seqnum++;
+ 
+-	return 5;
++	return 6;
+ }
+ 
+ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
+diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
+index 3df8092..af0cd1e 100644
+--- a/net/mac80211/mesh_hwmp.c
++++ b/net/mac80211/mesh_hwmp.c
+@@ -120,7 +120,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
+ 		*pos++ = WLAN_EID_PREP;
+ 		break;
+ 	default:
+-		kfree(skb);
++		kfree_skb(skb);
+ 		return -ENOTSUPP;
+ 		break;
+ 	}
+diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
+index 5845dc2..99c2d36 100644
+--- a/net/mac80211/mesh_pathtbl.c
++++ b/net/mac80211/mesh_pathtbl.c
+@@ -158,19 +158,25 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
+ 	if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
+ 		return -ENOSPC;
+ 
+-	read_lock(&pathtbl_resize_lock);
+-
+ 	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
+ 	if (!new_mpath) {
+ 		atomic_dec(&sdata->u.sta.mpaths);
+ 		err = -ENOMEM;
+ 		goto endadd2;
+ 	}
++	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
++	if (!new_node) {
++		kfree(new_mpath);
++		atomic_dec(&sdata->u.sta.mpaths);
++		err = -ENOMEM;
++		goto endadd2;
++	}
++
++	read_lock(&pathtbl_resize_lock);
+ 	memcpy(new_mpath->dst, dst, ETH_ALEN);
+ 	new_mpath->dev = dev;
+ 	new_mpath->flags = 0;
+ 	skb_queue_head_init(&new_mpath->frame_queue);
+-	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+ 	new_node->mpath = new_mpath;
+ 	new_mpath->timer.data = (unsigned long) new_mpath;
+ 	new_mpath->timer.function = mesh_path_timer;
+@@ -202,7 +208,6 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
+ 
+ endadd:
+ 	spin_unlock(&mesh_paths->hashwlock[hash_idx]);
+-endadd2:
+ 	read_unlock(&pathtbl_resize_lock);
+ 	if (!err && grow) {
+ 		struct mesh_table *oldtbl, *newtbl;
+@@ -215,10 +220,12 @@ endadd2:
+ 			return -ENOMEM;
+ 		}
+ 		rcu_assign_pointer(mesh_paths, newtbl);
++		write_unlock(&pathtbl_resize_lock);
++
+ 		synchronize_rcu();
+ 		mesh_table_free(oldtbl, false);
+-		write_unlock(&pathtbl_resize_lock);
+ 	}
++endadd2:
+ 	return err;
+ }
+ 
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index a5e5c31..4adba09 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -665,6 +665,26 @@ static void ieee80211_authenticate(struct net_device *dev,
+ 	mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
+ }
+ 
++static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
++				      struct ieee80211_supported_band *sband,
++				      u64 *rates)
++{
++	int i, j, count;
++	*rates = 0;
++	count = 0;
++	for (i = 0; i < bss->supp_rates_len; i++) {
++		int rate = (bss->supp_rates[i] & 0x7F) * 5;
++
++		for (j = 0; j < sband->n_bitrates; j++)
++			if (sband->bitrates[j].bitrate == rate) {
++				*rates |= BIT(j);
++				count++;
++				break;
++			}
++	}
++
++	return count;
++}
+ 
+ static void ieee80211_send_assoc(struct net_device *dev,
+ 				 struct ieee80211_if_sta *ifsta)
+@@ -673,11 +693,12 @@ static void ieee80211_send_assoc(struct net_device *dev,
+ 	struct sk_buff *skb;
+ 	struct ieee80211_mgmt *mgmt;
+ 	u8 *pos, *ies;
+-	int i, len;
++	int i, len, count, rates_len, supp_rates_len;
+ 	u16 capab;
+ 	struct ieee80211_sta_bss *bss;
+ 	int wmm = 0;
+ 	struct ieee80211_supported_band *sband;
++	u64 rates = 0;
+ 
+ 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ 			    sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
+@@ -740,24 +761,39 @@ static void ieee80211_send_assoc(struct net_device *dev,
+ 	*pos++ = ifsta->ssid_len;
+ 	memcpy(pos, ifsta->ssid, ifsta->ssid_len);
+ 
++	/* all supported rates should be added here but some APs
++	 * (e.g. D-Link DAP 1353 in b-only mode) don't like that
++	 * Therefore only add rates the AP supports */
++	rates_len = ieee80211_compatible_rates(bss, sband, &rates);
++	supp_rates_len = rates_len;
++	if (supp_rates_len > 8)
++		supp_rates_len = 8;
++
+ 	len = sband->n_bitrates;
+-	if (len > 8)
+-		len = 8;
+-	pos = skb_put(skb, len + 2);
++	pos = skb_put(skb, supp_rates_len + 2);
+ 	*pos++ = WLAN_EID_SUPP_RATES;
+-	*pos++ = len;
+-	for (i = 0; i < len; i++) {
+-		int rate = sband->bitrates[i].bitrate;
+-		*pos++ = (u8) (rate / 5);
+-	}
++	*pos++ = supp_rates_len;
+ 
+-	if (sband->n_bitrates > len) {
+-		pos = skb_put(skb, sband->n_bitrates - len + 2);
+-		*pos++ = WLAN_EID_EXT_SUPP_RATES;
+-		*pos++ = sband->n_bitrates - len;
+-		for (i = len; i < sband->n_bitrates; i++) {
++	count = 0;
++	for (i = 0; i < sband->n_bitrates; i++) {
++		if (BIT(i) & rates) {
+ 			int rate = sband->bitrates[i].bitrate;
+ 			*pos++ = (u8) (rate / 5);
++			if (++count == 8)
++				break;
++		}
++	}
++
++	if (count == 8) {
++		pos = skb_put(skb, rates_len - count + 2);
++		*pos++ = WLAN_EID_EXT_SUPP_RATES;
++		*pos++ = rates_len - count;
++
++		for (i++; i < sband->n_bitrates; i++) {
++			if (BIT(i) & rates) {
++				int rate = sband->bitrates[i].bitrate;
++				*pos++ = (u8) (rate / 5);
++			}
+ 		}
+ 	}
+ 
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 02f436a..1958bfb 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1305,11 +1305,11 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
+ 		if (is_multicast_ether_addr(skb->data)) {
+ 			if (*mesh_ttl > 0) {
+ 				xmit_skb = skb_copy(skb, GFP_ATOMIC);
+-				if (!xmit_skb && net_ratelimit())
++				if (xmit_skb)
++					xmit_skb->pkt_type = PACKET_OTHERHOST;
++				else if (net_ratelimit())
+ 					printk(KERN_DEBUG "%s: failed to clone "
+ 					       "multicast frame\n", dev->name);
+-				else
+-					xmit_skb->pkt_type = PACKET_OTHERHOST;
+ 			} else
+ 				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta,
+ 							     dropped_frames_ttl);
+@@ -1395,7 +1395,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
+ 		padding = ((4 - subframe_len) & 0x3);
+ 		/* the last MSDU has no padding */
+ 		if (subframe_len > remaining) {
+-			printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
++			printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name);
+ 			return RX_DROP_UNUSABLE;
+ 		}
+ 
+@@ -1418,7 +1418,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
+ 			eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
+ 							padding);
+ 			if (!eth) {
+-				printk(KERN_DEBUG "%s: wrong buffer size ",
++				printk(KERN_DEBUG "%s: wrong buffer size\n",
+ 				       dev->name);
+ 				dev_kfree_skb(frame);
+ 				return RX_DROP_UNUSABLE;
+@@ -1952,7 +1952,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+ 		if (!skb_new) {
+ 			if (net_ratelimit())
+ 				printk(KERN_DEBUG "%s: failed to copy "
+-				       "multicast frame for %s",
++				       "multicast frame for %s\n",
+ 				       wiphy_name(local->hw.wiphy),
+ 				       prev->dev->name);
+ 			continue;
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index f35eaea..1d7dd54 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1562,13 +1562,13 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 	 * be cloned. This could happen, e.g., with Linux bridge code passing
+ 	 * us broadcast frames. */
+ 
+-	if (head_need > 0 || skb_cloned(skb)) {
++	if (head_need > 0 || skb_header_cloned(skb)) {
+ #if 0
+ 		printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes "
+ 		       "of headroom\n", dev->name, head_need);
+ #endif
+ 
+-		if (skb_cloned(skb))
++		if (skb_header_cloned(skb))
+ 			I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
+ 		else
+ 			I802_DEBUG_INC(local->tx_expand_skb_head);
+@@ -1898,6 +1898,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
+ 			control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
+ 		control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
+ 		control->flags |= IEEE80211_TXCTL_NO_ACK;
++		control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+ 		control->retry_limit = 1;
+ 		control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
+ 	}
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index cc9f715..24a465c 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -153,15 +153,15 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
+ 	/* 7.1.3.5a.2 */
+ 	switch (ae) {
+ 	case 0:
+-		return 5;
++		return 6;
+ 	case 1:
+-		return 11;
++		return 12;
+ 	case 2:
+-		return 17;
++		return 18;
+ 	case 3:
+-		return 23;
++		return 24;
+ 	default:
+-		return 5;
++		return 6;
+ 	}
+ }
+ 
+diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
+index 64faa3d..dc1598b 100644
+--- a/net/mac80211/wme.c
++++ b/net/mac80211/wme.c
+@@ -394,7 +394,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
+ 						 qd->handle);
+ 		if (!q->queues[i]) {
+ 			q->queues[i] = &noop_qdisc;
+-			printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i);
++			printk(KERN_ERR "%s child qdisc %i creation failed\n",
++			       dev->name, i);
+ 		}
+ 	}
+ 
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 16774ec..0edefcf 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -472,6 +472,9 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
+ 		goto nla_put_failure;
+ 	nla_nest_end(skb, nest_parms);
+ 
++	if (ctnetlink_dump_id(skb, ct) < 0)
++		goto nla_put_failure;
++
+ 	if (events & IPCT_DESTROY) {
+ 		if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
+ 		    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
+diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
+index 500528d..c63e933 100644
+--- a/net/netfilter/xt_iprange.c
++++ b/net/netfilter/xt_iprange.c
+@@ -179,3 +179,5 @@ module_exit(iprange_mt_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>, Jan Engelhardt <jengelh at computergmbh.de>");
+ MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
++MODULE_ALIAS("ipt_iprange");
++MODULE_ALIAS("ip6t_iprange");
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 2507024..2cee87d 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -743,7 +743,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
+ 	if (len > dev->mtu+reserve)
+ 		goto out_unlock;
+ 
+-	skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev),
++	skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
+ 				msg->msg_flags & MSG_DONTWAIT, &err);
+ 	if (skb==NULL)
+ 		goto out_unlock;
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 81b6064..bbc7107 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -2418,7 +2418,8 @@ static int sctp_process_param(struct sctp_association *asoc,
+ 				break;
+ 
+ 			case SCTP_PARAM_IPV6_ADDRESS:
+-				asoc->peer.ipv6_address = 1;
++				if (PF_INET6 == asoc->base.sk->sk_family)
++					asoc->peer.ipv6_address = 1;
+ 				break;
+ 
+ 			case SCTP_PARAM_HOST_NAME_ADDRESS:
+@@ -2829,6 +2830,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
+ 	addr_param = (union sctp_addr_param *)
+ 			((void *)asconf_param + sizeof(sctp_addip_param_t));
+ 
++	switch (addr_param->v4.param_hdr.type) {
++	case SCTP_PARAM_IPV6_ADDRESS:
++		if (!asoc->peer.ipv6_address)
++			return SCTP_ERROR_INV_PARAM;
++		break;
++	case SCTP_PARAM_IPV4_ADDRESS:
++		if (!asoc->peer.ipv4_address)
++			return SCTP_ERROR_INV_PARAM;
++		break;
++	default:
++		return SCTP_ERROR_INV_PARAM;
++	}
++
+ 	af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
+ 	if (unlikely(!af))
+ 		return SCTP_ERROR_INV_PARAM;
+diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
+index 09cd9c0..3f964db 100644
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -25,11 +25,11 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
+ 	struct dst_entry *dst = skb->dst;
+ 	int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
+ 		- skb_headroom(skb);
++	int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
+ 
+-	if (nhead > 0)
+-		return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
++	if (nhead > 0 || ntail > 0)
++		return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
+ 
+-	/* Check tail too... */
+ 	return 0;
+ }
+ 
+diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
+index 630684f..09b1661 100644
+--- a/sound/soc/codecs/tlv320aic3x.c
++++ b/sound/soc/codecs/tlv320aic3x.c
+@@ -539,8 +539,8 @@ static const char *intercon[][3] = {
+ 	{"HPRCOM", NULL, "Right HP Com"},
+ 
+ 	/* Mono Output */
+-	{"MONOLOUT", NULL, "Mono Out"},
+-	{"MONOLOUT", NULL, "Mono Out"},
++	{"MONO_LOUT", NULL, "Mono Out"},
++	{"MONO_LOUT", NULL, "Mono Out"},
+ 
+ 	/* Left Input */
+ 	{"Left Line1L Mux", "single-ended", "LINE1L"},
+diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
+index b2a11b0..f588545 100644
+--- a/sound/soc/fsl/fsl_ssi.c
++++ b/sound/soc/fsl/fsl_ssi.c
+@@ -416,7 +416,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
+ 			 * to put data into its FIFO.  Without it, ALSA starts
+ 			 * to complain about overruns.
+ 			 */
+-			msleep(1);
++			mdelay(1);
+ 		}
+ 		break;
+ 
+diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
+index 83b1eb4..6533563 100644
+--- a/sound/soc/omap/n810.c
++++ b/sound/soc/omap/n810.c
+@@ -188,8 +188,8 @@ static const char *audio_map[][3] = {
+ static const char *spk_function[] = {"Off", "On"};
+ static const char *jack_function[] = {"Off", "Headphone"};
+ static const struct soc_enum n810_enum[] = {
+-	SOC_ENUM_SINGLE_EXT(2, spk_function),
+-	SOC_ENUM_SINGLE_EXT(3, jack_function),
++	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
++	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
+ };
+ 
+ static const struct snd_kcontrol_new aic33_n810_controls[] = {
+diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
+index 478369b..b343818 100644
+--- a/sound/synth/emux/emux_synth.c
++++ b/sound/synth/emux/emux_synth.c
+@@ -341,8 +341,12 @@ snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
+ 	case MIDI_CTL_SOFT_PEDAL:
+ #ifdef SNDRV_EMUX_USE_RAW_EFFECT
+ 		/* FIXME: this is an emulation */
+-		snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
++		if (chan->control[type] >= 64)
++			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
+ 				     EMUX_FX_FLAG_ADD);
++		else
++			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
++				     EMUX_FX_FLAG_OFF);
+ #endif
+ 		break;
+ 

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Thu May 15 10:10:41 2008
@@ -1,4 +1,4 @@
-+ bugfix/all/patch-2.6.26-rc2-git2
++ bugfix/all/patch-2.6.26-rc2-git4
 + debian/version.patch
 + debian/kernelvariables.patch
 + debian/doc-build-parallel.patch
@@ -23,7 +23,7 @@
 + bugfix/arm/disable-dvb_budget.patch
 + bugfix/arm/disable-netxen_nic.patch
 + bugfix/arm/disable-chelsio_t3.patch
-+ bugfix/arm/disable-video_bt848.patch
+#+ bugfix/arm/disable-video_bt848.patch
 + bugfix/arm/disable-scsi_acard.patch
 + bugfix/arm/disable-ath5k.patch
 + bugfix/arm/disable-r6040.patch
@@ -31,10 +31,6 @@
 + features/arm/cache-align2.patch
 + features/arm/speed_flush_cache.patch
 + features/arm/5281d0.patch
-+ features/all/drivers-net-atl1-PHY-power-save-mode.patch
-+ features/all/drivers-net-atl1-suspend-resume.patch
-+ features/all/drivers-net-atl1-shutdown-callback.patch
-+ features/all/drivers-net-atl1-version.patch
 + features/all/at76.patch 
 + bugfix/fix-hifn_795X-divdi3.patch
 + bugfix/all/mtd-prevent-physmap-from-causing-request_module-runaway-loop-modprobe-net-pf-1.patch



More information about the Kernel-svn-changes mailing list