diff --git a/CREDITS b/CREDITS
index 9bd099d960f38b8d6ba4a61cec7f8dccf53f2c00..d65ffe5a4d0803c59159592b258f0dfc049ec8d3 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2475,13 +2475,9 @@ S: Potsdam, New York 13676
 S: USA
 
 N: Dave Neuer
-E: dneuer@innovation-charter.com
-E: mr_fred_smoothie@yahoo.com
+E: dave.neuer@pobox.com
 D: Helped implement support for Compaq's H31xx series iPAQs
 D: Other mostly minor tweaks & bugfixes
-S: 325 E. Main St., Suite 3
-S: Carnegie, PA 15105
-S: USA
 
 N: Michael Neuffer
 E: mike@i-Connect.Net
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index cf2fce7707da202e7f408f40929dde7255cf742e..6df1dfd18b651fce1224fe0e127cf7e777981d34 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -14,7 +14,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2003</year>
+   <year>2003-2005</year>
    <holder>Jeff Garzik</holder>
   </copyright>
 
@@ -44,30 +44,38 @@
 
 <toc></toc>
 
-  <chapter id="libataThanks">
-     <title>Thanks</title>
+  <chapter id="libataIntroduction">
+     <title>Introduction</title>
   <para>
-  The bulk of the ATA knowledge comes thanks to long conversations with
-  Andre Hedrick (www.linux-ide.org).
+  libATA is a library used inside the Linux kernel to support ATA host
+  controllers and devices.  libATA provides an ATA driver API, class
+  transports for ATA and ATAPI devices, and SCSI&lt;-&gt;ATA translation
+  for ATA devices according to the T10 SAT specification.
   </para>
   <para>
-  Thanks to Alan Cox for pointing out similarities 
-  between SATA and SCSI, and in general for motivation to hack on
-  libata.
-  </para>
-  <para>
-  libata's device detection
-  method, ata_pio_devchk, and in general all the early probing was
-  based on extensive study of Hale Landis's probe/reset code in his
-  ATADRVR driver (www.ata-atapi.com).
+  This Guide documents the libATA driver API, library functions, library
+  internals, and a couple sample ATA low-level drivers.
   </para>
   </chapter>
 
   <chapter id="libataDriverApi">
      <title>libata Driver API</title>
+     <para>
+     struct ata_port_operations is defined for every low-level libata
+     hardware driver, and it controls how the low-level driver
+     interfaces with the ATA and SCSI layers.
+     </para>
+     <para>
+     FIS-based drivers will hook into the system with ->qc_prep() and
+     ->qc_issue() high-level hooks.  Hardware which behaves in a manner
+     similar to PCI IDE hardware may utilize several generic helpers,
+     defining at a bare minimum the bus I/O addresses of the ATA shadow
+     register blocks.
+     </para>
      <sect1>
         <title>struct ata_port_operations</title>
 
+	<sect2><title>Disable ATA port</title>
 	<programlisting>
 void (*port_disable) (struct ata_port *);
 	</programlisting>
@@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *);
 	unplug).
 	</para>
 
+	</sect2>
+
+	<sect2><title>Post-IDENTIFY device configuration</title>
 	<programlisting>
 void (*dev_config) (struct ata_port *, struct ata_device *);
 	</programlisting>
@@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Set PIO/DMA mode</title>
 	<programlisting>
 void (*set_piomode) (struct ata_port *, struct ata_device *);
 void (*set_dmamode) (struct ata_port *, struct ata_device *);
@@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap);
 	->set_dma_mode() is only called if DMA is possible.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Taskfile read/write</title>
 	<programlisting>
 void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
 	taskfile register values.
 	</para>
 
+	</sect2>
+
+	<sect2><title>ATA command execute</title>
 	<programlisting>
 void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	</programlisting>
@@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	->tf_load(), to be initiated in hardware.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Per-cmd ATAPI DMA capabilities filter</title>
+	<programlisting>
+int (*check_atapi_dma) (struct ata_queued_cmd *qc);
+	</programlisting>
+
+	<para>
+Allow low-level driver to filter ATA PACKET commands, returning a status
+indicating whether or not it is OK to use DMA for the supplied PACKET
+command.
+	</para>
+
+	</sect2>
+
+	<sect2><title>Read specific ATA shadow registers</title>
 	<programlisting>
 u8   (*check_status)(struct ata_port *ap);
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*check_err)(struct ata_port *ap);
 	</programlisting>
 
 	<para>
-	Reads the Status ATA shadow register from hardware.  On some
-	hardware, this has the side effect of clearing the interrupt
-	condition.
+	Reads the Status/AltStatus/Error ATA shadow register from
+	hardware.  On some hardware, reading the Status register has
+	the side effect of clearing the interrupt condition.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Select ATA device on bus</title>
 	<programlisting>
 void (*dev_select)(struct ata_port *ap, unsigned int device);
 	</programlisting>
@@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
 	<para>
 	Issues the low-level hardware command(s) that causes one of N
 	hardware devices to be considered 'selected' (active and
-	available for use) on the ATA bus.
+	available for use) on the ATA bus.  This generally has no
+meaning on FIS-based devices.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Reset ATA bus</title>
 	<programlisting>
 void (*phy_reset) (struct ata_port *ap);
 	</programlisting>
@@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap);
 	functions ata_bus_reset() or sata_phy_reset() for this hook.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Control PCI IDE BMDMA engine</title>
 	<programlisting>
 void (*bmdma_setup) (struct ata_queued_cmd *qc);
 void (*bmdma_start) (struct ata_queued_cmd *qc);
+void (*bmdma_stop) (struct ata_port *ap);
+u8   (*bmdma_status) (struct ata_port *ap);
 	</programlisting>
 
 	<para>
-	When setting up an IDE BMDMA transaction, these hooks arm
-	(->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
-	engine.
+When setting up an IDE BMDMA transaction, these hooks arm
+(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop)
+the hardware's DMA engine.  ->bmdma_status is used to read the standard
+PCI IDE DMA Status register.
 	</para>
 
+	<para>
+These hooks are typically either no-ops, or simply not implemented, in
+FIS-based drivers.
+	</para>
+
+	</sect2>
+
+	<sect2><title>High-level taskfile hooks</title>
 	<programlisting>
 void (*qc_prep) (struct ata_queued_cmd *qc);
 int (*qc_issue) (struct ata_queued_cmd *qc);
@@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
 	->qc_issue is used to make a command active, once the hardware
 	and S/G tables have been prepared.  IDE BMDMA drivers use the
 	helper function ata_qc_issue_prot() for taskfile protocol-based
-	dispatch.  More advanced drivers roll their own ->qc_issue
-	implementation, using this as the "issue new ATA command to
-	hardware" hook.
+	dispatch.  More advanced drivers implement their own ->qc_issue.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Timeout (error) handling</title>
 	<programlisting>
 void (*eng_timeout) (struct ata_port *ap);
 	</programlisting>
 
 	<para>
-	This is a high level error handling function, called from the
-	error handling thread, when a command times out.
+This is a high level error handling function, called from the
+error handling thread, when a command times out.  Most newer
+hardware will implement its own error handling code here.  IDE BMDMA
+drivers may use the helper function ata_eng_timeout().
 	</para>
 
+	</sect2>
+
+	<sect2><title>Hardware interrupt handling</title>
 	<programlisting>
 irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
 void (*irq_clear) (struct ata_port *);
@@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *);
 	is quiet.
 	</para>
 
+	</sect2>
+
+	<sect2><title>SATA phy read/write</title>
 	<programlisting>
 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
 	if ->phy_reset hook called the sata_phy_reset() helper function.
 	</para>
 
+	</sect2>
+
+	<sect2><title>Init and shutdown</title>
 	<programlisting>
 int (*port_start) (struct ata_port *ap);
 void (*port_stop) (struct ata_port *ap);
@@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set);
 	tasks.  
 	</para>
 	<para>
-	->host_stop() is called when the rmmod or hot unplug process
-	begins.  The hook must stop all hardware interrupts, DMA
-	engines, etc.
-	</para>
-	<para>
 	->port_stop() is called after ->host_stop().  It's sole function
 	is to release DMA/memory resources, now that they are no longer
 	actively being used.
 	</para>
+	<para>
+	->host_stop() is called after all ->port_stop() calls
+have completed.  The hook must finalize hardware shutdown, release DMA
+and other resources, etc.
+	</para>
+
+	</sect2>
 
      </sect1>
   </chapter>
@@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set);
 !Idrivers/scsi/sata_sil.c
   </chapter>
 
+  <chapter id="libataThanks">
+     <title>Thanks</title>
+  <para>
+  The bulk of the ATA knowledge comes thanks to long conversations with
+  Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
+  and SCSI specifications.
+  </para>
+  <para>
+  Thanks to Alan Cox for pointing out similarities 
+  between SATA and SCSI, and in general for motivation to hack on
+  libata.
+  </para>
+  <para>
+  libata's device detection
+  method, ata_pio_devchk, and in general all the early probing was
+  based on extensive study of Hale Landis's probe/reset code in his
+  ATADRVR driver (www.ata-atapi.com).
+  </para>
+  </chapter>
+
 </book>
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 9838d32b2fe70ac6cff1f1b6cd03785af00cab3b..4d35562b1cf976d7f63f7f555440686e44ae5db4 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -271,7 +271,7 @@ patch, which certifies that you wrote it or otherwise have the right to
 pass it on as a open-source patch.  The rules are pretty simple: if you
 can certify the below:
 
-        Developer's Certificate of Origin 1.0
+        Developer's Certificate of Origin 1.1
 
         By making a contribution to this project, I certify that:
 
@@ -291,6 +291,12 @@ can certify the below:
             person who certified (a), (b) or (c) and I have not modified
             it.
 
+	(d) I understand and agree that this project and the contribution
+	    are public and that a record of the contribution (including all
+	    personal information I submit with it, including my sign-off) is
+	    maintained indefinitely and may be redistributed consistent with
+	    this project or the open source license(s) involved.
+
 then you just add a line saying
 
 	Signed-off-by: Random J Developer <random@developer.org>
diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt
index fa12a9e4abdd2a4f23075c48ba8652c21cea27d1..80e1cb19609f552e958f7bd2259279e1a678e1cd 100644
--- a/Documentation/networking/vortex.txt
+++ b/Documentation/networking/vortex.txt
@@ -12,7 +12,7 @@ Don is no longer the prime maintainer of this version of the driver.
 Please report problems to one or more of:
 
   Andrew Morton <andrewm@uow.edu.au>
-  Netdev mailing list <netdev@oss.sgi.com>
+  Netdev mailing list <netdev@vger.kernel.org>
   Linux kernel mailing list <linux-kernel@vger.kernel.org>
 
 Please note the 'Reporting and Diagnosing Problems' section at the end
diff --git a/MAINTAINERS b/MAINTAINERS
index 65ad8251e4bc51a19acd189f425a346c31218296..86ba94f16e83082be25974bdfb859660e5686a6c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -73,7 +73,7 @@ S: Status, one of the following:
 3C359 NETWORK DRIVER
 P:	Mike Phillips
 M:	mikep@linuxtr.net
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
 S:	Maintained
@@ -81,13 +81,13 @@ S:	Maintained
 3C505 NETWORK DRIVER
 P:	Philip Blundell
 M:	philb@gnu.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 3CR990 NETWORK DRIVER
 P:	David Dillow
 M:	dave@thedillows.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 3W-XXXX ATA-RAID CONTROLLER DRIVER
@@ -130,7 +130,7 @@ S:	Maintained
 8169 10/100/1000 GIGABIT ETHERNET DRIVER
 P:	Francois Romieu
 M:	romieu@fr.zoreil.com
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
@@ -143,7 +143,7 @@ S:	Maintained
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 P:	Paul Gortmaker
 M:	p_gortmaker@yahoo.com
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 A2232 SERIAL BOARD DRIVER
@@ -332,7 +332,7 @@ S:	Maintained
 
 ARPD SUPPORT
 P:	Jonathan Layes
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 ASUS ACPI EXTRAS DRIVER
@@ -706,7 +706,7 @@ S:	Orphaned
 
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:	Rick Richardson
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 W:	http://www.digi.com
 S:	Orphaned
 
@@ -812,7 +812,7 @@ S:	Maintained
 ETHEREXPRESS-16 NETWORK DRIVER
 P:	Philip Blundell
 M:	philb@gnu.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 ETHERNET BRIDGE
@@ -875,7 +875,7 @@ S:	Maintained
 FRAME RELAY DLCI/FRAD (Sangoma drivers too)
 P:	Mike McLagan
 M:	mike.mclagan@linux.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 FREEVXFS FILESYSTEM
@@ -1215,7 +1215,7 @@ S:	Maintained
 IPX NETWORK LAYER
 P:	Arnaldo Carvalho de Melo
 M:	acme@conectiva.com.br
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 IRDA SUBSYSTEM
@@ -1482,7 +1482,7 @@ MARVELL MV64340 ETHERNET DRIVER
 P:	Manish Lachwani
 M:	Manish_Lachwani@pmc-sierra.com
 L:	linux-mips@linux-mips.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Supported
 
 MATROX FRAMEBUFFER DRIVER
@@ -1592,13 +1592,13 @@ P:	Andrew Morton
 M:	akpm@osdl.org
 P:	Jeff Garzik
 M:	jgarzik@pobox.com
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 NETWORKING [GENERAL]
 P:	Networking Team
-M:	netdev@oss.sgi.com
-L:	netdev@oss.sgi.com
+M:	netdev@vger.kernel.org
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 NETWORKING [IPv4/IPv6]
@@ -1614,7 +1614,7 @@ P:	Hideaki YOSHIFUJI
 M:	yoshfuji@linux-ipv6.org
 P:	Patrick McHardy
 M:	kaber@coreworks.de
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 IPVS
@@ -1634,7 +1634,7 @@ NI5010 NETWORK DRIVER
 P:	Jan-Pascal van Best and Andreas Mohr
 M:	Jan-Pascal van Best <jvbest@qv3pluto.leidenuniv.nl>
 M:	Andreas Mohr <100.30936@germany.net>
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
@@ -1676,7 +1676,7 @@ P:	Peter De Shrijver
 M:	p2@ace.ulyssis.student.kuleuven.ac.be
 P:	Mike Phillips
 M:	mikep@linuxtr.net 
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
 S:	Maintained
@@ -1783,7 +1783,7 @@ S:	Unmaintained
 PCNET32 NETWORK DRIVER
 P:	Thomas Bogendörfer
 M:	tsbogend@alpha.franken.de
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 PHRAM MTD DRIVER
@@ -1795,7 +1795,7 @@ S:	Maintained
 POSIX CLOCKS and TIMERS
 P:	George Anzinger
 M:	george@mvista.com
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Supported
 
 PNP SUPPORT
@@ -1830,7 +1830,7 @@ S:	Supported
 PRISM54 WIRELESS DRIVER
 P:	Prism54 Development Team
 M:	prism54-private@prism54.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 W:	http://prism54.org
 S:	Maintained
 
@@ -2047,7 +2047,7 @@ SIS 900/7016 FAST ETHERNET DRIVER
 P:	Daniele Venzano
 M:	venza@brownhat.org
 W:	http://www.brownhat.org/sis900.html
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 SIS FRAMEBUFFER DRIVER
@@ -2106,7 +2106,7 @@ S:	Maintained
 SONIC NETWORK DRIVER
 P:	Thomas Bogendoerfer
 M:	tsbogend@alpha.franken.de
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Maintained
 
 SONY VAIO CONTROL DEVICE DRIVER
@@ -2163,7 +2163,7 @@ S:	Supported
 SPX NETWORK LAYER
 P:	Jay Schulist
 M:	jschlst@samba.org
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 S:	Supported
 
 SRM (Alpha) environment access
@@ -2242,7 +2242,7 @@ S:	Maintained
 TOKEN-RING NETWORK DRIVER
 P:	Mike Phillips
 M:	mikep@linuxtr.net
-L:	netdev@oss.sgi.com
+L:	netdev@vger.kernel.org
 L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
 S:	Maintained
diff --git a/Makefile b/Makefile
index c11a317ea910df5c8456de992ae8f932a102b12b..0d1e74d50067dbce4bd3dc9bcbd7954460b5da61 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 12
-EXTRAVERSION =-rc5
+EXTRAVERSION =
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf397a9f8ac29bf0438234817963075149af7d39..475950c8a8317ec435f441137e4357d35efc93c1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -497,7 +497,7 @@ source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_SA1100
 	bool
-	depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB)
+	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
 	default y
 
 config CPU_FREQ_SA1110
@@ -689,7 +689,9 @@ source "drivers/block/Kconfig"
 
 source "drivers/acorn/block/Kconfig"
 
-if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
+if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
+	|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
 source "drivers/ide/Kconfig"
 endif
 
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 665bd2c2074303d44b7c3593125c7659cc5258f8..d3fe2533907ec1af9c812362eb91802a8af713f4 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -47,3 +47,10 @@ __XScale_start:
                orr     r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
 #endif
 
+#ifdef CONFIG_ARCH_IXP2000
+		mov	r1, #-1
+		mov	r0, #0xd6000000
+		str	r1, [r0, #0x14]
+		str	r1, [r0, #0x18]
+#endif
+
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 2b4059d2f8e457c05af2cba17f060b7dcf252388..5d92af975d870ae59b162d33e7ca49e56cca924d 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sat Mar 26 21:32:26 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 19:00:50 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,6 +134,7 @@ CONFIG_ISA=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -428,7 +433,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=y
+# CONFIG_VIA_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 # CONFIG_BT_SCO is not set
@@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -687,7 +691,6 @@ CONFIG_RTC=m
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m
 #
 CONFIG_USB_STORAGE=y
 CONFIG_USB_STORAGE_DEBUG=y
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -954,9 +958,11 @@ CONFIG_USB_USS720=m
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 # CONFIG_USB_SERIAL_TI is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index b4e297dd54b2286374dfa6814018fb65f03bf2cd..b9de07de80feac1f708039d39940864c5192c94b 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:02:26 2005
+# Linux kernel version: 2.6.12-rc4
+# Thu Jun  9 01:59:03 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 # CONFIG_LEDS is not set
@@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
@@ -379,7 +384,6 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -476,6 +480,7 @@ CONFIG_IRCOMM=m
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 CONFIG_SA1100_FIR=m
+# CONFIG_VIA_FIR is not set
 # CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
@@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 CONFIG_FB_SA1100=y
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index 6987c8c5ddb4ac3fe28f2285f3d7b4e7f235d03f..fb41a36a5a68fe42ce39f08a3367b9abf984ac6b 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Mon Mar 28 00:22:34 2005
+# Linux kernel version: 2.6.12-rc6-git3
+# Thu Jun  9 20:58:58 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y
 # Bus support
 #
 CONFIG_ISA=y
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -128,6 +131,7 @@ CONFIG_ISA=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_DISCONTIGMEM=y
 CONFIG_LEDS=y
@@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=y
 # CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_SA1100=y
 
 #
 # Floating point emulation
@@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
@@ -338,7 +343,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -484,7 +488,6 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 4eb36155dc93fa169b8853a75cd746566a31da49..e14278d59882367dc579f1dabeb5f2d191772ee2 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -269,7 +269,7 @@ __pabt_svc:
 	add	r5, sp, #S_PC
 	ldmia	r7, {r2 - r4}			@ Get USR pc, cpsr
 
-#if __LINUX_ARM_ARCH__ < 6
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 	@ make sure our user space atomic helper is aborted
 	cmp	r2, #VIRT_OFFSET
 	bichs	r3, r3, #PSR_Z_BIT
@@ -616,11 +616,17 @@ __kuser_helper_start:
 
 __kuser_cmpxchg:				@ 0xffff0fc0
 
-#if __LINUX_ARM_ARCH__ < 6
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 
-#ifdef CONFIG_SMP  /* sanity check */
-#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
-#endif
+	/*
+	 * Poor you.  No fast solution possible...
+	 * The kernel itself must perform the operation.
+	 * A special ghost syscall is used for that (see traps.c).
+	 */
+	swi	#0x9ffff0
+	mov	pc, lr
+
+#elif __LINUX_ARM_ARCH__ < 6
 
 	/*
 	 * Theory of operation:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 14df16b983f4ca5c1c08c804ceb3df3659bec34c..45d2a032d8900f4f4f4d12c97ed0da021a4aa233 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -464,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 #endif
 		return 0;
 
+#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
+	/*
+	 * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
+	 * Return zero in r0 if *MEM was changed or non-zero if no exchange
+	 * happened.  Also set the user C flag accordingly.
+	 * If access permissions have to be fixed up then non-zero is
+	 * returned and the operation has to be re-attempted.
+	 *
+	 * *NOTE*: This is a ghost syscall private to the kernel.  Only the
+	 * __kuser_cmpxchg code in entry-armv.S should be aware of its
+	 * existence.  Don't ever use this from user code.
+	 */
+	case 0xfff0:
+	{
+		extern void do_DataAbort(unsigned long addr, unsigned int fsr,
+					 struct pt_regs *regs);
+		unsigned long val;
+		unsigned long addr = regs->ARM_r2;
+		struct mm_struct *mm = current->mm;
+		pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+
+		regs->ARM_cpsr &= ~PSR_C_BIT;
+		spin_lock(&mm->page_table_lock);
+		pgd = pgd_offset(mm, addr);
+		if (!pgd_present(*pgd))
+			goto bad_access;
+		pmd = pmd_offset(pgd, addr);
+		if (!pmd_present(*pmd))
+			goto bad_access;
+		pte = pte_offset_map(pmd, addr);
+		if (!pte_present(*pte) || !pte_write(*pte))
+			goto bad_access;
+		val = *(unsigned long *)addr;
+		val -= regs->ARM_r0;
+		if (val == 0) {
+			*(unsigned long *)addr = regs->ARM_r1;
+			regs->ARM_cpsr |= PSR_C_BIT;
+		}
+		spin_unlock(&mm->page_table_lock);
+		return val;
+
+		bad_access:
+		spin_unlock(&mm->page_table_lock);
+		/* simulate a read access fault */
+		do_DataAbort(addr, 15 + (1 << 11), regs);
+		return -1;
+	}
+#endif
+
 	default:
 		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
 		   if not implemented, rather than raising SIGILL.  This
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index 6d1d7c27806e407f6c2efaf0c1f7fcbc16927614..5e240e452af6af66b2d9d18321009fddea82c73e 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw)
 		subs	r2, r2, #2
 		orr	ip, ip, r3, push_hbyte1
 		strh	ip, [r0]
-		bpl	2b
+		bpl	1b
 
-3:		tst	r2, #1
-2:		movne	ip, r3, lsr #8
+		tst	r2, #1
+3:		movne	ip, r3, lsr #8
 		strneh	ip, [r0]
 		mov	pc, lr
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 3b948e8c27513f7896263a87a99123ad5394b860..e0a01eef099345efc0dd202b443867db6312cef1 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -83,7 +83,6 @@ static struct map_desc intcp_io_desc[] __initdata = {
  { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
  { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
- { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE },
  { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE },
  { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE },
 };
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index dd012d6e2f5caecabc6792b3a7cee8e08b7994d3..f2c9e0d2b24b64517efb8c69391603d4ead0c58f 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/major.h>
 #include <linux/fb.h>
 #include <linux/interrupt.h>
@@ -106,6 +107,35 @@ static void __init lubbock_init_irq(void)
 	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
 }
 
+#ifdef CONFIG_PM
+
+static int lubbock_irq_resume(struct sys_device *dev)
+{
+	LUB_IRQ_MASK_EN = lubbock_irq_enabled;
+	return 0;
+}
+
+static struct sysdev_class lubbock_irq_sysclass = {
+	set_kset_name("cpld_irq"),
+	.resume = lubbock_irq_resume,
+};
+
+static struct sys_device lubbock_irq_device = {
+	.cls = &lubbock_irq_sysclass,
+};
+
+static int __init lubbock_irq_device_init(void)
+{
+	int ret = sysdev_class_register(&lubbock_irq_sysclass);
+	if (ret == 0)
+		ret = sysdev_register(&lubbock_irq_device);
+	return ret;
+}
+
+device_initcall(lubbock_irq_device_init);
+
+#endif
+
 static int lubbock_udc_is_connected(void)
 {
 	return (LUB_MISC_RD & (1 << 9)) == 0;
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 3f952237ae3ddd185410bb2af9b1a9bf9bb981ad..9896afca751fc580bb6692a946d014919713a1c4 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -15,6 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
@@ -62,7 +63,6 @@ static struct irqchip mainstone_irq_chip = {
 	.unmask		= mainstone_unmask_irq,
 };
 
-
 static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
 				  struct pt_regs *regs)
 {
@@ -100,6 +100,35 @@ static void __init mainstone_init_irq(void)
 	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
 }
 
+#ifdef CONFIG_PM
+
+static int mainstone_irq_resume(struct sys_device *dev)
+{
+	MST_INTMSKENA = mainstone_irq_enabled;
+	return 0;
+}
+
+static struct sysdev_class mainstone_irq_sysclass = {
+	set_kset_name("cpld_irq"),
+	.resume = mainstone_irq_resume,
+};
+
+static struct sys_device mainstone_irq_device = {
+	.cls = &mainstone_irq_sysclass,
+};
+
+static int __init mainstone_irq_device_init(void)
+{
+	int ret = sysdev_class_register(&mainstone_irq_sysclass);
+	if (ret == 0)
+		ret = sysdev_register(&mainstone_irq_device);
+	return ret;
+}
+
+device_initcall(mainstone_irq_device_init);
+
+#endif
+
 
 static struct resource smc91x_resources[] = {
 	[0] = {
@@ -304,6 +333,15 @@ static void __init mainstone_map_io(void)
 	PWER  = 0xC0000002;
 	PRER  = 0x00000002;
 	PFER  = 0x00000002;
+ 	/*	for use I SRAM as framebuffer.	*/
+ 	PSLR |= 0xF04;
+ 	PCFR = 0x66;
+ 	/*	For Keypad wakeup.	*/
+ 	KPC &=~KPC_ASACT;
+ 	KPC |=KPC_AS;
+ 	PKWR  = 0x000FD000;
+ 	/*	Need read PKWR back after set it.	*/
+ 	PKWR;
 }
 
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 82a4bf34c251c338cc735679a559eef2ecf4e46e..9799fe80df23255d6d77bca271100b7b683a9345 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -29,9 +29,6 @@
  */
 #undef DEBUG
 
-extern void pxa_cpu_suspend(void);
-extern void pxa_cpu_resume(void);
-
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
@@ -63,6 +60,12 @@ enum {	SLEEP_SAVE_START = 0,
 	SLEEP_SAVE_ICMR,
 	SLEEP_SAVE_CKEN,
 
+#ifdef CONFIG_PXA27x
+ 	SLEEP_SAVE_MDREFR,
+ 	SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+ 	SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+#endif
+
 	SLEEP_SAVE_CKSUM,
 
 	SLEEP_SAVE_SIZE
@@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state)
 	unsigned long checksum = 0;
 	struct timespec delta, rtc;
 	int i;
-
-	if (state != PM_SUSPEND_MEM)
-		return -EINVAL;
+	extern void pxa_cpu_pm_enter(suspend_state_t state);
 
 #ifdef CONFIG_IWMMXT
 	/* force any iWMMXt context to ram **/
@@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state)
 	SAVE(GAFR2_L); SAVE(GAFR2_U);
 
 #ifdef CONFIG_PXA27x
+	SAVE(MDREFR);
 	SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
 	SAVE(GAFR3_L); SAVE(GAFR3_U);
+	SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+	SAVE(PFER); SAVE(PKWR);
 #endif
 
 	SAVE(ICMR);
 	ICMR = 0;
 
 	SAVE(CKEN);
-	CKEN = 0;
-
 	SAVE(PSTR);
 
 	/* Note: wake up source are set up in each machine specific files */
@@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state)
 	/* Clear sleep reset status */
 	RCSR = RCSR_SMR;
 
-	/* set resume return address */
-	PSPR = virt_to_phys(pxa_cpu_resume);
-
 	/* before sleeping, calculate and save a checksum */
 	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
 		checksum += sleep_save[i];
 	sleep_save[SLEEP_SAVE_CKSUM] = checksum;
 
 	/* *** go zzz *** */
-	pxa_cpu_suspend();
+	pxa_cpu_pm_enter(state);
 
 	/* after sleeping, validate the checksum */
 	checksum = 0;
@@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state)
 		LUB_HEXLED = 0xbadbadc5;
 #endif
 		while (1)
-			pxa_cpu_suspend();
+			pxa_cpu_pm_enter(state);
 	}
 
 	/* ensure not to come back here if it wasn't intended */
@@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state)
 	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
 
 #ifdef CONFIG_PXA27x
+	RESTORE(MDREFR);
 	RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
 	RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+	RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+	RESTORE(PFER); RESTORE(PKWR);
 #endif
 
 	PSSR = PSSR_RDH | PSSR_PH;
@@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp)
  */
 static int pxa_pm_prepare(suspend_state_t state)
 {
-	return 0;
+	extern int pxa_cpu_pm_prepare(suspend_state_t state);
+
+	return pxa_cpu_pm_prepare(state);
 }
 
 /*
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index e887b7175ef33b8c547c04a14d6117deaf19ec49..7869c3b4e62f0447eee5737dc855b0b99afe5d10 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -16,6 +16,7 @@
  * initialization stuff for PXA machines which can be overridden later if
  * need be.
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -102,3 +103,35 @@ unsigned int get_lcdclk_frequency_10khz(void)
 }
 
 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+
+#ifdef CONFIG_PM
+
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+	extern void pxa_cpu_suspend(unsigned int);
+	extern void pxa_cpu_resume(void);
+
+	CKEN = 0;
+
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		/* set resume return address */
+		PSPR = virt_to_phys(pxa_cpu_resume);
+		pxa_cpu_suspend(3);
+		break;
+	}
+}
+
+#endif
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7e863afefb531e5a9fe6c20d22e6e1355fb3b41d..893964fb9659bbabed5ed818377f430315915ef2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -120,6 +120,42 @@ EXPORT_SYMBOL(get_clk_frequency_khz);
 EXPORT_SYMBOL(get_memclk_frequency_10khz);
 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
+#ifdef CONFIG_PM
+
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+	extern void pxa_cpu_standby(void);
+	extern void pxa_cpu_suspend(unsigned int);
+	extern void pxa_cpu_resume(void);
+
+	CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+
+	/* ensure voltage-change sequencer not initiated, which hangs */
+	PCFR &= ~PCFR_FVC;
+
+	/* Clear edge-detect status register. */
+	PEDR = 0xDF12FE1B;
+
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		/* set resume return address */
+		PSPR = virt_to_phys(pxa_cpu_resume);
+		pxa_cpu_suspend(3);
+		break;
+	}
+}
+
+#endif
 
 /*
  * device registration specific to PXA27x.
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index bc229fab86d44644fc4d3d5bc1793035f58ec4f9..c7c28890d406c25356b2643400360cb661ee1586 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
 	chan->client = NULL;
 	chan->in_use = 0;
 
+	if (chan->irq_claimed)
+		free_irq(chan->irq, (void *)chan);
+	chan->irq_claimed = 0;
+
 	local_irq_restore(flags);
 
 	return 0;
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 50cde576dadfc9cf9ebe06917c43e2e054976ed9..6923316b3d0df043f4140648bdbfd58aa0691c7e 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -150,7 +150,7 @@ config SA1100_SSP
 
 config H3600_SLEEVE
 	tristate "Compaq iPAQ Handheld sleeve support"
-	depends on SA1100_H3600
+	depends on SA1100_H3100 || SA1100_H3600
 	help
 	  Choose this option to enable support for extension packs (sleeves)
 	  for the Compaq iPAQ H3XXX series of handheld computers.  This option
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 554e1bd30d6e631ce2959f0ccac136f4d1b325f0..302c2a7b9b63745bbeae0f59cd49fad31c259435 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -543,7 +543,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
 		val |= SYS_CLCD_MODE_5551;
 		break;
 	case 6:
-		val |= SYS_CLCD_MODE_565_BLSB;
+		val |= SYS_CLCD_MODE_565_RLSB;
 		break;
 	case 8:
 		val |= SYS_CLCD_MODE_888;
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 48bac7da8c70589dba5f06be40b325457398c640..3fefb43c67f7c8cc851285e83e21d3648902027a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -228,7 +228,6 @@ config CPU_SA1100
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_TLB_V4WB
-	select CPU_MINICACHE
 
 # XScale
 config CPU_XSCALE
@@ -239,7 +238,6 @@ config CPU_XSCALE
 	select CPU_ABRT_EV5T
 	select CPU_CACHE_VIVT
 	select CPU_TLB_V4WBI
-	select CPU_MINICACHE
 
 # ARMv6
 config CPU_V6
@@ -345,11 +343,6 @@ config CPU_TLB_V4WBI
 config CPU_TLB_V6
 	bool
 
-config CPU_MINICACHE
-	bool
-	help
-	  Processor has a minicache.
-
 comment "Processor Features"
 
 config ARM_THUMB
@@ -429,3 +422,11 @@ config HAS_TLS_REG
 	  assume directly accessing that register and always obtain the
 	  expected value only on ARMv7 and above.
 
+config NEEDS_SYSCALL_FOR_CMPXCHG
+	bool
+	default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+	help
+	  SMP on a pre-ARMv6 processor?  Well OK then.
+	  Forget about fast user space cmpxchg support.
+	  It is just not possible.
+
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ccf316c11e02523f65b3cd21e3c13fe2afd71e59..59f47d4c2dfe6edf22560b861d6a3d554104dbf1 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6)	+= copypage-v6.o mmu.o
 obj-$(CONFIG_CPU_SA1100)	+= copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)	+= copypage-xscale.o
 
-obj-$(CONFIG_CPU_MINICACHE)	+= minicache.o
-
 obj-$(CONFIG_CPU_TLB_V3)	+= tlb-v3.o
 obj-$(CONFIG_CPU_TLB_V4WT)	+= tlb-v4.o
 obj-$(CONFIG_CPU_TLB_V4WB)	+= tlb-v4wb.o
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S
deleted file mode 100644
index bb277316ef52d59e7f3458706e7b3ac82e03bc77..0000000000000000000000000000000000000000
--- a/arch/arm/mm/copypage-xscale.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  linux/arch/arm/lib/copypage-xscale.S
- *
- *  Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/constants.h>
-
-/*
- * General note:
- *  We don't really want write-allocate cache behaviour for these functions
- *  since that will just eat through 8K of the cache.
- */
-
-	.text
-	.align	5
-/*
- * XScale optimised copy_user_page
- *  r0 = destination
- *  r1 = source
- *  r2 = virtual user address of ultimate destination page
- *
- * The source page may have some clean entries in the cache already, but we
- * can safely ignore them - break_cow() will flush them out of the cache
- * if we eventually end up using our copied page.
- *
- * What we could do is use the mini-cache to buffer reads from the source
- * page.  We rely on the mini-cache being smaller than one page, so we'll
- * cycle through the complete cache anyway.
- */
-ENTRY(xscale_mc_copy_user_page)
-	stmfd	sp!, {r4, r5, lr}
-	mov	r5, r0
-	mov	r0, r1
-	bl	map_page_minicache
-	mov	r1, r5
-	mov	lr, #PAGE_SZ/64-1
-
-	/*
-	 * Strangely enough, best performance is achieved
-	 * when prefetching destination as well.  (NP)
-	 */
-	pld	[r0, #0]
-	pld	[r0, #32]
-	pld	[r1, #0]
-	pld	[r1, #32]
-
-1:	pld	[r0, #64]
-	pld	[r0, #96]
-	pld	[r1, #64]
-	pld	[r1, #96]
-
-2:	ldrd	r2, [r0], #8
-	ldrd	r4, [r0], #8
-	mov	ip, r1
-	strd	r2, [r1], #8
-	ldrd	r2, [r0], #8
-	strd	r4, [r1], #8
-	ldrd	r4, [r0], #8
-	strd	r2, [r1], #8
-	strd	r4, [r1], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	ldrd	r2, [r0], #8
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	ldrd	r4, [r0], #8
-	mov	ip, r1
-	strd	r2, [r1], #8
-	ldrd	r2, [r0], #8
-	strd	r4, [r1], #8
-	ldrd	r4, [r0], #8
-	strd	r2, [r1], #8
-	strd	r4, [r1], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	subs	lr, lr, #1
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	bgt	1b
-	beq	2b
-
-	ldmfd	sp!, {r4, r5, pc}
-
-	.align	5
-/*
- * XScale optimised clear_user_page
- *  r0 = destination
- *  r1 = virtual user address of ultimate destination page
- */
-ENTRY(xscale_mc_clear_user_page)
-	mov	r1, #PAGE_SZ/32
-	mov	r2, #0
-	mov	r3, #0
-1:	mov	ip, r0
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	strd	r2, [r0], #8
-	mcr	p15, 0, ip, c7, c10, 1		@ clean D line
-	subs	r1, r1, #1
-	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line
-	bne	1b
-	mov	pc, lr
-
-	__INITDATA
-
-	.type	xscale_mc_user_fns, #object
-ENTRY(xscale_mc_user_fns)
-	.long	xscale_mc_clear_user_page
-	.long	xscale_mc_copy_user_page
-	.size	xscale_mc_user_fns, . - xscale_mc_user_fns
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
new file mode 100644
index 0000000000000000000000000000000000000000..42a6ee255ce0a29a2ae4a53a13c655d3ac4bb802
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -0,0 +1,131 @@
+/*
+ *  linux/arch/arm/lib/copypage-xscale.S
+ *
+ *  Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This handles the mini data cache, as found on SA11x0 and XScale
+ * processors.  When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache.  This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define COPYPAGE_MINICACHE	0xffff8000
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+				  L_PTE_CACHEABLE)
+
+#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * XScale mini-dcache optimised copy_user_page
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address.  Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ */
+static void __attribute__((naked))
+mc_copy_user_page(void *from, void *to)
+{
+	/*
+	 * Strangely enough, best performance is achieved
+	 * when prefetching destination as well.  (NP)
+	 */
+	asm volatile(
+	"stmfd	sp!, {r4, r5, lr}		\n\
+	mov	lr, %2				\n\
+	pld	[r0, #0]			\n\
+	pld	[r0, #32]			\n\
+	pld	[r1, #0]			\n\
+	pld	[r1, #32]			\n\
+1:	pld	[r0, #64]			\n\
+	pld	[r0, #96]			\n\
+	pld	[r1, #64]			\n\
+	pld	[r1, #96]			\n\
+2:	ldrd	r2, [r0], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	mov	ip, r1				\n\
+	strd	r2, [r1], #8			\n\
+	ldrd	r2, [r0], #8			\n\
+	strd	r4, [r1], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	strd	r2, [r1], #8			\n\
+	strd	r4, [r1], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	ldrd	r2, [r0], #8			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	ldrd	r4, [r0], #8			\n\
+	mov	ip, r1				\n\
+	strd	r2, [r1], #8			\n\
+	ldrd	r2, [r0], #8			\n\
+	strd	r4, [r1], #8			\n\
+	ldrd	r4, [r0], #8			\n\
+	strd	r2, [r1], #8			\n\
+	strd	r4, [r1], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	subs	lr, lr, #1			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	bgt	1b				\n\
+	beq	2b				\n\
+	ldmfd	sp!, {r4, r5, pc}		"
+	:
+	: "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
+}
+
+void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+	spin_lock(&minicache_lock);
+
+	set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+	flush_tlb_kernel_page(COPYPAGE_MINICACHE);
+
+	mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+	spin_unlock(&minicache_lock);
+}
+
+/*
+ * XScale optimised clear_user_page
+ */
+void __attribute__((naked))
+xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+	asm volatile(
+	"mov	r1, %0				\n\
+	mov	r2, #0				\n\
+	mov	r3, #0				\n\
+1:	mov	ip, r0				\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	strd	r2, [r0], #8			\n\
+	mcr	p15, 0, ip, c7, c10, 1		@ clean D line\n\
+	subs	r1, r1, #1			\n\
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate D line\n\
+	bne	1b				\n\
+	mov	pc, lr"
+	:
+	: "I" (PAGE_SIZE / 32));
+}
+
+struct cpu_user_fns xscale_mc_user_fns __initdata = {
+	.cpu_clear_user_page	= xscale_mc_clear_user_page, 
+	.cpu_copy_user_page	= xscale_mc_copy_user_page,
+};
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c
deleted file mode 100644
index dedf2ab01b2a7984309009130ab50f4e7901d13b..0000000000000000000000000000000000000000
--- a/arch/arm/mm/minicache.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  linux/arch/arm/mm/minicache.c
- *
- *  Copyright (C) 2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This handles the mini data cache, as found on SA11x0 and XScale
- * processors.  When we copy a user page page, we map it in such a way
- * that accesses to this page will not touch the main data cache, but
- * will be cached in the mini data cache.  This prevents us thrashing
- * the main data cache on page faults.
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-
-/*
- * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
- * specific hacks for copying pages efficiently.
- */
-#define minicache_address (0xffff8000)
-#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
-				  L_PTE_CACHEABLE)
-
-static pte_t *minicache_pte;
-
-/*
- * Note that this is intended to be called only from the copy_user_page
- * asm code; anything else will require special locking to prevent the
- * mini-cache space being re-used.  (Note: probably preempt unsafe).
- *
- * We rely on the fact that the minicache is 2K, and we'll be pushing
- * 4K of data through it, so we don't actually have to specifically
- * flush the minicache when we change the mapping.
- *
- * Note also: assert(PAGE_OFFSET <= virt < high_memory).
- * Unsafe: preempt, kmap.
- */
-unsigned long map_page_minicache(unsigned long virt)
-{
-	set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot));
-	flush_tlb_kernel_page(minicache_address);
-
-	return minicache_address;
-}
-
-static int __init minicache_init(void)
-{
-	pgd_t *pgd;
-	pmd_t *pmd;
-
-	spin_lock(&init_mm.page_table_lock);
-
-	pgd = pgd_offset_k(minicache_address);
-	pmd = pmd_alloc(&init_mm, pgd, minicache_address);
-	if (!pmd)
-		BUG();
-	minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address);
-	if (!minicache_pte)
-		BUG();
-
-	spin_unlock(&init_mm.page_table_lock);
-
-	return 0;
-}
-
-core_initcall(minicache_init);
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 0fbcfe00dd8d1514b33bd6aeff1b6cc01eebb4ac..51ecd512603da25153cbf194dcda57d724a8edd8 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200)		+= scx200.o
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
 targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
-targets += vsyscall.lds
+targets += vsyscall-note.o vsyscall.lds
 
 # The DSO images are built using a special linker script.
 quiet_cmd_syscall = SYSCALL $@
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 45641a87255009968c6882b4d04fcd4dbf52df90..0ff65abcd56c3c1139b4849a80228f555785c655 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1222,6 +1222,7 @@ static int suspend(int vetoable)
 
 	save_processor_state();
 	err = set_system_power_state(APM_STATE_SUSPEND);
+	ignore_normal_resume = 1;
 	restore_processor_state();
 
 	local_irq_disable();
@@ -1229,7 +1230,6 @@ static int suspend(int vetoable)
 	spin_lock(&i8253_lock);
 	reinit_timer();
 	set_time();
-	ignore_normal_resume = 1;
 
 	spin_unlock(&i8253_lock);
 	write_sequnlock(&xtime_lock);
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 4f3cdef75797ccb4bf9949e6e0da43b1284eed17..962b6c4e32b5b92f8182ff0b600350d37b35242c 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33])			// r14 <- *set
 	;;
 
 	st8 [r2]=r14				// update current->blocked with new mask
-	cmpxchg4.acq r14=[r9],r18,ar.ccv	// current->thread_info->flags <- r18
+	cmpxchg4.acq r8=[r9],r18,ar.ccv		// current->thread_info->flags <- r18
 	;;
-	cmp.ne p6,p0=r17,r14			// update failed?
+	cmp.ne p6,p0=r17,r8			// update failed?
 (p6)	br.cond.spnt.few 1b			// yes -> retry
 
 #ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index febc091c2f02d318cd4bfa72346a10b536f08d5f..f1aca7cffd120879e446e703a8783f93c36f6654 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
 		 * XXX Should have an arch-hook for running this after final section
 		 *     addresses have been selected...
 		 */
-		/* See if gp can cover the entire core module:  */
-		uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2;
-		if (mod->core_size >= MAX_LTOFF)
+		uint64_t gp;
+		if (mod->core_size > MAX_LTOFF)
 			/*
 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
 			 * at the end of the module.
 			 */
-			gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2;
+			gp = mod->core_size - MAX_LTOFF / 2;
+		else
+			gp = mod->core_size / 2;
+		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
 		mod->arch.gp = gp;
 		DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
 	}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 08c8a5eb25abc307c49bbc01ac34d6ad6e8e7bdb..575a8f657b3129bacc8ec2979470ecc84c9b7b3f 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task)
 {
 	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
 
+	/*
+	 * Prevent migrating this task while
+	 * we're fiddling with the FPU state
+	 */
+	preempt_disable();
 	if (ia64_is_local_fpu_owner(task) && psr->mfh) {
 		psr->mfh = 0;
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
 		ia64_save_fpu(&task->thread.fph[0]);
 	}
+	preempt_enable();
 }
 
 /*
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index b7e6b4cb374b89302f5ba58612bce333f7b8a1cd..d14692e0920acc5c6f0350b9b14bddc801b07221 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -720,7 +720,8 @@ cpu_init (void)
 	ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
 
 	/*
-	 * Initialize default control register to defer all speculative faults.  The
+	 * Initialize default control register to defer speculative faults except
+	 * for those arising from TLB misses, which are not deferred.  The
 	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
 	 * the kernel must have recovery code for all speculative accesses).  Turn on
 	 * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index e82ad78081b38724e5f80c2cbe8d107e0fbcb871..1861173bd4f6a7be2d76edeb008e7b83a3231856 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 	siginfo_t siginfo;
 	int sig, code;
 
+	/* break.b always sets cr.iim to 0, which causes problems for
+	 * debuggers.  Get the real break number from the original instruction,
+	 * but only for kernel code.  User space break.b is left alone, to
+	 * preserve the existing behaviour.  All break codings have the same
+	 * format, so there is no need to check the slot type.
+	 */
+	if (break_num == 0 && !user_mode(regs)) {
+		struct ia64_psr *ipsr = ia64_psr(regs);
+		unsigned long *bundle = (unsigned long *)regs->cr_iip;
+		unsigned long slot;
+		switch (ipsr->ri) {
+		      case 0:  slot = (bundle[0] >>  5); break;
+		      case 1:  slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
+		      default: slot = (bundle[1] >> 23); break;
+		}
+		break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
+	}
+
 	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
 	siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 	siginfo.si_imm = break_num;
@@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs)
 
 	/* first, grant user-level access to fph partition: */
 	psr->dfh = 0;
+
+	/*
+	 * Make sure that no other task gets in on this processor
+	 * while we're claiming the FPU
+	 */
+	preempt_disable();
 #ifndef CONFIG_SMP
 	{
 		struct task_struct *fpu_owner
 			= (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-		if (ia64_is_local_fpu_owner(current))
+		if (ia64_is_local_fpu_owner(current)) {
+			preempt_enable_no_resched();
 			return;
+		}
 
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
@@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs)
 		 */
 		psr->mfh = 1;
 	}
+	preempt_enable_no_resched();
 }
 
 static inline int
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 547785e3cba2fb3e63a7a9c7dbd10931caf47bba..4eb2f52b87a16b436007740a56abaf79574d51fa 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -305,8 +305,9 @@ setup_gate (void)
 	struct page *page;
 
 	/*
-	 * Map the gate page twice: once read-only to export the ELF headers etc. and once
-	 * execute-only page to enable privilege-promotion via "epc":
+	 * Map the gate page twice: once read-only to export the ELF
+	 * headers etc. and once execute-only page to enable
+	 * privilege-promotion via "epc":
 	 */
 	page = virt_to_page(ia64_imva(__start_gate_section));
 	put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
@@ -315,6 +316,20 @@ setup_gate (void)
 	put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
 #else
 	put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
+	/* Fill in the holes (if any) with read-only zero pages: */
+	{
+		unsigned long addr;
+
+		for (addr = GATE_ADDR + PAGE_SIZE;
+		     addr < GATE_ADDR + PERCPU_PAGE_SIZE;
+		     addr += PAGE_SIZE)
+		{
+			put_kernel_page(ZERO_PAGE(0), addr,
+					PAGE_READONLY);
+			put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE,
+					PAGE_READONLY);
+		}
+	}
 #endif
 	ia64_patch_gate();
 }
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e64cb8175f7a7450becd3ff9962ab348b80780d1..44bfc7f318cbd611752fcede5459ee3182807191 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -222,7 +222,7 @@ void __init early_sn_setup(void)
 
 extern int platform_intr_list[];
 extern nasid_t master_nasid;
-static int shub_1_1_found __initdata;
+static int __initdata shub_1_1_found = 0;
 
 /*
  * sn_check_for_wars
@@ -251,7 +251,7 @@ static void __init sn_check_for_wars(void)
 	} else {
 		for_each_online_node(cnode) {
 			if (is_shub_1_1(cnodeid_to_nasid(cnode)))
-				sn_hub_info->shub_1_1_found = 1;
+				shub_1_1_found = 1;
 		}
 	}
 }
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 7dbf997ff20525dd4ae6bf1ec2347a2a5c206b25..5649fbae430ebefeb525e529c5669bc45bfec929 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:05:59 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:23 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y
 #
 CONFIG_AMIGA_FLOPPY=y
 CONFIG_AMIGA_Z2RAM=y
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_PPA is not set
@@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_A3000_SCSI=y
 CONFIG_A2091_SCSI=y
@@ -492,7 +487,6 @@ CONFIG_HYDRA=m
 CONFIG_ZORRO8390=m
 CONFIG_APNE=m
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
@@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_PARKBD is not set
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 505a2968e60446443cd9c0dc1b6240b4e29939e7..63024b0b7ac3a0d05c58f125602cf50653b1b7f8 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:00 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:27 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 617aa73c3250dee5c93bcb9e00e51d7e6e805524..6433da2d2ce2ab65fcac9130869d9a0da76511d6 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:18 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:32 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index b501db51d9ec71c177fa994b9242019c19e6f820..da2a23a214632265c4b61c83c7c2f7ba2f474ece 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:19 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:37 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 2bf6cef4f2b21e800c642ef5e5b442245ec133f3..51251883adf863c55442a268404748ccd1d1a0eb 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:21 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:41 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 7074f856820c3971a81ed6908a9b1678c3e6897d..15b80abfe94a53e2462926f26d2417bed1113ceb 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:24 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:45 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 61f09bc4846a2d56a0d7f0e2636274a151b70708..f0d5534f683087c6771ad41cfc11b39ee648d5a0 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:28 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:50 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 69c01004ec412d1ade4ddadaf08c5eef6175f85e..1d5c46ff3c819d425c3a98a6bb05f5402b4e12f4 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:31 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:53 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 550ec26006c1cdbbd0b7706fb6778319e659bd76..856238634d424ad3c9f62d88282e5b74f08bf1f9 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:34 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:58 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
@@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_NCR53C406A is not set
@@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
@@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 5b5a619645aad9abb69f1b203cf0677e09611dc1..af903b5c5708c8150ddba154ae96190eac314175 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:37 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:35:02 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y
 #
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
-CONFIG_SUN3_SCSI=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -487,7 +488,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 704e42344cba19d47bb1e2a6752f6b2d4568b460..997143b7928adf71e6d3e4fc5e3559bdc8dd0045 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:06:40 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:35:06 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig
index 5b2296ecba8207db90c7ac996212763f1c3056af..7d935e48a9a88f8fc5d322bcebaf8b44cf837f0d 100644
--- a/arch/m68k/defconfig
+++ b/arch/m68k/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc2-m68k
-# Tue Apr  5 14:05:31 2005
+# Linux kernel version: 2.6.12-rc6-m68k
+# Tue Jun  7 20:34:17 2005
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 2b6c9d32b7a6267754ab11b202317755a825a0b5..c4a33f265dc07e53577350d5366b3a936c8bc665 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void);
  */
 void default_idle(void)
 {
-	while(1) {
-		if (need_resched())
-			__asm__("stop #0x2000" : : : "cc");
-		schedule();
+	local_irq_disable();
+ 	while (!need_resched()) {
+		/* This stop will re-enable interrupts */
+ 		__asm__("stop #0x2000" : : : "cc");
+		local_irq_disable();
 	}
+	local_irq_enable();
 }
 
 void (*idle)(void) = default_idle;
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle;
 void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
-	idle();
+	while (1) {
+		idle();
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+	}
 }
 
 void machine_restart(char * __unused)
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 8aa5e8c69009b43c89415b3ec643ad808ea41596..d44b7dc5390a0d64e7f58e3b71d70969de57c922 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -838,6 +838,17 @@ struct cpu_spec	cpu_specs[] = {
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 	},
+	{	/* 405EP */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x51210000,
+		.cpu_name		= "405EP",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+	},
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4f1615ec13f42eb034426443d881e2db0534d47..7329ef177a18c36c4f068d2a09dad48d34fce92e 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache)
 _GLOBAL(flush_icache_range)
 BEGIN_FTR_SECTION
 	blr				/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	li	r5,L1_CACHE_LINE_SIZE-1
 	andc	r3,r3,r5
 	subf	r4,r3,r4
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all)
 _GLOBAL(__flush_dcache_icache)
 BEGIN_FTR_SECTION
 	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	rlwinm	r3,r3,0,0,19			/* Get page base address */
 	li	r4,4096/L1_CACHE_LINE_SIZE	/* Number of lines in a page */
 	mtctr	r4
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
 _GLOBAL(__flush_dcache_icache_phys)
 BEGIN_FTR_SECTION
 	blr					/* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	mfmsr	r10
 	rlwinm	r0,r10,0,28,26			/* clear DR */
 	mtmsr	r0
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index 937f46df711eeda3dc94db367bb7a0e2e0c7c387..5fdd4f607a40f23b25e441a9b9140c22364fa323 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -83,7 +83,7 @@ static u32 frequency_gpio;
 static u32 slew_done_gpio;
 static int no_schedule;
 static int has_cpu_l2lve;
-
+static int is_pmu_based;
 
 /* There are only two frequency states for each processor. Values
  * are in kHz for the time being.
@@ -463,7 +463,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
 	 */
 	no_schedule = 1;
 	sleep_freq = cur_freq;
-	if (cur_freq == low_freq)
+	if (cur_freq == low_freq && !is_pmu_based)
 		do_set_cpu_speed(CPUFREQ_HIGH, 0);
 	return 0;
 }
@@ -588,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
 		return 1;
 	hi_freq = (*value) / 1000;
 	set_speed_proc = pmu_set_cpu_speed;
+	is_pmu_based = 1;
 
 	return 0;
 }
@@ -692,6 +693,7 @@ static int __init pmac_cpufreq_setup(void)
 		hi_freq = cur_freq;
 		low_freq = 400000;
 		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
 	}
 	/* Else check for TiPb 400 & 500 */
 	else if (machine_is_compatible("PowerBook3,2")) {
@@ -703,6 +705,7 @@ static int __init pmac_cpufreq_setup(void)
 		hi_freq = cur_freq;
 		low_freq = 300000;
 		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
 	}
 	/* Else check for 750FX */
 	else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
index 7b607d1862cb07a9c4fb9a1203447c8bdedde63b..d5218b15824e93444a5b2c8810ffff5e0e6416d4 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -11,6 +11,23 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 
+extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({				\
+	__u32 __base = (base);			\
+	__u32 __rem;					\
+	(void)(((typeof((n)) *)0) == ((unsigned long long *)0));	\
+	if (((n) >> 32) == 0) {			\
+		__rem = (__u32)(n) % __base;		\
+		(n) = (__u32)(n) / __base;		\
+	} else 						\
+		__rem = __div64_32(&(n), __base);	\
+	__rem;						\
+ })
+
 int (*prom)(void *);
 
 void *chosen_handle;
@@ -352,7 +369,7 @@ static int skip_atoi(const char **s)
 #define SPECIAL	32		/* 0x */
 #define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
 
-static char * number(char * str, long num, int base, int size, int precision, int type)
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
 {
 	char c,sign,tmp[66];
 	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
@@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in
 	c = (type & ZEROPAD) ? '0' : ' ';
 	sign = 0;
 	if (type & SIGN) {
-		if (num < 0) {
+		if ((signed long long)num < 0) {
 			sign = '-';
-			num = -num;
+			num = - (signed long long)num;
 			size--;
 		} else if (type & PLUS) {
 			sign = '+';
@@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in
 	if (num == 0)
 		tmp[i++]='0';
 	else while (num != 0) {
-		tmp[i++] = digits[num % base];
-		num /= base;
+		tmp[i++] = digits[do_div(num, base)];
 	}
 	if (i > precision)
 		precision = i;
@@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...);
 int vsprintf(char *buf, const char *fmt, va_list args)
 {
 	int len;
-	unsigned long num;
+	unsigned long long num;
 	int i, base;
 	char * str;
 	const char *s;
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
index 0f90df0b3f9c308b634c9aef891972e3e0710622..1eb33398648edf920bba7fe78137a499d65d1ac9 100644
--- a/arch/ppc64/configs/g5_defconfig
+++ b/arch/ppc64/configs/g5_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Thu Mar 10 16:47:04 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 16:59:20 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
@@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 # CONFIG_HOTPLUG_CPU is not set
 
 #
@@ -104,10 +109,6 @@ CONFIG_PCI_NAMES=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
@@ -394,7 +395,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -564,6 +564,8 @@ CONFIG_E1000=y
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=m
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -630,18 +632,6 @@ CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -659,6 +649,16 @@ CONFIG_INPUT_MOUSE=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_PMACZILOG is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # TPM devices
@@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_KEYWEST=y
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -830,6 +840,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
 CONFIG_FB_RIVA=y
 # CONFIG_FB_RIVA_I2C is not set
 # CONFIG_FB_RIVA_DEBUG is not set
@@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_RW_DETECT=y
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 CONFIG_USB_STORAGE_ISD200=y
@@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
 CONFIG_USB_SERIAL_TI=m
@@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_PRINTK_TIME is not set
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
index a39e9d2e25da1120946947ceac662f96bed0118e..f6a2b99afd6314b445d7b429776590818604f60f 100644
--- a/arch/ppc64/configs/iSeries_defconfig
+++ b/arch/ppc64/configs/iSeries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:52 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:01:28 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_MSCHUNKS=y
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -89,16 +97,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
@@ -280,7 +285,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -445,7 +449,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -471,6 +474,7 @@ CONFIG_E1000=m
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -538,14 +542,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -555,6 +551,12 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y
 #
 CONFIG_SERIAL_CORE=m
 CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 #
 # USB Gadget Support
@@ -848,10 +854,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig
index cf527501915c6051f3ceba11e7968b7353301f10..8051b0f47b6f6ece08107b5a9929943f41b43895 100644
--- a/arch/ppc64/configs/maple_defconfig
+++ b/arch/ppc64/configs/maple_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:53 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:12:48 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_AUDIT is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -94,16 +101,13 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -261,7 +265,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -376,6 +379,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -431,14 +436,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 # Input Device Drivers
 #
@@ -448,6 +445,12 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_PMACZILOG is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_AMD8111=y
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
@@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_SPLIT_ISO=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
 
@@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_PEGASUS=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y
 CONFIG_USB_SERIAL=y
 # CONFIG_USB_SERIAL_CONSOLE is not set
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
 CONFIG_USB_SERIAL_CYPRESS_M8=m
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 CONFIG_USB_SERIAL_TI=m
 # CONFIG_USB_SERIAL_CYBERJACK is not set
@@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
index 4fecf237d5c9f1be1c3a3b9b1f07b240d1472ad2..3eb5ef25d3a3cbf25984a318ff17f908c4cc7e13 100644
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:54 2005
+# Linux kernel version: 2.6.12-rc6
+# Tue Jun 14 17:13:47 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 CONFIG_HOTPLUG_CPU=y
 
 #
@@ -109,10 +119,6 @@ CONFIG_HOTPLUG_CPU=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y
 #
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_IPR=y
 CONFIG_SCSI_IPR_TRACE=y
 CONFIG_SCSI_IPR_DUMP=y
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -371,7 +377,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -539,7 +544,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -565,6 +569,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -635,20 +641,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -668,6 +660,18 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PCSPKR=m
 # CONFIG_INPUT_UINPUT is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_PMACZILOG is not set
 CONFIG_SERIAL_ICOM=m
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -718,9 +722,16 @@ CONFIG_HVCS=m
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=1024
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -838,6 +859,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
@@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 
@@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 537b1cc82eab0bdb01a19ac9552b38061aa643c7..2f31bf3046f901a85a4b4361b73b58396b21b150 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc3-bk6
-# Wed Feb  9 23:34:51 2005
+# Linux kernel version: 2.6.12-rc5-git9
+# Sun Jun  5 09:26:47 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
-CONFIG_FRAME_POINTER=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 
 #
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_AUDIT is not set
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
 CONFIG_LPARCFG=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # General setup
@@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 CONFIG_HOTPLUG_CPU=y
 
 #
@@ -111,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y
 #
 # CONFIG_PCCARD is not set
 
-#
-# PC-card bridges
-#
-
 #
 # PCI Hotplug Support
 #
@@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y
 #
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_ATA_PIIX is not set
 # CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
 # CONFIG_SCSI_SATA_SIS is not set
@@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_IPR=y
 CONFIG_SCSI_IPR_TRACE=y
 CONFIG_SCSI_IPR_DUMP=y
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
@@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
@@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m
 #
 CONFIG_ADB=y
 CONFIG_ADB_PMU=y
+CONFIG_PMAC_SMU=y
 # CONFIG_PMAC_PBOOK is not set
 # CONFIG_PMAC_BACKLIGHT is not set
 # CONFIG_INPUT_ADBHID is not set
@@ -420,7 +427,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
@@ -588,7 +594,6 @@ CONFIG_PCNET32=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -614,6 +619,8 @@ CONFIG_E1000=y
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -682,20 +689,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -715,6 +708,18 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_PCSPKR=m
 # CONFIG_INPUT_UINPUT is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_PMACZILOG is not set
 CONFIG_SERIAL_ICOM=m
+CONFIG_SERIAL_JSM=m
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -766,9 +772,16 @@ CONFIG_HVCS=m
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_AMD8111=y
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_KEYWEST=y
-# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -890,9 +913,8 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
-CONFIG_FB_RIVA=y
-CONFIG_FB_RIVA_I2C=y
-# CONFIG_FB_RIVA_DEBUG is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 
@@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_RW_DETECT=y
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y
 CONFIG_USB_PEGASUS=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
@@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index d3604056e1a9c53d2407243ecb44aa282609363c..b61572eb2a7130d7a46924f8412024b9879286e7 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	REST_8GPRS(14, r1)
 	REST_10GPRS(22, r1)
 
-#ifdef CONFIG_PPC_ISERIES
-	clrrdi	r7,r1,THREAD_SHIFT	/* get current_thread_info() */
-	ld	r7,TI_FLAGS(r7)		/* Get run light flag */
-	mfspr	r9,CTRLF
-	srdi	r7,r7,TIF_RUN_LIGHT
-	insrdi	r9,r7,1,63		/* Insert run light into CTRL */
-	mtspr	CTRLT,r9
-#endif
-
 	/* convert old thread to its task_struct for return value */
 	addi	r3,r3,-THREAD
 	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 92a744c31ab183b2aec6e4532a593cef614bba13..346dbf606b5dd910e1a3609d315d96a1a830fa00 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -626,10 +626,10 @@ system_reset_iSeries:
 	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
 	cmpwi	0,r24,0			/* Are we processor 0? */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
-	mfspr	r4,CTRLF
-	li	r5,RUNLATCH		/* Turn off the run light */
+	mfspr	r4,SPRN_CTRLF
+	li	r5,CTRL_RUNLATCH	/* Turn off the run light */
 	andc	r4,r4,r5
-	mtspr	CTRLT,r4
+	mtspr	SPRN_CTRLT,r4
 
 1:
 	HMT_LOW
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary)
 	mfspr	r4, HID0
 	ori	r4, r4, 0x1
 	mtspr	HID0, r4
-	mfspr	r4, CTRLF
+	mfspr	r4, SPRN_CTRLF
 	oris	r4, r4, 0x40
-	mtspr	CTRLT, r4
+	mtspr	SPRN_CTRLT, r4
 	blr
 #endif
 
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index da20120f22617515f554e405d9eaa744288aca57..6d06eb550a3fb839077953caab8d6f82d96afe8a 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void)
 
 late_initcall(iSeries_src_init);
 
+static int set_spread_lpevents(char *str)
+{
+	unsigned long i;
+	unsigned long val = simple_strtoul(str, NULL, 0);
+
+	/*
+	 * The parameter is the number of processors to share in processing
+	 * lp events.
+	 */
+	if (( val > 0) && (val <= NR_CPUS)) {
+		for (i = 1; i < val; ++i)
+			paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
+
+		printk("lpevent processing spread over %ld processors\n", val);
+	} else {
+		printk("invalid spread_lpevents %ld\n", val);
+	}
+
+	return 1;
+}
+__setup("spread_lpevents=", set_spread_lpevents);
+
 void __init iSeries_early_setup(void)
 {
 	iSeries_fixup_klimit();
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 6abc621d3ba0ca1fd2f52b934d83faaae4d8d81e..f24ce2b872004ae4feb1f419eddb3c0866c1c440 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -75,13 +75,9 @@ static int iSeries_idle(void)
 {
 	struct paca_struct *lpaca;
 	long oldval;
-	unsigned long CTRL;
 
 	/* ensure iSeries run light will be out when idle */
-	clear_thread_flag(TIF_RUN_LIGHT);
-	CTRL = mfspr(CTRLF);
-	CTRL &= ~RUNLATCH;
-	mtspr(CTRLT, CTRL);
+	ppc64_runlatch_off();
 
 	lpaca = get_paca();
 
@@ -111,7 +107,9 @@ static int iSeries_idle(void)
 			}
 		}
 
+		ppc64_runlatch_on();
 		schedule();
+		ppc64_runlatch_off();
 	}
 
 	return 0;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 103daaf735734e5a6006d95e5a9ecda68cc01f21..e950a2058a1994fc9a9e8531465813f9de3ff09c 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs;
 
 int arch_prepare_kprobe(struct kprobe *p)
 {
+	int ret = 0;
 	kprobe_opcode_t insn = *p->addr;
 
-	if (IS_MTMSRD(insn) || IS_RFID(insn))
-		/* cannot put bp on RFID/MTMSRD */
-		return 1;
-	return 0;
+	if ((unsigned long)p->addr & 0x03) {
+		printk("Attempt to register kprobe at an unaligned address\n");
+		ret = -EINVAL;
+	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
+		printk("Cannot register a kprobe on rfid or mtmsrd\n");
+		ret = -EINVAL;
+	}
+	return ret;
 }
 
 void arch_copy_kprobe(struct kprobe *p)
@@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
 	ret = emulate_step(regs, p->ainsn.insn[0]);
 	if (ret == 0)
 		regs->nip = (unsigned long)p->addr + 4;
-
-	regs->msr &= ~MSR_SE;
 }
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
@@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 
 	if (kprobe_status & KPROBE_HIT_SS) {
 		resume_execution(current_kprobe, regs);
+		regs->msr &= ~MSR_SE;
 		regs->msr |= kprobe_saved_msr;
 
 		unlock_kprobes();
@@ -233,8 +237,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
 	 */
 	preempt_disable();
 	switch (val) {
-	case DIE_IABR_MATCH:
-	case DIE_DABR_MATCH:
 	case DIE_BPT:
 		if (kprobe_handler(args->regs))
 			ret = NOTIFY_STOP;
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index b944717c1dbd97c7fdfd547a53be87dffec47862..e3c73b3425dc016447d7e417f536d7a66fde39c4 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32)
 	.llong .compat_sys_newstat
 	.llong .compat_sys_newlstat
 	.llong .compat_sys_newfstat
-	.llong .sys_uname
+	.llong .sys32_uname
 	.llong .sys_ni_syscall		/* 110 old iopl syscall */
 	.llong .sys_vhangup
 	.llong .sys_ni_syscall		/* old idle syscall */
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 8b06861227385709431ace73498417c448b10e5d..cdfecbeb331f58d586edd4b85aa58212f859d872 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
 		p->thread.regs = NULL;	/* no user register state */
 		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
-#ifdef CONFIG_PPC_ISERIES
-		set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
-#endif
 	} else {
 		childregs->gpr[1] = usp;
 		p->thread.regs = childregs;
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 3de950de3671d293fc0e9d6a74bf8b0059b0d06f..b7683abfbe6a5f71e8031610ef8cb67dd14a07bd 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -211,13 +211,23 @@ struct {
  */
 #define ADDR(x)		(u32) ((unsigned long)(x) - offset)
 
+/*
+ * Error results ... some OF calls will return "-1" on error, some
+ * will return 0, some will return either. To simplify, here are
+ * macros to use with any ihandle or phandle return value to check if
+ * it is valid
+ */
+
+#define PROM_ERROR		(-1u)
+#define PHANDLE_VALID(p)	((p) != 0 && (p) != PROM_ERROR)
+#define IHANDLE_VALID(i)	((i) != 0 && (i) != PROM_ERROR)
+
+
 /* This is the one and *ONLY* place where we actually call open
  * firmware from, since we need to make sure we're running in 32b
  * mode when we do.  We switch back to 64b mode upon return.
  */
 
-#define PROM_ERROR	(-1)
-
 static int __init call_prom(const char *service, int nargs, int nret, ...)
 {
 	int i;
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void)
 {
 	unsigned long offset = reloc_offset();
 	ihandle elfloader;
-	int ret;
 
 	elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
 	if (elfloader == 0) {
 		prom_printf("couldn't open /packages/elf-loader\n");
 		return;
 	}
-	ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+	call_prom("call-method", 3, 1, ADDR("process-elf-header"),
 			elfloader, ADDR(&fake_elf));
 	call_prom("close", 1, 0, elfloader);
 }
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
 	    base = _ALIGN_UP(base + 0x100000, align)) {
 		prom_debug("    trying: 0x%x\n\r", base);
 		addr = (unsigned long)prom_claim(base, size, 0);
-		if ((int)addr != PROM_ERROR)
+		if (addr != PROM_ERROR)
 			break;
 		addr = 0;
 		if (align == 0)
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
 	for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
 		prom_debug("    trying: 0x%x\n\r", base);
 		addr = (unsigned long)prom_claim(base, size, 0);
-		if ((int)addr != PROM_ERROR)
+		if (addr != PROM_ERROR)
 			break;
 		addr = 0;
 	}
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void)
 {
 	unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
-	phandle prom_rtas, rtas_node;
+	phandle rtas_node;
+	ihandle rtas_inst;
 	u32 base, entry = 0;
 	u32 size = 0;
 
 	prom_debug("prom_instantiate_rtas: start...\n");
 
-	prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	prom_debug("prom_rtas: %x\n", prom_rtas);
-	if (prom_rtas == (phandle) -1)
+	rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+	prom_debug("rtas_node: %x\n", rtas_node);
+	if (!PHANDLE_VALID(rtas_node))
 		return;
 
-	prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size));
+	prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
 	if (size == 0)
 		return;
 
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void)
 		prom_printf("RTAS allocation failed !\n");
 		return;
 	}
-	prom_printf("instantiating rtas at 0x%x", base);
 
-	rtas_node = call_prom("open", 1, 1, ADDR("/rtas"));
-	prom_printf("...");
+	rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
+	if (!IHANDLE_VALID(rtas_inst)) {
+		prom_printf("opening rtas package failed");
+		return;
+	}
+
+	prom_printf("instantiating rtas at 0x%x ...", base);
 
 	if (call_prom("call-method", 3, 2,
 		      ADDR("instantiate-rtas"),
-		      rtas_node, base) != PROM_ERROR) {
+		      rtas_inst, base) != PROM_ERROR) {
 		entry = (long)_prom->args.rets[1];
 	}
 	if (entry == 0) {
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void)
 
 	reserve_mem(base, size);
 
-	prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base));
-	prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry));
+	prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
+	prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
 
 	prom_debug("rtas base     = 0x%x\n", base);
 	prom_debug("rtas entry    = 0x%x\n", entry);
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void)
 
 		prom_printf("opening PHB %s", path);
 		phb_node = call_prom("open", 1, 1, path);
-		if ( (long)phb_node <= 0)
+		if (phb_node == 0)
 			prom_printf("... failed\n");
 		else
 			prom_printf("... done\n");
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp)
 
 	/* get a handle for the stdout device */
 	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
-	if ((long)_prom->chosen <= 0)
+	if (!PHANDLE_VALID(_prom->chosen))
 		prom_panic("cannot find chosen"); /* msg won't be printed :( */
 
 	/* get device tree root */
 	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
-	if ((long)_prom->root <= 0)
+	if (!PHANDLE_VALID(_prom->root))
 		prom_panic("cannot find device tree root"); /* msg won't be printed :( */
 }
 
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void)
 	}
 	/* Default to pSeries. We need to know if we are running LPAR */
 	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	if (rtas != (phandle) -1) {
-		unsigned long x;
-		x = prom_getproplen(rtas, "ibm,hypertas-functions");
+	if (PHANDLE_VALID(rtas)) {
+		int x = prom_getproplen(rtas, "ibm,hypertas-functions");
 		if (x != PROM_ERROR) {
 			prom_printf("Hypertas detected, assuming LPAR !\n");
 			return PLATFORM_PSERIES_LPAR;
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void)
 		 * leave some room at the end of the path for appending extra
 		 * arguments
 		 */
-		if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0)
+		if (call_prom("package-to-path", 3, 1, node, path,
+			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)
 			continue;
 		prom_printf("found display   : %s, opening ... ", path);
 		
 		ih = call_prom("open", 1, 1, path);
-		if (ih == (ihandle)0 || ih == (ihandle)-1) {
+		if (ih == 0) {
 			prom_printf("failed\n");
 			continue;
 		}
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str)
 	return 0;
 }
 
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
 static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 					 unsigned long *mem_end)
 {
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 	/* get and store all property names */
 	prev_name = RELOC("");
 	for (;;) {
-		
-		/* 32 is max len of name including nul. */
-		namep = make_room(mem_start, mem_end, 32, 1);
-		if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) {
+		int rc;
+
+		/* 64 is max len of name including nul. */
+		namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
+		rc = call_prom("nextprop", 3, 1, node, prev_name, namep);
+		if (rc != 1) {
 			/* No more nodes: unwind alloc */
 			*mem_start = (unsigned long)namep;
 			break;
@@ -1555,12 +1577,6 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 	}
 }
 
-/*
- * The Open Firmware 1275 specification states properties must be 31 bytes or
- * less, however not all firmwares obey this. Make it 64 bytes to be safe.
- */
-#define MAX_PROPERTY_NAME 64
-
 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 					unsigned long *mem_end)
 {
@@ -1607,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 	prev_name = RELOC("");
 	sstart = (char *)RELOC(dt_string_start);
 	for (;;) {
-		if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0)
+		int rc;
+
+		rc = call_prom("nextprop", 3, 1, node, prev_name, pname);
+		if (rc != 1)
 			break;
 
 		/* find string offset */
@@ -1623,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 		l = call_prom("getproplen", 2, 1, node, pname);
 
 		/* sanity checks */
-		if (l < 0)
+		if (l == PROM_ERROR)
 			continue;
 		if (l > MAX_PROPERTY_LENGTH) {
 			prom_printf("WARNING: ignoring large property ");
@@ -1771,17 +1790,18 @@ static void __init fixup_device_tree(void)
 
 	/* Some G5s have a missing interrupt definition, fix it up here */
 	u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
-	if ((long)u3 <= 0)
+	if (!PHANDLE_VALID(u3))
 		return;
 	i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
-	if ((long)i2c <= 0)
+	if (!PHANDLE_VALID(i2c))
 		return;
 	mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
-	if ((long)mpic <= 0)
+	if (!PHANDLE_VALID(mpic))
 		return;
 
 	/* check if proper rev of u3 */
-	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0)
+	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
+	    == PROM_ERROR)
 		return;
 	if (u3_rev != 0x35)
 		return;
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 21c57f539c29305b1bf7ecef8c8a7a5b72a33046..dce198d39328aefd6541efef430f6a6e71d9ca4f 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -103,11 +103,6 @@ extern void unflatten_device_tree(void);
 
 extern void smp_release_cpus(void);
 
-unsigned long decr_overclock = 1;
-unsigned long decr_overclock_proc0 = 1;
-unsigned long decr_overclock_set = 0;
-unsigned long decr_overclock_proc0_set = 0;
-
 int have_of = 1;
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
@@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
 	printk("[dump]%04x %s\n", src, msg);
 }
 
-int set_spread_lpevents( char * str )
-{
-	/* The parameter is the number of processors to share in processing lp events */
-	unsigned long i;
-	unsigned long val = simple_strtoul( str, NULL, 0 );
-	if ( ( val > 0 ) && ( val <= NR_CPUS ) ) {
-		for ( i=1; i<val; ++i )
-			paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
-		printk("lpevent processing spread over %ld processors\n", val);
-	}
-	else
-		printk("invalid spreaqd_lpevents %ld\n", val);
-	return 1;
-}	
-
 /* This should only be called on processor 0 during calibrate decr */
 void setup_default_decr(void)
 {
 	struct paca_struct *lpaca = get_paca();
 
-	if ( decr_overclock_set && !decr_overclock_proc0_set )
-		decr_overclock_proc0 = decr_overclock;
-
-	lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;	
+	lpaca->default_decr = tb_ticks_per_jiffy;
 	lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
 }
 
-int set_decr_overclock_proc0( char * str )
-{
-	unsigned long val = simple_strtoul( str, NULL, 0 );
-	if ( ( val >= 1 ) && ( val <= 48 ) ) {
-		decr_overclock_proc0_set = 1;
-		decr_overclock_proc0 = val;
-		printk("proc 0 decrementer overclock factor of %ld\n", val);
-	}
-	else
-		printk("invalid proc 0 decrementer overclock factor of %ld\n", val);
-	return 1;
-}
-
-int set_decr_overclock( char * str )
-{
-	unsigned long val = simple_strtoul( str, NULL, 0 );
-	if ( ( val >= 1 ) && ( val <= 48 ) ) {
-		decr_overclock_set = 1;
-		decr_overclock = val;
-		printk("decrementer overclock factor of %ld\n", val);
-	}
-	else
-		printk("invalid decrementer overclock factor of %ld\n", val);
-	return 1;
-
-}
-
-__setup("spread_lpevents=", set_spread_lpevents );
-__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
-__setup("decr_overclock=", set_decr_overclock );
-
 #ifndef CONFIG_PPC_ISERIES
 /*
  * This function can be used by platforms to "find" legacy serial ports.
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 3b906cd940378086b84d18f2d0b71c70a33308cc..9ef5d36d6b253d38127cc026554e2d0e698f87d5 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -334,7 +334,6 @@ void smp_call_function_interrupt(void)
 	}
 }
 
-extern unsigned long decr_overclock;
 extern struct gettimeofday_struct do_gtod;
 
 struct thread_info *current_set[NR_CPUS];
@@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu)
 	if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
 		return -EINVAL;
 
-	paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock;
+	paca[cpu].default_decr = tb_ticks_per_jiffy;
 
 	if (!cpu_has_feature(CPU_FTR_SLB)) {
 		void *tmp;
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 7cf7a9600025bdfeb793fbb43dbb2b11c22ea743..9c8e317c598d0ed40e6fcd61c41d61abcd847a98 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
 }
 
 
-asmlinkage int ppc64_newuname(struct new_utsname __user * name)
-{
-	int errno = sys_newuname(name);
-
-	if (current->personality == PER_LINUX32 && !errno) {
-		if(copy_to_user(name->machine, "ppc\0\0", 8)) {
-			errno = -EFAULT;
-		}
-	}
-	return errno;
-}
-
-asmlinkage int ppc64_personality(unsigned long personality)
-{
-	int ret;
-	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
-		personality = PER_LINUX32;
-	ret = sys_personality(personality);
-	if (ret == PER_LINUX32)
-		ret = PER_LINUX;
-	return ret;
-}
-
-
-
 /* Note: it is necessary to treat mode as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 }
 #endif
 
+asmlinkage int sys32_uname(struct old_utsname __user * name)
+{
+	int err = 0;
+	
+	down_read(&uts_sem);
+	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+		err = -EFAULT;
+	up_read(&uts_sem);
+	if (!err && personality(current->personality) == PER_LINUX32) {
+		/* change "ppc64" to "ppc" */
+		if (__put_user(0, name->machine + 3)
+		    || __put_user(0, name->machine + 4))
+			err = -EFAULT;
+	}
+	return err;
+}
+
 asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
 {
 	int error;
-	
-	if (!name)
-		return -EFAULT;
+
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
   
 	down_read(&uts_sem);
 	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
-	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
-	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
-	error -= __put_user(0,name->release+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
-	error -= __put_user(0,name->version+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+	error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+	error |= __put_user(0,name->release+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+	error |= __put_user(0,name->version+__OLD_UTS_LEN);
+	error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+	error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+	if (personality(current->personality) == PER_LINUX32) {
+		/* change "ppc64" to "ppc" */
+		error |= __put_user(0, name->machine + 3);
+		error |= __put_user(0, name->machine + 4);
+	}
+	
 	up_read(&uts_sem);
 
 	error = error ? -EFAULT : 0;
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index f2865ff8d2f93863c1d8eb4416f02a82e9a68ad2..a8cbb202b8cd482f8deb05e68287341600c44637 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -199,24 +199,33 @@ out:
 	return ret;
 }
 
-static int __init set_fakeppc(char *str)
+long ppc64_personality(unsigned long personality)
 {
-	if (*str)
-		return 0;
-	init_task.personality = PER_LINUX32;
-	return 1;
+	long ret;
+
+	if (personality(current->personality) == PER_LINUX32
+	    && personality == PER_LINUX)
+		personality = PER_LINUX32;
+	ret = sys_personality(personality);
+	if (ret == PER_LINUX32)
+		ret = PER_LINUX;
+	return ret;
 }
-__setup("fakeppc", set_fakeppc);
 
-asmlinkage int sys_uname(struct old_utsname __user * name)
+long ppc64_newuname(struct new_utsname __user * name)
 {
-	int err = -EFAULT;
-	
+	int err = 0;
+
 	down_read(&uts_sem);
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
-		err = 0;
+	if (copy_to_user(name, &system_utsname, sizeof(*name)))
+		err = -EFAULT;
 	up_read(&uts_sem);
-	
+	if (!err && personality(current->personality) == PER_LINUX32) {
+		/* change ppc64 to ppc */
+		if (__put_user(0, name->machine + 3)
+		    || __put_user(0, name->machine + 4))
+			err = -EFAULT;
+	}
 	return err;
 }
 
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 0925694c3ce5e7873438ae300075a80d648e7657..c8fa6569b2fd789fc3476a3c5ab86c3bf6b3c203 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void)
 #ifdef CONFIG_PPC_PSERIES
 	unsigned long set, reset;
 	int ret;
-	unsigned int ctrl;
 #endif /* CONFIG_PPC_PSERIES */
 
 	/* Only need to enable them once */
@@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void)
 	 * On SMT machines we have to set the run latch in the ctrl register
 	 * in order to make PMC6 spin.
 	 */
-	if (cpu_has_feature(CPU_FTR_SMT)) {
-		ctrl = mfspr(CTRLF);
-		ctrl |= RUNLATCH;
-		mtspr(CTRLT, ctrl);
-	}
+	if (cpu_has_feature(CPU_FTR_SMT))
+		ppc64_runlatch_on();
 #endif /* CONFIG_PPC_PSERIES */
 }
 
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 01ae1964c938cd828379dc594087299309531725..c067435bae4506130b9dd05cbf4e6a30078000a1 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -28,6 +28,7 @@
 //#include <linux/kernel_stat.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/workqueue.h>
 
 #include "appldata.h"
 
@@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL;
 static int appldata_timer_active;
 
 /*
- * Tasklet
+ * Work queue
  */
-static struct tasklet_struct appldata_tasklet_struct;
+static struct workqueue_struct *appldata_wq;
+static void appldata_work_fn(void *data);
+static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
+
 
 /*
  * Ops list
@@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock);
 static LIST_HEAD(appldata_ops_list);
 
 
-/************************* timer, tasklet, DIAG ******************************/
+/*************************** timer, work, DIAG *******************************/
 /*
  * appldata_timer_function()
  *
- * schedule tasklet and reschedule timer
+ * schedule work and reschedule timer
  */
 static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
 {
@@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
 		atomic_read(&appldata_expire_count));
 	if (atomic_dec_and_test(&appldata_expire_count)) {
 		atomic_set(&appldata_expire_count, num_online_cpus());
-		tasklet_schedule((struct tasklet_struct *) data);
+		queue_work(appldata_wq, (struct work_struct *) data);
 	}
 }
 
 /*
- * appldata_tasklet_function()
+ * appldata_work_fn()
  *
  * call data gathering function for each (active) module
  */
-static void appldata_tasklet_function(unsigned long data)
+static void appldata_work_fn(void *data)
 {
 	struct list_head *lh;
 	struct appldata_ops *ops;
 	int i;
 
-	P_DEBUG("  -= Tasklet =-\n");
+	P_DEBUG("  -= Work Queue =-\n");
 	i = 0;
 	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
@@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer,
 			: "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
 	return (int) ry;
 }
-/********************** timer, tasklet, DIAG <END> ***************************/
+/************************ timer, work, DIAG <END> ****************************/
 
 
 /****************************** /proc stuff **********************************/
@@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
 	struct list_head *lh;
 
 	found = 0;
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		tmp_ops = list_entry(lh, struct appldata_ops, list);
 		if (&tmp_ops->ctl_table[2] == ctl) {
@@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
 		}
 	}
 	if (!found) {
-		spin_unlock_bh(&appldata_ops_lock);
+		spin_unlock(&appldata_ops_lock);
 		return -ENODEV;
 	}
 	ops = ctl->data;
 	if (!try_module_get(ops->owner)) {	// protect this function
-		spin_unlock_bh(&appldata_ops_lock);
+		spin_unlock(&appldata_ops_lock);
 		return -ENODEV;
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	if (!*lenp || *ppos) {
 		*lenp = 0;
@@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
 		return -EFAULT;
 	}
 
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	if ((buf[0] == '1') && (ops->active == 0)) {
-		if (!try_module_get(ops->owner)) {	// protect tasklet
-			spin_unlock_bh(&appldata_ops_lock);
+		// protect work queue callback
+		if (!try_module_get(ops->owner)) {
+			spin_unlock(&appldata_ops_lock);
 			module_put(ops->owner);
 			return -ENODEV;
 		}
@@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
 		}
 		module_put(ops->owner);
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 out:
 	*lenp = len;
 	*ppos += len;
@@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops)
 	}
 	memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table));
 
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		tmp_ops = list_entry(lh, struct appldata_ops, list);
 		P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
@@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops)
 				APPLDATA_PROC_NAME_LENGTH) == 0) {
 			P_ERROR("Name \"%s\" already registered!\n", ops->name);
 			kfree(ops->ctl_table);
-			spin_unlock_bh(&appldata_ops_lock);
+			spin_unlock(&appldata_ops_lock);
 			return -EBUSY;
 		}
 		if (tmp_ops->ctl_nr == ops->ctl_nr) {
 			P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
 			kfree(ops->ctl_table);
-			spin_unlock_bh(&appldata_ops_lock);
+			spin_unlock(&appldata_ops_lock);
 			return -EBUSY;
 		}
 	}
 	list_add(&ops->list, &appldata_ops_list);
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	ops->ctl_table[0].ctl_name = CTL_APPLDATA;
 	ops->ctl_table[0].procname = appldata_proc_name;
@@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops)
  */
 void appldata_unregister_ops(struct appldata_ops *ops)
 {
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	unregister_sysctl_table(ops->sysctl_header);
 	list_del(&ops->list);
 	kfree(ops->ctl_table);
 	ops->ctl_table = NULL;
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 	P_INFO("%s-ops unregistered!\n", ops->name);
 }
 /********************** module-ops management <END> **************************/
@@ -602,7 +607,7 @@ appldata_online_cpu(int cpu)
 	init_virt_timer(&per_cpu(appldata_timer, cpu));
 	per_cpu(appldata_timer, cpu).function = appldata_timer_function;
 	per_cpu(appldata_timer, cpu).data = (unsigned long)
-		&appldata_tasklet_struct;
+		&appldata_work;
 	atomic_inc(&appldata_expire_count);
 	spin_lock(&appldata_timer_lock);
 	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu)
 	del_virt_timer(&per_cpu(appldata_timer, cpu));
 	if (atomic_dec_and_test(&appldata_expire_count)) {
 		atomic_set(&appldata_expire_count, num_online_cpus());
-		tasklet_schedule(&appldata_tasklet_struct);
+		queue_work(appldata_wq, &appldata_work);
 	}
 	spin_lock(&appldata_timer_lock);
 	__appldata_vtimer_setup(APPLDATA_MOD_TIMER);
@@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = {
 /*
  * appldata_init()
  *
- * init timer and tasklet, register /proc entries
+ * init timer, register /proc entries
  */
 static int __init appldata_init(void)
 {
@@ -657,6 +662,12 @@ static int __init appldata_init(void)
 	P_DEBUG("sizeof(parameter_list) = %lu\n",
 		sizeof(struct appldata_parameter_list));
 
+	appldata_wq = create_singlethread_workqueue("appldata");
+	if (!appldata_wq) {
+		P_ERROR("Could not create work queue\n");
+		return -ENOMEM;
+	}
+
 	for_each_online_cpu(i)
 		appldata_online_cpu(i);
 
@@ -670,7 +681,6 @@ static int __init appldata_init(void)
 	appldata_table[1].de->owner = THIS_MODULE;
 #endif
 
-	tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0);
 	P_DEBUG("Base interface initialized.\n");
 	return 0;
 }
@@ -678,7 +688,7 @@ static int __init appldata_init(void)
 /*
  * appldata_exit()
  *
- * stop timer and tasklet, unregister /proc entries
+ * stop timer, unregister /proc entries
  */
 static void __exit appldata_exit(void)
 {
@@ -690,7 +700,7 @@ static void __exit appldata_exit(void)
 	/*
 	 * ops list should be empty, but just in case something went wrong...
 	 */
-	spin_lock_bh(&appldata_ops_lock);
+	spin_lock(&appldata_ops_lock);
 	list_for_each(lh, &appldata_ops_list) {
 		ops = list_entry(lh, struct appldata_ops, list);
 		rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC,
@@ -700,7 +710,7 @@ static void __exit appldata_exit(void)
 				"return code: %d\n", ops->name, rc);
 		}
 	}
-	spin_unlock_bh(&appldata_ops_lock);
+	spin_unlock(&appldata_ops_lock);
 
 	for_each_online_cpu(i)
 		appldata_offline_cpu(i);
@@ -709,7 +719,7 @@ static void __exit appldata_exit(void)
 
 	unregister_sysctl_table(appldata_sysctl_header);
 
-	tasklet_kill(&appldata_tasklet_struct);
+	destroy_workqueue(appldata_wq);
 	P_DEBUG("... module unloaded!\n");
 }
 /**************************** init / exit <END> ******************************/
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 462ee9a84e7655fb39403fdcc4ff2ba83e33823b..f0e2fbed3d4cf86a8000ec212e435546098507fc 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -68,7 +68,7 @@ struct appldata_mem_data {
 	u64 pgmajfault;		/* page faults (major only) */
 // <-- New in 2.6
 
-} appldata_mem_data;
+} __attribute__((packed)) appldata_mem_data;
 
 
 static inline void appldata_debug_print(struct appldata_mem_data *mem_data)
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index dd61638d3027c6eddcaa0bf8bfd5e1d8d2477541..2a4c7432db4ac2960cde34ee6033671fe171cfc5 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -57,7 +57,7 @@ struct appldata_net_sum_data {
 	u64 rx_dropped;		/* no space in linux buffers     */
 	u64 tx_dropped;		/* no space available in linux   */
 	u64 collisions;		/* collisions while transmitting */
-} appldata_net_sum_data;
+} __attribute__((packed)) appldata_net_sum_data;
 
 
 static inline void appldata_print_debug(struct appldata_net_sum_data *net_data)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index b83f074845514ad409f8c5da3e57cf3a2c2b8459..e0a476bf4fd644691bf5b50e93db05a2367b59bd 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -49,7 +49,7 @@ struct appldata_os_per_cpu {
 	u32 per_cpu_softirq;	/* ... spent in softirqs            */
 	u32 per_cpu_iowait;	/* ... spent while waiting for I/O  */
 // <-- New in 2.6
-};
+} __attribute__((packed));
 
 struct appldata_os_data {
 	u64 timestamp;
@@ -75,7 +75,7 @@ struct appldata_os_data {
 
 	/* per cpu data */
 	struct appldata_os_per_cpu os_cpu[0];
-};
+} __attribute__((packed));
 
 static struct appldata_os_data *appldata_os_data;
 
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 26889366929a1ac3d9162a2ba357dd837a143877..06afa3103ace75143d44258c215cc9c3d1a7fb00 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -40,6 +40,7 @@
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unistd.h>
 
 #ifdef CONFIG_S390_SUPPORT
 #include "compat_ptrace.h"
@@ -130,13 +131,19 @@ static int
 peek_user(struct task_struct *child, addr_t addr, addr_t data)
 {
 	struct user *dummy = NULL;
-	addr_t offset, tmp;
+	addr_t offset, tmp, mask;
 
 	/*
 	 * Stupid gdb peeks/pokes the access registers in 64 bit with
 	 * an alignment of 4. Programmers from hell...
 	 */
-	if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+	mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+	if (addr >= (addr_t) &dummy->regs.acrs &&
+	    addr < (addr_t) &dummy->regs.orig_gpr2)
+		mask = 3;
+#endif
+	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
 		return -EIO;
 
 	if (addr < (addr_t) &dummy->regs.acrs) {
@@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+		/*
+		 * Very special case: old & broken 64 bit gdb reading
+		 * from acrs[15]. Result is a 64 bit value. Read the
+		 * 32 bit acrs[15] value and shift it by 32. Sick...
+		 */
+		if (addr == (addr_t) &dummy->regs.acrs[15])
+			tmp = ((unsigned long) child->thread.acrs[15]) << 32;
+		else
+#endif
 		tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
 
 	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
 		 */
 		offset = addr - (addr_t) &dummy->regs.fp_regs;
 		tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
+		if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
+			tmp &= (unsigned long) FPC_VALID_MASK
+				<< (BITS_PER_LONG - 32);
 
 	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
 		/*
@@ -191,13 +211,19 @@ static int
 poke_user(struct task_struct *child, addr_t addr, addr_t data)
 {
 	struct user *dummy = NULL;
-	addr_t offset;
+	addr_t offset, mask;
 
 	/*
 	 * Stupid gdb peeks/pokes the access registers in 64 bit with
 	 * an alignment of 4. Programmers from hell indeed...
 	 */
-	if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK)
+	mask = __ADDR_MASK;
+#ifdef CONFIG_ARCH_S390X
+	if (addr >= (addr_t) &dummy->regs.acrs &&
+	    addr < (addr_t) &dummy->regs.orig_gpr2)
+		mask = 3;
+#endif
+	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
 		return -EIO;
 
 	if (addr < (addr_t) &dummy->regs.acrs) {
@@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
+#ifdef CONFIG_ARCH_S390X
+		/*
+		 * Very special case: old & broken 64 bit gdb writing
+		 * to acrs[15] with a 64 bit value. Ignore the lower
+		 * half of the value and write the upper 32 bit to
+		 * acrs[15]. Sick...
+		 */
+		if (addr == (addr_t) &dummy->regs.acrs[15])
+			child->thread.acrs[15] = (unsigned int) (data >> 32);
+		else
+#endif
 		*(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
 
 	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
@@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
 		 * floating point regs. are stored in the thread structure
 		 */
 		if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
-		    (data & ~FPC_VALID_MASK) != 0)
+		    (data & ~((unsigned long) FPC_VALID_MASK
+			      << (BITS_PER_LONG - 32))) != 0)
 			return -EINVAL;
 		offset = addr - (addr_t) &dummy->regs.fp_regs;
 		*(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
@@ -722,6 +760,13 @@ syscall_trace(struct pt_regs *regs, int entryexit)
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
+	/*
+	 * If the debuffer has set an invalid system call number,
+	 * we prepare to skip the system call restart handling.
+	 */
+	if (!entryexit && regs->gprs[2] >= NR_syscalls)
+		regs->trap = -1;
+
 	/*
 	 * this isn't the same as continuing with a signal, but it will do
 	 * for normal use.  strace only continues with a signal if the
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 80306bc8c799b7c7e8c98d819806a78a1a7eb951..75fde949d12570a68d1a5aaa228fc946fccc0c4b 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
 	 * we are not in an interrupt and that there is a 
 	 * user context.
 	 */
-        if (user_address == 0 || in_interrupt() || !mm)
+        if (user_address == 0 || in_atomic() || !mm)
                 goto no_context;
 
 	/*
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 3e50fdb67626a20a64a85fa6e4d9ec748bcc28ca..62d87b71179b5b63497d6183c6b2f3c66c994fc1 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -204,5 +204,11 @@ config UML_RANDOM
 	http://sourceforge.net/projects/gkernel/).  rngd periodically reads
 	/dev/hwrng and injects the entropy into /dev/random.
 
+config MMAPPER
+	tristate "iomem emulation driver"
+	help
+	This driver allows a host file to be used as emulated IO memory inside
+	UML.
+
 endmenu
 
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 323f72c64cd207bb14e77280e540df3f7957ca45..b2de9916c32c08a543325dde86d8069f1535ea5a 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
 obj-$(CONFIG_SSL) += ssl.o
 obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
 
-obj-$(CONFIG_UML_NET_SLIP) += slip.o
-obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
+obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
+obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
 #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
 obj-$(CONFIG_UML_RANDOM) += random.o
 
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e137c334fe5dba0dee27c937eca6733b293..5d3768156c92b3a9653ac022ce6b9c1f3f486719 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
 {
 	struct winch_data data;
 	unsigned long stack;
-	int fds[2], pid, n, err;
+	int fds[2], n, err;
 	char c;
 
 	err = os_pipe(fds, 1, 1);
 	if(err < 0){
 		printk("winch_tramp : os_pipe failed, err = %d\n", -err);
-		return(err);
+		goto out;
 	}
 
 	data = ((struct winch_data) { .pty_fd 		= fd,
 				      .pipe_fd 		= fds[1],
 				      .close_me 	= fds[0] } );
-	pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
-	if(pid < 0){
+	err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+	if(err < 0){
 		printk("fork of winch_thread failed - errno = %d\n", errno);
-		return(pid);
+		goto out_close;
 	}
 
 	os_close_file(fds[1]);
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
 		printk("winch_tramp : failed to read synchronization byte\n");
 		printk("read failed, err = %d\n", -n);
 		printk("fd %d will not support SIGWINCH\n", fd);
-		*fd_out = -1;
+                err = -EINVAL;
+		goto out_close1;
 	}
-	return(pid);
+	return err ;
+
+ out_close:
+	os_close_file(fds[1]);
+ out_close1:
+	os_close_file(fds[0]);
+ out:
+	return err;
 }
 
 void register_winch(int fd, struct tty_struct *tty)
 {
-	int pid, thread, thread_fd;
+	int pid, thread, thread_fd = -1;
 	int count;
 	char c = 1;
 
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty)
 	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
 			     tty) && (pid == -1)){
 		thread = winch_tramp(fd, tty, &thread_fd);
-		if(fd != -1){
+		if(thread > 0){
 			register_winch_irq(thread_fd, fd, thread, tty);
 
 			count = os_write_file(thread_fd, &c, sizeof(c));
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231dffe058efc6ace1a2364715fd39f081df4..a37a5ac13c22b8fb709d0ced7ec5db0a2629ce63 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/init.h> 
 #include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = {
 	.release	= mmapper_release,
 };
 
+static struct miscdevice mmapper_dev = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= "mmapper",
+	.fops		= &mmapper_fops
+};
+
 static int __init mmapper_init(void)
 {
+	int err;
+
 	printk(KERN_INFO "Mapper v0.1\n");
 
 	v_buf = (char *) find_iomem("mmapper", &mmapper_size);
 	if(mmapper_size == 0){
 		printk(KERN_ERR "mmapper_init - find_iomem failed\n");
-		return(0);
+		goto out;
 	}
 
-	p_buf = __pa(v_buf);
+	err = misc_register(&mmapper_dev);
+	if(err){
+		printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
+		       err);
+		goto out;
+	}
 
-	devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper");
-	return(0);
+	p_buf = __pa(v_buf);
+out:
+	return 0;
 }
 
 static void mmapper_exit(void)
 {
+	misc_deregister(&mmapper_dev);
 }
 
 module_init(mmapper_init);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe4a8131022c13e09e4b2c660ab93b86013..3730d4f1271368e43ee147303973b8490ab153ea 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr)
 	return(0);
 }
 
-void tap_check_ips(char *gate_addr, char *eth_addr)
+void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
 {
 	int tap_addr[4];
 
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1b14202779b686bd93bb5dd053b8ac5bab..bb0dab41c2e43a464f5e7dbfe15c28aca84a197c 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -1,10 +1,7 @@
 #ifndef __UM_SLIP_H
 #define __UM_SLIP_H
 
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars +  * 
-  * terminating END char + initial END char                            */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
 
 struct slip_data {
 	void *dev;
@@ -12,28 +9,12 @@ struct slip_data {
 	char *addr;
 	char *gate_addr;
 	int slave;
-	char ibuf[ENC_BUF_SIZE];
-	char obuf[ENC_BUF_SIZE];
-	int more; /* more data: do not read fd until ibuf has been drained */
-	int pos;
-	int esc;
+	struct slip_proto slip;
 };
 
 extern struct net_user_info slip_user_info;
 
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
 extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
 extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
 
 #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/drivers/slip_common.c b/arch/um/drivers/slip_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..e89cfc68fc3e077b526186fefc4bd8b810bff9e4
--- /dev/null
+++ b/arch/um/drivers/slip_common.c
@@ -0,0 +1,54 @@
+#include <string.h>
+#include "slip_common.h"
+#include "net_user.h"
+
+int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
+{
+	int i, n, size, start;
+
+	if(slip->more > 0){
+		i = 0;
+		while(i < slip->more){
+			size = slip_unesc(slip->ibuf[i++], slip->ibuf,
+					  &slip->pos, &slip->esc);
+			if(size){
+				memcpy(buf, slip->ibuf, size);
+				memmove(slip->ibuf, &slip->ibuf[i],
+					slip->more - i);
+				slip->more = slip->more - i;
+				return size;
+			}
+		}
+		slip->more = 0;
+	}
+
+	n = net_read(fd, &slip->ibuf[slip->pos],
+		     sizeof(slip->ibuf) - slip->pos);
+	if(n <= 0)
+		return n;
+
+	start = slip->pos;
+	for(i = 0; i < n; i++){
+		size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
+				  &slip->esc);
+		if(size){
+			memcpy(buf, slip->ibuf, size);
+			memmove(slip->ibuf, &slip->ibuf[start+i+1],
+				n - (i + 1));
+			slip->more = n - (i + 1);
+			return size;
+		}
+	}
+	return 0;
+}
+
+int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
+{
+	int actual, n;
+
+	actual = slip_esc(buf, slip->obuf, len);
+	n = net_write(fd, slip->obuf, actual);
+	if(n < 0)
+		return n;
+	else return len;
+}
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h
similarity index 60%
rename from arch/um/drivers/slip_proto.h
rename to arch/um/drivers/slip_common.h
index 7206361ace4501f8a438e7b9104e17225d9ccc3b..2ae76d8f1be1ee594a74d54ea9a64c0f068803d9 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_common.h
@@ -1,10 +1,10 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
+#ifndef __UM_SLIP_COMMON_H
+#define __UM_SLIP_COMMON_H
 
-#ifndef __UM_SLIP_PROTO_H__
-#define __UM_SLIP_PROTO_H__
+#define BUF_SIZE 1500
+ /* two bytes each for a (pathological) max packet of escaped chars +  *
+  * terminating END char + initial END char                            */
+#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
 
 /* SLIP protocol characters. */
 #define SLIP_END             0300	/* indicates end of frame	*/
@@ -12,7 +12,8 @@
 #define SLIP_ESC_END         0334	/* ESC ESC_END means END 'data'	*/
 #define SLIP_ESC_ESC         0335	/* ESC ESC_ESC means ESC 'data'	*/
 
-static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
+static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
+                             int *esc)
 {
 	int ret;
 
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
 	return (ptr - d);
 }
 
-#endif
+struct slip_proto {
+	unsigned char ibuf[ENC_BUF_SIZE];
+	unsigned char obuf[ENC_BUF_SIZE];
+	int more; /* more data: do not read fd until ibuf has been drained */
+	int pos;
+	int esc;
+};
+
+#define SLIP_PROTO_INIT { \
+	.ibuf  	= { '\0' }, \
+	.obuf  	= { '\0' }, \
+        .more	= 0, \
+	.pos	= 0, \
+	.esc	= 0 \
+}
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+extern int slip_proto_read(int fd, void *buf, int len,
+			   struct slip_proto *slip);
+extern int slip_proto_write(int fd, void *buf, int len,
+			    struct slip_proto *slip);
+
+#endif
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 0886eedba213ad58926104b8c31b9899d39a82cc..9a6f5c85f902ad997a11538a51c8015a99fb5209 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data)
 		  .addr		= NULL,
 		  .gate_addr 	= init->gate_addr,
 		  .slave  	= -1,
-		  .ibuf  	= { '\0' },
-		  .obuf  	= { '\0' },
-		  .pos 		= 0,
-		  .esc 		= 0,
+		  .slip		= SLIP_PROTO_INIT,
 		  .dev 		= dev });
 
 	dev->init = NULL;
+	dev->header_cache_update = NULL;
+	dev->hard_header_cache = NULL;
+	dev->hard_header = NULL;
 	dev->hard_header_len = 0;
-	dev->addr_len = 4;
-	dev->type = ARPHRD_ETHER;
+	dev->addr_len = 0;
+	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 256;
 	dev->flags = IFF_NOARP;
 	printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index d94846b1b4cfd319e94bbeafbbeb21d7de5979ad..71af444e591f8bff7b097ac57dc85376529fb677 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -13,7 +13,7 @@
 #include "user.h"
 #include "net_user.h"
 #include "slip.h"
-#include "slip_proto.h"
+#include "slip_common.h"
 #include "helper.h"
 #include "os.h"
 
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd)
 	err = os_pipe(fds, 1, 0);
 	if(err < 0){
 		printk("slip_tramp : pipe failed, err = %d\n", -err);
-		return(err);
+		goto out;
 	}
 
 	err = 0;
 	pe_data.stdin = fd;
 	pe_data.stdout = fds[1];
 	pe_data.close_me = fds[0];
-	pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+	err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+	if(err < 0)
+		goto out_close;
+	pid = err;
+
+	output_len = page_size();
+	output = um_kmalloc(output_len);
+	if(output == NULL){
+		printk("slip_tramp : failed to allocate output buffer\n");
+		os_kill_process(pid, 1);
+		err = -ENOMEM;
+		goto out_free;
+	}
 
-	if(pid < 0) err = pid;
-	else {
-		output_len = page_size();
-		output = um_kmalloc(output_len);
-		if(output == NULL)
-			printk("slip_tramp : failed to allocate output "
-			       "buffer\n");
-
-		os_close_file(fds[1]);
-		read_output(fds[0], output, output_len);
-		if(output != NULL){
-			printk("%s", output);
-			kfree(output);
-		}
-		CATCH_EINTR(err = waitpid(pid, &status, 0));
-		if(err < 0)
-			err = errno;
-		else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
-			printk("'%s' didn't exit with status 0\n", argv[0]);
-			err = -EINVAL;
-		}
+	os_close_file(fds[1]);
+	read_output(fds[0], output, output_len);
+	printk("%s", output);
+
+	CATCH_EINTR(err = waitpid(pid, &status, 0));
+	if(err < 0)
+		err = errno;
+	else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
+		printk("'%s' didn't exit with status 0\n", argv[0]);
+		err = -EINVAL;
 	}
+	else err = 0;
 
 	os_close_file(fds[0]);
 
-	return(err);
+out_free:
+	kfree(output);
+	return err;
+
+out_close:
+	os_close_file(fds[0]);
+	os_close_file(fds[1]);
+out:
+	return err;
 }
 
 static int slip_open(void *data)
@@ -123,21 +133,26 @@ static int slip_open(void *data)
 			 NULL };
 	int sfd, mfd, err;
 
-	mfd = get_pty();
-	if(mfd < 0){
-		printk("umn : Failed to open pty, err = %d\n", -mfd);
-		return(mfd);
+	err = get_pty();
+	if(err < 0){
+		printk("slip-open : Failed to open pty, err = %d\n", -err);
+		goto out;
 	}
-	sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
-	if(sfd < 0){
-		printk("Couldn't open tty for slip line, err = %d\n", -sfd);
-		os_close_file(mfd);
-		return(sfd);
+	mfd = err;
+
+	err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
+	if(err < 0){
+		printk("Couldn't open tty for slip line, err = %d\n", -err);
+		goto out_close;
 	}
-	if(set_up_tty(sfd)) return(-1);
+	sfd = err;
+
+	if(set_up_tty(sfd))
+		goto out_close2;
+
 	pri->slave = sfd;
-	pri->pos = 0;
-	pri->esc = 0;
+	pri->slip.pos = 0;
+	pri->slip.esc = 0;
 	if(pri->gate_addr != NULL){
 		sprintf(version_buf, "%d", UML_NET_VERSION);
 		strcpy(gate_buf, pri->gate_addr);
@@ -146,12 +161,12 @@ static int slip_open(void *data)
 
 		if(err < 0){
 			printk("slip_tramp failed - err = %d\n", -err);
-			return(err);
+			goto out_close2;
 		}
 		err = os_get_ifname(pri->slave, pri->name);
 		if(err < 0){
 			printk("get_ifname failed, err = %d\n", -err);
-			return(err);
+			goto out_close2;
 		}
 		iter_addresses(pri->dev, open_addr, pri->name);
 	}
@@ -160,10 +175,16 @@ static int slip_open(void *data)
 		if(err < 0){
 			printk("Failed to set slip discipline encapsulation - "
 			       "err = %d\n", -err);
-			return(err);
+			goto out_close2;
 		}
 	}
 	return(mfd);
+out_close2:
+	os_close_file(sfd);
+out_close:
+	os_close_file(mfd);
+out:
+	return err;
 }
 
 static void slip_close(int fd, void *data)
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data)
 
 int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
 {
-	int i, n, size, start;
-
-	if(pri->more>0) {
-		i = 0;
-		while(i < pri->more) {
-			size = slip_unesc(pri->ibuf[i++],
-					pri->ibuf, &pri->pos, &pri->esc);
-			if(size){
-				memcpy(buf, pri->ibuf, size);
-				memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
-				pri->more=pri->more-i; 
-				return(size);
-			}
-		}
-		pri->more=0;
-	}
-
-	n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
-	if(n <= 0) return(n);
-
-	start = pri->pos;
-	for(i = 0; i < n; i++){
-		size = slip_unesc(pri->ibuf[start + i],
-				pri->ibuf, &pri->pos, &pri->esc);
-		if(size){
-			memcpy(buf, pri->ibuf, size);
-			memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
-			pri->more=n-(i+1); 
-			return(size);
-		}
-	}
-	return(0);
+	return slip_proto_read(fd, buf, len, &pri->slip);
 }
 
 int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
 {
-	int actual, n;
-
-	actual = slip_esc(buf, pri->obuf, len);
-	n = net_write(fd, pri->obuf, actual);
-	if(n < 0) return(n);
-	else return(len);
+	return slip_proto_write(fd, buf, len, &pri->slip);
 }
 
 static int slip_set_mtu(int mtu, void *data)
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = {
 	.delete_address = slip_del_addr,
 	.max_packet	= BUF_SIZE
 };
-
-/*
- * 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/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d1e44aeceb18ec5ef6313816899a8bd068..6cf88ab580c99a7828fbf545fa8b427ec8b862b5 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -1,10 +1,7 @@
 #ifndef __UM_SLIRP_H
 #define __UM_SLIRP_H
 
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars +  * 
-  * terminating END char + initial END char                            */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
 
 #define SLIRP_MAX_ARGS 100
 /*
@@ -24,28 +21,13 @@ struct slirp_data {
 	struct arg_list_dummy_wrapper argw;
 	int pid;
 	int slave;
-	char ibuf[ENC_BUF_SIZE];
-	char obuf[ENC_BUF_SIZE];
-	int more; /* more data: do not read fd until ibuf has been drained */
-	int pos;
-	int esc;
+	struct slip_proto slip;
 };
 
 extern struct net_user_info slirp_user_info;
 
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
 extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
-extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
+extern int slirp_user_write(int fd, void *buf, int len,
+			    struct slirp_data *pri);
 
 #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/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index c9d6b52a831de0c5836222bb14cf27bb3c760b0a..9864d27afdbe22f27319042030116caef12f93d9 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data)
 		{ .argw 	= init->argw,
 		  .pid  	= -1,
 		  .slave  	= -1,
-		  .ibuf  	= { '\0' },
-		  .obuf  	= { '\0' },
-		  .pos 		= 0,
-		  .esc 		= 0,
+		  .slip		= SLIP_PROTO_INIT,
 		  .dev 		= dev });
 
 	dev->init = NULL;
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c322515c71ccb4071cc6b0e4cf718720d047cbba..8d91f663d82c684267567f2489f8059b738590e8 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -12,7 +12,7 @@
 #include "user.h"
 #include "net_user.h"
 #include "slirp.h"
-#include "slip_proto.h"
+#include "slip_common.h"
 #include "helper.h"
 #include "os.h"
 
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd)
 	return(pid);
 }
 
-/* XXX This is just a trivial wrapper around os_pipe */
-static int slirp_datachan(int *mfd, int *sfd)
-{
-	int fds[2], err;
-
-	err = os_pipe(fds, 1, 1);
-	if(err < 0){
-		printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
-		return(err);
-	}
-
-	*mfd = fds[0];
-	*sfd = fds[1];
-	return(0);
-}
-
 static int slirp_open(void *data)
 {
 	struct slirp_data *pri = data;
-	int sfd, mfd, pid, err;
+	int fds[2], pid, err;
 
-	err = slirp_datachan(&mfd, &sfd);
+	err = os_pipe(fds, 1, 1);
 	if(err)
 		return(err);
 
-	pid = slirp_tramp(pri->argw.argv, sfd);
-
-	if(pid < 0){
-		printk("slirp_tramp failed - errno = %d\n", -pid);
-		os_close_file(sfd);	
-		os_close_file(mfd);	
-		return(pid);
+	err = slirp_tramp(pri->argw.argv, fds[1]);
+	if(err < 0){
+		printk("slirp_tramp failed - errno = %d\n", -err);
+		goto out;
 	}
-
-	pri->slave = sfd;
-	pri->pos = 0;
-	pri->esc = 0;
-
-	pri->pid = pid;
-
-	return(mfd);
+	pid = err;
+
+	pri->slave = fds[1];
+	pri->slip.pos = 0;
+	pri->slip.esc = 0;
+	pri->pid = err;
+
+	return(fds[0]);
+out:
+	os_close_file(fds[0]);
+	os_close_file(fds[1]);
+	return err;
 }
 
 static void slirp_close(int fd, void *data)
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data)
 
 int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
 {
-	int i, n, size, start;
-
-	if(pri->more>0) {
-		i = 0;
-		while(i < pri->more) {
-			size = slip_unesc(pri->ibuf[i++],
-					pri->ibuf,&pri->pos,&pri->esc);
-			if(size){
-				memcpy(buf, pri->ibuf, size);
-				memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
-				pri->more=pri->more-i; 
-				return(size);
-			}
-		}
-		pri->more=0;
-	}
-
-	n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
-	if(n <= 0) return(n);
-
-	start = pri->pos;
-	for(i = 0; i < n; i++){
-		size = slip_unesc(pri->ibuf[start + i],
-				pri->ibuf,&pri->pos,&pri->esc);
-		if(size){
-			memcpy(buf, pri->ibuf, size);
-			memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
-			pri->more=n-(i+1); 
-			return(size);
-		}
-	}
-	return(0);
+	return slip_proto_read(fd, buf, len, &pri->slip);
 }
 
 int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
 {
-	int actual, n;
-
-	actual = slip_esc(buf, pri->obuf, len);
-	n = net_write(fd, pri->obuf, actual);
-	if(n < 0) return(n);
-	else return(len);
+	return slip_proto_write(fd, buf, len, &pri->slip);
 }
 
 static int slirp_set_mtu(int mtu, void *data)
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = {
 	.delete_address = NULL,
 	.max_packet	= BUF_SIZE
 };
-
-/*
- * 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/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b53d170158a678a12b2ba72a582d4220854..429ae8e6c7e514f67fac718d9912828dec7e7768 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string,
 }
 
 static struct console stderr_console = {
-	.name		"stderr",
-	.write		stderr_console_write,
-	.flags		CON_PRINTBUFFER,
+	.name		= "stderr",
+	.write		= stderr_console_write,
+	.flags		= CON_PRINTBUFFER,
 };
 
 static int __init stderr_console_init(void)
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 9fbe3083fdd8c70c7e2ac74e8dbe4f5d7dd238fc..cfa368e045a548b76aa2bd05677effbf584d07f7 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -56,7 +56,7 @@ struct mc_request
 	int as_interrupt;
 
 	int originating_fd;
-	int originlen;
+	unsigned int originlen;
 	unsigned char origin[128];			/* sockaddr_un */
 
 	struct mconsole_request request;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 36807b796e9ffe542e57397034899a91691b898f..89885a77a771f203edbbf39d6fadd6742e54e2e2 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out);
 extern void free_output_buffer(void *buffer);
 
 extern int tap_open_common(void *dev, char *gate_addr);
-extern void tap_check_ips(char *gate_addr, char *eth_addr);
+extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
 
 extern void read_output(int fd, char *output_out, int len);
 
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index d246d5a24609e3657649cc0793b15233c63392db..881d2988d2d80ef2564a41309edf0c93099f4edd 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset);
 extern int os_open_file(char *file, struct openflags flags, int mode);
 extern int os_read_file(int fd, void *buf, int len);
 extern int os_write_file(int fd, const void *buf, int count);
-extern int os_file_size(char *file, long long *size_out);
+extern int os_file_size(char *file, unsigned long long *size_out);
 extern int os_file_modtime(char *file, unsigned long *modtime);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd, int owner);
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 6eaeb9919983ebd71dc6d6120207103fc2a481cf..c8ee9559f3ab2d3994fc83e424627b9c53993607 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -8,6 +8,8 @@
 
 #include "uml-config.h"
 #include "user_constants.h"
+#include "sysdep/faultinfo.h"
+#include "choose-mode.h"
 
 #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
 #define MAX_REG_OFFSET (UM_FRAME_SIZE)
@@ -58,9 +60,6 @@ extern int sysemu_supported;
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #endif
 
-#include "sysdep/faultinfo.h"
-#include "choose-mode.h"
-
 union uml_pt_regs {
 #ifdef UML_CONFIG_MODE_TT
 	struct tt_regs {
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index b8c5b8a952509395c790845e072714093f2655f7..7b6a24dfd302b7b90388a164c72e6c9ee79219f2 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -41,9 +41,6 @@ extern unsigned long highmem;
 extern char host_info[];
 
 extern char saved_command_line[];
-extern char command_line[];
-
-extern char *tempdir;
 
 extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
 extern unsigned long _unprotected_end;
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
index e42e6364ca130a957c67f066f1779d1d040571a2..e59f581526782adca0763540a98bc80505a7a79a 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -24,8 +24,6 @@
 #include "mode.h"
 #include "choose-mode.h"
 #include "uml-config.h"
-#include "irq_user.h"
-#include "time_user.h"
 #include "os.h"
 
 /* Set in set_stklim, which is called from main and __wrap_malloc.
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 51f8e5a8ac6a9d60357888e56462f18f6b2ff93e..1b5ef3e96c7161fad6a8c2c41a927e5d795ee2fa 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -30,7 +30,6 @@
 #include "init.h"
 #include "os.h"
 #include "uml-config.h"
-#include "ptrace_user.h"
 #include "choose-mode.h"
 #include "mode.h"
 #ifdef UML_CONFIG_MODE_SKAS
@@ -131,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
 	return(arg.pid);
 }
 
-static int ptrace_child(void *arg)
+static int ptrace_child(void)
 {
 	int ret;
 	int pid = os_getpid(), ppid = getppid();
@@ -160,20 +159,16 @@ static int ptrace_child(void *arg)
 	_exit(ret);
 }
 
-static int start_ptraced_child(void **stack_out)
+static int start_ptraced_child(void)
 {
-	void *stack;
-	unsigned long sp;
 	int pid, n, status;
 	
-	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if(stack == MAP_FAILED)
-		panic("check_ptrace : mmap failed, errno = %d", errno);
-	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-	pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
+	pid = fork();
+	if(pid == 0)
+		ptrace_child();
+
 	if(pid < 0)
-		panic("check_ptrace : clone failed, errno = %d", errno);
+		panic("check_ptrace : fork failed, errno = %d", errno);
 	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 	if(n < 0)
 		panic("check_ptrace : wait failed, errno = %d", errno);
@@ -181,7 +176,6 @@ static int start_ptraced_child(void **stack_out)
 		panic("check_ptrace : expected SIGSTOP, got status = %d",
 		      status);
 
-	*stack_out = stack;
 	return(pid);
 }
 
@@ -189,12 +183,12 @@ static int start_ptraced_child(void **stack_out)
  * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
  * So only for SYSEMU features we test mustpanic, while normal host features
  * must work anyway!*/
-static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
+static int stop_ptraced_child(int pid, int exitcode, int mustexit)
 {
 	int status, n, ret = 0;
 
 	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-		panic("check_ptrace : ptrace failed, errno = %d", errno);
+		panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
 	CATCH_EINTR(n = waitpid(pid, &status, 0));
 	if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
 		int exit_with = WEXITSTATUS(status);
@@ -205,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
 		printk("check_ptrace : child exited with exitcode %d, while "
 		      "expecting %d; status 0x%x", exit_with,
 		      exitcode, status);
-		if (mustpanic)
+		if (mustexit)
 			panic("\n");
 		else
 			printk("\n");
 		ret = -1;
 	}
 
-	if(munmap(stack, PAGE_SIZE) < 0)
-		panic("check_ptrace : munmap failed, errno = %d", errno);
 	return ret;
 }
 
@@ -235,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
 
 static void __init check_sysemu(void)
 {
-	void *stack;
 	int pid, syscall, n, status, count=0;
 
 	printk("Checking syscall emulation patch for ptrace...");
 	sysemu_supported = 0;
-	pid = start_ptraced_child(&stack);
+	pid = start_ptraced_child();
 
 	if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
 		goto fail;
@@ -258,7 +249,7 @@ static void __init check_sysemu(void)
 		panic("check_sysemu : failed to modify system "
 		      "call return, errno = %d", errno);
 
-	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+	if (stop_ptraced_child(pid, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 1;
@@ -266,7 +257,7 @@ static void __init check_sysemu(void)
 	set_using_sysemu(!force_sysemu_disabled);
 
 	printk("Checking advanced syscall emulation patch for ptrace...");
-	pid = start_ptraced_child(&stack);
+	pid = start_ptraced_child();
 	while(1){
 		count++;
 		if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -291,7 +282,7 @@ static void __init check_sysemu(void)
 			break;
 		}
 	}
-	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+	if (stop_ptraced_child(pid, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 2;
@@ -302,18 +293,17 @@ static void __init check_sysemu(void)
 	return;
 
 fail:
-	stop_ptraced_child(pid, stack, 1, 0);
+	stop_ptraced_child(pid, 1, 0);
 fail_stopped:
 	printk("missing\n");
 }
 
 void __init check_ptrace(void)
 {
-	void *stack;
 	int pid, syscall, n, status;
 
 	printk("Checking that ptrace can change system call numbers...");
-	pid = start_ptraced_child(&stack);
+	pid = start_ptraced_child();
 
 	if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
 		panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -340,7 +330,7 @@ void __init check_ptrace(void)
 			break;
 		}
 	}
-	stop_ptraced_child(pid, stack, 0, 1);
+	stop_ptraced_child(pid, 0, 1);
 	printk("OK\n");
 	check_sysemu();
 }
@@ -372,11 +362,10 @@ void forward_pending_sigio(int target)
 static inline int check_skas3_ptrace_support(void)
 {
 	struct ptrace_faultinfo fi;
-	void *stack;
 	int pid, n, ret = 1;
 
 	printf("Checking for the skas3 patch in the host...");
-	pid = start_ptraced_child(&stack);
+	pid = start_ptraced_child();
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
 	if (n < 0) {
@@ -391,7 +380,7 @@ static inline int check_skas3_ptrace_support(void)
 	}
 
 	init_registers(pid);
-	stop_ptraced_child(pid, stack, 1, 1);
+	stop_ptraced_child(pid, 1, 1);
 
 	return(ret);
 }
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index ab5d3271da0b08229a01964428a4d033fdd0604c..fc71ef295782296d10d118f3cc95b336e6b01fcb 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -68,8 +68,11 @@ void new_thread_handler(int sig)
 	 * 0 if it just exits
 	 */
 	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
-	if(n == 1)
+	if(n == 1){
+		/* Handle any immediate reschedules or signals */
+		interrupt_end();
 		userspace(&current->thread.regs.regs);
+	}
 	else do_exit(0);
 }
 
@@ -96,6 +99,8 @@ void fork_handler(int sig)
 	schedule_tail(current->thread.prev_sched);
 	current->thread.prev_sched = NULL;
 
+	/* Handle any immediate reschedules or signals */
+	interrupt_end();
 	userspace(&current->thread.regs.regs);
 }
 
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 418427107b2936b5cdc880aa113fb8f640367d0f..8736d098f0eed6ce704b137a455c5a0aa5f4660e 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -26,7 +26,6 @@
 #include "asm/setup.h"
 #include "ubd_user.h"
 #include "asm/current.h"
-#include "asm/setup.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "kern.h"
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 9aee0b62ebca19c1551242c49c3e11ed17ad0baf..f0d6060e3e57f601dd5a861e31ca7b7a87a0cf61 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp)
 				elf_aux_hwcap = auxv->a_un.a_val;
 				break;
 			case AT_PLATFORM:
-				elf_aux_platform = auxv->a_un.a_ptr;
+                                /* elf.h removed the pointer elements from
+                                 * a_un, so we have to use a_val, which is
+                                 * all that's left.
+                                 */
+				elf_aux_platform = (char *) auxv->a_un.a_val;
 				break;
 			case AT_PAGESZ:
 				page_size = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 77d4066d1af8e371b6e8255f2920b94043e580a2..fd45bb2609079a3bd3f13339ec8154d6a168ef69 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len)
 		       (int (*)(int, void *, int)) write, copy_to_user_proc));
 }
 
-int os_file_size(char *file, long long *size_out)
+int os_file_size(char *file, unsigned long long *size_out)
 {
 	struct uml_stat buf;
 	int err;
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 0b2491883d9c017d0ce7285d28c1abdfdfb8d8d4..98346c71149346f31be5f367535eea9ee00ca242 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -14,7 +14,7 @@ quiet_cmd_make_link = SYMLINK $@
 cmd_make_link       = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
 
 # this needs to be before the foreach, because targets does not accept
-# complete paths like $(obj)/$(f). To make sure this works, use a := assignment,
+# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
 # or we will get $(obj)/$(f) in the "targets" value.
 # Also, this forces you to use the := syntax when assigning to targets.
 # Otherwise the line below will cause an infinite loop (if you don't know why,
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index a491f72cc96663a79bf26a5e8f642cbab55dac26..504e634749938dcba3775cffb1bad10ecee7d848 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0;
 
 int fix_aperture __initdata = 1;
 
-#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
+/* This code runs before the PCI subsystem is initialized, so just
+   access the northbridge directly. */
 
-static struct resource aper_res = {
-	.name = "Aperture",
-	.flags = IORESOURCE_MEM,
-};
+#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
 static u32 __init allocate_aperture(void) 
 {
@@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void)
 	aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
 	/* 
-	 * Aperture has to be naturally aligned. This means an 2GB
-	 * aperture won't have much chances to find a place in the
-	 * lower 4GB of memory.  Unfortunately we cannot move it up
-	 * because that would make the IOMMU useless.
+	 * Aperture has to be naturally aligned. This means an 2GB aperture won't
+	 * have much chances to find a place in the lower 4GB of memory.
+	 * Unfortunately we cannot move it up because that would make the
+	 * IOMMU useless.
 	 */
-
-	/* First try to find some free unused space */
-	if (!allocate_resource(&iomem_resource, &aper_res,
-			       aper_size,
-			       0, 0xffffffff,
-			       aper_size,
-			       NULL, NULL)) {
-		printk(KERN_INFO "Putting aperture at %lx-%lx\n",
-		       aper_res.start, aper_res.end);
-		return aper_res.start;
-	}
-
-	/* No free space found. Go on to waste some memory... */
 	p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
 	if (!p || __pa(p)+aper_size > 0xffffffff) {
 		printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void)
 			free_bootmem_node(nd0, (unsigned long)p, aper_size); 
 		return 0;
 	}
-	printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
+	printk("Mapping aperture over %d KB of RAM @ %lx\n",
 	       aper_size >> 10, __pa(p)); 
 	return (u32)__pa(p); 
 }
@@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
 		printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
 		return 0; 
 	} 
-	/* Don't check the resource here because the aperture is usually
-	   in an e820 reserved area, and we allocated these earlier. */
 	return 1;
 } 
 
-/*
- * Find a PCI capability.
- * This code runs before the PCI subsystem is initialized, so just
- * access the northbridge directly.
- */
+/* Find a PCI capability */
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
 	u8 pos;
@@ -276,6 +255,8 @@ void __init iommu_hole_init(void)
 		   fallback_aper_force) { 
 		printk("Your BIOS doesn't leave a aperture memory hole\n");
 		printk("Please enable the IOMMU option in the BIOS setup\n");
+		printk("This costs you %d MB of RAM\n",
+		       32 << fallback_aper_order);
 
 		aper_order = fallback_aper_order;
 		aper_alloc = allocate_aperture();
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index d1dcd8eae3c901c3bacb00f08875ebb770141e44..5b77188527a9ad91f8d3f70691ba9c2d4393f4a1 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -39,7 +39,8 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
   fore_200e-objs		+= fore200e_pca_fw.o
   # guess the target endianess to choose the right PCA-200E firmware image
   ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
-    CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi)
+    byteorder.h			:= include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
+    CONFIG_ATM_FORE200E_PCA_FW	:= $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
   endif
 endif
 
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 9e65bfb85ba325285f299dcaf82388146bcafebb..5f702199543ac043eec3905b6231e119e421ba7c 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -383,8 +383,7 @@ fore200e_shutdown(struct fore200e* fore200e)
     switch(fore200e->state) {
 
     case FORE200E_STATE_COMPLETE:
-	if (fore200e->stats)
-	    kfree(fore200e->stats);
+	kfree(fore200e->stats);
 
     case FORE200E_STATE_IRQ:
 	free_irq(fore200e->irq, fore200e->atm_dev);
@@ -963,8 +962,7 @@ fore200e_tx_irq(struct fore200e* fore200e)
 		entry, txq->tail, entry->vc_map, entry->skb);
 
 	/* free copy of misaligned data */
-	if (entry->data)
-	    kfree(entry->data);
+	kfree(entry->data);
 	
 	/* remove DMA mapping */
 	fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 3022c548a132317e4b8c9334b0cd520b63bde32e..df2c83fd5496015ac64025ea9762e90e80c5093f 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -412,8 +412,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
 init_one_failure:
 	if (atm_dev)
 		atm_dev_deregister(atm_dev);
-	if (he_dev)
-		kfree(he_dev);
+	kfree(he_dev);
 	pci_disable_device(pci_dev);
 	return err;
 }
@@ -2534,8 +2533,7 @@ he_open(struct atm_vcc *vcc)
 open_failed:
 
 	if (err) {
-		if (he_vcc)
-			kfree(he_vcc);
+		kfree(he_vcc);
 		clear_bit(ATM_VF_ADDR, &vcc->flags);
 	}
 	else
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 85bf5c8442b000917465b56fb9ce12d2b0e68a14..b2a7b754fd1403a4c7dbd4ffe5ab47cd3de70b5e 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
    PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base);
       
    /* Initialize SCQ0, the only VBR SCQ used */
-   card->scq1 = (scq_info *) NULL;
-   card->scq2 = (scq_info *) NULL;
+   card->scq1 = NULL;
+   card->scq2 = NULL;
    card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0);
-   if (card->scq0 == (scq_info *) NULL)
+   if (card->scq0 == NULL)
    {
       printk("nicstar%d: can't get SCQ0.\n", i);
       error = 12;
@@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd)
    int i;
 
    if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
-      return (scq_info *) NULL;
+      return NULL;
 
    scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL);
-   if (scq == (scq_info *) NULL)
-      return (scq_info *) NULL;
+   if (scq == NULL)
+      return NULL;
    scq->org = kmalloc(2 * size, GFP_KERNEL);
    if (scq->org == NULL)
    {
       kfree(scq);
-      return (scq_info *) NULL;
+      return NULL;
    }
    scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) *
                                           (size / NS_SCQE_SIZE), GFP_KERNEL);
-   if (scq->skb == (struct sk_buff **) NULL)
+   if (scq->skb == NULL)
    {
       kfree(scq->org);
       kfree(scq);
-      return (scq_info *) NULL;
+      return NULL;
    }
    scq->num_entries = size / NS_SCQE_SIZE;
    scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size);
@@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc)
          vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
 
          scq = get_scq(CBR_SCQSIZE, vc->cbr_scd);
-         if (scq == (scq_info *) NULL)
+         if (scq == NULL)
          {
             PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index);
             card->scd2vc[frscdi] = NULL;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 47a800519ad01ed87638b329f1fd4a1213c6a641..8d5e65cb975528203ebb5b951044d9eaf73c91ad 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc)
 		zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
 		dealloc_shaper(vcc->dev,zatm_vcc->shaper);
 	}
-	if (zatm_vcc->ring) kfree(zatm_vcc->ring);
+	kfree(zatm_vcc->ring);
 }
 
 
@@ -1339,12 +1339,9 @@ static int __init zatm_start(struct atm_dev *dev)
 	return 0;
     out:
 	for (i = 0; i < NR_MBX; i++)
-		if (zatm_dev->mbx_start[i] != 0)
-			kfree((void *) zatm_dev->mbx_start[i]);
-	if (zatm_dev->rx_map != NULL)
-		kfree(zatm_dev->rx_map);
-	if (zatm_dev->tx_map != NULL)
-		kfree(zatm_dev->tx_map);
+		kfree(zatm_dev->mbx_start[i]);
+	kfree(zatm_dev->rx_map);
+	kfree(zatm_dev->tx_map);
 	free_irq(zatm_dev->irq, dev);
 	return error;
 }
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
index 0ef7a0065ece2c9468ced12e65016c37b40ad3c4..2210bacad56a34c4023a85036681c51657d19f8b 100644
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -1202,13 +1202,16 @@ retry:
 		if (new_cfqq) {
 			cfqq = new_cfqq;
 			new_cfqq = NULL;
-		} else if (gfp_mask & __GFP_WAIT) {
+		} else {
 			spin_unlock_irq(cfqd->queue->queue_lock);
 			new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
 			spin_lock_irq(cfqd->queue->queue_lock);
+
+			if (!new_cfqq && !(gfp_mask & __GFP_WAIT))
+				goto out;
+
 			goto retry;
-		} else
-			goto out;
+		}
 
 		memset(cfqq, 0, sizeof(*cfqq));
 
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 6b79b4314622053858e17598c50dda88496f06fa..89982925f9e2230d404c78349efe2b415133d5f7 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -220,11 +220,6 @@ void elevator_exit(elevator_t *e)
 	kfree(e);
 }
 
-static int elevator_global_init(void)
-{
-	return 0;
-}
-
 int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
 {
 	elevator_t *e = q->elevator;
@@ -322,7 +317,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
 			int nrq = q->rq.count[READ] + q->rq.count[WRITE]
 				  - q->in_flight;
 
-			if (nrq == q->unplug_thresh)
+			if (nrq >= q->unplug_thresh)
 				__generic_unplug_device(q);
 		}
 	} else
@@ -692,8 +687,6 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
 	return len;
 }
 
-module_init(elevator_global_init);
-
 EXPORT_SYMBOL(elv_add_request);
 EXPORT_SYMBOL(__elv_add_request);
 EXPORT_SYMBOL(elv_requeue_request);
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index ce42889f98fbdac287a2af1d50a8c66346a5433a..19c5e59bcfa826966d433c2edd6f921592a7f40f 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -8,13 +8,12 @@
  * and is not licensed separately. See file COPYING for details.
  *
  * TODO (sorted by decreasing priority)
+ *  -- Kill first_open (Al Viro fixed the block layer now)
  *  -- Do resets with usb_device_reset (needs a thread context, use khubd)
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
- *  -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...)
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
  *  -- verify the 13 conditions and do bulk resets
- *  -- normal pool of commands instead of cmdv[]?
  *  -- kill last_pipe and simply do two-state clearing on both pipes
  *  -- verify protocol (bulk) from USB descriptors (maybe...)
  *  -- highmem and sg
@@ -49,7 +48,14 @@
 #define US_SC_SCSI	0x06		/* Transparent */
 
 /*
+ * This many LUNs per USB device.
+ * Every one of them takes a host, see UB_MAX_HOSTS.
  */
+#define UB_MAX_LUNS   9
+
+/*
+ */
+
 #define UB_MINORS_PER_MAJOR	8
 
 #define UB_MAX_CDB_SIZE      16		/* Corresponds to Bulk */
@@ -65,7 +71,7 @@ struct bulk_cb_wrap {
 	u32	Tag;			/* unique per command id */
 	__le32	DataTransferLength;	/* size of data */
 	u8	Flags;			/* direction in bit 0 */
-	u8	Lun;			/* LUN normally 0 */
+	u8	Lun;			/* LUN */
 	u8	Length;			/* of of the CDB */
 	u8	CDB[UB_MAX_CDB_SIZE];	/* max command */
 };
@@ -168,6 +174,7 @@ struct ub_scsi_cmd {
 	unsigned int len;		/* Requested length */
 	// struct scatterlist sgv[UB_MAX_REQ_SG];
 
+	struct ub_lun *lun;
 	void (*done)(struct ub_dev *, struct ub_scsi_cmd *);
 	void *back;
 };
@@ -252,25 +259,47 @@ struct ub_scsi_cmd_queue {
 };
 
 /*
- * The UB device instance.
+ * The block device instance (one per LUN).
+ */
+struct ub_lun {
+	struct ub_dev *udev;
+	struct list_head link;
+	struct gendisk *disk;
+	int id;				/* Host index */
+	int num;			/* LUN number */
+	char name[16];
+
+	int changed;			/* Media was changed */
+	int removable;
+	int readonly;
+	int first_open;			/* Kludge. See ub_bd_open. */
+
+	/* Use Ingo's mempool if or when we have more than one command. */
+	/*
+	 * Currently we never need more than one command for the whole device.
+	 * However, giving every LUN a command is a cheap and automatic way
+	 * to enforce fairness between them.
+	 */
+	int cmda[1];
+	struct ub_scsi_cmd cmdv[1];
+
+	struct ub_capacity capacity; 
+};
+
+/*
+ * The USB device instance.
  */
 struct ub_dev {
 	spinlock_t lock;
-	int id;				/* Number among ub's */
 	atomic_t poison;		/* The USB device is disconnected */
 	int openc;			/* protected by ub_lock! */
 					/* kref is too implicit for our taste */
 	unsigned int tagcnt;
-	int changed;			/* Media was changed */
-	int removable;
-	int readonly;
-	int first_open;			/* Kludge. See ub_bd_open. */
-	char name[8];
+	char name[12];
 	struct usb_device *dev;
 	struct usb_interface *intf;
 
-	struct ub_capacity capacity; 
-	struct gendisk *disk;
+	struct list_head luns;
 
 	unsigned int send_bulk_pipe;	/* cached pipe values */
 	unsigned int recv_bulk_pipe;
@@ -279,10 +308,6 @@ struct ub_dev {
 
 	struct tasklet_struct tasklet;
 
-	/* XXX Use Ingo's mempool (once we have more than one) */
-	int cmda[1];
-	struct ub_scsi_cmd cmdv[1];
-
 	struct ub_scsi_cmd_queue cmd_queue;
 	struct ub_scsi_cmd top_rqs_cmd;	/* REQUEST SENSE */
 	unsigned char top_sense[UB_SENSE_SIZE];
@@ -301,9 +326,9 @@ struct ub_dev {
 /*
  */
 static void ub_cleanup(struct ub_dev *sc);
-static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq);
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq);
+static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq);
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq);
 static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     struct request *rq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -320,8 +345,10 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
-static int ub_sync_tur(struct ub_dev *sc);
-static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret);
+static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
+static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_capacity *ret);
+static int ub_probe_lun(struct ub_dev *sc, int lnum);
 
 /*
  */
@@ -342,6 +369,7 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids);
  */
 #define UB_MAX_HOSTS  26
 static char ub_hostv[UB_MAX_HOSTS];
+
 static DEFINE_SPINLOCK(ub_lock);	/* Locks globals and ->openc */
 
 /*
@@ -406,6 +434,8 @@ static ssize_t ub_diag_show(struct device *dev, char *page)
 {
 	struct usb_interface *intf;
 	struct ub_dev *sc;
+	struct list_head *p;
+	struct ub_lun *lun;
 	int cnt;
 	unsigned long flags;
 	int nc, nh;
@@ -421,9 +451,15 @@ static ssize_t ub_diag_show(struct device *dev, char *page)
 	spin_lock_irqsave(&sc->lock, flags);
 
 	cnt += sprintf(page + cnt,
-	    "qlen %d qmax %d changed %d removable %d readonly %d\n",
-	    sc->cmd_queue.qlen, sc->cmd_queue.qmax,
-	    sc->changed, sc->removable, sc->readonly);
+	    "qlen %d qmax %d\n",
+	    sc->cmd_queue.qlen, sc->cmd_queue.qmax);
+
+	list_for_each (p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		cnt += sprintf(page + cnt,
+		    "lun %u changed %d removable %d readonly %d\n",
+		    lun->num, lun->changed, lun->removable, lun->readonly);
+	}
 
 	if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0;
 	for (j = 0; j < SCMD_TRACE_SZ; j++) {
@@ -523,53 +559,63 @@ static void ub_put(struct ub_dev *sc)
  */
 static void ub_cleanup(struct ub_dev *sc)
 {
+	struct list_head *p;
+	struct ub_lun *lun;
 	request_queue_t *q;
 
-	/* I don't think queue can be NULL. But... Stolen from sx8.c */
-	if ((q = sc->disk->queue) != NULL)
-		blk_cleanup_queue(q);
+	while (!list_empty(&sc->luns)) {
+		p = sc->luns.next;
+		lun = list_entry(p, struct ub_lun, link);
+		list_del(p);
 
-	/*
-	 * If we zero disk->private_data BEFORE put_disk, we have to check
-	 * for NULL all over the place in open, release, check_media and
-	 * revalidate, because the block level semaphore is well inside the
-	 * put_disk. But we cannot zero after the call, because *disk is gone.
-	 * The sd.c is blatantly racy in this area.
-	 */
-	/* disk->private_data = NULL; */
-	put_disk(sc->disk);
-	sc->disk = NULL;
+		/* I don't think queue can be NULL. But... Stolen from sx8.c */
+		if ((q = lun->disk->queue) != NULL)
+			blk_cleanup_queue(q);
+		/*
+		 * If we zero disk->private_data BEFORE put_disk, we have
+		 * to check for NULL all over the place in open, release,
+		 * check_media and revalidate, because the block level
+		 * semaphore is well inside the put_disk.
+		 * But we cannot zero after the call, because *disk is gone.
+		 * The sd.c is blatantly racy in this area.
+		 */
+		/* disk->private_data = NULL; */
+		put_disk(lun->disk);
+		lun->disk = NULL;
+
+		ub_id_put(lun->id);
+		kfree(lun);
+	}
 
-	ub_id_put(sc->id);
 	kfree(sc);
 }
 
 /*
  * The "command allocator".
  */
-static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc)
+static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun)
 {
 	struct ub_scsi_cmd *ret;
 
-	if (sc->cmda[0])
+	if (lun->cmda[0])
 		return NULL;
-	ret = &sc->cmdv[0];
-	sc->cmda[0] = 1;
+	ret = &lun->cmdv[0];
+	lun->cmda[0] = 1;
 	return ret;
 }
 
-static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd)
 {
-	if (cmd != &sc->cmdv[0]) {
+	if (cmd != &lun->cmdv[0]) {
 		printk(KERN_WARNING "%s: releasing a foreign cmd %p\n",
-		    sc->name, cmd);
+		    lun->name, cmd);
 		return;
 	}
-	if (!sc->cmda[0]) {
-		printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name);
+	if (!lun->cmda[0]) {
+		printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name);
 		return;
 	}
-	sc->cmda[0] = 0;
+	lun->cmda[0] = 0;
 }
 
 /*
@@ -630,29 +676,30 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc)
 
 static void ub_bd_rq_fn(request_queue_t *q)
 {
-	struct ub_dev *sc = q->queuedata;
+	struct ub_lun *lun = q->queuedata;
 	struct request *rq;
 
 	while ((rq = elv_next_request(q)) != NULL) {
-		if (ub_bd_rq_fn_1(sc, rq) != 0) {
+		if (ub_bd_rq_fn_1(lun, rq) != 0) {
 			blk_stop_queue(q);
 			break;
 		}
 	}
 }
 
-static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq)
+static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
 {
+	struct ub_dev *sc = lun->udev;
 	struct ub_scsi_cmd *cmd;
 	int rc;
 
-	if (atomic_read(&sc->poison) || sc->changed) {
+	if (atomic_read(&sc->poison) || lun->changed) {
 		blkdev_dequeue_request(rq);
 		ub_end_rq(rq, 0);
 		return 0;
 	}
 
-	if ((cmd = ub_get_cmd(sc)) == NULL)
+	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
@@ -661,32 +708,30 @@ static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq)
 	if (blk_pc_request(rq)) {
 		rc = ub_cmd_build_packet(sc, cmd, rq);
 	} else {
-		rc = ub_cmd_build_block(sc, cmd, rq);
+		rc = ub_cmd_build_block(sc, lun, cmd, rq);
 	}
 	if (rc != 0) {
-		ub_put_cmd(sc, cmd);
+		ub_put_cmd(lun, cmd);
 		ub_end_rq(rq, 0);
-		blk_start_queue(sc->disk->queue);
 		return 0;
 	}
-
 	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;
 	cmd->done = ub_rw_cmd_done;
 	cmd->back = rq;
 
 	cmd->tag = sc->tagcnt++;
 	if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
-		ub_put_cmd(sc, cmd);
+		ub_put_cmd(lun, cmd);
 		ub_end_rq(rq, 0);
-		blk_start_queue(sc->disk->queue);
 		return 0;
 	}
 
 	return 0;
 }
 
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-    struct request *rq)
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct request *rq)
 {
 	int ub_dir;
 #if 0 /* We use rq->buffer for now */
@@ -707,7 +752,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 	sg = &cmd->sgv[0];
 	n_elem = blk_rq_map_sg(q, rq, sg);
 	if (n_elem <= 0) {
-		ub_put_cmd(sc, cmd);
+		ub_put_cmd(lun, cmd);
 		ub_end_rq(rq, 0);
 		blk_start_queue(q);
 		return 0;		/* request with no s/g entries? */
@@ -716,7 +761,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 	if (n_elem != 1) {		/* Paranoia */
 		printk(KERN_WARNING "%s: request with %d segments\n",
 		    sc->name, n_elem);
-		ub_put_cmd(sc, cmd);
+		ub_put_cmd(lun, cmd);
 		ub_end_rq(rq, 0);
 		blk_start_queue(q);
 		return 0;
@@ -748,8 +793,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 	 * The call to blk_queue_hardsect_size() guarantees that request
 	 * is aligned, but it is given in terms of 512 byte units, always.
 	 */
-	block = rq->sector >> sc->capacity.bshift;
-	nblks = rq->nr_sectors >> sc->capacity.bshift;
+	block = rq->sector >> lun->capacity.bshift;
+	nblks = rq->nr_sectors >> lun->capacity.bshift;
 
 	cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
 	/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
@@ -803,7 +848,8 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
 	struct request *rq = cmd->back;
-	struct gendisk *disk = sc->disk;
+	struct ub_lun *lun = cmd->lun;
+	struct gendisk *disk = lun->disk;
 	request_queue_t *q = disk->queue;
 	int uptodate;
 
@@ -818,7 +864,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	else
 		uptodate = 0;
 
-	ub_put_cmd(sc, cmd);
+	ub_put_cmd(lun, cmd);
 	ub_end_rq(rq, uptodate);
 	blk_start_queue(q);
 }
@@ -887,7 +933,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	bcb->Tag = cmd->tag;		/* Endianness is not important */
 	bcb->DataTransferLength = cpu_to_le32(cmd->len);
 	bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0;
-	bcb->Lun = 0;			/* No multi-LUN yet */
+	bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0;
 	bcb->Length = cmd->cdb_len;
 
 	/* copy the command payload */
@@ -1002,9 +1048,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
-			printk(KERN_NOTICE "%s: "
-			    "stall on control pipe for device %u\n",
-			    sc->name, sc->dev->devnum);
+			printk(KERN_NOTICE "%s: stall on control pipe\n",
+			    sc->name);
 			goto Bad_End;
 		}
 
@@ -1025,9 +1070,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
-			printk(KERN_NOTICE "%s: "
-			    "stall on control pipe for device %u\n",
-			    sc->name, sc->dev->devnum);
+			printk(KERN_NOTICE "%s: stall on control pipe\n",
+			    sc->name);
 			goto Bad_End;
 		}
 
@@ -1046,9 +1090,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u"
-				    " (code %d)\n",
-				    sc->name, sc->dev->devnum, rc);
+				    "unable to submit clear (%d)\n",
+				    sc->name, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
 				 * Retrying is pointless. Just do Bad End on it...
@@ -1107,9 +1150,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u"
-				    " (code %d)\n",
-				    sc->name, sc->dev->devnum, rc);
+				    "unable to submit clear (%d)\n",
+				    sc->name, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
 				 * Retrying is pointless. Just do Bad End on it...
@@ -1140,9 +1182,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u"
-				    " (code %d)\n",
-				    sc->name, sc->dev->devnum, rc);
+				    "unable to submit clear (%d)\n",
+				    sc->name, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
 				 * Retrying is pointless. Just do Bad End on it...
@@ -1164,9 +1205,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			 * encounter such a thing, try to read the CSW again.
 			 */
 			if (++cmd->stat_count >= 4) {
-				printk(KERN_NOTICE "%s: "
-				    "unable to get CSW on device %u\n",
-				    sc->name, sc->dev->devnum);
+				printk(KERN_NOTICE "%s: unable to get CSW\n",
+				    sc->name);
 				goto Bad_End;
 			}
 			__ub_state_stat(sc, cmd);
@@ -1207,10 +1247,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 			 */
 			if (++cmd->stat_count >= 4) {
 				printk(KERN_NOTICE "%s: "
-				    "tag mismatch orig 0x%x reply 0x%x "
-				    "on device %u\n",
-				    sc->name, cmd->tag, bcs->Tag,
-				    sc->dev->devnum);
+				    "tag mismatch orig 0x%x reply 0x%x\n",
+				    sc->name, cmd->tag, bcs->Tag);
 				goto Bad_End;
 			}
 			__ub_state_stat(sc, cmd);
@@ -1244,8 +1282,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
 	} else {
 		printk(KERN_WARNING "%s: "
-		    "wrong command state %d on device %u\n",
-		    sc->name, cmd->state, sc->dev->devnum);
+		    "wrong command state %d\n",
+		    sc->name, cmd->state);
 		goto Bad_End;
 	}
 	return;
@@ -1288,7 +1326,6 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 		/* XXX Clear stalls */
-		printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */
 		ub_complete(&sc->work_done);
 		ub_state_done(sc, cmd, rc);
 		return;
@@ -1333,6 +1370,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->data = sc->top_sense;
 	scmd->len = UB_SENSE_SIZE;
+	scmd->lun = cmd->lun;
 	scmd->done = ub_top_sense_done;
 	scmd->back = cmd;
 
@@ -1411,14 +1449,14 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
 	}
 	if (cmd != scmd->back) {
 		printk(KERN_WARNING "%s: "
-		    "sense done for wrong command 0x%x on device %u\n",
-		    sc->name, cmd->tag, sc->dev->devnum);
+		    "sense done for wrong command 0x%x\n",
+		    sc->name, cmd->tag);
 		return;
 	}
 	if (cmd->state != UB_CMDST_SENSE) {
 		printk(KERN_WARNING "%s: "
-		    "sense done with bad cmd state %d on device %u\n",
-		    sc->name, cmd->state, sc->dev->devnum);
+		    "sense done with bad cmd state %d\n",
+		    sc->name, cmd->state);
 		return;
 	}
 
@@ -1429,68 +1467,32 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
 	ub_scsi_urb_compl(sc, cmd);
 }
 
-#if 0
-/* Determine what the maximum LUN supported is */
-int usb_stor_Bulk_max_lun(struct us_data *us)
-{
-	int result;
-
-	/* issue the command */
-	result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
-				 US_BULK_GET_MAX_LUN, 
-				 USB_DIR_IN | USB_TYPE_CLASS | 
-				 USB_RECIP_INTERFACE,
-				 0, us->ifnum, us->iobuf, 1, HZ);
-
-	/* 
-	 * Some devices (i.e. Iomega Zip100) need this -- apparently
-	 * the bulk pipes get STALLed when the GetMaxLUN request is
-	 * processed.   This is, in theory, harmless to all other devices
-	 * (regardless of if they stall or not).
-	 */
-	if (result < 0) {
-		usb_stor_clear_halt(us, us->recv_bulk_pipe);
-		usb_stor_clear_halt(us, us->send_bulk_pipe);
-	}
-
-	US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 
-		  result, us->iobuf[0]);
-
-	/* if we have a successful request, return the result */
-	if (result == 1)
-		return us->iobuf[0];
-
-	/* return the default -- no LUNs */
-	return 0;
-}
-#endif
-
 /*
  * This is called from a process context.
  */
-static void ub_revalidate(struct ub_dev *sc)
+static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
 {
 
-	sc->readonly = 0;	/* XXX Query this from the device */
+	lun->readonly = 0;	/* XXX Query this from the device */
 
-	sc->capacity.nsec = 0;
-	sc->capacity.bsize = 512;
-	sc->capacity.bshift = 0;
+	lun->capacity.nsec = 0;
+	lun->capacity.bsize = 512;
+	lun->capacity.bshift = 0;
 
-	if (ub_sync_tur(sc) != 0)
+	if (ub_sync_tur(sc, lun) != 0)
 		return;			/* Not ready */
-	sc->changed = 0;
+	lun->changed = 0;
 
-	if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
+	if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) {
 		/*
 		 * The retry here means something is wrong, either with the
 		 * device, with the transport, or with our code.
 		 * We keep this because sd.c has retries for capacity.
 		 */
-		if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
-			sc->capacity.nsec = 0;
-			sc->capacity.bsize = 512;
-			sc->capacity.bshift = 0;
+		if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) {
+			lun->capacity.nsec = 0;
+			lun->capacity.bsize = 512;
+			lun->capacity.bshift = 0;
 		}
 	}
 }
@@ -1503,12 +1505,15 @@ static void ub_revalidate(struct ub_dev *sc)
 static int ub_bd_open(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
+	struct ub_lun *lun;
 	struct ub_dev *sc;
 	unsigned long flags;
 	int rc;
 
-	if ((sc = disk->private_data) == NULL)
+	if ((lun = disk->private_data) == NULL)
 		return -ENXIO;
+	sc = lun->udev;
+
 	spin_lock_irqsave(&ub_lock, flags);
 	if (atomic_read(&sc->poison)) {
 		spin_unlock_irqrestore(&ub_lock, flags);
@@ -1529,15 +1534,15 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
 	 * The bottom line is, Al Viro says that we should not allow
 	 * bdev->bd_invalidated to be set when doing add_disk no matter what.
 	 */
-	if (sc->first_open) {
-		if (sc->changed) {
-			sc->first_open = 0;
+	if (lun->first_open) {
+		lun->first_open = 0;
+		if (lun->changed) {
 			rc = -ENOMEDIUM;
 			goto err_open;
 		}
 	}
 
-	if (sc->removable || sc->readonly)
+	if (lun->removable || lun->readonly)
 		check_disk_change(inode->i_bdev);
 
 	/*
@@ -1545,12 +1550,12 @@ static int ub_bd_open(struct inode *inode, struct file *filp)
 	 * under some pretty murky conditions (a failure of READ CAPACITY).
 	 * We may need it one day.
 	 */
-	if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) {
+	if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) {
 		rc = -ENOMEDIUM;
 		goto err_open;
 	}
 
-	if (sc->readonly && (filp->f_mode & FMODE_WRITE)) {
+	if (lun->readonly && (filp->f_mode & FMODE_WRITE)) {
 		rc = -EROFS;
 		goto err_open;
 	}
@@ -1567,7 +1572,8 @@ err_open:
 static int ub_bd_release(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct ub_dev *sc = disk->private_data;
+	struct ub_lun *lun = disk->private_data;
+	struct ub_dev *sc = lun->udev;
 
 	ub_put(sc);
 	return 0;
@@ -1597,20 +1603,14 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp,
  */
 static int ub_bd_revalidate(struct gendisk *disk)
 {
-	struct ub_dev *sc = disk->private_data;
-
-	ub_revalidate(sc);
-	/* This is pretty much a long term P3 */
-	if (!atomic_read(&sc->poison)) {		/* Cover sc->dev */
-		printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",
-		    sc->name, sc->dev->devnum,
-		    sc->capacity.nsec, sc->capacity.bsize);
-	}
+	struct ub_lun *lun = disk->private_data;
+
+	ub_revalidate(lun->udev, lun);
 
 	/* XXX Support sector size switching like in sr.c */
-	blk_queue_hardsect_size(disk->queue, sc->capacity.bsize);
-	set_capacity(disk, sc->capacity.nsec);
-	// set_disk_ro(sdkp->disk, sc->readonly);
+	blk_queue_hardsect_size(disk->queue, lun->capacity.bsize);
+	set_capacity(disk, lun->capacity.nsec);
+	// set_disk_ro(sdkp->disk, lun->readonly);
 
 	return 0;
 }
@@ -1626,9 +1626,9 @@ static int ub_bd_revalidate(struct gendisk *disk)
  */
 static int ub_bd_media_changed(struct gendisk *disk)
 {
-	struct ub_dev *sc = disk->private_data;
+	struct ub_lun *lun = disk->private_data;
 
-	if (!sc->removable)
+	if (!lun->removable)
 		return 0;
 
 	/*
@@ -1640,12 +1640,12 @@ static int ub_bd_media_changed(struct gendisk *disk)
 	 * will fail, then block layer discards the data. Since we never
 	 * spin drives up, such devices simply cannot be used with ub anyway.
 	 */
-	if (ub_sync_tur(sc) != 0) {
-		sc->changed = 1;
+	if (ub_sync_tur(lun->udev, lun) != 0) {
+		lun->changed = 1;
 		return 1;
 	}
 
-	return sc->changed;
+	return lun->changed;
 }
 
 static struct block_device_operations ub_bd_fops = {
@@ -1669,7 +1669,7 @@ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 /*
  * Test if the device has a check condition on it, synchronously.
  */
-static int ub_sync_tur(struct ub_dev *sc)
+static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun)
 {
 	struct ub_scsi_cmd *cmd;
 	enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) };
@@ -1688,6 +1688,7 @@ static int ub_sync_tur(struct ub_dev *sc)
 	cmd->cdb_len = 6;
 	cmd->dir = UB_DIR_NONE;
 	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;			/* This may be NULL, but that's ok */
 	cmd->done = ub_probe_done;
 	cmd->back = &compl;
 
@@ -1718,7 +1719,8 @@ err_alloc:
 /*
  * Read the SCSI capacity synchronously (for probing).
  */
-static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret)
+static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_capacity *ret)
 {
 	struct ub_scsi_cmd *cmd;
 	char *p;
@@ -1743,6 +1745,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret)
 	cmd->state = UB_CMDST_INIT;
 	cmd->data = p;
 	cmd->len = 8;
+	cmd->lun = lun;
 	cmd->done = ub_probe_done;
 	cmd->back = &compl;
 
@@ -1811,6 +1814,90 @@ static void ub_probe_timeout(unsigned long arg)
 	complete(cop);
 }
 
+/*
+ * Get number of LUNs by the way of Bulk GetMaxLUN command.
+ */
+static int ub_sync_getmaxlun(struct ub_dev *sc)
+{
+	int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber;
+	unsigned char *p;
+	enum { ALLOC_SIZE = 1 };
+	struct usb_ctrlrequest *cr;
+	struct completion compl;
+	struct timer_list timer;
+	int nluns;
+	int rc;
+
+	init_completion(&compl);
+
+	rc = -ENOMEM;
+	if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
+		goto err_alloc;
+	*p = 55;
+
+	cr = &sc->work_cr;
+	cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+	cr->bRequest = US_BULK_GET_MAX_LUN;
+	cr->wValue = cpu_to_le16(0);
+	cr->wIndex = cpu_to_le16(ifnum);
+	cr->wLength = cpu_to_le16(1);
+
+	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,
+	    (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);
+	sc->work_urb.transfer_flags = 0;
+	sc->work_urb.actual_length = 0;
+	sc->work_urb.error_count = 0;
+	sc->work_urb.status = 0;
+
+	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
+		if (rc == -EPIPE) {
+			printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
+			     sc->name); /* P3 */
+		} else {
+			printk(KERN_WARNING
+			     "%s: Unable to submit GetMaxLUN (%d)\n",
+			     sc->name, rc);
+		}
+		goto err_submit;
+	}
+
+	init_timer(&timer);
+	timer.function = ub_probe_timeout;
+	timer.data = (unsigned long) &compl;
+	timer.expires = jiffies + UB_CTRL_TIMEOUT;
+	add_timer(&timer);
+
+	wait_for_completion(&compl);
+
+	del_timer_sync(&timer);
+	usb_kill_urb(&sc->work_urb);
+
+	if (sc->work_urb.actual_length != 1) {
+		printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
+		    sc->work_urb.actual_length); /* P3 */
+		nluns = 0;
+	} else {
+		if ((nluns = *p) == 55) {
+			nluns = 0;
+		} else {
+  			/* GetMaxLUN returns the maximum LUN number */
+			nluns += 1;
+			if (nluns > UB_MAX_LUNS)
+				nluns = UB_MAX_LUNS;
+		}
+		printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name,
+		    *p, nluns); /* P3 */
+	}
+
+	kfree(p);
+	return nluns;
+
+err_submit:
+	kfree(p);
+err_alloc:
+	return rc;
+}
+
 /*
  * Clear initial stalls.
  */
@@ -1897,8 +1984,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
 	}
 
 	if (ep_in == NULL || ep_out == NULL) {
-		printk(KERN_NOTICE "%s: device %u failed endpoint check\n",
-		    sc->name, sc->dev->devnum);
+		printk(KERN_NOTICE "%s: failed endpoint check\n",
+		    sc->name);
 		return -EIO;
 	}
 
@@ -1921,8 +2008,7 @@ static int ub_probe(struct usb_interface *intf,
     const struct usb_device_id *dev_id)
 {
 	struct ub_dev *sc;
-	request_queue_t *q;
-	struct gendisk *disk;
+	int nluns;
 	int rc;
 	int i;
 
@@ -1931,6 +2017,7 @@ static int ub_probe(struct usb_interface *intf,
 		goto err_core;
 	memset(sc, 0, sizeof(struct ub_dev));
 	spin_lock_init(&sc->lock);
+	INIT_LIST_HEAD(&sc->luns);
 	usb_init_urb(&sc->work_urb);
 	tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
 	atomic_set(&sc->poison, 0);
@@ -1942,19 +2029,16 @@ static int ub_probe(struct usb_interface *intf,
 	ub_init_completion(&sc->work_done);
 	sc->work_done.done = 1;		/* A little yuk, but oh well... */
 
-	rc = -ENOSR;
-	if ((sc->id = ub_id_get()) == -1)
-		goto err_id;
-	snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a');
-
 	sc->dev = interface_to_usbdev(intf);
 	sc->intf = intf;
 	// sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
-
 	usb_set_intfdata(intf, sc);
 	usb_get_dev(sc->dev);
 	// usb_get_intf(sc->intf);	/* Do we need this? */
 
+	snprintf(sc->name, 12, DRV_NAME "(%d.%d)",
+	    sc->dev->bus->busnum, sc->dev->devnum);
+
 	/* XXX Verify that we can handle the device (from descriptors) */
 
 	ub_get_pipes(sc, sc->dev, intf);
@@ -1992,35 +2076,88 @@ static int ub_probe(struct usb_interface *intf,
 	 * In any case it's not our business how revaliadation is implemented.
 	 */
 	for (i = 0; i < 3; i++) {	/* Retries for benh's key */
-		if ((rc = ub_sync_tur(sc)) <= 0) break;
+		if ((rc = ub_sync_tur(sc, NULL)) <= 0) break;
 		if (rc != 0x6) break;
 		msleep(10);
 	}
 
-	sc->removable = 1;		/* XXX Query this from the device */
-	sc->changed = 1;		/* ub_revalidate clears only */
-	sc->first_open = 1;
+	nluns = 1;
+	for (i = 0; i < 3; i++) {
+		if ((rc = ub_sync_getmaxlun(sc)) < 0) {
+			/* 
+			 * Some devices (i.e. Iomega Zip100) need this --
+			 * apparently the bulk pipes get STALLed when the
+			 * GetMaxLUN request is processed.
+			 * XXX I have a ZIP-100, verify it does this.
+			 */
+			if (rc == -EPIPE) {
+				ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
+				ub_probe_clear_stall(sc, sc->send_bulk_pipe);
+			}
+			break;
+		}
+		if (rc != 0) {
+			nluns = rc;
+			break;
+		}
+		msleep(100);
+	}
 
-	ub_revalidate(sc);
-	/* This is pretty much a long term P3 */
-	printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",
-	    sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize);
+	for (i = 0; i < nluns; i++) {
+		ub_probe_lun(sc, i);
+	}
+	return 0;
+
+	/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
+err_diag:
+	usb_set_intfdata(intf, NULL);
+	// usb_put_intf(sc->intf);
+	usb_put_dev(sc->dev);
+	kfree(sc);
+err_core:
+	return rc;
+}
+
+static int ub_probe_lun(struct ub_dev *sc, int lnum)
+{
+	struct ub_lun *lun;
+	request_queue_t *q;
+	struct gendisk *disk;
+	int rc;
+
+	rc = -ENOMEM;
+	if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
+		goto err_alloc;
+	memset(lun, 0, sizeof(struct ub_lun));
+	lun->num = lnum;
+
+	rc = -ENOSR;
+	if ((lun->id = ub_id_get()) == -1)
+		goto err_id;
+
+	lun->udev = sc;
+	list_add(&lun->link, &sc->luns);
+
+	snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)",
+	    lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num);
+
+	lun->removable = 1;		/* XXX Query this from the device */
+	lun->changed = 1;		/* ub_revalidate clears only */
+	lun->first_open = 1;
+	ub_revalidate(sc, lun);
 
-	/*
-	 * Just one disk per sc currently, but maybe more.
-	 */
 	rc = -ENOMEM;
 	if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
 		goto err_diskalloc;
 
-	sc->disk = disk;
-	sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a');
-	sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a');
+	lun->disk = disk;
+	sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
+	sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
 	disk->major = UB_MAJOR;
-	disk->first_minor = sc->id * UB_MINORS_PER_MAJOR;
+	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
 	disk->fops = &ub_bd_fops;
-	disk->private_data = sc;
-	disk->driverfs_dev = &intf->dev;
+	disk->private_data = lun;
+	disk->driverfs_dev = &sc->intf->dev;	/* XXX Many to one ok? */
 
 	rc = -ENOMEM;
 	if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL)
@@ -2028,28 +2165,17 @@ static int ub_probe(struct usb_interface *intf,
 
 	disk->queue = q;
 
-        // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
+	blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
 	blk_queue_max_hw_segments(q, UB_MAX_REQ_SG);
 	blk_queue_max_phys_segments(q, UB_MAX_REQ_SG);
-	// blk_queue_segment_boundary(q, CARM_SG_BOUNDARY);
+	blk_queue_segment_boundary(q, 0xffffffff);	/* Dubious. */
 	blk_queue_max_sectors(q, UB_MAX_SECTORS);
-	blk_queue_hardsect_size(q, sc->capacity.bsize);
-
-	/*
-	 * This is a serious infraction, caused by a deficiency in the
-	 * USB sg interface (usb_sg_wait()). We plan to remove this once
-	 * we get mileage on the driver and can justify a change to USB API.
-	 * See blk_queue_bounce_limit() to understand this part.
-	 *
-	 * XXX And I still need to be aware of the DMA mask in the HC.
-	 */
-	q->bounce_pfn = blk_max_low_pfn;
-	q->bounce_gfp = GFP_NOIO;
+	blk_queue_hardsect_size(q, lun->capacity.bsize);
 
-	q->queuedata = sc;
+	q->queuedata = lun;
 
-	set_capacity(disk, sc->capacity.nsec);
-	if (sc->removable)
+	set_capacity(disk, lun->capacity.nsec);
+	if (lun->removable)
 		disk->flags |= GENHD_FL_REMOVABLE;
 
 	add_disk(disk);
@@ -2059,22 +2185,20 @@ static int ub_probe(struct usb_interface *intf,
 err_blkqinit:
 	put_disk(disk);
 err_diskalloc:
-	device_remove_file(&sc->intf->dev, &dev_attr_diag);
-err_diag:
-	usb_set_intfdata(intf, NULL);
-	// usb_put_intf(sc->intf);
-	usb_put_dev(sc->dev);
-	ub_id_put(sc->id);
+	list_del(&lun->link);
+	ub_id_put(lun->id);
 err_id:
-	kfree(sc);
-err_core:
+	kfree(lun);
+err_alloc:
 	return rc;
 }
 
 static void ub_disconnect(struct usb_interface *intf)
 {
 	struct ub_dev *sc = usb_get_intfdata(intf);
-	struct gendisk *disk = sc->disk;
+	struct list_head *p;
+	struct ub_lun *lun;
+	struct gendisk *disk;
 	unsigned long flags;
 
 	/*
@@ -2124,14 +2248,18 @@ static void ub_disconnect(struct usb_interface *intf)
 	/*
 	 * Unregister the upper layer.
 	 */
-	if (disk->flags & GENHD_FL_UP)
-		del_gendisk(disk);
-	/*
-	 * I wish I could do:
-	 *    set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);
-	 * As it is, we rely on our internal poisoning and let
-	 * the upper levels to spin furiously failing all the I/O.
-	 */
+	list_for_each (p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		disk = lun->disk;
+		if (disk->flags & GENHD_FL_UP)
+			del_gendisk(disk);
+		/*
+		 * I wish I could do:
+		 *    set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);
+		 * As it is, we rely on our internal poisoning and let
+		 * the upper levels to spin furiously failing all the I/O.
+		 */
+	}
 
 	/*
 	 * Taking a lock on a structure which is about to be freed
@@ -2182,8 +2310,8 @@ static int __init ub_init(void)
 {
 	int rc;
 
-	/* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n",
-			sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev));
+	/* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n",
+			sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun));
 
 	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
 		goto err_regblkdev;
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index ad9c11391d81112409b2aaf27549cb5d766e2219..c1fe013c64f34c31c1d9b9cceded9d0d2b51ad08 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -278,6 +278,8 @@ void agp3_generic_cleanup(void);
 #define AGP_GENERIC_SIZES_ENTRIES 11
 extern struct aper_size_info_16 agp3_generic_sizes[];
 
+#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
+#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
 
 extern int agp_off;
 extern int agp_try_unsupported_boot;
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 0212febda654b06da557ec331e3c4c4893c9bfab..9c9c9c2247cecfe8c48d0607e8a5d5a0b5f0921f 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge)
 	pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 	pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 			(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-			  virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
+			  virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN ));
 	return addr;
 }
 
@@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr)
 	pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 	pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 			(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-			  virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
+			  virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN));
 	agp_generic_destroy_page(addr);
 }
 
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index e62a3c2c44a9b891c5dcdb2fa002cd0a56276c62..3a41672e4d6682112f19a19ee8ceae2752984be0 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
 
 	SetPageReserved(virt_to_page(page_map->real));
 	global_cache_flush();
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
 	/* Calculate the agp offset */
 	for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 399c042f68f04f0634ae7375f3917d1f1475edee..1407945a5892887565219b6594dde1444a6e30ea 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] =
 
 static int amd_8151_configure(void)
 {
-	unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
+	unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
 
 	/* Configure AGP regs in each x86-64 host bridge. */
 	for_each_nb() {
@@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev)
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
-	release_mem_region(virt_to_phys(bridge->gatt_table_real),
+	release_mem_region(virt_to_gart(bridge->gatt_table_real),
 			   amd64_aperture_sizes[bridge->aperture_size_idx].size);
 	agp_remove_bridge(bridge);
 	agp_put_bridge(bridge);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index a65f8827c2831d40f33e0baf5970211e5bba07d9..e572ced9100aeb8d78fc9bdf5379952ae3ff3905 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map)
 
 	SetPageReserved(virt_to_page(page_map->real));
 	err = map_page_into_agp(virt_to_page(page_map->real));
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL || err) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Write out the size register */
 	current_size = A_SIZE_LVL2(agp_bridge->current_size);
@@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
 	/* Calculate the agp offset */
 	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 2f3dfb63bdc6518742ebdbd08e9f88ae800974d8..4d4e602fdc7e7cfa326000b84135583ed866296d 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 			return -ENOMEM;
 		}
 
-		bridge->scratch_page_real = virt_to_phys(addr);
+		bridge->scratch_page_real = virt_to_gart(addr);
 		bridge->scratch_page =
 		    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
 	}
@@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 err_out:
 	if (bridge->driver->needs_scratch_page)
 		bridge->driver->agp_destroy_page(
-				phys_to_virt(bridge->scratch_page_real));
+				gart_to_virt(bridge->scratch_page_real));
 	if (got_gatt)
 		bridge->driver->free_gatt_table(bridge);
 	if (got_keylist) {
@@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
 	if (bridge->driver->agp_destroy_page &&
 	    bridge->driver->needs_scratch_page)
 		bridge->driver->agp_destroy_page(
-				phys_to_virt(bridge->scratch_page_real));
+				gart_to_virt(bridge->scratch_page_real));
 }
 
 /* When we remove the global variable agp_bridge from all drivers
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 1383c3165ea1942143ad8f1fa18872cf78b982d0..ac19fdcd21c1c7583246256edba92157b42d278e 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
 
 		efficeon_private.l1_table[index] = page;
 
-		value = __pa(page) | pati | present | index;
+		value = virt_to_gart(page) | pati | present | index;
 
 		pci_write_config_dword(agp_bridge->dev,
 			EFFICEON_ATTPAGE, value);
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c321a924e38a8241e7d9c9cc2e0927a2bfc384ce..f0079e991bdc4ffaf95c787e50bd9618a848e225 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr)
 	}
 	if (curr->page_count != 0) {
 		for (i = 0; i < curr->page_count; i++) {
-			curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
+			curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
 		}
 	}
 	agp_free_key(curr->key);
@@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
 			agp_free_memory(new);
 			return NULL;
 		}
-		new->memory[i] = virt_to_phys(addr);
+		new->memory[i] = virt_to_gart(addr);
 		new->page_count++;
 	}
        new->bridge = bridge;
@@ -295,19 +295,6 @@ int agp_num_entries(void)
 EXPORT_SYMBOL_GPL(agp_num_entries);
 
 
-static int check_bridge_mode(struct pci_dev *dev)
-{
-	u32 agp3;
-	u8 cap_ptr;
-
-	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
-	pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3);
-	if (agp3 & AGPSTAT_MODE_3_0)
-		return 1;
-	return 0;
-}
-
-
 /**
  *	agp_copy_info  -  copy bridge state information
  *
@@ -328,7 +315,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
 	info->version.minor = bridge->version->minor;
 	info->chipset = SUPPORTED;
 	info->device = bridge->dev;
-	if (check_bridge_mode(bridge->dev))
+	if (bridge->mode & AGPSTAT_MODE_3_0)
 		info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
 	else
 		info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
@@ -661,7 +648,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
 		bridge_agpstat &= ~AGPSTAT_FW;
 
 	/* Check to see if we are operating in 3.0 mode */
-	if (check_bridge_mode(agp_bridge->dev))
+	if (agp_bridge->mode & AGPSTAT_MODE_3_0)
 		agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
 	else
 		agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat);
@@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
 
 	/* Do AGP version specific frobbing. */
 	if (bridge->major_version >= 3) {
-		if (check_bridge_mode(bridge->dev)) {
+		if (bridge->mode & AGPSTAT_MODE_3_0) {
 			/* If we have 3.5, we can do the isoch stuff. */
 			if (bridge->minor_version >= 5)
 				agp_3_5_enable(bridge);
@@ -806,8 +793,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 				break;
 			}
 
-			table = (char *) __get_free_pages(GFP_KERNEL,
-							  page_order);
+			table = alloc_gatt_pages(page_order);
 
 			if (table == NULL) {
 				i++;
@@ -838,7 +824,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 		size = ((struct aper_size_info_fixed *) temp)->size;
 		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
 		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
-		table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+		table = alloc_gatt_pages(page_order);
 	}
 
 	if (table == NULL)
@@ -853,7 +839,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 	agp_gatt_table = (void *)table;
 
 	bridge->driver->cache_flush();
-	bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
+	bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
 					(PAGE_SIZE * (1 << page_order)));
 	bridge->driver->cache_flush();
 
@@ -861,11 +847,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 			ClearPageReserved(page);
 
-		free_pages((unsigned long) table, page_order);
+		free_gatt_pages(table, page_order);
 
 		return -ENOMEM;
 	}
-	bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real);
+	bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real);
 
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = 0; i < num_entries; i++) {
@@ -919,7 +905,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge)
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 		ClearPageReserved(page);
 
-	free_pages((unsigned long) bridge->gatt_table_real, page_order);
+	free_gatt_pages(bridge->gatt_table_real, page_order);
 
 	agp_gatt_table = NULL;
 	bridge->gatt_table = NULL;
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 6052bfa04c728c5a7373597d81137635a3ed71ac..99762b6c19aea2fdc82119d44f28dde30479f969 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void)
 	hp->gart_size = HP_ZX1_GART_SIZE;
 	hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-	hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
+	hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -248,7 +248,7 @@ hp_zx1_configure (void)
 	agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
-		writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+		writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
 		readl(hp->ioc_regs+HP_ZX1_TCNFG);
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index adbea896c0d2e73f0ee6ab5d51c40fa17aedf47d..94943298c03eb42056d00ba73875147bd40b7e24 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp)
 	}
 	memset(lp->alloced_map, 0, map_size);
 
-	lp->paddr = virt_to_phys(lpage);
+	lp->paddr = virt_to_gart(lpage);
 	lp->refcount = 0;
 	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 	return 0;
@@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp)
 	kfree(lp->alloced_map);
 	lp->alloced_map = NULL;
 
-	free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
+	free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
 	atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 8c7d727432bb5b02c25fa22467de24cbd52ef300..51266d6b4d78af9bf138f52dbbdf6f43413ac0c7 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
 	if (new == NULL)
 		return NULL;
 
-	new->memory[0] = virt_to_phys(addr);
+	new->memory[0] = virt_to_gart(addr);
 	if (pg_count == 4) {
 		/* kludge to get 4 physical pages for ARGB cursor */
 		new->memory[1] = new->memory[0] + PAGE_SIZE;
@@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
 	agp_free_key(curr->key);
 	if(curr->type == AGP_PHYS_MEMORY) {
 		if (curr->page_count == 4)
-			i8xx_destroy_pages(phys_to_virt(curr->memory[0]));
+			i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
 		else
 			agp_bridge->driver->agp_destroy_page(
-				 phys_to_virt(curr->memory[0]));
+				 gart_to_virt(curr->memory[0]));
 		vfree(curr->memory);
 	}
 	kfree(curr);
@@ -418,7 +418,8 @@ static void intel_i830_init_gtt_entries(void)
 		case I915_GMCH_GMS_STOLEN_48M:
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
 				gtt_entries = MB(48) - KB(size);
 			else
 				gtt_entries = 0;
@@ -426,7 +427,8 @@ static void intel_i830_init_gtt_entries(void)
 		case I915_GMCH_GMS_STOLEN_64M:
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
 				gtt_entries = MB(64) - KB(size);
 			else
 				gtt_entries = 0;
@@ -1662,6 +1664,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 		}
 		name = "915GM";
 		break;
+	case PCI_DEVICE_ID_INTEL_82945G_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) {
+			bridge->driver = &intel_915_driver;
+		} else {
+			bridge->driver = &intel_845_driver;
+		}
+		name = "945G";
+		break;
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
 		name = "E7505";
@@ -1801,6 +1811,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
 	ID(PCI_DEVICE_ID_INTEL_7205_0),
 	ID(PCI_DEVICE_ID_INTEL_82915G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
+	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 	{ }
 };
 
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 4b3eda2679761ff5937ba044b2047422ad8c03ce..d3aa159c9decbfa0ba99e6b42db5aa7f22ac6859 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -133,11 +133,14 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
 	off_t j;
 	void *temp;
 	struct agp_bridge_data *bridge;
+	u64 *table;
 
 	bridge = mem->bridge;
 	if (!bridge)
 		return -EINVAL;
 
+	table = (u64 *)bridge->gatt_table;
+
 	temp = bridge->current_size;
 
 	switch (bridge->driver->size_type) {
@@ -175,7 +178,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
 	j = pg_start;
 
 	while (j < (pg_start + mem->page_count)) {
-		if (*(bridge->gatt_table + j))
+		if (table[j])
 			return -EBUSY;
 		j++;
 	}
@@ -186,7 +189,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		*(bridge->gatt_table + j) =
+		table[j] =
 		    bridge->driver->mask_memory(bridge, mem->memory[i],
 						mem->type);
 	}
@@ -200,6 +203,7 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start,
 {
 	size_t i;
 	struct agp_bridge_data *bridge;
+	u64 *table;
 
 	bridge = mem->bridge;
 	if (!bridge)
@@ -209,8 +213,10 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start,
 		return -EINVAL;
 	}
 
+	table = (u64 *)bridge->gatt_table;
+
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		*(bridge->gatt_table + i) = 0;
+		table[i] = 0;
 	}
 
 	bridge->driver->tlb_flush(mem);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 10c23302dd840d3bcc747c93871b2b1f9cc36209..a9fb12c20eb72e92aa343413094270022a159e47 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
 	}
 	SetPageReserved(virt_to_page(page_map->real));
 	global_cache_flush();
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
+	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 	/* Create a fake scratch directory */
 	for(i = 0; i < 1024; i++) {
 		writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
-		writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
+		writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
 	}
 
 	retval = serverworks_create_gatt_pages(value->num_entries / 1024);
@@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 	/* Calculate the agp offset */	
 
 	for(i = 0; i < value->num_entries / 1024; i++)
-		writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
+		writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
 
 	return 0;
 }
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a673971f2a90309becddc27835d195bd36f30fad..c8255312b8c1f3728fb608928ebf554913cff4d2 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 
 	bridge->gatt_table_real = (u32 *) table;
 	bridge->gatt_table = (u32 *)table;
-	bridge->gatt_bus_addr = virt_to_phys(table);
+	bridge->gatt_bus_addr = virt_to_gart(table);
 
 	for (i = 0; i < num_entries; i++)
 		bridge->gatt_table[i] = 0;
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 54a2914e3a321a31c0093b9f53fef81934b99427..11c6950158b3d7606bc3bb859ed1c7132177bacb 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -220,5 +220,6 @@
 	{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0, 0, 0}
 
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 5b18bee6492e898936d994dab4c5ec93d93fbecf..cd25f28e26a38874738705d935c37d51de4cda42 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -123,11 +123,6 @@ static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
 
 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 
-	/* This is a hack to work around mysterious freezes on certain
-	 * systems:
-	 */ 
-	radeon_acknowledge_irqs( dev_priv );
-
 	DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, 
 		     RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
 
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 7a245068e3e55e2ba47801ca8ea9fa08f99cf66a..f022f0944434158f31eb3a9b3f0c9da35abadf1b 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1995,9 +1995,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
 	unsigned char ch, gdl;
 	int ignored = 0;
 	int cnt = 0;
-	unsigned char *cp;
-	char *fp;
-	int count;
 	int recv_room;
 	int max = 256;
 	unsigned long flags;
@@ -2011,10 +2008,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
 		//return;
 	}
 
-	cp = tty->flip.char_buf;
-	fp = tty->flip.flag_buf;
-	count = 0;
-
 	// following add by Victor Yu. 09-02-2002
 	if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
 
@@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
 		}
 		while (gdl--) {
 			ch = inb(info->base + UART_RX);
-			count++;
-			*cp++ = ch;
-			*fp++ = 0;
+			tty_insert_flip_char(tty, ch, 0);
 			cnt++;
 			/*
-			   if((count>=HI_WATER) && (info->stop_rx==0)){
+			   if((cnt>=HI_WATER) && (info->stop_rx==0)){
 			   mxser_stoprx(tty);
 			   info->stop_rx=1;
 			   break;
@@ -2061,7 +2052,7 @@ intr_old:
 		if (max-- < 0)
 			break;
 		/*
-		   if((count>=HI_WATER) && (info->stop_rx==0)){
+		   if((cnt>=HI_WATER) && (info->stop_rx==0)){
 		   mxser_stoprx(tty);
 		   info->stop_rx=1;
 		   break;
@@ -2078,36 +2069,33 @@ intr_old:
 			if (++ignored > 100)
 				break;
 		} else {
-			count++;
+			char flag = 0;
 			if (*status & UART_LSR_SPECIAL) {
 				if (*status & UART_LSR_BI) {
-					*fp++ = TTY_BREAK;
+					flag = TTY_BREAK;
 /* added by casper 1/11/2000 */
 					info->icount.brk++;
-
 /* */
 					if (info->flags & ASYNC_SAK)
 						do_SAK(tty);
 				} else if (*status & UART_LSR_PE) {
-					*fp++ = TTY_PARITY;
+					flag = TTY_PARITY;
 /* added by casper 1/11/2000 */
 					info->icount.parity++;
 /* */
 				} else if (*status & UART_LSR_FE) {
-					*fp++ = TTY_FRAME;
+					flag = TTY_FRAME;
 /* added by casper 1/11/2000 */
 					info->icount.frame++;
 /* */
 				} else if (*status & UART_LSR_OE) {
-					*fp++ = TTY_OVERRUN;
+					flag = TTY_OVERRUN;
 /* added by casper 1/11/2000 */
 					info->icount.overrun++;
 /* */
-				} else
-					*fp++ = 0;
-			} else
-				*fp++ = 0;
-			*cp++ = ch;
+				}
+			}
+			tty_insert_flip_char(tty, ch, flag);
 			cnt++;
 			if (cnt >= recv_room) {
 				if (!info->ldisc_stop_rx) {
@@ -2132,13 +2120,13 @@ intr_old:
 		// above add by Victor Yu. 09-02-2002
 	} while (*status & UART_LSR_DR);
 
-      end_intr:		// add by Victor Yu. 09-02-2002
+end_intr:		// add by Victor Yu. 09-02-2002
 
 	mxvar_log.rxcnt[info->port] += cnt;
 	info->mon_data.rxcnt += cnt;
 	info->mon_data.up_rxcnt += cnt;
 	spin_unlock_irqrestore(&info->slock, flags);
-	
+
 	tty_flip_buffer_push(tty);
 }
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 00c7b958361ada06432ffe96173b23222d591b5e..ab82d6addd7fb78bca4cf0d83da3e14a09aa88d6 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -745,7 +745,8 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
 	list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids);
 
 	/* Register our host with the SCSI stack. */
-	scsi_host = scsi_host_alloc(&scsi_driver_template, 0);
+	scsi_host = scsi_host_alloc(&scsi_driver_template,
+				    sizeof (unsigned long));
 	if (!scsi_host) {
 		SBP2_ERR("failed to register scsi host");
 		goto failed_alloc;
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index af0446c6de823d665d4099fb4e7d37be7befe3c2..48fdf1e517cfb07c3771a79f692ca63dd1cdea55 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -54,7 +54,7 @@ static int atkbd_softraw = 1;
 module_param_named(softraw, atkbd_softraw, bool, 0);
 MODULE_PARM_DESC(softraw, "Use software generated rawmode");
 
-static int atkbd_scroll = 1;
+static int atkbd_scroll = 0;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
 
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 42a9f7f6f8cb2a9b31e65404959dfbb1305be942..7bf4be733e9a89f6646ccf979503d8e4797e4400 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -352,7 +352,7 @@ static int alps_reconnect(struct psmouse *psmouse)
 	if (alps_get_status(psmouse, param))
 		return -1;
 
-	if (param[0] & 0x04)
+	if (!(param[0] & 0x04))
 		alps_tap_mode(psmouse, 1);
 
 	if (alps_absolute_mode(psmouse)) {
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index bb9f4044c74deaf0cae595581e3f6cb574bfbcdf..b941ee220997adbc96b50b48862d0e47c687afda 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2593,6 +2593,9 @@ powerbook_sleep_Core99(void)
 	/* Restore VIA */
 	restore_via_state();
 
+	/* tweak LPJ before cpufreq is there */
+	loops_per_jiffy *= 2;
+
 	/* Restore video */
 	pmac_call_early_video_resume();
 
@@ -2613,6 +2616,9 @@ powerbook_sleep_Core99(void)
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
 	pmu_wait_complete(&req);
 
+	/* Restore LPJ, cpufreq will adjust the cpu frequency */
+	loops_per_jiffy /= 2;
+
 	pmac_wakeup_devices();
 
 	return 0;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 1e97b3c12bd5dae147963fa7331ae3512554538d..0c1b8520ef86f9105c20b45632eb00d9a114c8be 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -985,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio,
 	if (!error)
 		return 0;	/* I/O complete */
 
+	if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
+		return error;
+
 	spin_lock(&m->lock);
 	if (!m->nr_valid_paths) {
 		if (!m->queue_if_no_path || m->suspended) {
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 7b74c87b569e77869cbbe72a8c574c1a258059f7..4830b775906104d718b882c720a3ea1d306b96f3 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -573,6 +573,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
 static void i2o_block_event(struct i2o_event *evt)
 {
 	osm_info("block-osm: event received\n");
+	kfree(evt);
 };
 
 /*
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 1c563f905a5964fb094d40ab6626e4b590a6bcb2..a7f15d9f13e5ccd04faa36b6dda826c20e750fbb 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc,
 }
 
 /* --------------------------------------------------------------------- */
-/*
- * high performance HDLC encoder
- * yes, it's ugly, but generates pretty good code
- */
-
-#define ENCODEITERA(j)                         \
-({                                             \
-        if (!(notbitstream & (0x1f0 << j)))    \
-                goto stuff##j;                 \
-  encodeend##j:    	;                      \
-})
-
-#define ENCODEITERB(j)                                          \
-({                                                              \
-  stuff##j:                                                     \
-        bitstream &= ~(0x100 << j);                             \
-        bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |        \
-                ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);  \
-        numbit++;                                               \
-        notbitstream = ~bitstream;                              \
-        goto encodeend##j;                                      \
-})
-
 
 static void encode_hdlc(struct baycom_state *bc)
 {
@@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc)
 	int pkt_len;
         unsigned bitstream, notbitstream, bitbuf, numbit, crc;
 	unsigned char crcarr[2];
+	int j;
 	
 	if (bc->hdlctx.bufcnt > 0)
 		return;
@@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc)
 		pkt_len--;
 		if (!pkt_len)
 			bp = crcarr;
-		ENCODEITERA(0);
-		ENCODEITERA(1);
-		ENCODEITERA(2);
-		ENCODEITERA(3);
-		ENCODEITERA(4);
-		ENCODEITERA(5);
-		ENCODEITERA(6);
-		ENCODEITERA(7);
-		goto enditer;
-		ENCODEITERB(0);
-		ENCODEITERB(1);
-		ENCODEITERB(2);
-		ENCODEITERB(3);
-		ENCODEITERB(4);
-		ENCODEITERB(5);
-		ENCODEITERB(6);
-		ENCODEITERB(7);
-	enditer:
+		for (j = 0; j < 8; j++)
+			if (unlikely(!(notbitstream & (0x1f0 << j)))) {
+				bitstream &= ~(0x100 << j);
+ 				bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) |
+					((bitbuf & ~(((2 << j) << numbit) - 1)) << 1);
+				numbit++;
+				notbitstream = ~bitstream;
+			}
 		numbit += 8;
 		while (numbit >= 8) {
 			*wp++ = bitbuf;
@@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev)
 	bc->stats.rx_packets++;
 }
 
-#define DECODEITERA(j)                                                        \
-({                                                                            \
-        if (!(notbitstream & (0x0fc << j)))              /* flag or abort */  \
-                goto flgabrt##j;                                              \
-        if ((bitstream & (0x1f8 << j)) == (0xf8 << j))   /* stuffed bit */    \
-                goto stuff##j;                                                \
-  enditer##j:      ;                                                           \
-})
-
-#define DECODEITERB(j)                                                                 \
-({                                                                                     \
-  flgabrt##j:                                                                          \
-        if (!(notbitstream & (0x1fc << j))) {              /* abort received */        \
-                state = 0;                                                             \
-                goto enditer##j;                                                       \
-        }                                                                              \
-        if ((bitstream & (0x1fe << j)) != (0x0fc << j))   /* flag received */          \
-                goto enditer##j;                                                       \
-        if (state)                                                                     \
-                do_rxpacket(dev);                                                      \
-        bc->hdlcrx.bufcnt = 0;                                                         \
-        bc->hdlcrx.bufptr = bc->hdlcrx.buf;                                            \
-        state = 1;                                                                     \
-        numbits = 7-j;                                                                 \
-        goto enditer##j;                                                               \
-  stuff##j:                                                                            \
-        numbits--;                                                                     \
-        bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);        \
-        goto enditer##j;                                                               \
-})
-        
 static int receive(struct net_device *dev, int cnt)
 {
 	struct baycom_state *bc = netdev_priv(dev);
@@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt)
 	unsigned char tmp[128];
         unsigned char *cp;
 	int cnt2, ret = 0;
+	int j;
         
         numbits = bc->hdlcrx.numbits;
 	state = bc->hdlcrx.state;
@@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt)
 			bitbuf |= (*cp) << 8;
 			numbits += 8;
 			notbitstream = ~bitstream;
-			DECODEITERA(0);
-			DECODEITERA(1);
-			DECODEITERA(2);
-			DECODEITERA(3);
-			DECODEITERA(4);
-			DECODEITERA(5);
-			DECODEITERA(6);
-			DECODEITERA(7);
-			goto enddec;
-			DECODEITERB(0);
-			DECODEITERB(1);
-			DECODEITERB(2);
-			DECODEITERB(3);
-			DECODEITERB(4);
-			DECODEITERB(5);
-			DECODEITERB(6);
-			DECODEITERB(7);
-		enddec:
+			for (j = 0; j < 8; j++) {
+
+				/* flag or abort */
+			        if (unlikely(!(notbitstream & (0x0fc << j)))) {
+
+					/* abort received */
+					if (!(notbitstream & (0x1fc << j)))
+						state = 0;
+
+					/* not flag received */
+					else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) {
+						if (state)
+							do_rxpacket(dev);
+						bc->hdlcrx.bufcnt = 0;
+						bc->hdlcrx.bufptr = bc->hdlcrx.buf;
+						state = 1;
+						numbits = 7-j;
+						}
+					}
+
+				/* stuffed bit */
+				else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
+					numbits--;
+					bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1);
+					}
+				}
 			while (state && numbits >= 8) {
 				if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) {
 					state = 0;
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 1c553d7efdd9f42b2874f37b08428d96cb4be8a8..ca5914091d3afb9550a80b571312700492d85693 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -389,7 +389,7 @@ config VIA_FIR
 	help
 	  Say Y here if you want to build support for the VIA VT8231
 	  and VIA VT1211 IrDA controllers, found on the motherboards using
-	  those those VIA chipsets. To use this controller, you will need
+	  those VIA chipsets. To use this controller, you will need
 	  to plug a specific 5 pins FIR IrDA dongle in the specific
 	  motherboard connector. The driver provides support for SIR, MIR
 	  and FIR (4Mbps) speeds.
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 13ed8dc1e91d64b5603ca71e363920fd5cf8d90b..55af32e9bf082ad7f8d88b96b2e068eb0e35304f 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -802,13 +802,14 @@ static void veth_tx_timeout(struct net_device *dev)
 
 	spin_lock_irqsave(&port->pending_gate, flags);
 
+	if (!port->pending_lpmask) {
+		spin_unlock_irqrestore(&port->pending_gate, flags);
+		return;
+	}
+
 	printk(KERN_WARNING "%s: Tx timeout!  Resetting lp connections: %08x\n",
 	       dev->name, port->pending_lpmask);
 
-	/* If we've timed out the queue must be stopped, which should
-	 * only ever happen when there is a pending packet. */
-	WARN_ON(! port->pending_lpmask);
-
 	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
 		struct veth_lpar_connection *cnx = veth_cnx[i];
 
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 41e517114807052707dad7bace8529f7080ba25a..c6e8b25f968529837ec3987baac52e7f55d73dea 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -1274,6 +1274,9 @@ static int el3_close(struct net_device *dev)
 		spin_lock_irqsave(&lp->window_lock, flags);
 		update_stats(dev);
 		spin_unlock_irqrestore(&lp->window_lock, flags);
+
+		/* force interrupts off */
+		outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 	}
 
 	link->open--;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c59507f8a76befe001f1313f55b6780423d1e778..d6d0e43dab65cf55db1e6feedcfac4e0874f7898 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -415,7 +415,7 @@ struct rtl8169_private {
 	struct work_struct task;
 };
 
-MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@oss.sgi.com>");
+MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 module_param_array(media, int, &num_media, 0);
 module_param(rx_copybreak, int, 0);
@@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev)
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	/* For gigabit rtl8169, MTU + header + CRC + VLAN */
-	RTL_W16(RxMaxSize, tp->rx_buf_sz);
+	/* Low hurts. Let's disable the filtering. */
+	RTL_W16(RxMaxSize, 16383);
 
 	/* Set Rx Config register */
 	i = rtl8169_rx_config |
@@ -2127,6 +2127,11 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 	}
 }
 
+static inline int rtl8169_fragmented_frame(u32 status)
+{
+	return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
+}
+
 static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
 {
 	u32 opts1 = le32_to_cpu(desc->opts1);
@@ -2177,27 +2182,41 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 
 	while (rx_left > 0) {
 		unsigned int entry = cur_rx % NUM_RX_DESC;
+		struct RxDesc *desc = tp->RxDescArray + entry;
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->RxDescArray[entry].opts1);
+		status = le32_to_cpu(desc->opts1);
 
 		if (status & DescOwn)
 			break;
 		if (status & RxRES) {
-			printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
+			printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
+			       dev->name, status);
 			tp->stats.rx_errors++;
 			if (status & (RxRWT | RxRUNT))
 				tp->stats.rx_length_errors++;
 			if (status & RxCRC)
 				tp->stats.rx_crc_errors++;
+			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
 		} else {
-			struct RxDesc *desc = tp->RxDescArray + entry;
 			struct sk_buff *skb = tp->Rx_skbuff[entry];
 			int pkt_size = (status & 0x00001FFF) - 4;
 			void (*pci_action)(struct pci_dev *, dma_addr_t,
 				size_t, int) = pci_dma_sync_single_for_device;
 
+			/*
+			 * The driver does not support incoming fragmented
+			 * frames. They are seen as a symptom of over-mtu
+			 * sized frames.
+			 */
+			if (unlikely(rtl8169_fragmented_frame(status))) {
+				tp->stats.rx_dropped++;
+				tp->stats.rx_length_errors++;
+				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
+				goto move_on;
+			}
+
 			rtl8169_rx_csum(skb, desc);
 			
 			pci_dma_sync_single_for_cpu(tp->pci_dev,
@@ -2224,7 +2243,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 			tp->stats.rx_bytes += pkt_size;
 			tp->stats.rx_packets++;
 		}
-		
+move_on:		
 		cur_rx++; 
 		rx_left--;
 	}
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index e68cf5fb4920fe70bfbcfb5c43680af523f7e24a..20edeb3457921e5377c68a6e7d69681682fca135 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -100,35 +100,8 @@ static int sh_debug;		/* Debug flag */
 
 #define SHAPER_BANNER	"CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n"
 
-/*
- *	Locking
- */
- 
-static int shaper_lock(struct shaper *sh)
-{
-	/*
-	 *	Lock in an interrupt must fail
-	 */
-	while (test_and_set_bit(0, &sh->locked))
-	{
-		if (!in_interrupt())
-			sleep_on(&sh->wait_queue);
-		else
-			return 0;
-			
-	}
-	return 1;
-}
-
 static void shaper_kick(struct shaper *sh);
 
-static void shaper_unlock(struct shaper *sh)
-{
-	clear_bit(0, &sh->locked);
-	wake_up(&sh->wait_queue);
-	shaper_kick(sh);
-}
-
 /*
  *	Compute clocks on a buffer
  */
@@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec)
  *	Throw a frame at a shaper.
  */
   
-static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
+
+static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct shaper *shaper = dev->priv;
  	struct sk_buff *ptr;
    
- 	/*
- 	 *	Get ready to work on this shaper. Lock may fail if its
- 	 *	an interrupt and locked.
- 	 */
- 	 
- 	if(!shaper_lock(shaper))
- 		return -1;
+	if (down_trylock(&shaper->sem))
+		return -1;
+
  	ptr=shaper->sendq.prev;
  	
  	/*
@@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
                 dev_kfree_skb(ptr);
                 shaper->stats.collisions++;
  	}
- 	shaper_unlock(shaper);
+	shaper_kick(shaper);
+	up(&shaper->sem);
  	return 0;
 }
 
@@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb)
  
 static void shaper_timer(unsigned long data)
 {
-	struct shaper *sh=(struct shaper *)data;
-	shaper_kick(sh);
+	struct shaper *shaper = (struct shaper *)data;
+
+	if (!down_trylock(&shaper->sem)) {
+		shaper_kick(shaper);
+		up(&shaper->sem);
+	} else
+		mod_timer(&shaper->timer, jiffies);
 }
 
 /*
@@ -310,19 +287,6 @@ static void shaper_kick(struct shaper *shaper)
 {
 	struct sk_buff *skb;
 	
-	/*
-	 *	Shaper unlock will kick
-	 */
-	 
-	if (test_and_set_bit(0, &shaper->locked))
-	{
-		if(sh_debug)
-			printk("Shaper locked.\n");
-		mod_timer(&shaper->timer, jiffies);
-		return;
-	}
-
-		
 	/*
 	 *	Walk the list (may be empty)
 	 */
@@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper)
 	 
 	if(skb!=NULL)
 		mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock);
-
-	clear_bit(0, &shaper->locked);
 }
 
 
@@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper)
 static void shaper_flush(struct shaper *shaper)
 {
 	struct sk_buff *skb;
- 	if(!shaper_lock(shaper))
-	{
-		printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n");
- 		return;
-	}
+
+	down(&shaper->sem);
 	while((skb=skb_dequeue(&shaper->sendq))!=NULL)
 		dev_kfree_skb(skb);
-	shaper_unlock(shaper);
+	shaper_kick(shaper);
+	up(&shaper->sem);
 }
 
 /*
@@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev)
  *	ARP and other resolutions and not before.
  */
 
-
-static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct shaper *sh=dev->priv;
-	return shaper_qframe(sh, skb);
-}
-
 static struct net_device_stats *shaper_get_stats(struct net_device *dev)
 {
      	struct shaper *sh=dev->priv;
@@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev)
 	init_timer(&sh->timer);
 	sh->timer.function=shaper_timer;
 	sh->timer.data=(unsigned long)sh;
-	init_waitqueue_head(&sh->wait_queue);
 }
 
 /*
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index fc9b5cd957aa70cfc6c7ca63e1f7c09d960f86de..a0b8848049c9ede346a9160c370d0b1df49c2798 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7,7 +7,12 @@
  * Copyright (C) 2005 Broadcom Corporation.
  *
  * Firmware is:
- * 	Copyright (C) 2000-2003 Broadcom Corporation.
+ *	Derived from proprietary unpublished source code,
+ *	Copyright (C) 2000-2003 Broadcom Corporation.
+ *
+ *	Permission is hereby granted for the distribution of this firmware
+ *	data in hexadecimal or equivalent format, provided this copyright
+ *	notice is accompanying it.
  */
 
 #include <linux/config.h>
@@ -61,8 +66,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.29"
-#define DRV_MODULE_RELDATE	"May 23, 2005"
+#define DRV_MODULE_VERSION	"3.31"
+#define DRV_MODULE_RELDATE	"June 8, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -8555,6 +8560,16 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 
 		case NIC_SRAM_DATA_CFG_LED_MODE_MAC:
 			tp->led_ctrl = LED_CTRL_MODE_MAC;
+
+			/* Default to PHY_1_MODE if 0 (MAC_MODE) is
+			 * read on some older 5700/5701 bootcode.
+			 */
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5700 ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5701)
+				tp->led_ctrl = LED_CTRL_MODE_PHY_1;
+
 			break;
 
 		case SHASTA_EXT_LED_SHARED:
@@ -9680,10 +9695,24 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
 	}
 	if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
 	    DMA_RWCTRL_WRITE_BNDRY_16) {
+		static struct pci_device_id dma_wait_state_chipsets[] = {
+			{ PCI_DEVICE(PCI_VENDOR_ID_APPLE,
+				     PCI_DEVICE_ID_APPLE_UNI_N_PCI15) },
+			{ },
+		};
+
 		/* DMA test passed without adjusting DMA boundary,
-		 * just restore the calculated DMA boundary
+		 * now look for chipsets that are known to expose the
+		 * DMA bug without failing the test.
 		 */
-		tp->dma_rwctrl = saved_dma_rwctrl;
+		if (pci_dev_present(dma_wait_state_chipsets)) {
+			tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK;
+			tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16;
+		}
+		else
+			/* Safe to use the calculated DMA boundary. */
+			tp->dma_rwctrl = saved_dma_rwctrl;
+
 		tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
 	}
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 8132d946c384865287a3271358752aaf34a5e987..30af105271a2883d559c7ec89a2f5b0efe8f3ed6 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -217,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 	kfree(slot->hotplug_slot->info);
 	kfree(slot->hotplug_slot->name);
 	kfree(slot->hotplug_slot);
+	if (slot->dev)
+		pci_dev_put(slot->dev);
 	kfree(slot);
 }
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index c878028ad2151e9393ed93c0d3e86eca0738e62d..225b5e551dd6f53133b982087624b541310bc0ee 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -315,9 +315,12 @@ int cpci_unconfigure_slot(struct slot* slot)
 				    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
 		if (dev) {
 			pci_remove_bus_device(dev);
-			slot->dev = NULL;
+			pci_dev_put(dev);
 		}
 	}
+	pci_dev_put(slot->dev);
+	slot->dev = NULL;
+
 	dbg("%s - exit", __FUNCTION__);
 	return 0;
 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index fe98553c978f335dae47646cee5df32c8f69b42e..f315df2005bca0ca85e4c2bfaa531641ba983933 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -393,7 +393,10 @@ int pci_register_driver(struct pci_driver *drv)
 	drv->driver.bus = &pci_bus_type;
 	drv->driver.probe = pci_device_probe;
 	drv->driver.remove = pci_device_remove;
-	drv->driver.shutdown = pci_device_shutdown,
+	/* FIXME, once all of the existing PCI drivers have been fixed to set
+	 * the pci shutdown function, this test can go away. */
+	if (!drv->driver.shutdown)
+		drv->driver.shutdown = pci_device_shutdown,
 	drv->driver.owner = drv->owner;
 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
 	pci_init_dynids(&drv->dynids);
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 93481b41b613e33b75f1b494074372c80fe299cd..1d2ef1e2ffc6178398c2347b3b4295fee763dda1 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -7173,6 +7173,7 @@
 	080f  Sentry5 DDR/SDR RAM Controller
 	0811  Sentry5 External Interface Core
 	0816  BCM3302 Sentry5 MIPS32 CPU
+	1600  NetXtreme BCM5752 Gigabit Ethernet PCI Express
 	1644  NetXtreme BCM5700 Gigabit Ethernet
 		1014 0277  Broadcom Vigil B5700 1000Base-T
 		1028 00d1  Broadcom BCM5700
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b7ae87823c69777f772717947b6911ffdeac6b2b..fd48b201eb53ac18e443519c17046ba7b68bb94c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -125,7 +125,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags)
 /*
  * Find the extent of a PCI decode..
  */
-static u32 pci_size(u32 base, u32 maxbase, unsigned long mask)
+static u32 pci_size(u32 base, u32 maxbase, u32 mask)
 {
 	u32 size = mask & maxbase;	/* Find the significant bits */
 	if (!size)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 637e9493034bce2bc6d35e9e43efa14decefe5ad..968033fd29f0bfc287a23399e5d6f9e2d8776f82 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -456,20 +456,15 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC,         quirk_amd_8131_ioapic ); 
 
+static void __init quirk_svw_msi(struct pci_dev *dev)
+{
+	pci_msi_quirk = 1;
+	printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi );
 #endif /* CONFIG_X86_IO_APIC */
 
 
-/*
- * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
- * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
- * when written, it makes an internal connection to the PIC.
- * For these devices, this register is defined to be 4 bits wide.
- * Normally this is fine.  However for IO-APIC motherboards, or
- * non-x86 architectures (yes Via exists on PPC among other places),
- * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
- * interrupts delivered properly.
- */
-
 /*
  * FIXME: it is questionable that quirk_via_acpi
  * is needed.  It shows up as an ISA bridge, and does not
@@ -492,28 +487,30 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );
 
-static void quirk_via_irqpic(struct pci_dev *dev)
+/*
+ * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
+ * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
+ * when written, it makes an internal connection to the PIC.
+ * For these devices, this register is defined to be 4 bits wide.
+ * Normally this is fine.  However for IO-APIC motherboards, or
+ * non-x86 architectures (yes Via exists on PPC among other places),
+ * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
+ * interrupts delivered properly.
+ */
+static void quirk_via_irq(struct pci_dev *dev)
 {
 	u8 irq, new_irq;
 
-#ifdef CONFIG_X86_IO_APIC
-	if (nr_ioapics && !skip_ioapic_setup)
-		return;
-#endif
-#ifdef CONFIG_ACPI
-	if (acpi_irq_model != ACPI_IRQ_MODEL_PIC)
-		return;
-#endif
 	new_irq = dev->irq & 0xf;
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	if (new_irq != irq) {
-		printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n",
+		printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",
 			pci_name(dev), irq, new_irq);
 		udelay(15);	/* unknown if delay really needed */
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
 	}
 }
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
 
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 1811cb240315a33c8aea5ddf9d6ccd24c5c51060..27fec8a5eb5bff4642c28160fb4d0ad6941dcd15 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1752,7 +1752,7 @@ config SCSI_NCR53C7xx_FAST
 
 config SUN3_SCSI
 	tristate "Sun3 NCR5380 SCSI"
-	depends on SUN3 && SCSI
+	depends on SUN3 && SCSI && BROKEN
 	help
 	  This option will enable support for the OBIO (onboard io) NCR5380
 	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 54c52349adc53297971c6e04067d931aabf3148d..3be546439252332131fac6aca81cbdea71d9934a 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -665,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 	return ata_pci_init_one(pdev, port_info, n_ports);
 }
 
-/**
- *	piix_init -
- *
- *	LOCKING:
- *
- *	RETURNS:
- *
- */
-
 static int __init piix_init(void)
 {
 	int rc;
@@ -689,13 +680,6 @@ static int __init piix_init(void)
 	return 0;
 }
 
-/**
- *	piix_exit -
- *
- *	LOCKING:
- *
- */
-
 static void __exit piix_exit(void)
 {
 	pci_unregister_driver(&piix_pci_driver);
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 30a88f0e7bd61b4c6a1c2f5919da0c4df656e87e..9e58f134f68bf45767813d249220b322a33b005b 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
 	ata_wait_idle(ap);
 }
 
+
+/**
+ *	ata_tf_load - send taskfile registers to host controller
+ *	@ap: Port to which output is sent
+ *	@tf: ATA taskfile register set
+ *
+ *	Outputs ATA taskfile to standard ATA host controller using MMIO
+ *	or PIO as indicated by the ATA_FLAG_MMIO flag.
+ *	Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ *	Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ *	hob_lbal, hob_lbam, and hob_lbah.
+ *
+ *	This function waits for idle (!BUSY and !DRQ) after writing
+ *	registers.  If the control register has a new value, this
+ *	function also waits for idle after writing control and before
+ *	writing the remaining registers.
+ *
+ *	May be used as the tf_load() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
 void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
 {
 	if (ap->flags & ATA_FLAG_MMIO)
@@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
 }
 
 /**
- *	ata_exec_command - issue ATA command to host controller
+ *	ata_exec_command_pio - issue ATA command to host controller
  *	@ap: port to which command is being issued
  *	@tf: ATA taskfile register set
  *
- *	Issues PIO/MMIO write to ATA command register, with proper
+ *	Issues PIO write to ATA command register, with proper
  *	synchronization with interrupt handler / other threads.
  *
  *	LOCKING:
@@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
 	ata_pause(ap);
 }
 
+
+/**
+ *	ata_exec_command - issue ATA command to host controller
+ *	@ap: port to which command is being issued
+ *	@tf: ATA taskfile register set
+ *
+ *	Issues PIO/MMIO write to ATA command register, with proper
+ *	synchronization with interrupt handler / other threads.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
 void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf)
 {
 	if (ap->flags & ATA_FLAG_MMIO)
@@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf)
 }
 
 /**
- *	ata_tf_read - input device's ATA taskfile shadow registers
+ *	ata_tf_read_pio - input device's ATA taskfile shadow registers
  *	@ap: Port from which input is read
  *	@tf: ATA taskfile register set for storing input
  *
@@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
 	}
 }
 
+
+/**
+ *	ata_tf_read - input device's ATA taskfile shadow registers
+ *	@ap: Port from which input is read
+ *	@tf: ATA taskfile register set for storing input
+ *
+ *	Reads ATA taskfile registers for currently-selected device
+ *	into @tf.
+ *
+ *	Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
+ *	is set, also reads the hob registers.
+ *
+ *	May be used as the tf_read() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
 void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 {
 	if (ap->flags & ATA_FLAG_MMIO)
@@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  *	@ap: port where the device is
  *
  *	Reads ATA taskfile status register for currently-selected device
- *	and return it's value. This also clears pending interrupts
+ *	and return its value. This also clears pending interrupts
  *      from this device
  *
  *	LOCKING:
@@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap)
  *	@ap: port where the device is
  *
  *	Reads ATA taskfile status register for currently-selected device
- *	via MMIO and return it's value. This also clears pending interrupts
+ *	via MMIO and return its value. This also clears pending interrupts
  *      from this device
  *
  *	LOCKING:
@@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
        	return readb((void __iomem *) ap->ioaddr.status_addr);
 }
 
+
+/**
+ *	ata_check_status - Read device status reg & clear interrupt
+ *	@ap: port where the device is
+ *
+ *	Reads ATA taskfile status register for currently-selected device
+ *	and return its value. This also clears pending interrupts
+ *      from this device
+ *
+ *	May be used as the check_status() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
 u8 ata_check_status(struct ata_port *ap)
 {
 	if (ap->flags & ATA_FLAG_MMIO)
@@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap)
 	return ata_check_status_pio(ap);
 }
 
+
+/**
+ *	ata_altstatus - Read device alternate status reg
+ *	@ap: port where the device is
+ *
+ *	Reads ATA taskfile alternate status register for
+ *	currently-selected device and return its value.
+ *
+ *	Note: may NOT be used as the check_altstatus() entry in
+ *	ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
 u8 ata_altstatus(struct ata_port *ap)
 {
 	if (ap->ops->check_altstatus)
@@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap)
 	return inb(ap->ioaddr.altstatus_addr);
 }
 
+
+/**
+ *	ata_chk_err - Read device error reg
+ *	@ap: port where the device is
+ *
+ *	Reads ATA taskfile error register for
+ *	currently-selected device and return its value.
+ *
+ *	Note: may NOT be used as the check_err() entry in
+ *	ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
 u8 ata_chk_err(struct ata_port *ap)
 {
 	if (ap->ops->check_err)
@@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s,
 	}
 }
 
+
+/**
+ *	ata_noop_dev_select - Select device 0/1 on ATA bus
+ *	@ap: ATA channel to manipulate
+ *	@device: ATA device (numbered from zero) to select
+ *
+ *	This function performs no actual function.
+ *
+ *	May be used as the dev_select() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	caller.
+ */
 void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
 {
 }
 
+
 /**
  *	ata_std_dev_select - Select device 0/1 on ATA bus
  *	@ap: ATA channel to manipulate
@@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device)
  *
  *	Use the method defined in the ATA specification to
  *	make either device 0, or device 1, active on the
- *	ATA channel.
+ *	ATA channel.  Works with both PIO and MMIO.
+ *
+ *	May be used as the dev_select() entry in ata_port_operations.
  *
  *	LOCKING:
  *	caller.
@@ -1190,7 +1299,12 @@ err_out:
  *	ata_bus_probe - Reset and probe ATA bus
  *	@ap: Bus to probe
  *
+ *	Master ATA bus probing function.  Initiates a hardware-dependent
+ *	bus reset, then attempts to identify any devices found on
+ *	the bus.
+ *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  *	RETURNS:
  *	Zero on success, non-zero on error.
@@ -1229,10 +1343,14 @@ err_out:
 }
 
 /**
- *	ata_port_probe -
- *	@ap:
+ *	ata_port_probe - Mark port as enabled
+ *	@ap: Port for which we indicate enablement
  *
- *	LOCKING:
+ *	Modify @ap data structure such that the system
+ *	thinks that the entire port is enabled.
+ *
+ *	LOCKING: host_set lock, or some other form of
+ *	serialization.
  */
 
 void ata_port_probe(struct ata_port *ap)
@@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap)
 }
 
 /**
- *	__sata_phy_reset -
- *	@ap:
+ *	__sata_phy_reset - Wake/reset a low-level SATA PHY
+ *	@ap: SATA port associated with target SATA PHY.
+ *
+ *	This function issues commands to standard SATA Sxxx
+ *	PHY registers, to wake up the phy (and device), and
+ *	clear any reset condition.
  *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  */
 void __sata_phy_reset(struct ata_port *ap)
@@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap)
 }
 
 /**
- *	__sata_phy_reset -
- *	@ap:
+ *	sata_phy_reset - Reset SATA bus.
+ *	@ap: SATA port associated with target SATA PHY.
+ *
+ *	This function resets the SATA bus, and then probes
+ *	the bus for devices.
  *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  */
 void sata_phy_reset(struct ata_port *ap)
@@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap)
 }
 
 /**
- *	ata_port_disable -
- *	@ap:
+ *	ata_port_disable - Disable port.
+ *	@ap: Port to be disabled.
  *
- *	LOCKING:
+ *	Modify @ap data structure such that the system
+ *	thinks that the entire port is disabled, and should
+ *	never attempt to probe or communicate with devices
+ *	on this port.
+ *
+ *	LOCKING: host_set lock, or some other form of
+ *	serialization.
  */
 
 void ata_port_disable(struct ata_port *ap)
@@ -1416,7 +1549,10 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
  *	ata_set_mode - Program timings and issue SET FEATURES - XFER
  *	@ap: port on which timings will be programmed
  *
+ *	Set ATA device disk transfer mode (PIO3, UDMA6, etc.).
+ *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  */
 static void ata_set_mode(struct ata_port *ap)
@@ -1467,7 +1603,10 @@ err_out:
  *	@tmout_pat: impatience timeout
  *	@tmout: overall timeout
  *
- *	LOCKING:
+ *	Sleep until ATA Status register bit BSY clears,
+ *	or a timeout occurs.
+ *
+ *	LOCKING: None.
  *
  */
 
@@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
 }
 
 /**
- *	ata_bus_edd -
- *	@ap:
+ *	ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
+ *	@ap: Port to reset and probe
+ *
+ *	Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
+ *	probe the bus.  Not often used these days.
  *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  */
 
@@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
  *	the device is ATA or ATAPI.
  *
  *	LOCKING:
- *	Inherited from caller.  Some functions called by this function
- *	obtain the host_set lock.
+ *	PCI/etc. bus probe sem.
+ *	Obtains host_set lock.
  *
  *	SIDE EFFECTS:
  *	Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
@@ -1876,7 +2019,11 @@ static int fgb(u32 bitmap)
  *	@xfer_mode_out: (output) SET FEATURES - XFER MODE code
  *	@xfer_shift_out: (output) bit shift that selects this mode
  *
+ *	Based on host and device capabilities, determine the
+ *	maximum transfer mode that is amenable to all.
+ *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  *	RETURNS:
  *	Zero on success, negative on error.
@@ -1909,7 +2056,11 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
  *	@ap: Port associated with device @dev
  *	@dev: Device to which command will be sent
  *
+ *	Issue SET FEATURES - XFER MODE command to device @dev
+ *	on port @ap.
+ *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  */
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
@@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 }
 
 /**
- *	ata_sg_clean -
- *	@qc:
+ *	ata_sg_clean - Unmap DMA memory associated with command
+ *	@qc: Command containing DMA memory to be released
+ *
+ *	Unmap all mapped DMA memory associated with this command.
  *
  *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
  */
 
 static void ata_sg_clean(struct ata_queued_cmd *qc)
@@ -1981,7 +2135,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
  *	ata_fill_sg - Fill PCI IDE PRD table
  *	@qc: Metadata associated with taskfile to be transferred
  *
+ *	Fill PCI IDE PRD (scatter-gather) table with segments
+ *	associated with the current disk command.
+ *
  *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
  *
  */
 static void ata_fill_sg(struct ata_queued_cmd *qc)
@@ -2028,7 +2186,13 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
  *	ata_check_atapi_dma - Check whether ATAPI DMA can be supported
  *	@qc: Metadata associated with taskfile to check
  *
+ *	Allow low-level driver to filter ATA PACKET commands, returning
+ *	a status indicating whether or not it is OK to use DMA for the
+ *	supplied PACKET command.
+ *
  *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ *
  *	RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
  */
@@ -2046,6 +2210,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
  *	ata_qc_prep - Prepare taskfile for submission
  *	@qc: Metadata associated with taskfile to be prepared
  *
+ *	Prepare ATA taskfile for submission.
+ *
  *	LOCKING:
  *	spin_lock_irqsave(host_set lock)
  */
@@ -2057,6 +2223,32 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
 	ata_fill_sg(qc);
 }
 
+/**
+ *	ata_sg_init_one - Associate command with memory buffer
+ *	@qc: Command to be associated
+ *	@buf: Memory buffer
+ *	@buflen: Length of memory buffer, in bytes.
+ *
+ *	Initialize the data-related elements of queued_cmd @qc
+ *	to point to a single memory buffer, @buf of byte length @buflen.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+
+
+
+/**
+ *	ata_sg_init_one - Prepare a one-entry scatter-gather list.
+ *	@qc:  Queued command
+ *	@buf:  transfer buffer
+ *	@buflen:  length of buf
+ *
+ *	Builds a single-entry scatter-gather list to initiate a
+ *	transfer utilizing the specified buffer.
+ *
+ *	LOCKING:
+ */
 void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 {
 	struct scatterlist *sg;
@@ -2074,6 +2266,32 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 	sg->length = buflen;
 }
 
+/**
+ *	ata_sg_init - Associate command with scatter-gather table.
+ *	@qc: Command to be associated
+ *	@sg: Scatter-gather table.
+ *	@n_elem: Number of elements in s/g table.
+ *
+ *	Initialize the data-related elements of queued_cmd @qc
+ *	to point to a scatter-gather table @sg, containing @n_elem
+ *	elements.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+
+
+/**
+ *	ata_sg_init - Assign a scatter gather list to a queued command
+ *	@qc:  Queued command
+ *	@sg:  Scatter-gather list
+ *	@n_elem:  length of sg list
+ *
+ *	Attaches a scatter-gather list to a queued command.
+ *
+ *	LOCKING:
+ */
+
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 		 unsigned int n_elem)
 {
@@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 }
 
 /**
- *	ata_sg_setup_one -
- *	@qc:
+ *	ata_sg_setup_one - DMA-map the memory buffer associated with a command.
+ *	@qc: Command with memory buffer to be mapped.
+ *
+ *	DMA-map the memory buffer associated with queued_cmd @qc.
  *
  *	LOCKING:
  *	spin_lock_irqsave(host_set lock)
  *
  *	RETURNS:
- *
+ *	Zero on success, negative on error.
  */
 
 static int ata_sg_setup_one(struct ata_queued_cmd *qc)
@@ -2115,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
 }
 
 /**
- *	ata_sg_setup -
- *	@qc:
+ *	ata_sg_setup - DMA-map the scatter-gather table associated with a command.
+ *	@qc: Command with scatter-gather table to be mapped.
+ *
+ *	DMA-map the scatter-gather table associated with queued_cmd @qc.
  *
  *	LOCKING:
  *	spin_lock_irqsave(host_set lock)
  *
  *	RETURNS:
+ *	Zero on success, negative on error.
  *
  */
 
@@ -2151,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
  *	@ap:
  *
  *	LOCKING:
+ *	None.  (executing in kernel thread context)
  *
  *	RETURNS:
  *
@@ -2198,6 +2422,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
  *	@ap:
  *
  *	LOCKING:
+ *	None.  (executing in kernel thread context)
  */
 
 static void ata_pio_complete (struct ata_port *ap)
@@ -2240,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap)
 	ata_qc_complete(qc, drv_stat);
 }
 
+
+/**
+ *	swap_buf_le16 -
+ *	@buf:  Buffer to swap
+ *	@buf_words:  Number of 16-bit words in buffer.
+ *
+ *	Swap halves of 16-bit words if needed to convert from
+ *	little-endian byte order to native cpu byte order, or
+ *	vice-versa.
+ *
+ *	LOCKING:
+ */
 void swap_buf_le16(u16 *buf, unsigned int buf_words)
 {
 #ifdef __BIG_ENDIAN
@@ -2340,7 +2577,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
 next_sg:
 	sg = &qc->sg[qc->cursg];
 
-next_page:
 	page = sg->page;
 	offset = sg->offset + qc->cursg_ofs;
 
@@ -2348,6 +2584,7 @@ next_page:
 	page = nth_page(page, (offset >> PAGE_SHIFT));
 	offset %= PAGE_SIZE;
 
+	/* don't overrun current sg */
 	count = min(sg->length - qc->cursg_ofs, bytes);
 
 	/* don't cross page boundaries */
@@ -2372,8 +2609,6 @@ next_page:
 	kunmap(page);
 
 	if (bytes) {
-		if (qc->cursg_ofs < sg->length)
-			goto next_page;
 		goto next_sg;
 	}
 }
@@ -2415,6 +2650,7 @@ err_out:
  *	@ap:
  *
  *	LOCKING:
+ *	None.  (executing in kernel thread context)
  */
 
 static void ata_pio_block(struct ata_port *ap)
@@ -2583,6 +2819,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
  *	transaction completed successfully.
  *
  *	LOCKING:
+ *	Inherited from SCSI layer (none, can sleep)
  */
 
 static void ata_qc_timeout(struct ata_queued_cmd *qc)
@@ -2692,6 +2929,7 @@ out:
  *	@dev: Device from whom we request an available command structure
  *
  *	LOCKING:
+ *	None.
  */
 
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
@@ -2717,6 +2955,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
  *	@dev: Device from whom we request an available command structure
  *
  *	LOCKING:
+ *	None.
  */
 
 struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
@@ -2781,6 +3020,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
  *	in case something prevents using it.
  *
  *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
  *
  */
 void ata_qc_free(struct ata_queued_cmd *qc)
@@ -2794,9 +3034,13 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 /**
  *	ata_qc_complete - Complete an active ATA command
  *	@qc: Command to complete
- *	@drv_stat: ATA status register contents
+ *	@drv_stat: ATA Status register contents
+ *
+ *	Indicate to the mid and upper layers that an ATA
+ *	command has completed, with either an ok or not-ok status.
  *
  *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
  *
  */
 
@@ -2892,6 +3136,7 @@ err_out:
 	return -1;
 }
 
+
 /**
  *	ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
  *	@qc: command to issue to device
@@ -2901,6 +3146,8 @@ err_out:
  *	classes called "protocols", and issuing each type of protocol
  *	is slightly different.
  *
+ *	May be used as the qc_issue() entry in ata_port_operations.
+ *
  *	LOCKING:
  *	spin_lock_irqsave(host_set lock)
  *
@@ -2958,7 +3205,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 }
 
 /**
- *	ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ *	ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
  *	@qc: Info associated with this ATA transaction.
  *
  *	LOCKING:
@@ -3065,6 +3312,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
 	     ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 }
 
+
+/**
+ *	ata_bmdma_start - Start a PCI IDE BMDMA transaction
+ *	@qc: Info associated with this ATA transaction.
+ *
+ *	Writes the ATA_DMA_START flag to the DMA command register.
+ *
+ *	May be used as the bmdma_start() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
 void ata_bmdma_start(struct ata_queued_cmd *qc)
 {
 	if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3073,6 +3332,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc)
 		ata_bmdma_start_pio(qc);
 }
 
+
+/**
+ *	ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ *	@qc: Info associated with this ATA transaction.
+ *
+ *	Writes address of PRD table to device's PRD Table Address
+ *	register, sets the DMA control register, and calls
+ *	ops->exec_command() to start the transfer.
+ *
+ *	May be used as the bmdma_setup() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
 void ata_bmdma_setup(struct ata_queued_cmd *qc)
 {
 	if (qc->ap->flags & ATA_FLAG_MMIO)
@@ -3081,6 +3354,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
 		ata_bmdma_setup_pio(qc);
 }
 
+
+/**
+ *	ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ *	@ap: Port associated with this ATA transaction.
+ *
+ *	Clear interrupt and error flags in DMA status register.
+ *
+ *	May be used as the irq_clear() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+
 void ata_bmdma_irq_clear(struct ata_port *ap)
 {
     if (ap->flags & ATA_FLAG_MMIO) {
@@ -3093,6 +3379,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
 
 }
 
+
+/**
+ *	ata_bmdma_status - Read PCI IDE BMDMA status
+ *	@ap: Port associated with this ATA transaction.
+ *
+ *	Read and return BMDMA status register.
+ *
+ *	May be used as the bmdma_status() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+
 u8 ata_bmdma_status(struct ata_port *ap)
 {
 	u8 host_stat;
@@ -3104,6 +3403,19 @@ u8 ata_bmdma_status(struct ata_port *ap)
 	return host_stat;
 }
 
+
+/**
+ *	ata_bmdma_stop - Stop PCI IDE BMDMA transfer
+ *	@ap: Port associated with this ATA transaction.
+ *
+ *	Clears the ATA_DMA_START flag in the dma control register
+ *
+ *	May be used as the bmdma_stop() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	spin_lock_irqsave(host_set lock)
+ */
+
 void ata_bmdma_stop(struct ata_port *ap)
 {
 	if (ap->flags & ATA_FLAG_MMIO) {
@@ -3203,13 +3515,18 @@ idle_irq:
 
 /**
  *	ata_interrupt - Default ATA host interrupt handler
- *	@irq: irq line
- *	@dev_instance: pointer to our host information structure
+ *	@irq: irq line (unused)
+ *	@dev_instance: pointer to our ata_host_set information structure
  *	@regs: unused
  *
+ *	Default interrupt handler for PCI IDE devices.  Calls
+ *	ata_host_intr() for each port that is not disabled.
+ *
  *	LOCKING:
+ *	Obtains host_set lock during operation.
  *
  *	RETURNS:
+ *	IRQ_NONE or IRQ_HANDLED.
  *
  */
 
@@ -3302,6 +3619,19 @@ err_out:
 	ata_qc_complete(qc, ATA_ERR);
 }
 
+
+/**
+ *	ata_port_start - Set port up for dma.
+ *	@ap: Port to initialize
+ *
+ *	Called just after data structures for each port are
+ *	initialized.  Allocates space for PRD table.
+ *
+ *	May be used as the port_start() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ */
+
 int ata_port_start (struct ata_port *ap)
 {
 	struct device *dev = ap->host_set->dev;
@@ -3315,6 +3645,18 @@ int ata_port_start (struct ata_port *ap)
 	return 0;
 }
 
+
+/**
+ *	ata_port_stop - Undo ata_port_start()
+ *	@ap: Port to shut down
+ *
+ *	Frees the PRD table.
+ *
+ *	May be used as the port_stop() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ */
+
 void ata_port_stop (struct ata_port *ap)
 {
 	struct device *dev = ap->host_set->dev;
@@ -3357,7 +3699,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
  *	@ent: Probe information provided by low-level driver
  *	@port_no: Port number associated with this ata_port
  *
+ *	Initialize a new ata_port structure, and its associated
+ *	scsi_host.
+ *
  *	LOCKING:
+ *	Inherited from caller.
  *
  */
 
@@ -3412,9 +3758,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
  *	@host_set: Collections of ports to which we add
  *	@port_no: Port number associated with this host
  *
+ *	Attach low-level ATA driver to system.
+ *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  *	RETURNS:
+ *	New ata_port on success, for NULL on error.
  *
  */
 
@@ -3447,12 +3797,22 @@ err_out:
 }
 
 /**
- *	ata_device_add -
- *	@ent:
+ *	ata_device_add - Register hardware device with ATA and SCSI layers
+ *	@ent: Probe information describing hardware device to be registered
+ *
+ *	This function processes the information provided in the probe
+ *	information struct @ent, allocates the necessary ATA and SCSI
+ *	host information structures, initializes them, and registers
+ *	everything with requisite kernel subsystems.
+ *
+ *	This function requests irqs, probes the ATA bus, and probes
+ *	the SCSI bus.
  *
  *	LOCKING:
+ *	PCI/etc. bus probe sem.
  *
  *	RETURNS:
+ *	Number of ports registered.  Zero on error (no ports registered).
  *
  */
 
@@ -3604,7 +3964,15 @@ int ata_scsi_release(struct Scsi_Host *host)
 /**
  *	ata_std_ports - initialize ioaddr with standard port offsets.
  *	@ioaddr: IO address structure to be initialized
+ *
+ *	Utility function which initializes data_addr, error_addr,
+ *	feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+ *	device_addr, status_addr, and command_addr to standard offsets
+ *	relative to cmd_addr.
+ *
+ *	Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
  */
+
 void ata_std_ports(struct ata_ioports *ioaddr)
 {
 	ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
@@ -3646,6 +4014,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port)
 	return probe_ent;
 }
 
+
+
+/**
+ *	ata_pci_init_native_mode - Initialize native-mode driver
+ *	@pdev:  pci device to be initialized
+ *	@port:  array[2] of pointers to port info structures.
+ *
+ *	Utility function which allocates and initializes an
+ *	ata_probe_ent structure for a standard dual-port
+ *	PIO-based IDE controller.  The returned ata_probe_ent
+ *	structure can be passed to ata_device_add().  The returned
+ *	ata_probe_ent structure should then be freed with kfree().
+ */
+
 #ifdef CONFIG_PCI
 struct ata_probe_ent *
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
@@ -3727,10 +4109,19 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port,
  *	@port_info: Information from low-level host driver
  *	@n_ports: Number of ports attached to host controller
  *
+ *	This is a helper function which can be called from a driver's
+ *	xxx_init_one() probe function if the hardware uses traditional
+ *	IDE taskfile registers.
+ *
+ *	This function calls pci_enable_device(), reserves its register
+ *	regions, sets the dma mask, enables bus master mode, and calls
+ *	ata_device_add()
+ *
  *	LOCKING:
  *	Inherited from PCI layer (may sleep).
  *
  *	RETURNS:
+ *	Zero on success, negative on errno-based value on error.
  *
  */
 
@@ -3949,15 +4340,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
 #endif /* CONFIG_PCI */
 
 
-/**
- *	ata_init -
- *
- *	LOCKING:
- *
- *	RETURNS:
- *
- */
-
 static int __init ata_init(void)
 {
 	ata_wq = create_workqueue("ata");
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 416ba67ba9ee37b1fa0b7cad9ca0bc431e973017..7a4adc4c8f09d6ef9cdb7460f4e6846d0def4647 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
 }
 
 /**
- *	ata_scsiop_noop -
+ *	ata_scsiop_noop - Command handler that simply returns success.
  *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 579448222d691d77bd656a35fa536d58be3ad417..3c97aa45772dc4aea2b7c4dbd759e76fa46c1745 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	int ret, i;
 	unsigned int id, lun;
 	unsigned long serial;
+	unsigned long flags;
 
 	if (!CMD_SP(cmd))
 		return FAILED;
@@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
 	/* Check active list for command command. */
 	spin_unlock_irq(ha->host->host_lock);
-	spin_lock(&ha->hardware_lock);
+	spin_lock_irqsave(&ha->hardware_lock, flags);
 	for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
 		sp = ha->outstanding_cmds[i];
 
@@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 		    sp->state));
 		DEBUG3(qla2x00_print_scsi_cmd(cmd);)
 
-		spin_unlock(&ha->hardware_lock);
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		if (qla2x00_abort_command(ha, sp)) {
 			DEBUG2(printk("%s(%ld): abort_command "
 			    "mbx failed.\n", __func__, ha->host_no));
@@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 			    "mbx success.\n", __func__, ha->host_no));
 			ret = SUCCESS;
 		}
-		spin_lock(&ha->hardware_lock);
+		spin_lock_irqsave(&ha->hardware_lock, flags);
 
 		break;
 	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	/* Wait for the command to be returned. */
 	if (ret == SUCCESS) {
-		spin_unlock(&ha->hardware_lock);
 		if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
 			qla_printk(KERN_ERR, ha, 
 			    "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
 			    "%x.\n", ha->host_no, id, lun, serial, ret);
 		}
-		spin_lock(&ha->hardware_lock);
 	}
 	spin_lock_irq(ha->host->host_lock);
 
@@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
 	int	status;
 	srb_t		*sp;
 	struct scsi_cmnd *cmd;
+	unsigned long flags;
 
 	status = 0;
 
@@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
 	 * array
 	 */
 	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-		spin_lock(&ha->hardware_lock);
+		spin_lock_irqsave(&ha->hardware_lock, flags);
 		sp = ha->outstanding_cmds[cnt];
 		if (sp) {
 			cmd = sp->cmd;
-			spin_unlock(&ha->hardware_lock);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 			if (cmd->device->id == t) {
 				if (!qla2x00_eh_wait_on_command(ha, cmd)) {
 					status = 1;
@@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
 				}
 			}
 		} else {
-			spin_unlock(&ha->hardware_lock);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		}
 	}
 	return (status);
@@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
 	int	status;
 	srb_t		*sp;
 	struct scsi_cmnd *cmd;
+	unsigned long flags;
 
 	status = 1;
 
@@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
 	 * array
 	 */
 	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-		spin_lock(&ha->hardware_lock);
+		spin_lock_irqsave(&ha->hardware_lock, flags);
 		sp = ha->outstanding_cmds[cnt];
 		if (sp) {
 			cmd = sp->cmd;
-			spin_unlock(&ha->hardware_lock);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 			status = qla2x00_eh_wait_on_command(ha, cmd);
 			if (status == 0)
 				break;
 		}
 		else {
-			spin_unlock(&ha->hardware_lock);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		}
 	}
 	return (status);
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 238580d244e697ec22427cda94ce1418a945aa2b..49ed557a4b661e4cfa9569b0d2af72f4375573d8 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -432,7 +432,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 		writeb(cls, mmio_base + SIL_FIFO_R0);
 		writeb(cls, mmio_base + SIL_FIFO_W0);
 		writeb(cls, mmio_base + SIL_FIFO_R1);
-		writeb(cls, mmio_base + SIL_FIFO_W2);
+		writeb(cls, mmio_base + SIL_FIFO_W1);
+		if (ent->driver_data == sil_3114) {
+			writeb(cls, mmio_base + SIL_FIFO_R2);
+			writeb(cls, mmio_base + SIL_FIFO_W2);
+			writeb(cls, mmio_base + SIL_FIFO_R3);
+			writeb(cls, mmio_base + SIL_FIFO_W3);
+		}
 	} else
 		printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
 			pci_name(pdev));
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index cca772624ae701ea8278ce770c10c8617e710c5e..8d0d302844a1d5a5c3a9df8530e1be0974f5c4d6 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
 	if (!starget)
 		return ERR_PTR(-ENOMEM);
 
+	get_device(&starget->dev);
 	down(&shost->scan_mutex);
 	res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
 	if (res != SCSI_SCAN_LUN_PRESENT)
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 22565a67a57cd0e6e63a85540addbcbbe2ec5321..98641c3f5ab9dedb9de0dd1be2eb1806469fb692 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -197,7 +197,7 @@ static void
 sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
 {
 	struct tty_struct *tty = sport->port.info->tty;
-	unsigned int status, ch, flg, ignored = 0;
+	unsigned int status, ch, flg;
 
 	status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
 		 UTSR0_TO_SM(UART_GET_UTSR0(sport));
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 5d2ceb623e6fcebe34319cac6c4bcd72d2c78739..1f985327b0d485ec8b4648073ef39a80d25d28f1 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port)
 		return "DSIU";
 	}
 
-	return "unknown";
+	return NULL;
 }
 
 static unsigned int siu_tx_empty(struct uart_port *port)
@@ -482,9 +482,6 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 	struct uart_port *port;
 	uint8_t iir, lsr;
 
-	if (dev_id == NULL)
-		return IRQ_NONE;
-
 	port = (struct uart_port *)dev_id;
 
 	iir = siu_read(port, UART_IIR);
@@ -507,6 +504,9 @@ static int siu_startup(struct uart_port *port)
 {
 	int retval;
 
+	if (port->membase == NULL)
+		return -ENODEV;
+
 	siu_clear_fifo(port);
 
 	(void)siu_read(port, UART_LSR);
@@ -545,9 +545,6 @@ static void siu_shutdown(struct uart_port *port)
 	unsigned long flags;
 	uint8_t lcr;
 
-	if (port->membase == NULL)
-		return;
-
 	siu_write(port, UART_IER, 0);
 
 	spin_lock_irqsave(&port->lock, flags);
@@ -802,53 +799,6 @@ static int siu_init_ports(void)
 
 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
 
-static void early_set_termios(struct uart_port *port, struct termios *new,
-                              struct termios *old)
-{
-	tcflag_t c_cflag;
-	uint8_t lcr;
-	unsigned int baud, quot;
-
-	c_cflag = new->c_cflag;
-	switch (c_cflag & CSIZE) {
-	case CS5:
-		lcr = UART_LCR_WLEN5;
-		break;
-	case CS6:
-		lcr = UART_LCR_WLEN6;
-		break;
-	case CS7:
-		lcr = UART_LCR_WLEN7;
-		break;
-	default:
-		lcr = UART_LCR_WLEN8;
-		break;
-	}
-
-	if (c_cflag & CSTOPB)
-		lcr |= UART_LCR_STOP;
-	if (c_cflag & PARENB)
-		lcr |= UART_LCR_PARITY;
-	if ((c_cflag & PARODD) != PARODD)
-		lcr |= UART_LCR_EPAR;
-	if (c_cflag & CMSPAR)
-		lcr |= UART_LCR_SPAR;
-
-	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
-	quot = uart_get_divisor(port, baud);
-
-	siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
-
-	siu_write(port, UART_DLL, (uint8_t)quot);
-	siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
-
-	siu_write(port, UART_LCR, lcr);
-}
-
-static struct uart_ops early_uart_ops = {
-	.set_termios	= early_set_termios,
-};
-
 #define BOTH_EMPTY	(UART_LSR_TEMT | UART_LSR_THRE)
 
 static void wait_for_xmitr(struct uart_port *port)
@@ -915,7 +865,7 @@ static int siu_console_setup(struct console *con, char *options)
 	if (port->membase == NULL) {
 		if (port->mapbase == 0)
 			return -ENODEV;
-		port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase);
+		port->membase = ioremap(port->mapbase, siu_port_size(port));
 	}
 
 	vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
@@ -949,7 +899,7 @@ static int __devinit siu_console_init(void)
 
 	for (i = 0; i < num; i++) {
 		port = &siu_uart_ports[i];
-		port->ops = &early_uart_ops;
+		port->ops = &siu_uart_ops;
 	}
 
 	register_console(&siu_console);
@@ -994,8 +944,10 @@ static int siu_probe(struct device *dev)
 		port->dev = dev;
 
 		retval = uart_add_one_port(&siu_uart_driver, port);
-		if (retval)
+		if (retval < 0) {
+			port->dev = NULL;
 			break;
+		}
 	}
 
 	if (i == 0 && retval < 0) {
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 4ab50009291d91fb1a54be002e6c9064607da6b6..4d0c9e65cd039e87612dedec707b4d0f4baf0675 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -290,32 +290,30 @@ static ssize_t show_modalias(struct device *dev, char *buf)
 {
 	struct usb_interface *intf;
 	struct usb_device *udev;
+	int len;
 
 	intf = to_usb_interface(dev);
 	udev = interface_to_usbdev(intf);
-	if (udev->descriptor.bDeviceClass == 0) {
-		struct usb_host_interface *alt = intf->cur_altsetting;
 
-		return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n",
+	len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
 			       le16_to_cpu(udev->descriptor.idVendor),
 			       le16_to_cpu(udev->descriptor.idProduct),
 			       le16_to_cpu(udev->descriptor.bcdDevice),
 			       udev->descriptor.bDeviceClass,
 			       udev->descriptor.bDeviceSubClass,
-			       udev->descriptor.bDeviceProtocol,
+			       udev->descriptor.bDeviceProtocol);
+	buf += len;
+
+	if (udev->descriptor.bDeviceClass == 0) {
+		struct usb_host_interface *alt = intf->cur_altsetting;
+
+		return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
 			       alt->desc.bInterfaceClass,
 			       alt->desc.bInterfaceSubClass,
 			       alt->desc.bInterfaceProtocol);
  	} else {
-		return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n",
-			       le16_to_cpu(udev->descriptor.idVendor),
-			       le16_to_cpu(udev->descriptor.idProduct),
-			       le16_to_cpu(udev->descriptor.bcdDevice),
-			       udev->descriptor.bDeviceClass,
-			       udev->descriptor.bDeviceSubClass,
-			       udev->descriptor.bDeviceProtocol);
+		return len + sprintf(buf, "*isc*ip*\n");
 	}
-
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 429330bc38de08f35b198a74d0fb190121bbc03c..d7b4f7939ded4d16989478ca58fa3edc573fb728 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -439,9 +439,12 @@ static int ehci_hub_control (
 			/* force reset to complete */
 			writel (temp & ~PORT_RESET,
 					&ehci->regs->port_status [wIndex]);
+			/* REVISIT:  some hardware needs 550+ usec to clear
+			 * this bit; seems too long to spin routinely...
+			 */
 			retval = handshake (
 					&ehci->regs->port_status [wIndex],
-					PORT_RESET, 0, 500);
+					PORT_RESET, 0, 750);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d reset error %d\n",
 					wIndex + 1, retval);
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 869ff73690acebf04655691c4edc01a017a6abe4..2d8bd9dcc6edae2b8d1c4ea112f0c5e66cddc149 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_DEVICE_ID_WACOM_INTUOS2	0x0040
 #define USB_DEVICE_ID_WACOM_VOLITO	0x0060
 #define USB_DEVICE_ID_WACOM_PTU		0x0003
+#define USB_DEVICE_ID_WACOM_INTUOS3	0x00B0
+#define USB_DEVICE_ID_WACOM_CINTIQ	0x003F
 
 #define USB_VENDOR_ID_KBGEAR		0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO	0x1001
@@ -1401,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid)
 
 #define USB_VENDOR_ID_DELORME		0x1163
 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
+#define USB_DEVICE_ID_DELORME_EM_LT20	0x0200
 
 #define USB_VENDOR_ID_MCC		0x09db
 #define USB_DEVICE_ID_MCC_PMD1024LS	0x0076
@@ -1412,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_BTC		0x046e
 #define USB_DEVICE_ID_BTC_KEYBOARD	0x5303
 
+#define USB_VENDOR_ID_VERNIER		0x08f7
+#define USB_DEVICE_ID_VERNIER_LABPRO	0x0001
+#define USB_DEVICE_ID_VERNIER_GOTEMP	0x0002
+#define USB_DEVICE_ID_VERNIER_SKIP	0x0003
+#define USB_DEVICE_ID_VERNIER_CYCLOPS	0x0004
+
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1437,6 +1446,7 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
@@ -1456,6 +1466,10 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
@@ -1481,6 +1495,10 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
 
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog
deleted file mode 100644
index b2eb71a9afb5a837b294354cb0771e84d28aa9a9..0000000000000000000000000000000000000000
--- a/drivers/usb/media/pwc/ChangeLog
+++ /dev/null
@@ -1,143 +0,0 @@
-9.0.2
-
-* Adding #ifdef to compile PWC before and after 2.6.5
-
-9.0.1
-
-9.0
-
-
-8.12
-
-* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere.
-
-8.11.1
-
-* Fix for PCVC720/40, would not be able to set videomode
-* Fix for Samsung MPC models, appearantly they are based on a newer chipset
-
-8.11
-
-* 20 dev_hints (per request)
-* Hot unplugging should be better, no more dangling pointers or memory leaks
-* Added reserved Logitech webcam IDs
-* Device now remembers size & fps between close()/open()
-* Removed palette stuff altogether
-
-8.10.1
-
-* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro
-
-8.10
-
-* Fixed ID for QuickCam Notebook pro
-* Added GREALSIZE ioctl() call
-* Fixed bug in case PWCX was not loaded and invalid size was set
-
-8.9
-
-* Merging with kernel 2.5.49
-* Adding IDs for QuickCam Zoom & QuickCam Notebook
-
-8.8
-
-* Fixing 'leds' parameter
-* Adding IDs for Logitech QuickCam Pro 4000
-* Making URB init/cleanup a little nicer
-
-8.7
-
-* Incorporating changes in ioctl() parameter passing
-* Also changes to URB mechanism
-
-8.6
-
-* Added ID's for Visionite VCS UM100 and UC300
-* Removed YUV420-interlaced palette altogether (was confusing)
-* Removed MIRROR stuff as it didn't work anyway
-* Fixed a problem with the 'leds' parameter (wouldn't blink)
-* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s,
-  CONTOUR, BACKLIGHT, FLICKER, DYNNOISE.
-* VIDIOCGCAP.name now contains real camera model name instead of
-  'Philips xxx webcam'
-* Added PROBE ioctl (see previous point & API doc)
-
-8.5
-
-* Adding IDs for Creative Labs Webcam 5
-* Adding IDs for SOTEC CMS-001 webcam
-* Solving possible hang in VIDIOCSYNC when unplugging the cam 
-* Forgot to return structure in VIDIOCPWCGAWB, oops
-* Time interval for the LEDs are now in milliseconds
-
-8.4
-
-* Fixing power_save option for Vesta range
-* Handling new error codes in ISOC callback
-* Adding dev_hint module parameter, to specify /dev/videoX device nodes
-
-8.3
-
-* Adding Samsung C10 and C30 cameras
-* Removing palette module parameter
-* Fixed typo in ID of QuickCam 3000 Pro
-* Adding LED settings (blinking while in use) for ToUCam cameras.
-* Turns LED off when camera is not in use.
-
-8.2
-
-* Making module more silent when trace = 0 
-* Adding QuickCam 3000 Pro IDs
-* Chrominance control for the Vesta cameras
-* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM
-* Included Oliver Neukem's lock_kernel() patch
-* Allocates less memory for image buffers
-* Adds ioctl()s for the whitebalancing
-
-8.1
-
-* Adding support for 750
-* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls
-
-8.0
-* 'damage control' after inclusion in 2.4.5.
-* Changed wait-queue mechanism in read/mmap/poll according to the book.
-* Included YUV420P palette.
-* Changed interface to decompressor module.
-* Cleaned up pwc structure a bit.
-
-7.0
-
-* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned.
-* There is now a clear error message when an image size is selected that
-  is only supported using the decompressor, and the decompressor isn't
-  loaded.
-* When the decompressor wasn't loaded, selecting large image size
-  would create skewed or double images.
-
-6.3
-
-* Introduced spinlocks for the buffer pointer manipulation; a number of
-  reports seem to suggest the down()/up() semaphores were the cause of
-  lockups, since they are not suitable for interrupt/user locking.
-* Separated decompressor and core code into 2 modules.
-
-6.2
-
-* Non-integral image sizes are now padded with gray or black.
-* Added SHUTTERSPEED ioctl().
-* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error,
-  even though the call succeeded.
-* Added hotplug support for 2.4.*.
-* Memory: the 645/646 uses less memory now.
-
-6.1
-
-* VIDIOCSPICT returns -EINVAL with invalid palettes.
-* Added saturation control.
-* Split decompressors from rest.
-* Fixed bug that would reset the framerate to the default framerate if 
-  the rate field was set to 0 (which is not what I intended, nl. do not 
-  change the framerate!).
-* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately.
-* Workaround for a bug in the 730 sensor.
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 5429ff3b97537336f4846a346c783a913fe92624..b77e65c03659a0bdffda1a758f7ef04beb44201d 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -332,10 +332,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
 #endif	 
 	;
 	 }
-	if (kbuf == NULL) {
-	   Err("Failed to allocate decompress table.\n");
-	   return -ENOMEM;
-	}
 	pdev->decompress_data = kbuf;
 	
 	/* Allocate image buffer; double buffer for mmap() */
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index a9a7cf4a38ebd2035cbaf5f1c842f259953583aa..fd6ff4cb2c6273d753d4daaaffebb230ce22b498 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -520,7 +520,7 @@ static void int_callback(struct urb *u, struct pt_regs *regs)
 
 	/* we check the link state to report changes */
 	if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {
-		if (!act_state)
+		if (act_state)
 			netif_carrier_on(kaweth->net);
 		else
 			netif_carrier_off(kaweth->net);
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 85476e76b244c4b166042dfa5e2bdbad368fdc82..4cbb408af72749b5f2f432c10bac69ebe4e2e1b7 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
 			}
 			/* expect bcdVersion 1.0, ignore */
 			if (memcmp(&desc->bGUID, blan_guid, 16)
-				    && memcmp(&desc->bGUID, blan_guid, 16) ) {
+				    && memcmp(&desc->bGUID, safe_guid, 16) ) {
 				/* hey, this one might _really_ be MDLM! */
 				dev_dbg (&intf->dev, "MDLM guid\n");
 				goto bad_desc;
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index bc798edf0358828f83ab486bde704d52f9ee1fbf..9438909e87a52bbd7c4ef625ce2f678403648341 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -455,6 +455,17 @@ config USB_SERIAL_XIRCOM
 	  To compile this driver as a module, choose M here: the
 	  module will be called keyspan_pda.
 
+config USB_SERIAL_OPTION
+	tristate "USB Option PCMCIA serial driver"
+	depends on USB_SERIAL && USB_OHCI_HCD && PCCARD
+	help
+	  Say Y here if you want to use an Option card. This is a
+	  GSM card, controlled by three serial ports which are connected
+	  via an OHCI adapter located on a PC card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called option.
+
 config USB_SERIAL_OMNINET
 	tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
 	depends on USB_SERIAL && EXPERIMENTAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index d56ff6d86cce220860ae63ca7bfbab532956847b..6c7cdcc99a9e2da387a12a352947a22e7ef08d6b 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI)			+= kl5kusb105.o
 obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)		+= kobil_sct.o
 obj-$(CONFIG_USB_SERIAL_MCT_U232)		+= mct_u232.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)		+= omninet.o
+obj-$(CONFIG_USB_SERIAL_OPTION)			+= option.o
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
 obj-$(CONFIG_USB_SERIAL_SAFE)			+= safe_serial.o
 obj-$(CONFIG_USB_SERIAL_TI)			+= ti_usb_3410_5052.o
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 7e9bb63eb466d3e09e608b22b4073448845e6802..4ace9964fc6bd36a22c0a82da2fc432be4eef5f7 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -7,6 +7,14 @@
  *	modify it under the terms of the GNU General Public License version
  *	2 as published by the Free Software Foundation.
  *
+ * Support to set flow control line levels using TIOCMGET and TIOCMSET
+ * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
+ * control thanks to Munir Nassar nassarmu@real-time.com
+ *
+ * Outstanding Issues:
+ *  Buffers are not flushed when the port is opened.
+ *  Multiple calls to write() may fail with "Resource temporarily unavailable"
+ *
  */
 
 #include <linux/config.h>
@@ -24,7 +32,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.03"
+#define DRIVER_VERSION "v0.04"
 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
 
 /*
@@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*);
 static void cp2101_close(struct usb_serial_port*, struct file*);
 static void cp2101_get_termios(struct usb_serial_port*);
 static void cp2101_set_termios(struct usb_serial_port*, struct termios*);
+static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
+static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
+		unsigned int, unsigned int);
 static void cp2101_break_ctl(struct usb_serial_port*, int);
 static int cp2101_startup (struct usb_serial *);
 static void cp2101_shutdown(struct usb_serial*);
@@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*);
 static int debug;
 
 static struct usb_device_id id_table [] = {
-	{USB_DEVICE(0x10c4, 0xea60) },	/*Silicon labs factory default*/
-	{USB_DEVICE(0x10ab, 0x10c5) },	/*Siemens MC60 Cable*/
-	{ } /* Terminating Entry*/
+	{ USB_DEVICE(0x10C4, 0xEA60) },	/* Silicon Labs factory default */
+	{ USB_DEVICE(0x10C4, 0x80CA) },	/* Degree Controls Inc */
+	{ USB_DEVICE(0x10AB, 0x10C5) },	/* Siemens MC60 Cable */
+	{ } /* Terminating Entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table);
@@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = {
 	.close			= cp2101_close,
 	.break_ctl		= cp2101_break_ctl,
 	.set_termios		= cp2101_set_termios,
+	.tiocmget 		= cp2101_tiocmget,
+	.tiocmset		= cp2101_tiocmset,
 	.attach			= cp2101_startup,
 	.shutdown		= cp2101_shutdown,
 };
 
-/*Config request types*/
+/* Config request types */
 #define REQTYPE_HOST_TO_DEVICE	0x41
 #define REQTYPE_DEVICE_TO_HOST	0xc1
 
-/*Config SET requests. To GET, add 1 to the request number*/
-#define CP2101_UART 		0x00	/*Enable / Disable*/
-#define CP2101_BAUDRATE		0x01	/*(BAUD_RATE_GEN_FREQ / baudrate)*/
-#define CP2101_BITS		0x03	/*0x(0)(data bits)(parity)(stop bits)*/
-#define CP2101_BREAK		0x05	/*On / Off*/
-#define CP2101_DTRRTS		0x07	/*101 / 202  ???*/
-#define CP2101_CONFIG_16	0x13	/*16 bytes of config data ???*/
-#define CP2101_CONFIG_6		0x19	/*6 bytes of config data ???*/
+/* Config SET requests. To GET, add 1 to the request number */
+#define CP2101_UART 		0x00	/* Enable / Disable */
+#define CP2101_BAUDRATE		0x01	/* (BAUD_RATE_GEN_FREQ / baudrate) */
+#define CP2101_BITS		0x03	/* 0x(0)(databits)(parity)(stopbits) */
+#define CP2101_BREAK		0x05	/* On / Off */
+#define CP2101_CONTROL		0x07	/* Flow control line states */
+#define CP2101_MODEMCTL		0x13	/* Modem controls */
+#define CP2101_CONFIG_6		0x19	/* 6 bytes of config data ??? */
 
-/*CP2101_UART*/
+/* CP2101_UART */
 #define UART_ENABLE		0x0001
 #define UART_DISABLE		0x0000
 
-/*CP2101_BAUDRATE*/
+/* CP2101_BAUDRATE */
 #define BAUD_RATE_GEN_FREQ	0x384000
 
-/*CP2101_BITS*/
+/* CP2101_BITS */
 #define BITS_DATA_MASK		0X0f00
+#define BITS_DATA_5		0X0500
 #define BITS_DATA_6		0X0600
 #define BITS_DATA_7		0X0700
 #define BITS_DATA_8		0X0800
@@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = {
 #define BITS_STOP_1		0x0000
 #define BITS_STOP_1_5		0x0001
 #define BITS_STOP_2		0x0002
+
+/* CP2101_BREAK */
 #define BREAK_ON		0x0000
 #define BREAK_OFF		0x0001
 
+/* CP2101_CONTROL */
+#define CONTROL_DTR		0x0001
+#define CONTROL_RTS		0x0002
+#define CONTROL_CTS		0x0010
+#define CONTROL_DSR		0x0020
+#define CONTROL_RING		0x0040
+#define CONTROL_DCD		0x0080
+#define CONTROL_WRITE_DTR	0x0100
+#define CONTROL_WRITE_RTS	0x0200
 
-static int cp2101_get_config(struct usb_serial_port* port, u8 request)
+/*
+ * cp2101_get_config
+ * Reads from the CP2101 configuration registers
+ * 'size' is specified in bytes.
+ * 'data' is a pointer to a pre-allocated array of integers large
+ * enough to hold 'size' bytes (with 4 bytes to each integer)
+ */
+static int cp2101_get_config(struct usb_serial_port* port, u8 request,
+		unsigned int *data, int size)
 {
 	struct usb_serial *serial = port->serial;
-	unsigned char buf[4];
-	unsigned int value;
-	int result, i;
+	u32 *buf;
+	int result, i, length;
+
+	/* Number of integers required to contain the array */
+	length = (((size - 1) | 3) + 1)/4;
+
+	buf = kmalloc (length * sizeof(u32), GFP_KERNEL);
+	memset(buf, 0, length * sizeof(u32));
+
+	if (!buf) {
+		dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__);
+		return -ENOMEM;
+	}
 
-	/*For get requests, the request number must be incremented*/
+	/* For get requests, the request number must be incremented */
 	request++;
 
-	/*Issue the request, attempting to read 4 bytes*/
+	/* Issue the request, attempting to read 'size' bytes */
 	result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
 				request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-				0, buf, 4, 300);
+				0, buf, size, 300);
 
-	if (result < 0) {
-		dev_err(&port->dev, "%s - Unable to send config request, "
-				"request=0x%x result=%d\n",
-				__FUNCTION__, request, result);
-		return result;
-	}
+	/* Convert data into an array of integers */
+	for (i=0; i<length; i++)
+		data[i] = le32_to_cpu(buf[i]);
 
-	/*Assemble each byte read into an integer value*/
-	value = 0;
-	for (i=0; i<4 && i<result; i++)
-		value |= (buf[i] << (i * 8));
+	kfree(buf);
 
-	dbg( " %s - request=0x%x result=%d value=0x%x",
-			__FUNCTION__, request, result, value);
+	if (result != size) {
+		dev_err(&port->dev, "%s - Unable to send config request, "
+				"request=0x%x size=%d result=%d\n",
+				__FUNCTION__, request, size, result);
+		return -EPROTO;
+	}
 
-	return value;
+	return 0;
 }
 
-static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value)
+/*
+ * cp2101_set_config
+ * Writes to the CP2101 configuration registers
+ * Values less than 16 bits wide are sent directly
+ * 'size' is specified in bytes.
+ */
+static int cp2101_set_config(struct usb_serial_port* port, u8 request,
+		unsigned int *data, int size)
 {
 	struct usb_serial *serial = port->serial;
-	int result;
-	result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			request, REQTYPE_HOST_TO_DEVICE, value,
-			0, NULL, 0, 300);
+	u32 *buf;
+	int result, i, length;
 
-	if (result <0) {
-		dev_err(&port->dev, "%s - Unable to send config request, "
-				"request=0x%x value=0x%x result=%d\n",
-				__FUNCTION__, request, value, result);
-		return result;
+	/* Number of integers required to contain the array */
+	length = (((size - 1) | 3) + 1)/4;
+
+	buf = kmalloc(length * sizeof(u32), GFP_KERNEL);
+	if (!buf) {
+		dev_err(&port->dev, "%s - out of memory.\n",
+				__FUNCTION__);
+		return -ENOMEM;
+	}
+
+	/* Array of integers into bytes */
+	for (i = 0; i < length; i++)
+		buf[i] = cpu_to_le32(data[i]);
+
+	if (size > 2) {
+		result = usb_control_msg (serial->dev,
+				usb_sndctrlpipe(serial->dev, 0),
+				request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+				0, buf, size, 300);
+	} else {
+		result = usb_control_msg (serial->dev,
+				usb_sndctrlpipe(serial->dev, 0),
+				request, REQTYPE_HOST_TO_DEVICE, data[0],
+				0, NULL, 0, 300);
 	}
 
-	dbg(" %s - request=0x%x value=0x%x result=%d",
-			__FUNCTION__, request, value, result);
+	kfree(buf);
+
+	if ((size > 2 && result != size) || result < 0) {
+		dev_err(&port->dev, "%s - Unable to send request, "
+				"request=0x%x size=%d result=%d\n",
+				__FUNCTION__, request, size, result);
+		return -EPROTO;
+	}
 
+	/* Single data value */
+	result = usb_control_msg (serial->dev,
+			usb_sndctrlpipe(serial->dev, 0),
+			request, REQTYPE_HOST_TO_DEVICE, data[0],
+			0, NULL, 0, 300);
 	return 0;
 }
 
+/*
+ * cp2101_set_config_single
+ * Convenience function for calling cp2101_set_config on single data values
+ * without requiring an integer pointer
+ */
+static inline int cp2101_set_config_single(struct usb_serial_port* port,
+		u8 request, unsigned int data)
+{
+	return cp2101_set_config(port, request, &data, 2);
+}
+
 static int cp2101_open (struct usb_serial_port *port, struct file *filp)
 {
 	struct usb_serial *serial = port->serial;
@@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) {
+	if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) {
 		dev_err(&port->dev, "%s - Unable to enable UART\n",
 				__FUNCTION__);
 		return -EPROTO;
@@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
 		return result;
 	}
 
-	/*Configure the termios structure*/
+	/* Configure the termios structure */
 	cp2101_get_termios(port);
 
+	/* Set the DTR and RTS pins low */
+	cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+
 	return 0;
 }
 
@@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
 	usb_kill_urb(port->write_urb);
 	usb_kill_urb(port->read_urb);
 
-	cp2101_set_config(port, CP2101_UART, UART_DISABLE);
+	cp2101_set_config_single(port, CP2101_UART, UART_DISABLE);
 }
 
-/* cp2101_get_termios*/
-/* Reads the baud rate, data bits, parity and stop bits from the device*/
-/* Corrects any unsupported values*/
-/* Configures the termios structure to reflect the state of the device*/
+/*
+ * cp2101_get_termios
+ * Reads the baud rate, data bits, parity, stop bits and flow control mode
+ * from the device, corrects any unsupported values, and configures the
+ * termios structure to reflect the state of the device
+ */
 static void cp2101_get_termios (struct usb_serial_port *port)
 {
-	unsigned int cflag;
+	unsigned int cflag, modem_ctl[4];
 	int baud;
 	int bits;
 
@@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 	}
 	cflag = port->tty->termios->c_cflag;
 
-	baud = cp2101_get_config(port, CP2101_BAUDRATE);
-	/*Convert to baudrate*/
+	cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
+	/* Convert to baudrate */
 	if (baud)
 		baud = BAUD_RATE_GEN_FREQ / baud;
 
 	dbg("%s - baud rate = %d", __FUNCTION__, baud);
 	cflag &= ~CBAUD;
 	switch (baud) {
-		/* The baud rates which are commented out below
+		/*
+		 * The baud rates which are commented out below
 		 * appear to be supported by the device
 		 * but are non-standard
 		 */
@@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 			dbg("%s - Baud rate is not supported, "
 					"using 9600 baud", __FUNCTION__);
 			cflag |= B9600;
-			cp2101_set_config(port, CP2101_BAUDRATE,
+			cp2101_set_config_single(port, CP2101_BAUDRATE,
 					(BAUD_RATE_GEN_FREQ/9600));
 			break;
 	}
 
-	bits = cp2101_get_config(port, CP2101_BITS);
+	cp2101_get_config(port, CP2101_BITS, &bits, 2);
 	cflag &= ~CSIZE;
 	switch(bits & BITS_DATA_MASK) {
+		case BITS_DATA_5:
+			dbg("%s - data bits = 5", __FUNCTION__);
+			cflag |= CS5;
+			break;
 		case BITS_DATA_6:
 			dbg("%s - data bits = 6", __FUNCTION__);
 			cflag |= CS6;
@@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 			cflag |= CS8;
 			bits &= ~BITS_DATA_MASK;
 			bits |= BITS_DATA_8;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 		default:
 			dbg("%s - Unknown number of data bits, "
@@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 			cflag |= CS8;
 			bits &= ~BITS_DATA_MASK;
 			bits |= BITS_DATA_8;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 	}
 
@@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 					"disabling parity)", __FUNCTION__);
 			cflag &= ~PARENB;
 			bits &= ~BITS_PARITY_MASK;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 		case BITS_PARITY_SPACE:
 			dbg("%s - parity = SPACE (not supported, "
 					"disabling parity)", __FUNCTION__);
 			cflag &= ~PARENB;
 			bits &= ~BITS_PARITY_MASK;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 		default:
 			dbg("%s - Unknown parity mode, "
 					"disabling parity", __FUNCTION__);
 			cflag &= ~PARENB;
 			bits &= ~BITS_PARITY_MASK;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 	}
 
@@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 			break;
 		case BITS_STOP_1_5:
 			dbg("%s - stop bits = 1.5 (not supported, "
-					"using 1 stop bit", __FUNCTION__);
+					"using 1 stop bit)", __FUNCTION__);
 			bits &= ~BITS_STOP_MASK;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 		case BITS_STOP_2:
 			dbg("%s - stop bits = 2", __FUNCTION__);
@@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 			dbg("%s - Unknown number of stop bits, "
 					"using 1 stop bit", __FUNCTION__);
 			bits &= ~BITS_STOP_MASK;
-			cp2101_set_config(port, CP2101_BITS, bits);
+			cp2101_set_config(port, CP2101_BITS, &bits, 2);
 			break;
 	}
 
+	cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+	if (modem_ctl[0] & 0x0008) {
+		dbg("%s - flow control = CRTSCTS", __FUNCTION__);
+		cflag |= CRTSCTS;
+	} else {
+		dbg("%s - flow control = NONE", __FUNCTION__);
+		cflag &= ~CRTSCTS;
+	}
+
 	port->tty->termios->c_cflag = cflag;
 }
 
@@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 		struct termios *old_termios)
 {
 	unsigned int cflag, old_cflag=0;
-	int baud=0;
-	int bits;
+	int baud=0, bits;
+	unsigned int modem_ctl[4];
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 	}
 	cflag = port->tty->termios->c_cflag;
 
-	/* check that they really want us to change something */
+	/* Check that they really want us to change something */
 	if (old_termios) {
 		if ((cflag == old_termios->c_cflag) &&
 				(RELEVANT_IFLAG(port->tty->termios->c_iflag)
@@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 	/* If the baud rate is to be updated*/
 	if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
 		switch (cflag & CBAUD) {
-			/* The baud rates which are commented out below
+			/*
+			 * The baud rates which are commented out below
 			 * appear to be supported by the device
 			 * but are non-standard
 			 */
@@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 		if (baud) {
 			dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
 					baud);
-			if (cp2101_set_config(port, CP2101_BAUDRATE,
+			if (cp2101_set_config_single(port, CP2101_BAUDRATE,
 						(BAUD_RATE_GEN_FREQ / baud)))
 				dev_err(&port->dev, "Baud rate requested not "
 						"supported by device\n");
 		}
 	}
 
-	/*If the number of data bits is to be updated*/
+	/* If the number of data bits is to be updated */
 	if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
-		bits = cp2101_get_config(port, CP2101_BITS);
+		cp2101_get_config(port, CP2101_BITS, &bits, 2);
 		bits &= ~BITS_DATA_MASK;
 		switch (cflag & CSIZE) {
+			case CS5:
+				bits |= BITS_DATA_5;
+				dbg("%s - data bits = 5", __FUNCTION__);
+				break;
 			case CS6:
 				bits |= BITS_DATA_6;
 				dbg("%s - data bits = 6", __FUNCTION__);
@@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 				bits |= BITS_DATA_8;
 				break;
 		}
-		if (cp2101_set_config(port, CP2101_BITS, bits))
+		if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
 			dev_err(&port->dev, "Number of data bits requested "
 					"not supported by device\n");
 	}
 
 	if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
-		bits = cp2101_get_config(port, CP2101_BITS);
+		cp2101_get_config(port, CP2101_BITS, &bits, 2);
 		bits &= ~BITS_PARITY_MASK;
 		if (cflag & PARENB) {
 			if (cflag & PARODD) {
@@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 				dbg("%s - parity = EVEN", __FUNCTION__);
 			}
 		}
-		if (cp2101_set_config(port, CP2101_BITS, bits))
+		if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
 			dev_err(&port->dev, "Parity mode not supported "
 					"by device\n");
 	}
 
 	if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
-		bits = cp2101_get_config(port, CP2101_BITS);
+		cp2101_get_config(port, CP2101_BITS, &bits, 2);
 		bits &= ~BITS_STOP_MASK;
 		if (cflag & CSTOPB) {
 			bits |= BITS_STOP_2;
@@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 			bits |= BITS_STOP_1;
 			dbg("%s - stop bits = 1", __FUNCTION__);
 		}
-		if (cp2101_set_config(port, CP2101_BITS, bits))
+		if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
 			dev_err(&port->dev, "Number of stop bits requested "
 					"not supported by device\n");
 	}
+
+	if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
+		cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+		dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
+				__FUNCTION__, modem_ctl[0], modem_ctl[1],
+				modem_ctl[2], modem_ctl[3]);
+
+		if (cflag & CRTSCTS) {
+			modem_ctl[0] &= ~0x7B;
+			modem_ctl[0] |= 0x09;
+			modem_ctl[1] = 0x80;
+			dbg("%s - flow control = CRTSCTS", __FUNCTION__);
+		} else {
+			modem_ctl[0] &= ~0x7B;
+			modem_ctl[0] |= 0x01;
+			modem_ctl[1] |= 0x40;
+			dbg("%s - flow control = NONE", __FUNCTION__);
+		}
+
+		dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
+				__FUNCTION__, modem_ctl[0], modem_ctl[1],
+				modem_ctl[2], modem_ctl[3]);
+		cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16);
+	}
+
+}
+
+static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
+		unsigned int set, unsigned int clear)
+{
+	int control = 0;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (set & TIOCM_RTS) {
+		control |= CONTROL_RTS;
+		control |= CONTROL_WRITE_RTS;
+	}
+	if (set & TIOCM_DTR) {
+		control |= CONTROL_DTR;
+		control |= CONTROL_WRITE_DTR;
+	}
+	if (clear & TIOCM_RTS) {
+		control &= ~CONTROL_RTS;
+		control |= CONTROL_WRITE_RTS;
+	}
+	if (clear & TIOCM_DTR) {
+		control &= ~CONTROL_DTR;
+		control |= CONTROL_WRITE_DTR;
+	}
+
+	dbg("%s - control = 0x%.4x", __FUNCTION__, control);
+
+	return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
+
+}
+
+static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
+{
+	int control, result;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	cp2101_get_config(port, CP2101_CONTROL, &control, 1);
+
+	result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
+		|((control & CONTROL_RTS) ? TIOCM_RTS : 0)
+		|((control & CONTROL_CTS) ? TIOCM_CTS : 0)
+		|((control & CONTROL_DSR) ? TIOCM_DSR : 0)
+		|((control & CONTROL_RING)? TIOCM_RI  : 0)
+		|((control & CONTROL_DCD) ? TIOCM_CD  : 0);
+
+	dbg("%s - control = 0x%.2x", __FUNCTION__, control);
+
+	return result;
 }
 
 static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
 {
-	u16 state;
+	int state;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 	if (break_state == 0)
@@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
 		state = BREAK_ON;
 	dbg("%s - turning break %s", __FUNCTION__,
 			state==BREAK_OFF ? "off" : "on");
-	cp2101_set_config(port, CP2101_BREAK, state);
+	cp2101_set_config(port, CP2101_BREAK, &state, 2);
 }
 
 static int cp2101_startup (struct usb_serial *serial)
 {
-	/*CP2101 buffers behave strangely unless device is reset*/
+	/* CP2101 buffers behave strangely unless device is reset */
 	usb_reset_device(serial->dev);
 	return 0;
 }
@@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial)
 
 	dbg("%s", __FUNCTION__);
 
-	/* stop reads and writes on all ports */
+	/* Stop reads and writes on all ports */
 	for (i=0; i < serial->num_ports; ++i) {
 		cp2101_cleanup(serial->port[i]);
 	}
@@ -560,16 +747,16 @@ static int __init cp2101_init (void)
 
 	retval = usb_serial_register(&cp2101_device);
 	if (retval)
-		return retval; /*Failed to register*/
+		return retval; /* Failed to register */
 
 	retval = usb_register(&cp2101_driver);
 	if (retval) {
-		/*Failed to register*/
+		/* Failed to register */
 		usb_serial_deregister(&cp2101_device);
 		return retval;
 	}
 
-	/*Success*/
+	/* Success */
 	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 051c3a77b41b749acf55922c7ec6851df3866feb..3bfcc7b9f861c898924451cb6680066214cd4504 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -264,7 +264,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.4.1"
+#define DRIVER_VERSION "v1.4.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
@@ -687,6 +687,8 @@ struct ftdi_private {
  	char prev_status, diff_status;        /* Used for TIOCMIWAIT */
 	__u8 rx_flags;		/* receive state flags (throttling) */
 	spinlock_t rx_lock;	/* spinlock for receive state */
+	struct work_struct rx_work;
+	int rx_processed;
 
 	__u16 interface;	/* FT2232C port interface (0 for FT232/245) */
 
@@ -717,7 +719,7 @@ static int  ftdi_write_room		(struct usb_serial_port *port);
 static int  ftdi_chars_in_buffer	(struct usb_serial_port *port);
 static void ftdi_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 static void ftdi_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
-static void ftdi_process_read		(struct usb_serial_port *port);
+static void ftdi_process_read		(void *param);
 static void ftdi_set_termios		(struct usb_serial_port *port, struct termios * old);
 static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
 static int  ftdi_tiocmset		(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
@@ -1387,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial)
 		port->read_urb->transfer_buffer_length = BUFSZ;
 	}
 
+	INIT_WORK(&priv->rx_work, ftdi_process_read, port);
+
 	/* Free port's existing write urb and transfer buffer. */
 	if (port->write_urb) {
 		usb_free_urb (port->write_urb);
@@ -1617,6 +1621,7 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
 	spin_unlock_irqrestore(&priv->rx_lock, flags);
 
 	/* Start reading from the device */
+	priv->rx_processed = 0;
 	usb_fill_bulk_urb(port->read_urb, dev,
 		      usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
 		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
@@ -1667,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
 			err("Error from RTS LOW urb");
 		}
 	} /* Note change no line if hupcl is off */
+
+	/* cancel any scheduled reading */
+	cancel_delayed_work(&priv->rx_work);
+	flush_scheduled_work();
 	
 	/* shutdown our bulk read */
 	if (port->read_urb)
@@ -1862,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 		return;
 	}
 
-	/* If throttled, delay receive processing until unthrottled. */
-	spin_lock(&priv->rx_lock);
-	if (priv->rx_flags & THROTTLED) {
-		dbg("Deferring read urb processing until unthrottled");
-		priv->rx_flags |= ACTUALLY_THROTTLED;
-		spin_unlock(&priv->rx_lock);
-		return;
-	}
-	spin_unlock(&priv->rx_lock);
-
 	ftdi_process_read(port);
 
 } /* ftdi_read_bulk_callback */
 
 
-static void ftdi_process_read (struct usb_serial_port *port)
+static void ftdi_process_read (void *param)
 { /* ftdi_process_read */
+	struct usb_serial_port *port = (struct usb_serial_port*)param;
 	struct urb *urb;
 	struct tty_struct *tty;
 	struct ftdi_private *priv;
@@ -1889,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port)
 	int result;
 	int need_flip;
 	int packet_offset;
+	unsigned long flags;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1915,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port)
 
 	data = urb->transfer_buffer;
 
-        /* The first two bytes of every read packet are status */
-	if (urb->actual_length > 2) {
-		usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+	if (priv->rx_processed) {
+		dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__,
+				priv->rx_processed,
+				urb->actual_length - priv->rx_processed);
 	} else {
-                dbg("Status only: %03oo %03oo",data[0],data[1]);
-        }
+		/* The first two bytes of every read packet are status */
+		if (urb->actual_length > 2) {
+			usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+		} else {
+			dbg("Status only: %03oo %03oo",data[0],data[1]);
+		}
+	}
 
 
 	/* TO DO -- check for hung up line and handle appropriately: */
@@ -1929,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port)
 	/* if CD is dropped and the line is not CLOCAL then we should hangup */
 
 	need_flip = 0;
-	for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+	for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+		int length;
+
 		/* Compare new line status to the old one, signal if different */
+		/* N.B. packet may be processed more than once, but differences
+		 * are only processed once.  */
 		if (priv != NULL) {
 			char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
 			if (new_status != priv->prev_status) {
@@ -1940,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port)
 			}
 		}
 
+		length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+		if (length < 0) {
+			err("%s - bad packet length: %d", __FUNCTION__, length+2);
+			length = 0;
+		}
+
+		/* have to make sure we don't overflow the buffer
+		   with tty_insert_flip_char's */
+		if (tty->flip.count+length > TTY_FLIPBUF_SIZE) {
+			tty_flip_buffer_push(tty);
+			need_flip = 0;
+
+			if (tty->flip.count != 0) {
+				/* flip didn't work, this happens when ftdi_process_read() is
+				 * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */
+				dbg("%s - flip buffer push failed", __FUNCTION__);
+				break;
+			}
+		}
+		if (priv->rx_flags & THROTTLED) {
+			dbg("%s - throttled", __FUNCTION__);
+			break;
+		}
+		if (tty->ldisc.receive_room(tty)-tty->flip.count < length) {
+			/* break out & wait for throttling/unthrottling to happen */
+			dbg("%s - receive room low", __FUNCTION__);
+			break;
+		}
+
 		/* Handle errors and break */
 		error_flag = TTY_NORMAL;
 		/* Although the device uses a bitmask and hence can have multiple */
@@ -1962,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port)
 			error_flag = TTY_FRAME;
 			dbg("FRAMING error");
 		}
-		if (urb->actual_length > packet_offset + 2) {
-			for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) {
-				/* have to make sure we don't overflow the buffer
-				  with tty_insert_flip_char's */
-				if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-					tty_flip_buffer_push(tty);
-				}
+		if (length > 0) {
+			for (i = 2; i < length+2; i++) {
 				/* Note that the error flag is duplicated for 
 				   every character received since we don't know
 				   which character it applied to */
@@ -2005,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port)
 		tty_flip_buffer_push(tty);
 	}
 
+	if (packet_offset < urb->actual_length) {
+		/* not completely processed - record progress */
+		priv->rx_processed = packet_offset;
+		dbg("%s - incomplete, %d bytes processed, %d remain",
+				__FUNCTION__, packet_offset,
+				urb->actual_length - packet_offset);
+		/* check if we were throttled while processing */
+		spin_lock_irqsave(&priv->rx_lock, flags);
+		if (priv->rx_flags & THROTTLED) {
+			priv->rx_flags |= ACTUALLY_THROTTLED;
+			spin_unlock_irqrestore(&priv->rx_lock, flags);
+			dbg("%s - deferring remainder until unthrottled",
+					__FUNCTION__);
+			return;
+		}
+		spin_unlock_irqrestore(&priv->rx_lock, flags);
+		/* if the port is closed stop trying to read */
+		if (port->open_count > 0){
+			/* delay processing of remainder */
+			schedule_delayed_work(&priv->rx_work, 1);
+		} else {
+			dbg("%s - port is closed", __FUNCTION__);
+		}
+		return;
+	}
+
+	/* urb is completely processed */
+	priv->rx_processed = 0;
+
 	/* if the port is closed stop trying to read */
 	if (port->open_count > 0){
 		/* Continue trying to always read  */
@@ -2444,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port)
 	spin_unlock_irqrestore(&priv->rx_lock, flags);
 
 	if (actually_throttled)
-		ftdi_process_read(port);
+		schedule_work(&priv->rx_work);
 }
 
 static int __init ftdi_init (void)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
new file mode 100644
index 0000000000000000000000000000000000000000..b722175f108f60b63eab8f811b96d478054bf6b7
--- /dev/null
+++ b/drivers/usb/serial/option.c
@@ -0,0 +1,729 @@
+/*
+  Option Card (PCMCIA to) USB to Serial Driver
+
+  Copyright (C) 2005  Matthias Urlichs <smurf@smurf.noris.de>
+
+  This driver is free software; you can redistribute it and/or modify
+  it under the terms of Version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
+
+  History:
+
+  2005-05-19  v0.1   Initial version, based on incomplete docs
+                     and analysis of misbehavior of the standard driver
+  2005-05-20  v0.2   Extended the input buffer to avoid losing
+                     random 64-byte chunks of data
+  2005-05-21  v0.3   implemented chars_in_buffer()
+                     turned on low_latency
+                     simplified the code somewhat
+*/
+#define DRIVER_VERSION "v0.3"
+#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
+#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usb-serial.h"
+
+/* Function prototypes */
+static int  option_open (struct usb_serial_port *port, struct file *filp);
+static void option_close (struct usb_serial_port *port, struct file *filp);
+static int  option_startup (struct usb_serial *serial);
+static void option_shutdown (struct usb_serial *serial);
+static void option_rx_throttle (struct usb_serial_port *port);
+static void option_rx_unthrottle (struct usb_serial_port *port);
+static int  option_write_room (struct usb_serial_port *port);
+
+static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
+
+
+static int  option_write (struct usb_serial_port *port,
+                          const unsigned char *buf, int count);
+
+static int  option_chars_in_buffer (struct usb_serial_port *port);
+static int  option_ioctl (struct usb_serial_port *port, struct file *file,
+                          unsigned int cmd, unsigned long arg);
+static void option_set_termios (struct usb_serial_port *port,
+                                struct termios *old);
+static void option_break_ctl (struct usb_serial_port *port, int break_state);
+static int  option_tiocmget (struct usb_serial_port *port, struct file *file);
+static int  option_tiocmset (struct usb_serial_port *port, struct file *file,
+                             unsigned int set, unsigned int clear);
+static int  option_send_setup (struct usb_serial_port *port);
+
+/* Vendor and product IDs */
+#define OPTION_VENDOR_ID		0x0AF0
+
+#define	OPTION_PRODUCT_OLD		0x5000
+#define	OPTION_PRODUCT_WLAN		0x6000
+
+static struct usb_device_id option_ids[] = {
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
+	{ } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, option_ids);
+
+static struct usb_driver option_driver = {
+	.owner      = THIS_MODULE,
+	.name       = "option",
+	.probe      = usb_serial_probe,
+	.disconnect = usb_serial_disconnect,
+	.id_table   = option_ids,
+};
+
+/* The card has three separate interfaces, wich the serial driver
+ * recognizes separately, thus num_port=1.
+ */
+static struct usb_serial_device_type option_3port_device = {
+	.owner			= THIS_MODULE,
+	.name			= "Option 3-port card",
+	.short_name		= "option",
+	.id_table		= option_ids,
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= NUM_DONT_CARE,
+	.num_bulk_out		= NUM_DONT_CARE,
+	.num_ports		= 1, /* 3 */
+	.open			= option_open,
+	.close			= option_close,
+	.write			= option_write,
+	.write_room		= option_write_room,
+	.chars_in_buffer	= option_chars_in_buffer,
+	.throttle		= option_rx_throttle,
+	.unthrottle		= option_rx_unthrottle,
+	.ioctl			= option_ioctl,
+	.set_termios		= option_set_termios,
+	.break_ctl		= option_break_ctl,
+	.tiocmget		= option_tiocmget,
+	.tiocmset		= option_tiocmset,
+	.attach			= option_startup,
+	.shutdown		= option_shutdown,
+	.read_int_callback	= option_instat_callback,
+};
+
+static int debug;
+
+/* per port private data */
+
+#define N_IN_URB	4
+#define N_OUT_URB	1
+#define IN_BUFLEN	1024
+#define OUT_BUFLEN	1024
+
+struct option_port_private {
+	/* Input endpoints and buffer for this port */
+	struct urb	*in_urbs[N_IN_URB];
+	char		in_buffer[N_IN_URB][IN_BUFLEN];
+	/* Output endpoints and buffer for this port */
+	struct urb	*out_urbs[N_OUT_URB];
+	char		out_buffer[N_OUT_URB][OUT_BUFLEN];
+
+	/* Settings for the port */
+	int		rts_state;	/* Handshaking pins (outputs) */
+	int		dtr_state;
+	int		cts_state;	/* Handshaking pins (inputs) */
+	int		dsr_state;
+	int		dcd_state;
+	int		ri_state;
+	// int		break_on;
+
+	unsigned long	tx_start_time[N_OUT_URB];
+};
+
+
+/* Functions used by new usb-serial code. */
+static int __init
+option_init (void)
+{
+	int retval;
+	retval = usb_serial_register(&option_3port_device);
+	if (retval)
+		goto failed_3port_device_register;
+	retval = usb_register(&option_driver);
+	if (retval)
+		goto failed_driver_register;
+
+	info(DRIVER_DESC ": " DRIVER_VERSION);
+
+	return 0;
+
+failed_driver_register:
+	usb_serial_deregister (&option_3port_device);
+failed_3port_device_register:
+	return retval;
+}
+
+static void __exit
+option_exit (void)
+{
+	usb_deregister (&option_driver);
+	usb_serial_deregister (&option_3port_device);
+}
+
+module_init(option_init);
+module_exit(option_exit);
+
+static void
+option_rx_throttle (struct usb_serial_port *port)
+{
+	dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_rx_unthrottle (struct usb_serial_port *port)
+{
+	dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_break_ctl (struct usb_serial_port *port, int break_state)
+{
+	/* Unfortunately, I don't know how to send a break */
+ 	dbg("%s", __FUNCTION__);
+}
+
+
+static void
+option_set_termios (struct usb_serial_port *port,
+				     struct termios *old_termios)
+{
+	dbg("%s", __FUNCTION__);
+
+	option_send_setup(port);
+}
+
+static int
+option_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+	unsigned int			value;
+	struct option_port_private 	*portdata;
+
+	portdata = usb_get_serial_port_data(port);
+
+	value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
+		((portdata->dtr_state) ? TIOCM_DTR : 0) |
+		((portdata->cts_state) ? TIOCM_CTS : 0) |
+		((portdata->dsr_state) ? TIOCM_DSR : 0) |
+		((portdata->dcd_state) ? TIOCM_CAR : 0) |
+		((portdata->ri_state) ? TIOCM_RNG : 0);
+
+	return value;
+}
+
+static int
+option_tiocmset (struct usb_serial_port *port, struct file *file,
+                 unsigned int set, unsigned int clear)
+{
+	struct option_port_private 	*portdata;
+
+	portdata = usb_get_serial_port_data(port);
+
+	if (set & TIOCM_RTS)
+		portdata->rts_state = 1;
+	if (set & TIOCM_DTR)
+		portdata->dtr_state = 1;
+
+	if (clear & TIOCM_RTS)
+		portdata->rts_state = 0;
+	if (clear & TIOCM_DTR)
+		portdata->dtr_state = 0;
+	return option_send_setup(port);
+}
+
+static int
+option_ioctl (struct usb_serial_port *port, struct file *file,
+              unsigned int cmd, unsigned long arg)
+{
+	return -ENOIOCTLCMD;
+}
+
+/* Write */
+static int
+option_write(struct usb_serial_port *port,
+			 const unsigned char *buf, int count)
+{
+	struct option_port_private 	*portdata;
+	int				i;
+	int 				left, todo;
+	struct urb			*this_urb = NULL; /* spurious */
+ 	int 				err;
+
+	portdata = usb_get_serial_port_data(port);
+
+	dbg("%s: write (%d chars)", __FUNCTION__, count);
+
+#if 0
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
+		dbg("%s: already writing", __FUNCTION__);
+		return 0;
+	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
+#endif
+
+	i = 0;
+	left = count;
+	while (left>0) {
+		todo = left;
+		if (todo > OUT_BUFLEN)
+			todo = OUT_BUFLEN;
+
+		for (;i < N_OUT_URB; i++) {
+			/* Check we have a valid urb/endpoint before we use it... */
+			this_urb = portdata->out_urbs[i];
+			if (this_urb->status != -EINPROGRESS)
+				break;
+			if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
+				continue;
+			if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
+				continue;
+			this_urb->transfer_flags |= URB_ASYNC_UNLINK;
+			usb_unlink_urb(this_urb);
+		}
+
+		if (i == N_OUT_URB) {
+			/* no bulk out free! */
+			dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
+#if 0
+			port->write_urb_busy = 0;
+#endif
+			return count-left;
+		}
+
+		dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
+
+		memcpy (this_urb->transfer_buffer, buf, todo);
+
+		/* send the data out the bulk port */
+		this_urb->transfer_buffer_length = todo;
+
+		this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+		this_urb->dev = port->serial->dev;
+		err = usb_submit_urb(this_urb, GFP_ATOMIC);
+		if (err) {
+			dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
+			continue;
+		}
+		portdata->tx_start_time[i] = jiffies;
+		buf += todo;
+		left -= todo;
+	}
+
+	count -= left;
+#if 0
+	port->write_urb_busy = 0;
+#endif
+	dbg("%s: wrote (did %d)", __FUNCTION__, count);
+	return count;
+}
+
+static void
+option_indat_callback (struct urb *urb, struct pt_regs *regs)
+{
+	int	i, err;
+	int endpoint;
+	struct usb_serial_port *port;
+	struct tty_struct *tty;
+	unsigned char *data = urb->transfer_buffer;
+
+	dbg("%s: %p", __FUNCTION__, urb);
+
+	endpoint = usb_pipeendpoint(urb->pipe);
+	port = (struct usb_serial_port *) urb->context;
+
+	if (urb->status) {
+		dbg("%s: nonzero status: %d on endpoint %02x.",
+		    __FUNCTION__, urb->status, endpoint);
+	} else {
+		tty = port->tty;
+		if (urb->actual_length) {
+			for (i = 0; i < urb->actual_length ; ++i) {
+				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+					tty_flip_buffer_push(tty);
+				tty_insert_flip_char(tty, data[i], 0);
+			}
+			tty_flip_buffer_push(tty);
+		} else {
+			dbg("%s: empty read urb received", __FUNCTION__);
+		}
+
+		/* Resubmit urb so we continue receiving */
+		if (port->open_count && urb->status != -ESHUTDOWN) {
+			err = usb_submit_urb(urb, GFP_ATOMIC);
+			if (err)
+				printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err);
+		}
+	}
+	return;
+}
+
+static void
+option_outdat_callback (struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_serial_port *port;
+
+	dbg("%s", __FUNCTION__);
+
+	port = (struct usb_serial_port *) urb->context;
+
+	if (port->open_count)
+		schedule_work(&port->work);
+}
+
+static void
+option_instat_callback (struct urb *urb, struct pt_regs *regs)
+{
+	int err;
+	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+	struct option_port_private *portdata = usb_get_serial_port_data(port);
+	struct usb_serial *serial = port->serial;
+
+	dbg("%s", __FUNCTION__);
+	dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
+
+	if (urb->status == 0) {
+		struct usb_ctrlrequest *req_pkt =
+				(struct usb_ctrlrequest *)urb->transfer_buffer;
+
+		if (!req_pkt) {
+			dbg("%s: NULL req_pkt\n", __FUNCTION__);
+			return;
+		}
+		if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) {
+			int old_dcd_state;
+			unsigned char signals = *((unsigned char *)
+					urb->transfer_buffer + sizeof(struct usb_ctrlrequest));
+
+			dbg("%s: signal x%x", __FUNCTION__, signals);
+
+			old_dcd_state = portdata->dcd_state;
+			portdata->cts_state = 1;
+			portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
+			portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
+			portdata->ri_state = ((signals & 0x08) ? 1 : 0);
+
+			if (port->tty && !C_CLOCAL(port->tty)
+					&& old_dcd_state && !portdata->dcd_state) {
+				tty_hangup(port->tty);
+			}
+		} else
+			dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest);
+	} else
+		dbg("%s: error %d", __FUNCTION__, urb->status);
+
+	/* Resubmit urb so we continue receiving IRQ data */
+	if (urb->status != -ESHUTDOWN) {
+		urb->dev = serial->dev;
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err)
+			dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err);
+	}
+}
+
+
+static int
+option_write_room (struct usb_serial_port *port)
+{
+	struct option_port_private *portdata;
+	int i;
+	int data_len = 0;
+	struct urb *this_urb;
+
+	portdata = usb_get_serial_port_data(port);
+
+	for (i=0; i < N_OUT_URB; i++)
+		this_urb = portdata->out_urbs[i];
+		if (this_urb && this_urb->status != -EINPROGRESS)
+			data_len += OUT_BUFLEN;
+
+	dbg("%s: %d", __FUNCTION__, data_len);
+	return data_len;
+}
+
+
+static int
+option_chars_in_buffer (struct usb_serial_port *port)
+{
+	struct option_port_private *portdata;
+	int i;
+	int data_len = 0;
+	struct urb *this_urb;
+
+	portdata = usb_get_serial_port_data(port);
+
+	for (i=0; i < N_OUT_URB; i++)
+		this_urb = portdata->out_urbs[i];
+		if (this_urb && this_urb->status == -EINPROGRESS)
+			data_len += this_urb->transfer_buffer_length;
+
+	dbg("%s: %d", __FUNCTION__, data_len);
+	return data_len;
+}
+
+
+static int
+option_open (struct usb_serial_port *port, struct file *filp)
+{
+	struct option_port_private 	*portdata;
+	struct usb_serial 		*serial = port->serial;
+	int				i, err;
+	struct urb			*urb;
+
+	portdata = usb_get_serial_port_data(port);
+
+	dbg("%s", __FUNCTION__);
+
+	/* Set some sane defaults */
+	portdata->rts_state = 1;
+	portdata->dtr_state = 1;
+
+	/* Reset low level data toggle and start reading from endpoints */
+	for (i = 0; i < N_IN_URB; i++) {
+		urb = portdata->in_urbs[i];
+		if (! urb)
+			continue;
+		if (urb->dev != serial->dev) {
+			dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev);
+			continue;
+		}
+
+		/* make sure endpoint data toggle is synchronized with the device */
+
+		usb_clear_halt(urb->dev, urb->pipe);
+
+		err = usb_submit_urb(urb, GFP_KERNEL);
+		if (err) {
+			dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err,
+				urb->transfer_buffer_length);
+		}
+	}
+
+	/* Reset low level data toggle on out endpoints */
+	for (i = 0; i < N_OUT_URB; i++) {
+		urb = portdata->out_urbs[i];
+		if (! urb)
+			continue;
+		urb->dev = serial->dev;
+		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+	}
+
+	port->tty->low_latency = 1;
+
+	option_send_setup(port);
+
+	return (0);
+}
+
+static inline void
+stop_urb(struct urb *urb)
+{
+	if (urb && urb->status == -EINPROGRESS) {
+		urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+		usb_kill_urb(urb);
+	}
+}
+
+static void
+option_close(struct usb_serial_port *port, struct file *filp)
+{
+	int			i;
+	struct usb_serial	*serial = port->serial;
+	struct option_port_private 	*portdata;
+
+	dbg("%s", __FUNCTION__);
+	portdata = usb_get_serial_port_data(port);
+
+	portdata->rts_state = 0;
+	portdata->dtr_state = 0;
+
+	if (serial->dev) {
+		option_send_setup(port);
+
+		/* Stop reading/writing urbs */
+		for (i = 0; i < N_IN_URB; i++)
+			stop_urb(portdata->in_urbs[i]);
+		for (i = 0; i < N_OUT_URB; i++)
+			stop_urb(portdata->out_urbs[i]);
+	}
+	port->tty = NULL;
+}
+
+
+/* Helper functions used by option_setup_urbs */
+static struct urb *
+option_setup_urb (struct usb_serial *serial, int endpoint,
+                  int dir, void *ctx, char *buf, int len,
+                  void (*callback)(struct urb *, struct pt_regs *regs))
+{
+	struct urb *urb;
+
+	if (endpoint == -1)
+		return NULL;		/* endpoint not needed */
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);		/* No ISO */
+	if (urb == NULL) {
+		dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
+		return NULL;
+	}
+
+		/* Fill URB using supplied data. */
+	usb_fill_bulk_urb(urb, serial->dev,
+		      usb_sndbulkpipe(serial->dev, endpoint) | dir,
+		      buf, len, callback, ctx);
+
+	return urb;
+}
+
+/* Setup urbs */
+static void
+option_setup_urbs(struct usb_serial *serial)
+{
+	int				j;
+	struct usb_serial_port		*port;
+	struct option_port_private	*portdata;
+
+	dbg("%s", __FUNCTION__);
+
+	port = serial->port[0];
+	portdata = usb_get_serial_port_data(port);
+
+	/* Do indat endpoints first */
+	for (j = 0; j <= N_IN_URB; ++j) {
+		portdata->in_urbs[j] = option_setup_urb (serial,
+                  port->bulk_in_endpointAddress, USB_DIR_IN, port,
+                  portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+	}
+
+	/* outdat endpoints */
+	for (j = 0; j <= N_OUT_URB; ++j) {
+		portdata->out_urbs[j] = option_setup_urb (serial,
+                  port->bulk_out_endpointAddress, USB_DIR_OUT, port,
+                  portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+	}
+}
+
+
+static int
+option_send_setup(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct option_port_private *portdata;
+
+	dbg("%s", __FUNCTION__);
+
+	portdata = usb_get_serial_port_data(port);
+
+	if (port->tty) {
+		int val = 0;
+		if (portdata->dtr_state)
+			val |= 0x01;
+		if (portdata->rts_state)
+			val |= 0x02;
+
+		return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+					0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+	}
+
+	return 0;
+}
+
+
+static int
+option_startup (struct usb_serial *serial)
+{
+	int				i, err;
+	struct usb_serial_port		*port;
+	struct option_port_private	*portdata;
+
+	dbg("%s", __FUNCTION__);
+
+	/* Now setup per port private data */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL);
+		if (!portdata) {
+			dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i);
+			return (1);
+		}
+		memset(portdata, 0, sizeof(struct option_port_private));
+
+		usb_set_serial_port_data(port, portdata);
+
+		if (! port->interrupt_in_urb)
+			continue;
+		err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+		if (err)
+			dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err);
+	}
+
+	option_setup_urbs(serial);
+
+	return (0);
+}
+
+static void
+option_shutdown (struct usb_serial *serial)
+{
+	int				i, j;
+	struct usb_serial_port		*port;
+	struct option_port_private	*portdata;
+
+	dbg("%s", __FUNCTION__);
+
+	/* Stop reading/writing urbs */
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		portdata = usb_get_serial_port_data(port);
+		for (j = 0; j < N_IN_URB; j++)
+			stop_urb(portdata->in_urbs[j]);
+		for (j = 0; j < N_OUT_URB; j++)
+			stop_urb(portdata->out_urbs[j]);
+	}
+
+	/* Now free them */
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		portdata = usb_get_serial_port_data(port);
+
+		for (j = 0; j < N_IN_URB; j++) {
+			if (portdata->in_urbs[j]) {
+				usb_free_urb(portdata->in_urbs[j]);
+				portdata->in_urbs[j] = NULL;
+			}
+		}
+		for (j = 0; j < N_OUT_URB; j++) {
+			if (portdata->out_urbs[j]) {
+				usb_free_urb(portdata->out_urbs[j]);
+				portdata->out_urbs[j] = NULL;
+			}
+		}
+	}
+
+	/* Now free per port private data */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		kfree(usb_get_serial_port_data(port));
+	}
+}
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug messages");
+
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index d2891f475793678078ce6fffa3326d5bbe6bfaa3..9fcc7bd1fbe427f2f55dd1dd4a774cccc617e93b 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -862,6 +862,15 @@ UNUSUAL_DEV(  0x090a, 0x1001, 0x0100, 0x0100,
 		US_SC_DEVICE, US_PR_BULK, NULL,
 		US_FL_NEED_OVERRIDE ),
 
+/* Reported by Filippo Bardelli <filibard@libero.it>
+ * The device reports a subclass of RBC, which is wrong.
+ */
+UNUSUAL_DEV(  0x090a, 0x1050, 0x0100, 0x0100,
+		"Trumpion Microelectronics, Inc.",
+		"33520 USB Digital Voice Recorder",
+		US_SC_UFI, US_PR_DEVICE, NULL,
+		0),
+
 /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */
 UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
 		"Trumpion",
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index ee25b9e8db60992fd8a6e6d041dc12fb49775a44..47a6b12bc9685af76cb8f844da52b49803f6293a 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2374,10 +2374,9 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
 	} while (   rinfo->fb_base == 0 &&
 		  ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) );
 
-	if (rinfo->fb_base)
-		memset_io(rinfo->fb_base, 0, rinfo->mapped_vram);
-	else {
-		printk (KERN_ERR "radeonfb (%s): cannot map FB\n", pci_name(rinfo->pdev));
+	if (rinfo->fb_base == NULL) {
+		printk (KERN_ERR "radeonfb (%s): cannot map FB\n",
+			pci_name(rinfo->pdev));
 		ret = -EIO;
 		goto err_unmap_rom;
 	}
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index c78a2c5961d3bada42cd7362085fe414f9fcd40e..277d733c6d00a4150436c42b234aec4edc572b15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -241,7 +241,7 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
 	struct fb_info *fb_info =
 		(struct fb_info *)class_get_devdata(class_device);
 	return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual,
-			fb_info->var.xres_virtual);
+			fb_info->var.yres_virtual);
 }
 
 static ssize_t store_cmap(struct class_device *class_device, const char * buf,
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index de5a0f383600832ec8f216764827376b0e2f66d9..2fc71081f7e7077749ff659ec9176d0c7f75f6c1 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -387,3 +387,4 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
 }
 EXPORT_SYMBOL(mac_find_mode);
 
+MODULE_LICENSE("GPL");
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c374be51b041a698341ddbda6b9fc5fe1329df46..f8f6b6b76179da87bfca266adadf360b10f2e91a 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1125,7 +1125,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
 	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
 }
 
-static int dump_seek(struct file *file, off_t off)
+static int dump_seek(struct file *file, loff_t off)
 {
 	if (file->f_op->llseek) {
 		if (file->f_op->llseek(file, off, 0) != off)
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d9d31b96393d4f33680dee26393fc9797c..c8998dc668824df41ef382e65af0b76124d41536 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm,
 		DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
 		down_write(&current->mm->mmap_sem);
-		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+		textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
 		up_write(&current->mm->mmap_sem);
 		if (!textpos  || textpos >= (unsigned long) -4096) {
 			if (!textpos)
@@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm,
 		down_write(&current->mm->mmap_sem);
 		realdatastart = do_mmap(0, 0, data_len + extra +
 				MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+				PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
 		up_write(&current->mm->mmap_sem);
 
 		if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm,
 		down_write(&current->mm->mmap_sem);
 		textpos = do_mmap(0, 0, text_len + data_len + extra +
 					MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+				PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
 		up_write(&current->mm->mmap_sem);
 		if (!textpos  || textpos >= (unsigned long) -4096) {
 			if (!textpos)
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 95483baab706baa9921eb14757c08da90970fdb5..dab4774ee7bbb6c7d9a92655a4a600d80c0da896 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not
 recommended, unmount and rmmod cifs will kill them when they are
 no longer needed).  Fix readdir to ASCII servers (ie older servers
 which do not support Unicode) and also require asterik.
-
+Fix out of memory case in which data could be written one page
+off in the page cache.
 
 Version 1.33
 ------------
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d00b3bfe1a5213830c6aec6c39f56d0910be390a..78af5850c558127bde1a5c929e72f90cf7470403 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -96,5 +96,5 @@ extern ssize_t	cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
 		       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.34"
+#define CIFS_VERSION   "1.35"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dde2d251fc3d6b0d387559bf5c590ede89bcf80a..30ab70ce554716df92739f0b1643ce79053497e7 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
 				      GFP_KERNEL)) {
 			page_cache_release(page);
 			cFYI(1, ("Add page cache failed"));
+			data += PAGE_CACHE_SIZE;
+			bytes_read -= PAGE_CACHE_SIZE;
 			continue;
 		}
 
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b8b78cbb34c97f304a1b5ac9f03b773f7d1073f5..8d336a90025584a6fb524001ef71c123b6d881ec 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 		/* get new inode */
 		if (*pinode == NULL) {
 			*pinode = new_inode(sb);
-			if(*pinode == NULL) 
+			if (*pinode == NULL) 
 				return -ENOMEM;
 			/* Is an i_ino of zero legal? */
 			/* Are there sanity checks we can use to ensure that
 			   the server is really filling in that field? */
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
 				(*pinode)->i_ino =
 					(unsigned long)findData.UniqueId;
 			} /* note ino incremented to unique num in new_inode */
@@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 		inode->i_gid = le64_to_cpu(findData.Gid);
 		inode->i_nlink = le64_to_cpu(findData.Nlinks);
 
-		if(is_size_safe_to_change(cifsInfo)) {
+		if (is_size_safe_to_change(cifsInfo)) {
 		/* can not safely change the file size here if the
 		   client is writing to it due to potential races */
 
@@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 		if (S_ISREG(inode->i_mode)) {
 			cFYI(1, (" File inode "));
 			inode->i_op = &cifs_file_inode_ops;
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
 				inode->i_fop = &cifs_file_direct_ops;
 			else
 				inode->i_fop = &cifs_file_ops;
@@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode,
 	pTcon = cifs_sb->tcon;
 	cFYI(1,("Getting info on %s ", search_path));
 
-	if((pfindData == NULL) && (*pinode != NULL)) {
-		if(CIFS_I(*pinode)->clientCanCacheRead) {
+	if ((pfindData == NULL) && (*pinode != NULL)) {
+		if (CIFS_I(*pinode)->clientCanCacheRead) {
 			cFYI(1,("No need to revalidate cached inode sizes"));
 			return rc;
 		}
 	}
 
 	/* if file info not passed in then get it from server */
-	if(pfindData == NULL) {
+	if (pfindData == NULL) {
 		buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
-		if(buf == NULL)
+		if (buf == NULL)
 			return -ENOMEM;
 		pfindData = (FILE_ALL_INFO *)buf;
 		/* could do find first instead but this returns more info */
@@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode,
 			   IndexNumber field is not guaranteed unique? */
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL		
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
 				int rc1 = 0;
 				__u64 inode_num;
 
@@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode,
 					cifs_sb->local_nls,
 					cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
-				if(rc1) {
+				if (rc1) {
 					cFYI(1,("GetSrvInodeNum rc %d", rc1));
 					/* BB EOPNOSUPP disable SERVER_INUM? */
 				} else /* do we need cast or hash to ino? */
@@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode,
 		if (S_ISREG(inode->i_mode)) {
 			cFYI(1, (" File inode "));
 			inode->i_op = &cifs_file_inode_ops;
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
 				inode->i_fop = &cifs_file_direct_ops;
 			else
 				inode->i_fop = &cifs_file_ops;
@@ -422,7 +422,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 	if (!rc) {
-		if(direntry->d_inode)
+		if (direntry->d_inode)
 			direntry->d_inode->i_nlink--;
 	} else if (rc == -ENOENT) {
 		d_drop(direntry);
@@ -441,7 +441,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 					      cifs_sb->mnt_cifs_flags & 
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			CIFSSMBClose(xid, pTcon, netfid);
-			if(direntry->d_inode)
+			if (direntry->d_inode)
 				direntry->d_inode->i_nlink--;
 		}
 	} else if (rc == -EACCES) {
@@ -496,7 +496,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 					    cifs_sb->mnt_cifs_flags & 
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			if (!rc) {
-				if(direntry->d_inode)
+				if (direntry->d_inode)
 					direntry->d_inode->i_nlink--;
 			} else if (rc == -ETXTBSY) {
 				int oplock = FALSE;
@@ -517,14 +517,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 						cifs_sb->mnt_cifs_flags &
 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 					CIFSSMBClose(xid, pTcon, netfid);
-					if(direntry->d_inode)
+					if (direntry->d_inode)
 			                        direntry->d_inode->i_nlink--;
 				}
 			/* BB if rc = -ETXTBUSY goto the rename logic BB */
 			}
 		}
 	}
-	if(direntry->d_inode) {
+	if (direntry->d_inode) {
 		cifsInode = CIFS_I(direntry->d_inode);
 		cifsInode->time = 0;	/* will force revalidate to get info
 					   when needed */
@@ -582,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
 		if (direntry->d_inode)
 			direntry->d_inode->i_nlink = 2;
 		if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode,
 						    (__u64)current->euid,
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 98d830401c56c7e50463e85acfe994f76171bb99..5a97e346bd95a247c12f0edcc5b33d1b065d6419 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
 		} else {
 			jbd_unlock_bh_state(bh);
 		}
-		jh = next_jh;
 	} while (jh != last_jh);
 
 	return ret;
@@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal)
 			}
 		} while (jh != last_jh && !retry);
 
-		if (batch_count)
+		if (batch_count) {
 			__flush_batch(journal, bhs, &batch_count);
+			retry = 1;
+		}
 
 		/*
 		 * If someone cleaned up this transaction while we slept, we're
diff --git a/fs/mpage.c b/fs/mpage.c
index b92c0e64aefa313d74456db2d4c718ad08182dc3..bb9aebe93862d8c03a94990d4b28fc4832e93a1f 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
 
-		if (!uptodate)
+		if (!uptodate){
 			SetPageError(page);
+			if (page->mapping)
+				set_bit(AS_EIO, &page->mapping->flags);
+		}
 		end_page_writeback(page);
 	} while (bvec >= bio->bi_io_vec);
 	bio_put(bio);
diff --git a/fs/namei.c b/fs/namei.c
index dd78f01b6de801baf30fd88229b6e6aed3986db3..a7f7f44119b3dda8e18a3de1e23990eb4f3ffb05 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -493,12 +493,21 @@ fail:
 	return PTR_ERR(link);
 }
 
-static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
+struct path {
+	struct vfsmount *mnt;
+	struct dentry *dentry;
+};
+
+static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 {
 	int error;
+	struct dentry *dentry = path->dentry;
 
-	touch_atime(nd->mnt, dentry);
+	touch_atime(path->mnt, dentry);
 	nd_set_link(nd, NULL);
+
+	if (path->mnt == nd->mnt)
+		mntget(path->mnt);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
 	if (!error) {
 		char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
 		if (dentry->d_inode->i_op->put_link)
 			dentry->d_inode->i_op->put_link(dentry, nd);
 	}
+	dput(dentry);
+	mntput(path->mnt);
 
 	return error;
 }
@@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
  * Without that kind of total limit, nasty chains of consecutive
  * symlinks can cause almost arbitrarily long lookups. 
  */
-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
+static inline int do_follow_link(struct path *path, struct nameidata *nd)
 {
 	int err = -ELOOP;
 	if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
 		goto loop;
 	BUG_ON(nd->depth >= MAX_NESTED_LINKS);
 	cond_resched();
-	err = security_inode_follow_link(dentry, nd);
+	err = security_inode_follow_link(path->dentry, nd);
 	if (err)
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
 	nd->depth++;
-	err = __do_follow_link(dentry, nd);
+	err = __do_follow_link(path, nd);
 	current->link_count--;
 	nd->depth--;
 	return err;
 loop:
+	dput(path->dentry);
+	if (path->mnt != nd->mnt)
+		mntput(path->mnt);
 	path_release(nd);
 	return err;
 }
@@ -565,87 +579,91 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry)
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static int follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static int __follow_mount(struct path *path)
 {
 	int res = 0;
+	while (d_mountpoint(path->dentry)) {
+		struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
+		if (!mounted)
+			break;
+		dput(path->dentry);
+		if (res)
+			mntput(path->mnt);
+		path->mnt = mounted;
+		path->dentry = dget(mounted->mnt_root);
+		res = 1;
+	}
+	return res;
+}
+
+static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+{
 	while (d_mountpoint(*dentry)) {
 		struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
 		if (!mounted)
 			break;
+		dput(*dentry);
 		mntput(*mnt);
 		*mnt = mounted;
-		dput(*dentry);
 		*dentry = dget(mounted->mnt_root);
-		res = 1;
 	}
-	return res;
 }
 
 /* no need for dcache_lock, as serialization is taken care in
  * namespace.c
  */
-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct vfsmount **mnt, struct dentry **dentry)
 {
 	struct vfsmount *mounted;
 
 	mounted = lookup_mnt(*mnt, *dentry);
 	if (mounted) {
+		dput(*dentry);
 		mntput(*mnt);
 		*mnt = mounted;
-		dput(*dentry);
 		*dentry = dget(mounted->mnt_root);
 		return 1;
 	}
 	return 0;
 }
 
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
-{
-	return __follow_down(mnt,dentry);
-}
- 
-static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
+static inline void follow_dotdot(struct nameidata *nd)
 {
 	while(1) {
 		struct vfsmount *parent;
-		struct dentry *old = *dentry;
+		struct dentry *old = nd->dentry;
 
                 read_lock(&current->fs->lock);
-		if (*dentry == current->fs->root &&
-		    *mnt == current->fs->rootmnt) {
+		if (nd->dentry == current->fs->root &&
+		    nd->mnt == current->fs->rootmnt) {
                         read_unlock(&current->fs->lock);
 			break;
 		}
                 read_unlock(&current->fs->lock);
 		spin_lock(&dcache_lock);
-		if (*dentry != (*mnt)->mnt_root) {
-			*dentry = dget((*dentry)->d_parent);
+		if (nd->dentry != nd->mnt->mnt_root) {
+			nd->dentry = dget(nd->dentry->d_parent);
 			spin_unlock(&dcache_lock);
 			dput(old);
 			break;
 		}
 		spin_unlock(&dcache_lock);
 		spin_lock(&vfsmount_lock);
-		parent = (*mnt)->mnt_parent;
-		if (parent == *mnt) {
+		parent = nd->mnt->mnt_parent;
+		if (parent == nd->mnt) {
 			spin_unlock(&vfsmount_lock);
 			break;
 		}
 		mntget(parent);
-		*dentry = dget((*mnt)->mnt_mountpoint);
+		nd->dentry = dget(nd->mnt->mnt_mountpoint);
 		spin_unlock(&vfsmount_lock);
 		dput(old);
-		mntput(*mnt);
-		*mnt = parent;
+		mntput(nd->mnt);
+		nd->mnt = parent;
 	}
-	follow_mount(mnt, dentry);
+	follow_mount(&nd->mnt, &nd->dentry);
 }
 
-struct path {
-	struct vfsmount *mnt;
-	struct dentry *dentry;
-};
-
 /*
  *  It's more convoluted than I'd like it to be, but... it's still fairly
  *  small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
 done:
 	path->mnt = mnt;
 	path->dentry = dentry;
+	__follow_mount(path);
 	return 0;
 
 need_lookup:
@@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 			case 2:	
 				if (this.name[1] != '.')
 					break;
-				follow_dotdot(&nd->mnt, &nd->dentry);
+				follow_dotdot(nd);
 				inode = nd->dentry->d_inode;
 				/* fallthrough */
 			case 1:
@@ -771,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 		err = do_lookup(nd, &this, &next);
 		if (err)
 			break;
-		/* Check mountpoints.. */
-		follow_mount(&next.mnt, &next.dentry);
 
 		err = -ENOENT;
 		inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 			goto out_dput;
 
 		if (inode->i_op->follow_link) {
-			mntget(next.mnt);
-			err = do_follow_link(next.dentry, nd);
-			dput(next.dentry);
-			mntput(next.mnt);
+			err = do_follow_link(&next, nd);
 			if (err)
 				goto return_err;
 			err = -ENOENT;
@@ -798,6 +812,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 				break;
 		} else {
 			dput(nd->dentry);
+			if (nd->mnt != next.mnt)
+				mntput(nd->mnt);
 			nd->mnt = next.mnt;
 			nd->dentry = next.dentry;
 		}
@@ -819,7 +835,7 @@ last_component:
 			case 2:	
 				if (this.name[1] != '.')
 					break;
-				follow_dotdot(&nd->mnt, &nd->dentry);
+				follow_dotdot(nd);
 				inode = nd->dentry->d_inode;
 				/* fallthrough */
 			case 1:
@@ -833,19 +849,17 @@ last_component:
 		err = do_lookup(nd, &this, &next);
 		if (err)
 			break;
-		follow_mount(&next.mnt, &next.dentry);
 		inode = next.dentry->d_inode;
 		if ((lookup_flags & LOOKUP_FOLLOW)
 		    && inode && inode->i_op && inode->i_op->follow_link) {
-			mntget(next.mnt);
-			err = do_follow_link(next.dentry, nd);
-			dput(next.dentry);
-			mntput(next.mnt);
+			err = do_follow_link(&next, nd);
 			if (err)
 				goto return_err;
 			inode = nd->dentry->d_inode;
 		} else {
 			dput(nd->dentry);
+			if (nd->mnt != next.mnt)
+				mntput(nd->mnt);
 			nd->mnt = next.mnt;
 			nd->dentry = next.dentry;
 		}
@@ -885,6 +899,8 @@ return_base:
 		return 0;
 out_dput:
 		dput(next.dentry);
+		if (nd->mnt != next.mnt)
+			mntput(next.mnt);
 		break;
 	}
 	path_release(nd);
@@ -1398,7 +1414,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
 int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
 {
 	int acc_mode, error = 0;
-	struct dentry *dentry;
+	struct path path;
 	struct dentry *dir;
 	int count = 0;
 
@@ -1442,23 +1458,24 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
 	dir = nd->dentry;
 	nd->flags &= ~LOOKUP_PARENT;
 	down(&dir->d_inode->i_sem);
-	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.mnt = nd->mnt;
 
 do_last:
-	error = PTR_ERR(dentry);
-	if (IS_ERR(dentry)) {
+	error = PTR_ERR(path.dentry);
+	if (IS_ERR(path.dentry)) {
 		up(&dir->d_inode->i_sem);
 		goto exit;
 	}
 
 	/* Negative dentry, just create the file */
-	if (!dentry->d_inode) {
+	if (!path.dentry->d_inode) {
 		if (!IS_POSIXACL(dir->d_inode))
 			mode &= ~current->fs->umask;
-		error = vfs_create(dir->d_inode, dentry, mode, nd);
+		error = vfs_create(dir->d_inode, path.dentry, mode, nd);
 		up(&dir->d_inode->i_sem);
 		dput(nd->dentry);
-		nd->dentry = dentry;
+		nd->dentry = path.dentry;
 		if (error)
 			goto exit;
 		/* Don't check for write permission, don't truncate */
@@ -1476,22 +1493,24 @@ do_last:
 	if (flag & O_EXCL)
 		goto exit_dput;
 
-	if (d_mountpoint(dentry)) {
+	if (__follow_mount(&path)) {
 		error = -ELOOP;
 		if (flag & O_NOFOLLOW)
 			goto exit_dput;
-		while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
 	}
 	error = -ENOENT;
-	if (!dentry->d_inode)
+	if (!path.dentry->d_inode)
 		goto exit_dput;
-	if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
+	if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
 		goto do_link;
 
 	dput(nd->dentry);
-	nd->dentry = dentry;
+	nd->dentry = path.dentry;
+	if (nd->mnt != path.mnt)
+		mntput(nd->mnt);
+	nd->mnt = path.mnt;
 	error = -EISDIR;
-	if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+	if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
 		goto exit;
 ok:
 	error = may_open(nd, acc_mode, flag);
@@ -1500,7 +1519,9 @@ ok:
 	return 0;
 
 exit_dput:
-	dput(dentry);
+	dput(path.dentry);
+	if (nd->mnt != path.mnt)
+		mntput(path.mnt);
 exit:
 	path_release(nd);
 	return error;
@@ -1520,18 +1541,15 @@ do_link:
 	 * are done. Procfs-like symlinks just set LAST_BIND.
 	 */
 	nd->flags |= LOOKUP_PARENT;
-	error = security_inode_follow_link(dentry, nd);
+	error = security_inode_follow_link(path.dentry, nd);
 	if (error)
 		goto exit_dput;
-	error = __do_follow_link(dentry, nd);
-	dput(dentry);
+	error = __do_follow_link(&path, nd);
 	if (error)
 		return error;
 	nd->flags &= ~LOOKUP_PARENT;
-	if (nd->last_type == LAST_BIND) {
-		dentry = nd->dentry;
+	if (nd->last_type == LAST_BIND)
 		goto ok;
-	}
 	error = -EISDIR;
 	if (nd->last_type != LAST_NORM)
 		goto exit;
@@ -1546,7 +1564,8 @@ do_link:
 	}
 	dir = nd->dentry;
 	down(&dir->d_inode->i_sem);
-	dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+	path.mnt = nd->mnt;
 	putname(nd->last.name);
 	goto do_last;
 }
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f96acd5d378b1b8e8aafd091b11c211f367afb..ff6155f5e8d9e3e30bbc5fa7422d67119426b1e0 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry)
 	dentry->d_time = jiffies;
 }
 
+/*
+ * Return the intent data that applies to this particular path component
+ *
+ * Note that the current set of intents only apply to the very last
+ * component of the path.
+ * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
+ */
+static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
+{
+	if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
+		return 0;
+	return nd->flags & mask;
+}
+
+/*
+ * Inode and filehandle revalidation for lookups.
+ *
+ * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
+ * or if the intent information indicates that we're about to open this
+ * particular file and the "nocto" mount flag is not set.
+ *
+ */
 static inline
 int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 
 	if (nd != NULL) {
-		int ndflags = nd->flags;
 		/* VFS wants an on-the-wire revalidation */
-		if (ndflags & LOOKUP_REVAL)
+		if (nd->flags & LOOKUP_REVAL)
 			goto out_force;
 		/* This is an open(2) */
-		if ((ndflags & LOOKUP_OPEN) &&
-				!(ndflags & LOOKUP_CONTINUE) &&
+		if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
 				!(server->flags & NFS_MOUNT_NOCTO))
 			goto out_force;
 	}
@@ -560,12 +580,8 @@ static inline
 int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
 		       struct nameidata *nd)
 {
-	int ndflags = 0;
-
-	if (nd)
-		ndflags = nd->flags;
 	/* Don't revalidate a negative dentry if we're creating a new file */
-	if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE))
+	if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
 		return 0;
 	return !nfs_check_verifier(dir, dentry);
 }
@@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = {
 	.d_iput		= nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to check whether or not we're going to do
+ * an O_EXCL create using this path component.
+ */
 static inline
 int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
 {
 	if (NFS_PROTO(dir)->version == 2)
 		return 0;
-	if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
+	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
 		return 0;
 	return (nd->intent.open.flags & O_EXCL) != 0;
 }
@@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = {
 	.d_iput		= nfs_dentry_iput,
 };
 
+/*
+ * Use intent information to determine whether we need to substitute
+ * the NFSv4-style stateful OPEN for the LOOKUP call
+ */
 static int is_atomic_open(struct inode *dir, struct nameidata *nd)
 {
-	if (!nd)
-		return 0;
-	/* Check that we are indeed trying to open this file */
-	if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN))
+	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
 		return 0;
 	/* NFS does not (yet) have a stateful open for directories */
 	if (nd->flags & LOOKUP_DIRECTORY)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f06eee6dcff57e3d4d4d7f88fe71545fd5b2c6e6..55c907592490a7fa6357c2bc17018b378c25433f 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -37,6 +37,7 @@
 
 static int nfs_file_open(struct inode *, struct file *);
 static int nfs_file_release(struct inode *, struct file *);
+static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
 static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
 static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
 static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
@@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
 
 struct file_operations nfs_file_operations = {
-	.llseek		= remote_llseek,
+	.llseek		= nfs_file_llseek,
 	.read		= do_sync_read,
 	.write		= do_sync_write,
 	.aio_read		= nfs_file_read,
@@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp)
 	return NFS_PROTO(inode)->file_release(inode, filp);
 }
 
+/**
+ * nfs_revalidate_size - Revalidate the file size
+ * @inode - pointer to inode struct
+ * @file - pointer to struct file
+ *
+ * Revalidates the file length. This is basically a wrapper around
+ * nfs_revalidate_inode() that takes into account the fact that we may
+ * have cached writes (in which case we don't care about the server's
+ * idea of what the file length is), or O_DIRECT (in which case we
+ * shouldn't trust the cache).
+ */
+static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	if (server->flags & NFS_MOUNT_NOAC)
+		goto force_reval;
+	if (filp->f_flags & O_DIRECT)
+		goto force_reval;
+	if (nfsi->npages != 0)
+		return 0;
+	return nfs_revalidate_inode(server, inode);
+force_reval:
+	return __nfs_revalidate_inode(server, inode);
+}
+
+static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+{
+	/* origin == SEEK_END => we must revalidate the cached file length */
+	if (origin == 2) {
+		struct inode *inode = filp->f_mapping->host;
+		int retval = nfs_revalidate_file_size(inode, filp);
+		if (retval < 0)
+			return (loff_t)retval;
+	}
+	return remote_llseek(filp, offset, origin);
+}
+
 /*
  * Flush all dirty pages, and check for write errors.
  *
diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h
index c99dbbb5bcb5ae32f02d8c3f4af9d3c4d2638f77..ef855a3bc0f54eed5048af5cf636d4c365bf29e7 100644
--- a/include/asm-alpha/agp.h
+++ b/include/asm-alpha/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h
index bd364f5a99bcc221f8e55bcb8f582737f977accc..96ad3d2a66d1ead1ce639fb47569e642ebbb6050 100644
--- a/include/asm-arm/arch-integrator/platform.h
+++ b/include/asm-arm/arch-integrator/platform.h
@@ -293,7 +293,11 @@
 #define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
 
 
+#if defined(CONFIG_ARCH_INTEGRATOR_AP)
 #define INTEGRATOR_GPIO_BASE            0x1B000000	 /*  GPIO */
+#elif defined(CONFIG_ARCH_INTEGRATOR_CP)
+#define INTEGRATOR_GPIO_BASE            0xC9000000	 /*  GPIO */
+#endif
 
 /* ------------------------------------------------------------------------
  *  KMI keyboard/mouse definitions
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index a8e3c2daefd61528485d42b7f4b5b38d68345ce8..083462668e184a8953ef49ed8eb9753c38d35d24 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length)
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		u8 *buf8 = (u8*)buf;
 		register u32 tmp32;
 
@@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length)
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		register u32 tmp32;
 		u8 *buf8 = (u8*)buf;
 		do {
@@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr)
 	 * Is this cycle meant for the CS8900?
 	 */
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		return (u16)(*port);  
 	}
 
@@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr)
 	register volatile u32 *port = (volatile u32 *)ptr;
 
 	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		((port >= IXDP2X01_CS8900_VIRT_BASE) && 
-		 (port <= IXDP2X01_CS8900_VIRT_END))) {
+		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
+		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
 		*port = value;  
 		return;
 	}
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 39741d3c9a34b199023762377c57f575b0b7e1f7..b5e54a9e9fa76992f06da1e944ead0bd951d95a0 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1296,6 +1296,7 @@
 #define GPIO111_MMCDAT3		111	/* MMC DAT3 (PXA27x) */
 #define GPIO111_MMCCS1		111	/* MMC Chip Select 1 (PXA27x) */
 #define GPIO112_MMCCMD		112	/* MMC CMD (PXA27x) */
+#define GPIO113_I2S_SYSCLK	113	/* I2S System Clock (PXA27x) */
 #define GPIO113_AC97_RESET_N	113	/* AC97 NRESET on (PXA27x) */
 
 /* GPIO alternate function mode & direction */
@@ -1428,6 +1429,7 @@
 #define GPIO111_MMCDAT3_MD	(111 | GPIO_ALT_FN_1_OUT)
 #define GPIO110_MMCCS1_MD	(111 | GPIO_ALT_FN_1_OUT)
 #define GPIO112_MMCCMD_MD	(112 | GPIO_ALT_FN_1_OUT)
+#define GPIO113_I2S_SYSCLK_MD	(113 | GPIO_ALT_FN_1_OUT)
 #define GPIO113_AC97_RESET_N_MD	(113 | GPIO_ALT_FN_2_OUT)
 #define GPIO117_I2CSCL_MD	(117 | GPIO_ALT_FN_1_OUT)
 #define GPIO118_I2CSDA_MD	(118 | GPIO_ALT_FN_1_IN)
diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h
index 2598d1f08548a1258e33a06e354886866fc1ef4a..a71093e44c58b0c0854ee381ff8dae8d7d358902 100644
--- a/include/asm-arm/arch-versatile/platform.h
+++ b/include/asm-arm/arch-versatile/platform.h
@@ -498,11 +498,17 @@
 /*
  * IB2 Versatile/AB expansion board definitions
  */
-#define VERSATILE_IB2_CAMERA_BANK	0x24000000
-#define VERSATILE_IB2_KBD_DATAREG	0x25000000
-#define VERSATILE_IB2_IER		0x26000000	/* for VICINTSOURCE27 */
-#define VERSATILE_IB2_CTRL		0x27000000
-#define VERSATILE_IB2_STAT		0x27000004
+#define VERSATILE_IB2_CAMERA_BANK	VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG	(VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE		(VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER		(VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR		(VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE		(VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL		(VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT		(VERSATILE_IB2_CTL_BASE + 4)
 #endif
 
 #endif
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index cbceacbe5afadae6e8ee0b5ce8b7e993e56a9eaf..a1696ba238d3aad1c891f194ac93d8c0b73c1362 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t;
  */
 #define ELF_CLASS	ELFCLASS32
 #ifdef __ARMEB__
-#define ELF_DATA	ELFDATA2MSB;
+#define ELF_DATA	ELFDATA2MSB
 #else
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2LSB
 #endif
 #define ELF_ARCH	EM_ARM
 
diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h
index 8b149474db2488092635c23eeb8498a1701ef399..5a47fdb3015da78a8f851acfb5e3fb2777350f69 100644
--- a/include/asm-arm26/elf.h
+++ b/include/asm-arm26/elf.h
@@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t;
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_ARM
 
 #define USE_ELF_CORE_DUMP
diff --git a/include/asm-arm26/signal.h b/include/asm-arm26/signal.h
index dedb29280303c719177637ca150cf75b79096c5c..37ad25355591f57bdbc3fb3dbc3795c2a452b818 100644
--- a/include/asm-arm26/signal.h
+++ b/include/asm-arm26/signal.h
@@ -166,9 +166,6 @@ typedef struct sigaltstack {
 #include <asm/sigcontext.h>
 
 #define sigmask(sig)	(1UL << ((sig) - 1))
-//FIXME!!!
-//#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
-
 #endif
 
 
diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
index 82431edeb2a108a83df9a44a768b2d3f33471385..1ec8a3427120876f6ef7d998b72798a37c0cc53a 100644
--- a/include/asm-h8300/kmap_types.h
+++ b/include/asm-h8300/kmap_types.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
+#ifndef _ASM_H8300_KMAP_TYPES_H
+#define _ASM_H8300_KMAP_TYPES_H
 
 enum km_type {
 	KM_BOUNCE_READ,
@@ -13,6 +13,8 @@ enum km_type {
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h
index abe08856c84fdc86e58a495c37c42cb4d9eb5227..63f727a59850bfa64f3723d30d2dc7a324553ed6 100644
--- a/include/asm-h8300/mman.h
+++ b/include/asm-h8300/mman.h
@@ -4,6 +4,7 @@
 #define PROT_READ	0x1		/* page can be read */
 #define PROT_WRITE	0x2		/* page can be written */
 #define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_SEM	0x8		/* page may be used for atomic ops */
 #define PROT_NONE	0x0		/* page can not be accessed */
 #define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
 #define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end of growsup vma */
@@ -19,6 +20,8 @@
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 #define MAP_LOCKED	0x2000		/* pages are locked */
 #define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h
index a917ff50354f363b69b909099cfbdcca1fed20ab..b82f5f3ab887b4307fa2e248c2122bdfe8d32bfc 100644
--- a/include/asm-i386/agp.h
+++ b/include/asm-i386/agp.h
@@ -21,4 +21,14 @@ int unmap_page_from_agp(struct page *page);
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h
index 1b46fd3f2ae3156447ee7b74b5b2d827bafc9882..c6044488e9e6085a971c7a59640a56adefe22d7b 100644
--- a/include/asm-i386/mach-numaq/mach_ipi.h
+++ b/include/asm-i386/mach-numaq/mach_ipi.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_MACH_IPI_H
 #define __ASM_MACH_IPI_H
 
-inline void send_IPI_mask_sequence(cpumask_t, int vector);
+void send_IPI_mask_sequence(cpumask_t, int vector);
 
 static inline void send_IPI_mask(cpumask_t mask, int vector)
 {
diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h
index d1316f1e6ee18f464926ba1de462f4cb6f7a2e4d..4e517f0e6afa34e81e9aecdeee51bf0eaec2b967 100644
--- a/include/asm-ia64/agp.h
+++ b/include/asm-ia64/agp.h
@@ -18,4 +18,14 @@
 #define flush_agp_mappings()		/* nothing */
 #define flush_agp_cache()		mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif /* _ASM_IA64_AGP_H */
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index ea121a002309176cd50055c6fcd497be1d1b2d94..fcc9c3344ab40f3ebd3891eb273fd1898f9e3fdc 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -8,7 +8,7 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h>.
  *
- * Copyright (C) 1998-2004 Hewlett-Packard Co
+ * Copyright (C) 1998-2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -551,7 +551,11 @@ do {											\
 
 /* These tell get_user_pages() that the first gate page is accessible from user-level.  */
 #define FIXADDR_USER_START	GATE_ADDR
-#define FIXADDR_USER_END	(GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#ifdef HAVE_BUGGY_SEGREL
+# define FIXADDR_USER_END	(GATE_ADDR + 2*PAGE_SIZE)
+#else
+# define FIXADDR_USER_END	(GATE_ADDR + 2*PERCPU_PAGE_SIZE)
+#endif
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 9e1ba8b7fb68ada212e21dd89ce3606948ddc274..91bbd1f2246140121bbaec497101790c6dc278cf 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void);
  * task_struct at this point.
  */
 
-/* Return TRUE if task T owns the fph partition of the CPU we're running on. */
+/*
+ * Return TRUE if task T owns the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_is_local_fpu_owner(t)								\
 ({												\
 	struct task_struct *__ia64_islfo_task = (t);						\
@@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void);
 	 && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER));	\
 })
 
-/* Mark task T as owning the fph partition of the CPU we're running on. */
+/*
+ * Mark task T as owning the fph partition of the CPU we're running on.
+ * Must be called from code that has preemption disabled.
+ */
 #define ia64_set_local_fpu_owner(t) do {						\
 	struct task_struct *__ia64_slfo_task = (t);					\
 	__ia64_slfo_task->thread.last_fph_cpu = smp_processor_id();			\
diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h
index be27cfa8c5b0a3ccc5e5d91c240f65966f324e2a..ca9e423307f4c881f177260b83b390cebb61a1ff 100644
--- a/include/asm-ppc/agp.h
+++ b/include/asm-ppc/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h
index f82dcccdee1e974c770b9dfe8c7aeb20ce144872..b7a417e0a9217c758384d4227975b7580a33902b 100644
--- a/include/asm-ppc/sigcontext.h
+++ b/include/asm-ppc/sigcontext.h
@@ -2,7 +2,7 @@
 #define _ASM_PPC_SIGCONTEXT_H
 
 #include <asm/ptrace.h>
-
+#include <linux/compiler.h>
 
 struct sigcontext {
 	unsigned long	_unused[4];
diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h
index be27cfa8c5b0a3ccc5e5d91c240f65966f324e2a..ca9e423307f4c881f177260b83b390cebb61a1ff 100644
--- a/include/asm-ppc64/agp.h
+++ b/include/asm-ppc64/agp.h
@@ -10,4 +10,14 @@
 #define flush_agp_mappings()
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
index 6c42d61bedd13447e219150362a0dbc7e058734a..085eedb956fe02f7a0f34c1cbea0895e476b00ee 100644
--- a/include/asm-ppc64/elf.h
+++ b/include/asm-ppc64/elf.h
@@ -221,9 +221,7 @@ do {								\
 		set_thread_flag(TIF_ABI_PENDING);		\
 	else							\
 		clear_thread_flag(TIF_ABI_PENDING);		\
-	if (ibcs2)						\
-		set_personality(PER_SVR4);			\
-	else if (current->personality != PER_LINUX32)		\
+	if (personality(current->personality) != PER_LINUX32)	\
 		set_personality(PER_LINUX);			\
 } while (0)
 
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index 0035efe2db2ba7591fce0f6be861e6f23b7ecfd6..809c634ba1dfa03e41078b737a3f0be4945f7314 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -120,103 +120,18 @@
 
 /* Special Purpose Registers (SPRNs)*/
 
-#define	SPRN_CDBCR	0x3D7	/* Cache Debug Control Register */
 #define	SPRN_CTR	0x009	/* Count Register */
 #define	SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
-#define	SPRN_DAC1	0x3F6	/* Data Address Compare 1 */
-#define	SPRN_DAC2	0x3F7	/* Data Address Compare 2 */
+#define   DABR_TRANSLATION	(1UL << 2)
 #define	SPRN_DAR	0x013	/* Data Address Register */
-#define	SPRN_DBCR	0x3F2	/* Debug Control Regsiter */
-#define	  DBCR_EDM	0x80000000
-#define	  DBCR_IDM	0x40000000
-#define	  DBCR_RST(x)	(((x) & 0x3) << 28)
-#define	    DBCR_RST_NONE       	0
-#define	    DBCR_RST_CORE       	1
-#define	    DBCR_RST_CHIP       	2
-#define	    DBCR_RST_SYSTEM		3
-#define	  DBCR_IC	0x08000000	/* Instruction Completion Debug Evnt */
-#define	  DBCR_BT	0x04000000	/* Branch Taken Debug Event */
-#define	  DBCR_EDE	0x02000000	/* Exception Debug Event */
-#define	  DBCR_TDE	0x01000000	/* TRAP Debug Event */
-#define	  DBCR_FER	0x00F80000	/* First Events Remaining Mask */
-#define	  DBCR_FT	0x00040000	/* Freeze Timers on Debug Event */
-#define	  DBCR_IA1	0x00020000	/* Instr. Addr. Compare 1 Enable */
-#define	  DBCR_IA2	0x00010000	/* Instr. Addr. Compare 2 Enable */
-#define	  DBCR_D1R	0x00008000	/* Data Addr. Compare 1 Read Enable */
-#define	  DBCR_D1W	0x00004000	/* Data Addr. Compare 1 Write Enable */
-#define	  DBCR_D1S(x)	(((x) & 0x3) << 12)	/* Data Adrr. Compare 1 Size */
-#define	    DAC_BYTE	0
-#define	    DAC_HALF	1
-#define	    DAC_WORD	2
-#define	    DAC_QUAD	3
-#define	  DBCR_D2R	0x00000800	/* Data Addr. Compare 2 Read Enable */
-#define	  DBCR_D2W	0x00000400	/* Data Addr. Compare 2 Write Enable */
-#define	  DBCR_D2S(x)	(((x) & 0x3) << 8)	/* Data Addr. Compare 2 Size */
-#define	  DBCR_SBT	0x00000040	/* Second Branch Taken Debug Event */
-#define	  DBCR_SED	0x00000020	/* Second Exception Debug Event */
-#define	  DBCR_STD	0x00000010	/* Second Trap Debug Event */
-#define	  DBCR_SIA	0x00000008	/* Second IAC Enable */
-#define	  DBCR_SDA	0x00000004	/* Second DAC Enable */
-#define	  DBCR_JOI	0x00000002	/* JTAG Serial Outbound Int. Enable */
-#define	  DBCR_JII	0x00000001	/* JTAG Serial Inbound Int. Enable */
-#define	SPRN_DBCR0	0x3F2	/* Debug Control Register 0 */
-#define	SPRN_DBCR1	0x3BD	/* Debug Control Register 1 */
-#define	SPRN_DBSR	0x3F0	/* Debug Status Register */
-#define	SPRN_DCCR	0x3FA	/* Data Cache Cacheability Register */
-#define	  DCCR_NOCACHE		0	/* Noncacheable */
-#define	  DCCR_CACHE		1	/* Cacheable */
-#define	SPRN_DCMP	0x3D1	/* Data TLB Compare Register */
-#define	SPRN_DCWR	0x3BA	/* Data Cache Write-thru Register */
-#define	  DCWR_COPY		0	/* Copy-back */
-#define	  DCWR_WRITE		1	/* Write-through */
-#define	SPRN_DEAR	0x3D5	/* Data Error Address Register */
 #define	SPRN_DEC	0x016	/* Decrement Register */
-#define	SPRN_DMISS	0x3D0	/* Data TLB Miss Register */
 #define	SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
 #define   DSISR_NOHPTE		0x40000000	/* no translation found */
 #define   DSISR_PROTFAULT	0x08000000	/* protection fault */
 #define   DSISR_ISSTORE		0x02000000	/* access was a store */
 #define   DSISR_DABRMATCH	0x00400000	/* hit data breakpoint */
 #define   DSISR_NOSEGMENT	0x00200000	/* STAB/SLB miss */
-#define	SPRN_EAR	0x11A	/* External Address Register */
-#define	SPRN_ESR	0x3D4	/* Exception Syndrome Register */
-#define	  ESR_IMCP	0x80000000	/* Instr. Machine Check - Protection */
-#define	  ESR_IMCN	0x40000000	/* Instr. Machine Check - Non-config */
-#define	  ESR_IMCB	0x20000000	/* Instr. Machine Check - Bus error */
-#define	  ESR_IMCT	0x10000000	/* Instr. Machine Check - Timeout */
-#define	  ESR_PIL	0x08000000	/* Program Exception - Illegal */
-#define	  ESR_PPR	0x04000000	/* Program Exception - Priveleged */
-#define	  ESR_PTR	0x02000000	/* Program Exception - Trap */
-#define	  ESR_DST	0x00800000	/* Storage Exception - Data miss */
-#define	  ESR_DIZ	0x00400000	/* Storage Exception - Zone fault */
-#define	SPRN_EVPR	0x3D6	/* Exception Vector Prefix Register */
-#define	SPRN_HASH1	0x3D2	/* Primary Hash Address Register */
-#define	SPRN_HASH2	0x3D3	/* Secondary Hash Address Resgister */
 #define	SPRN_HID0	0x3F0	/* Hardware Implementation Register 0 */
-#define	  HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
-#define	  HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
-#define	  HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
-#define	  HID0_SBCLK	(1<<27)
-#define	  HID0_EICE	(1<<26)
-#define	  HID0_ECLK	(1<<25)
-#define	  HID0_PAR	(1<<24)
-#define	  HID0_DOZE	(1<<23)
-#define	  HID0_NAP	(1<<22)
-#define	  HID0_SLEEP	(1<<21)
-#define	  HID0_DPM	(1<<20)
-#define	  HID0_ICE	(1<<15)		/* Instruction Cache Enable */
-#define	  HID0_DCE	(1<<14)		/* Data Cache Enable */
-#define	  HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
-#define	  HID0_DLOCK	(1<<12)		/* Data Cache Lock */
-#define	  HID0_ICFI	(1<<11)		/* Instr. Cache Flash Invalidate */
-#define	  HID0_DCI	(1<<10)		/* Data Cache Invalidate */
-#define   HID0_SPD	(1<<9)		/* Speculative disable */
-#define   HID0_SGE	(1<<7)		/* Store Gathering Enable */
-#define	  HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
-#define   HID0_BTIC	(1<<5)		/* Branch Target Instruction Cache Enable */
-#define   HID0_ABE	(1<<3)		/* Address Broadcast Enable */
-#define	  HID0_BHTE	(1<<2)		/* Branch History Table Enable */
-#define	  HID0_BTCD	(1<<1)		/* Branch target cache disable */
 #define	SPRN_MSRDORM	0x3F1	/* Hardware Implementation Register 1 */
 #define SPRN_HID1	0x3F1	/* Hardware Implementation Register 1 */
 #define	SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
@@ -225,23 +140,8 @@
 #define SPRN_HID5	0x3F6	/* 970 HID5 */
 #define	SPRN_TSC 	0x3FD	/* Thread switch control */
 #define	SPRN_TST 	0x3FC	/* Thread switch timeout */
-#define	SPRN_IAC1	0x3F4	/* Instruction Address Compare 1 */
-#define	SPRN_IAC2	0x3F5	/* Instruction Address Compare 2 */
-#define	SPRN_ICCR	0x3FB	/* Instruction Cache Cacheability Register */
-#define	  ICCR_NOCACHE		0	/* Noncacheable */
-#define	  ICCR_CACHE		1	/* Cacheable */
-#define	SPRN_ICDBDR	0x3D3	/* Instruction Cache Debug Data Register */
-#define	SPRN_ICMP	0x3D5	/* Instruction TLB Compare Register */
-#define	SPRN_ICTC	0x3FB	/* Instruction Cache Throttling Control Reg */
-#define	SPRN_IMISS	0x3D4	/* Instruction TLB Miss Register */
-#define	SPRN_IMMR	0x27E  	/* Internal Memory Map Register */
 #define	SPRN_L2CR	0x3F9	/* Level 2 Cache Control Regsiter */
 #define	SPRN_LR		0x008	/* Link Register */
-#define	SPRN_PBL1	0x3FC	/* Protection Bound Lower 1 */
-#define	SPRN_PBL2	0x3FE	/* Protection Bound Lower 2 */
-#define	SPRN_PBU1	0x3FD	/* Protection Bound Upper 1 */
-#define	SPRN_PBU2	0x3FF	/* Protection Bound Upper 2 */
-#define	SPRN_PID	0x3B1	/* Process ID */
 #define	SPRN_PIR	0x3FF	/* Processor Identification Register */
 #define	SPRN_PIT	0x3DB	/* Programmable Interval Timer */
 #define	SPRN_PURR	0x135	/* Processor Utilization of Resources Register */
@@ -249,9 +149,6 @@
 #define	SPRN_RPA	0x3D6	/* Required Physical Address Register */
 #define	SPRN_SDA	0x3BF	/* Sampled Data Address Register */
 #define	SPRN_SDR1	0x019	/* MMU Hash Base Register */
-#define	SPRN_SGR	0x3B9	/* Storage Guarded Register */
-#define	  SGR_NORMAL		0
-#define	  SGR_GUARDED		1
 #define	SPRN_SIA	0x3BB	/* Sampled Instruction Address Register */
 #define	SPRN_SPRG0	0x110	/* Special Purpose Register General 0 */
 #define	SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
@@ -264,50 +161,12 @@
 #define	SPRN_TBWL	0x11C	/* Time Base Lower Register (super, W/O) */
 #define	SPRN_TBWU	0x11D	/* Time Base Write Upper Register (super, W/O) */
 #define SPRN_HIOR	0x137	/* 970 Hypervisor interrupt offset */
-#define	SPRN_TCR	0x3DA	/* Timer Control Register */
-#define	  TCR_WP(x)		(((x)&0x3)<<30)	/* WDT Period */
-#define	    WP_2_17		0		/* 2^17 clocks */
-#define	    WP_2_21		1		/* 2^21 clocks */
-#define	    WP_2_25		2		/* 2^25 clocks */
-#define	    WP_2_29		3		/* 2^29 clocks */
-#define	  TCR_WRC(x)		(((x)&0x3)<<28)	/* WDT Reset Control */
-#define	    WRC_NONE		0		/* No reset will occur */
-#define	    WRC_CORE		1		/* Core reset will occur */
-#define	    WRC_CHIP		2		/* Chip reset will occur */
-#define	    WRC_SYSTEM		3		/* System reset will occur */
-#define	  TCR_WIE		0x08000000	/* WDT Interrupt Enable */
-#define	  TCR_PIE		0x04000000	/* PIT Interrupt Enable */
-#define	  TCR_FP(x)		(((x)&0x3)<<24)	/* FIT Period */
-#define	    FP_2_9		0		/* 2^9 clocks */
-#define	    FP_2_13		1		/* 2^13 clocks */
-#define	    FP_2_17		2		/* 2^17 clocks */
-#define	    FP_2_21		3		/* 2^21 clocks */
-#define	  TCR_FIE		0x00800000	/* FIT Interrupt Enable */
-#define	  TCR_ARE		0x00400000	/* Auto Reload Enable */
-#define	SPRN_THRM1	0x3FC	/* Thermal Management Register 1 */
-#define	  THRM1_TIN		(1<<0)
-#define	  THRM1_TIV		(1<<1)
-#define	  THRM1_THRES		(0x7f<<2)
-#define	  THRM1_TID		(1<<29)
-#define	  THRM1_TIE		(1<<30)
-#define	  THRM1_V		(1<<31)
-#define	SPRN_THRM2	0x3FD	/* Thermal Management Register 2 */
-#define	SPRN_THRM3	0x3FE	/* Thermal Management Register 3 */
-#define	  THRM3_E		(1<<31)
-#define	SPRN_TSR	0x3D8	/* Timer Status Register */
-#define	  TSR_ENW		0x80000000	/* Enable Next Watchdog */
-#define	  TSR_WIS		0x40000000	/* WDT Interrupt Status */
-#define	  TSR_WRS(x)		(((x)&0x3)<<28)	/* WDT Reset Status */
-#define	    WRS_NONE		0		/* No WDT reset occurred */
-#define	    WRS_CORE		1		/* WDT forced core reset */
-#define	    WRS_CHIP		2		/* WDT forced chip reset */
-#define	    WRS_SYSTEM		3		/* WDT forced system reset */
-#define	  TSR_PIS		0x08000000	/* PIT Interrupt Status */
-#define	  TSR_FIS		0x04000000	/* FIT Interrupt Status */
 #define	SPRN_USIA	0x3AB	/* User Sampled Instruction Address Register */
 #define	SPRN_XER	0x001	/* Fixed Point Exception Register */
-#define	SPRN_ZPR	0x3B0	/* Zone Protection Register */
 #define SPRN_VRSAVE     0x100   /* Vector save */
+#define SPRN_CTRLF	0x088
+#define SPRN_CTRLT	0x098
+#define   CTRL_RUNLATCH	0x1
 
 /* Performance monitor SPRs */
 #define SPRN_SIAR	780
@@ -352,28 +211,19 @@
 #define	CTR	SPRN_CTR	/* Counter Register */
 #define	DAR	SPRN_DAR	/* Data Address Register */
 #define	DABR	SPRN_DABR	/* Data Address Breakpoint Register */
-#define	DCMP	SPRN_DCMP      	/* Data TLB Compare Register */
 #define	DEC	SPRN_DEC       	/* Decrement Register */
-#define	DMISS	SPRN_DMISS     	/* Data TLB Miss Register */
 #define	DSISR	SPRN_DSISR	/* Data Storage Interrupt Status Register */
-#define	EAR	SPRN_EAR       	/* External Address Register */
-#define	HASH1	SPRN_HASH1	/* Primary Hash Address Register */
-#define	HASH2	SPRN_HASH2	/* Secondary Hash Address Register */
 #define	HID0	SPRN_HID0	/* Hardware Implementation Register 0 */
 #define	MSRDORM	SPRN_MSRDORM	/* MSR Dormant Register */
 #define	NIADORM	SPRN_NIADORM	/* NIA Dormant Register */
 #define	TSC    	SPRN_TSC 	/* Thread switch control */
 #define	TST    	SPRN_TST 	/* Thread switch timeout */
 #define	IABR	SPRN_IABR      	/* Instruction Address Breakpoint Register */
-#define	ICMP	SPRN_ICMP	/* Instruction TLB Compare Register */
-#define	IMISS	SPRN_IMISS	/* Instruction TLB Miss Register */
-#define	IMMR	SPRN_IMMR      	/* PPC 860/821 Internal Memory Map Register */
 #define	L2CR	SPRN_L2CR    	/* PPC 750 L2 control register */
 #define	__LR	SPRN_LR
 #define	PVR	SPRN_PVR	/* Processor Version */
 #define	PIR	SPRN_PIR	/* Processor ID */
 #define	PURR	SPRN_PURR	/* Processor Utilization of Resource Register */
-//#define	RPA	SPRN_RPA	/* Required Physical Address Register */
 #define	SDR1	SPRN_SDR1      	/* MMU hash base register */
 #define	SPR0	SPRN_SPRG0	/* Supervisor Private Registers */
 #define	SPR1	SPRN_SPRG1
@@ -389,10 +239,6 @@
 #define	TBRU	SPRN_TBRU	/* Time Base Read Upper Register */
 #define	TBWL	SPRN_TBWL	/* Time Base Write Lower Register */
 #define	TBWU	SPRN_TBWU	/* Time Base Write Upper Register */
-#define ICTC	1019
-#define	THRM1	SPRN_THRM1	/* Thermal Management Register 1 */
-#define	THRM2	SPRN_THRM2	/* Thermal Management Register 2 */
-#define	THRM3	SPRN_THRM3	/* Thermal Management Register 3 */
 #define	XER	SPRN_XER
 
 /* Processor Version Register (PVR) field extraction */
@@ -436,12 +282,6 @@
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
 
-/* iSeries CTRL register (for runlatch) */
-
-#define CTRLT		0x098
-#define CTRLF		0x088
-#define RUNLATCH	0x0001
-
 #ifdef __ASSEMBLY__
 
 #define _GLOBAL(name) \
@@ -656,6 +496,24 @@ static inline void prefetchw(const void *x)
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
+static inline void ppc64_runlatch_on(void)
+{
+	unsigned long ctrl;
+
+	ctrl = mfspr(SPRN_CTRLF);
+	ctrl |= CTRL_RUNLATCH;
+	mtspr(SPRN_CTRLT, ctrl);
+}
+
+static inline void ppc64_runlatch_off(void)
+{
+	unsigned long ctrl;
+
+	ctrl = mfspr(SPRN_CTRLF);
+	ctrl &= ~CTRL_RUNLATCH;
+	mtspr(SPRN_CTRLT, ctrl);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index 037b5e06083c0c58ca8f2c624c7edd3b6c12df3a..48b7900e90ec2db801de1a22fe50c2b4ff429c33 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -96,7 +96,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
 #define TIF_32BIT		5	/* 32 bit binary */
-#define TIF_RUN_LIGHT		6	/* iSeries run light */
+/* #define SPARE		6 */
 #define TIF_ABI_PENDING		7	/* 32/64 bit switch needed */
 #define TIF_SYSCALL_AUDIT	8	/* syscall auditing active */
 #define TIF_SINGLESTEP		9	/* singlestepping active */
@@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_32BIT		(1<<TIF_32BIT)
-#define _TIF_RUN_LIGHT		(1<<TIF_RUN_LIGHT)
+/* #define _SPARE		(1<<SPARE) */
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h
index c64f8c181df39b6f8d3890be531645efab24026d..1dc74baf03c4c16027d1811bfd32bf4be00c21b9 100644
--- a/include/asm-s390/user.h
+++ b/include/asm-s390/user.h
@@ -10,7 +10,7 @@
 #define _S390_USER_H
 
 #include <asm/page.h>
-#include <linux/ptrace.h>
+#include <asm/ptrace.h>
 /* Core file format: The core file is written in such a way that gdb
    can understand it and provide useful information to the user (under
    linux we use the 'trad-core' bfd).  There are quite a number of
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
index f461144067eea33924e44f9223002ef7e723200e..0a780e84a12b749fd6f1e4381407f34affcb895b 100644
--- a/include/asm-sparc/uaccess.h
+++ b/include/asm-sparc/uaccess.h
@@ -41,10 +41,11 @@
  * No one can read/write anything from userland in the kernel space by setting
  * large size and address near to PAGE_OFFSET - a fault will break his intentions.
  */
-#define __user_ok(addr,size) ((addr) < STACK_TOP)
+#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
-#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+#define access_ok(type, addr, size)					\
+	({ (void)(type); __access_ok((unsigned long)(addr), size); })
 
 /* this function will go away soon - use access_ok() instead */
 static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size)
diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h
index ba05bdf9a211db17909d773b559738167ea826b5..58f8cb6ae767d536769a8a43ab46564a5665b96b 100644
--- a/include/asm-sparc64/agp.h
+++ b/include/asm-sparc64/agp.h
@@ -8,4 +8,14 @@
 #define flush_agp_mappings() 
 #define flush_agp_cache() mb()
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h
index 0bb9019d58aae5283f79df1ae1b957dca6409a53..06c52ee9c06b3b398b79e30a213f134d457e18e2 100644
--- a/include/asm-x86_64/agp.h
+++ b/include/asm-x86_64/agp.h
@@ -19,4 +19,14 @@ int unmap_page_from_agp(struct page *page);
    worth it. Would need a page for it. */
 #define flush_agp_cache() asm volatile("wbinvd":::"memory")
 
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)		\
+	((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)	\
+	free_pages((unsigned long)(table), (order))
+
 #endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d5a55bdb9c3cca13bc4c66e01da0b440341f0781..b123cc08773d30fccf89c1d0a0aa4e79fcaa2512 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,6 +25,8 @@
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#include <linux/config.h>
+
 #ifdef	CONFIG_ACPI
 
 #ifndef _LINUX
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
index 0485b256d043adbb3c823f9a0369021643695820..004e6f09a6e2daf89387bb2d1794cdd377c0ec1d 100644
--- a/include/linux/if_shaper.h
+++ b/include/linux/if_shaper.h
@@ -23,7 +23,7 @@ struct shaper
 	__u32 shapeclock;
 	unsigned long recovery;	/* Time we can next clock a packet out on
 				   an empty queue */
-        unsigned long locked;
+	struct semaphore sem;
         struct net_device_stats stats;
 	struct net_device *dev;
 	int  (*hard_start_xmit) (struct sk_buff *skb,
@@ -38,7 +38,6 @@ struct shaper
 	int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh);
 	void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char *  haddr);
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
-	wait_queue_head_t  wait_queue;
 	struct timer_list timer;
 };
 
diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h
index 6688b414c529277d893445d500e091bcd79d115f..3fba9e2f5427d633a9260854112647e9294b07a3 100644
--- a/include/linux/if_tr.h
+++ b/include/linux/if_tr.h
@@ -19,6 +19,8 @@
 #ifndef _LINUX_IF_TR_H
 #define _LINUX_IF_TR_H
 
+#include <asm/byteorder.h>	/* For __be16 */
+
 /* IEEE 802.5 Token-Ring magic constants.  The frame sizes omit the preamble
    and FCS/CRC (frame check sequence). */
 #define TR_ALEN		6		/* Octets in one token-ring addr */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e74f301e9baea59df14efbbd75943a61b496651c..b009f801e7c5880d671668fa31176bf824d4bf31 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -467,12 +467,34 @@ static inline u8 ata_chk_status(struct ata_port *ap)
 	return ap->ops->check_status(ap);
 }
 
+
+/**
+ *	ata_pause - Flush writes and pause 400 nanoseconds.
+ *	@ap: Port to wait for.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+
 static inline void ata_pause(struct ata_port *ap)
 {
 	ata_altstatus(ap);
 	ndelay(400);
 }
 
+
+/**
+ *	ata_busy_wait - Wait for a port status register
+ *	@ap: Port to wait for.
+ *
+ *	Waits up to max*10 microseconds for the selected bits in the port's
+ *	status register to be cleared.
+ *	Returns final value of status register.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+
 static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
 			       unsigned int max)
 {
@@ -487,6 +509,18 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
 	return status;
 }
 
+
+/**
+ *	ata_wait_idle - Wait for a port to be idle.
+ *	@ap: Port to wait for.
+ *
+ *	Waits up to 10ms for port's BUSY and DRQ signals to clear.
+ *	Returns final value of status register.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+
 static inline u8 ata_wait_idle(struct ata_port *ap)
 {
 	u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
@@ -525,6 +559,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns
 		tf->device = ATA_DEVICE_OBS | ATA_DEV1;
 }
 
+
+/**
+ *	ata_irq_on - Enable interrupts on a port.
+ *	@ap: Port on which interrupts are enabled.
+ *
+ *	Enable interrupts on a legacy IDE device using MMIO or PIO,
+ *	wait for idle, clear any pending interrupts.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+
 static inline u8 ata_irq_on(struct ata_port *ap)
 {
 	struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -544,6 +590,18 @@ static inline u8 ata_irq_on(struct ata_port *ap)
 	return tmp;
 }
 
+
+/**
+ *	ata_irq_ack - Acknowledge a device interrupt.
+ *	@ap: Port on which interrupts are enabled.
+ *
+ *	Wait up to 10 ms for legacy IDE device to become idle (BUSY
+ *	or BUSY+DRQ clear).  Obtain dma status and port status from
+ *	device.  Clear the interrupt.  Return port status.
+ *
+ *	LOCKING:
+ */
+
 static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 {
 	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 470af8c1a4a01a680198b53a2fe3da15d3f2c2c0..ba5d1236aa170c75a92c1137e34b3c0fb242f93b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -204,7 +204,7 @@ struct hh_cache
 	/* cached hardware header; allow for machine alignment needs.        */
 #define HH_DATA_MOD	16
 #define HH_DATA_OFF(__len) \
-	(HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
+	(HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1))
 #define HH_DATA_ALIGN(__len) \
 	(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
 	unsigned long	hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index b0d6134e1ee6a0f3db385490306b5d87a7c4461e..b8b4ebf9abf1f3b28089030edcb067f4f08a080f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -874,6 +874,7 @@
 #define PCI_DEVICE_ID_APPLE_KL_USB_P	0x0026
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P	0x0027
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15	0x002d
+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15	0x002e
 #define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2	0x0032
 #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA	0x0033
@@ -2382,6 +2383,8 @@
 #define PCI_DEVICE_ID_INTEL_82915G_IG	0x2582
 #define PCI_DEVICE_ID_INTEL_82915GM_HB	0x2590
 #define PCI_DEVICE_ID_INTEL_82915GM_IG	0x2592
+#define PCI_DEVICE_ID_INTEL_82945G_HB	0x2770
+#define PCI_DEVICE_ID_INTEL_82945G_IG	0x2772
 #define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
 #define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
 #define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 0a98f5ec5caed28fdfcaa91c183e7ef181534833..7be18b5e2fb41a9ec1794028a0364324360a6828 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -231,10 +231,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
 extern long do_sigpending(void __user *, unsigned long);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 
-#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 struct pt_regs;
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
-#endif
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 23032d9d607154fd48e41422f346c3ddcb8e72e6..a17745c80a91a6ce19fdeeb007aa1f529ce440df 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -346,6 +346,7 @@ enum
 	NET_TCP_MODERATE_RCVBUF=106,
 	NET_TCP_TSO_WIN_DIVISOR=107,
 	NET_TCP_BIC_BETA=108,
+	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
 };
 
 enum {
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index aa6b48bb4dcd0c1fbeec59278d84eb3e15244da0..a6b2cc530af5e1be70ed02d2cf05240c2894c297 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -56,6 +56,36 @@ enum
 	TCF_META_ID_TCCLASSID,
 	TCF_META_ID_RTCLASSID,
 	TCF_META_ID_RTIIF,
+	TCF_META_ID_SK_FAMILY,
+	TCF_META_ID_SK_STATE,
+	TCF_META_ID_SK_REUSE,
+	TCF_META_ID_SK_BOUND_IF,
+	TCF_META_ID_SK_REFCNT,
+	TCF_META_ID_SK_SHUTDOWN,
+	TCF_META_ID_SK_PROTO,
+	TCF_META_ID_SK_TYPE,
+	TCF_META_ID_SK_RCVBUF,
+	TCF_META_ID_SK_RMEM_ALLOC,
+	TCF_META_ID_SK_WMEM_ALLOC,
+	TCF_META_ID_SK_OMEM_ALLOC,
+	TCF_META_ID_SK_WMEM_QUEUED,
+	TCF_META_ID_SK_RCV_QLEN,
+	TCF_META_ID_SK_SND_QLEN,
+ 	TCF_META_ID_SK_ERR_QLEN,
+	TCF_META_ID_SK_FORWARD_ALLOCS,
+	TCF_META_ID_SK_SNDBUF,
+ 	TCF_META_ID_SK_ALLOCS,
+ 	TCF_META_ID_SK_ROUTE_CAPS,
+ 	TCF_META_ID_SK_HASHENT,
+ 	TCF_META_ID_SK_LINGERTIME,
+ 	TCF_META_ID_SK_ACK_BACKLOG,
+ 	TCF_META_ID_SK_MAX_ACK_BACKLOG,
+ 	TCF_META_ID_SK_PRIO,
+ 	TCF_META_ID_SK_RCVLOWAT,
+ 	TCF_META_ID_SK_RCVTIMEO,
+ 	TCF_META_ID_SK_SNDTIMEO,
+ 	TCF_META_ID_SK_SENDMSG_OFF,
+ 	TCF_META_ID_SK_WRITE_PENDING,
 	__TCF_META_ID_MAX
 };
 #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 41d1a644c9d43aa8206cf2b6e708c4a8173b7fd2..2d1ac5058534cdd8db3ecb86233ab31d247e2c44 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -796,6 +796,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
  * of the iso_frame_desc array, and the number of errors is reported in
  * error_count.  Completion callbacks for ISO transfers will normally
  * (re)submit URBs to ensure a constant transfer rate.
+ *
+ * Note that even fields marked "public" should not be touched by the driver
+ * when the urb is owned by the hcd, that is, since the call to
+ * usb_submit_urb() till the entry into the completion routine.
  */
 struct urb
 {
@@ -803,12 +807,12 @@ struct urb
 	struct kref kref;		/* reference count of the URB */
 	spinlock_t lock;		/* lock for the URB */
 	void *hcpriv;			/* private data for host controller */
-	struct list_head urb_list;	/* list pointer to all active urbs */
 	int bandwidth;			/* bandwidth for INT/ISO request */
 	atomic_t use_count;		/* concurrent submissions counter */
 	u8 reject;			/* submissions will fail */
 
 	/* public, documented fields in the urb that can be used by drivers */
+	struct list_head urb_list;	/* list head for use by the urb owner */
 	struct usb_device *dev; 	/* (in) pointer to associated device */
 	unsigned int pipe;		/* (in) pipe information */
 	int status;			/* (return) non-ISO status */
diff --git a/include/net/ip.h b/include/net/ip.h
index 3f63992eb71292da8a08f6ed44dc3f72a743b245..32360bbe143faebcefe80eb9ae7a43d19585680c 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -163,6 +163,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
 
 extern int sysctl_local_port_range[2];
 extern int sysctl_ip_default_ttl;
+extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_INET
 /* The function in 2.2 was invalid, producing wrong result for
diff --git a/kernel/exit.c b/kernel/exit.c
index edaa50b5bbfaecc36f1e492e28d9b80ef55b5dae..2ef2ad54020177cd355174b8d4a52656edebd6d2 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -811,10 +811,8 @@ fastcall NORET_TYPE void do_exit(long code)
 	acct_update_integrals(tsk);
 	update_mem_hiwater(tsk);
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
-	if (group_dead) {
- 		del_timer_sync(&tsk->signal->real_timer);
+	if (group_dead)
 		acct_process(code);
-	}
 	exit_mm(tsk);
 
 	exit_sem(tsk);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index fd316c2722604a866b359548db9659aa5c1eefbc..cabb63fc9e16c5437b6ea879074a9a6c0783cf9d 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1197,6 +1197,7 @@ void exit_itimers(struct signal_struct *sig)
 		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
 		itimer_delete(tmr);
 	}
+	del_timer_sync(&sig->real_timer);
 }
 
 /*
diff --git a/kernel/sched.c b/kernel/sched.c
index 66b2ed784822739b1c2e46c317dca2e3324fc6f1..f12a0c8a7d98d0cbda8507dd9fa8233acb51f087 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3755,19 +3755,22 @@ EXPORT_SYMBOL(cond_resched);
  */
 int cond_resched_lock(spinlock_t * lock)
 {
+	int ret = 0;
+
 	if (need_lockbreak(lock)) {
 		spin_unlock(lock);
 		cpu_relax();
+		ret = 1;
 		spin_lock(lock);
 	}
 	if (need_resched()) {
 		_raw_spin_unlock(lock);
 		preempt_enable_no_resched();
 		__cond_resched();
+		ret = 1;
 		spin_lock(lock);
-		return 1;
 	}
-	return 0;
+	return ret;
 }
 
 EXPORT_SYMBOL(cond_resched_lock);
diff --git a/mm/filemap.c b/mm/filemap.c
index 1d33fec7bac615ed864a504bf99c9e899c5d85f7..4a2fee2cb62bad714491e1e910406ecd66dc2557 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1968,6 +1968,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 	do {
 		unsigned long index;
 		unsigned long offset;
+		unsigned long maxlen;
 		size_t copied;
 
 		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
@@ -1982,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 		 * same page as we're writing to, without it being marked
 		 * up-to-date.
 		 */
-		fault_in_pages_readable(buf, bytes);
+		maxlen = cur_iov->iov_len - iov_base;
+		if (maxlen > bytes)
+			maxlen = bytes;
+		fault_in_pages_readable(buf, maxlen);
 
 		page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
 		if (!page) {
@@ -2024,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 					filemap_set_next_iovec(&cur_iov,
 							&iov_base, status);
 					buf = cur_iov->iov_base + iov_base;
+				} else {
+					iov_base += status;
 				}
 			}
 		}
diff --git a/net/core/dev.c b/net/core/dev.c
index f15a3ffff635d9c6ef5edf65c8dbeff02509793b..ab935778ce81009cadea261d289f7bd44e623850 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1744,6 +1744,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget)
 	struct softnet_data *queue = &__get_cpu_var(softnet_data);
 	unsigned long start_time = jiffies;
 
+	backlog_dev->weight = weight_p;
 	for (;;) {
 		struct sk_buff *skb;
 		struct net_device *dev;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 8ec484894d6805662dd98ef5f495f34611aee57a..a3eeb88e1c81fabe1eea26499958723955b08615 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -356,7 +356,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_coalesce coalesce;
 
-	if (!dev->ethtool_ops->get_coalesce)
+	if (!dev->ethtool_ops->set_coalesce)
 		return -EOPNOTSUPP;
 
 	if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 910eb4c05a4782f5b5de56f1e417a527dc99ffbf..e2137f3e489d1adbb39cecb7abb88e8567f448e4 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -185,6 +185,22 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz
 static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, 
 			 store_tx_queue_len);
 
+NETDEVICE_SHOW(weight, fmt_dec);
+
+static int change_weight(struct net_device *net, unsigned long new_weight)
+{
+	net->weight = new_weight;
+	return 0;
+}
+
+static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len)
+{
+	return netdev_store(dev, buf, len, change_weight);
+}
+
+static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 
+			 store_weight);
+
 
 static struct class_device_attribute *net_class_attributes[] = {
 	&class_device_attr_ifindex,
@@ -194,6 +210,7 @@ static struct class_device_attribute *net_class_attributes[] = {
 	&class_device_attr_features,
 	&class_device_attr_mtu,
 	&class_device_attr_flags,
+	&class_device_attr_weight,
 	&class_device_attr_type,
 	&class_device_attr_address,
 	&class_device_attr_broadcast,
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index b3cb49ce5fad433acafce912f9efeb5e81d7d3a2..03942f13394471c2e0816a70765da05fc518d9ff 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1181,6 +1181,7 @@ EXPORT_SYMBOL(inet_stream_connect);
 EXPORT_SYMBOL(inet_stream_ops);
 EXPORT_SYMBOL(inet_unregister_protosw);
 EXPORT_SYMBOL(net_statistics);
+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
 
 #ifdef INET_REFCNT_DEBUG
 EXPORT_SYMBOL(inet_sock_nr);
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 85bf0d3e294b2c6d5da9fe721904ff07f2c47567..cb759484979d94d46d946a66cca3ef4bf87d84a1 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -207,6 +207,7 @@ int sysctl_icmp_ignore_bogus_error_responses;
 
 int sysctl_icmp_ratelimit = 1 * HZ;
 int sysctl_icmp_ratemask = 0x1818;
+int sysctl_icmp_errors_use_inbound_ifaddr;
 
 /*
  *	ICMP control array. This specifies what to do with each ICMP.
@@ -511,8 +512,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
 	 */
 
 	saddr = iph->daddr;
-	if (!(rt->rt_flags & RTCF_LOCAL))
-		saddr = 0;
+	if (!(rt->rt_flags & RTCF_LOCAL)) {
+		if (sysctl_icmp_errors_use_inbound_ifaddr)
+			saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+		else
+			saddr = 0;
+	}
 
 	tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
 					   IPTOS_PREC_INTERNETCONTROL) :
diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile
index a788461a40c9228688dcc42ce72f5a7543339140..30e85de9fffff03662455d2357b5d384135d3db0 100644
--- a/net/ipv4/ipvs/Makefile
+++ b/net/ipv4/ipvs/Makefile
@@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o
 
 ip_vs-objs :=	ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o	   \
 		ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o	   		   \
-		ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o		   \
+		ip_vs_est.o ip_vs_proto.o 				   \
 		$(ip_vs_proto-objs-y)
 
 
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 253c46252bd5b1dfeae6382c94a2eaf7340278ae..867d4e9c6594c3a62eb70475d6b2c26cfe74c2ca 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -216,9 +216,6 @@ int ip_vs_protocol_init(void)
 #ifdef CONFIG_IP_VS_PROTO_UDP
 	REGISTER_PROTOCOL(&ip_vs_protocol_udp);
 #endif
-#ifdef CONFIG_IP_VS_PROTO_ICMP
-	REGISTER_PROTOCOL(&ip_vs_protocol_icmp);
-#endif
 #ifdef CONFIG_IP_VS_PROTO_AH
 	REGISTER_PROTOCOL(&ip_vs_protocol_ah);
 #endif
diff --git a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c
deleted file mode 100644
index 191e94aa1c1f2961745600a8104fa5b886fb2d92..0000000000000000000000000000000000000000
--- a/net/ipv4/ipvs/ip_vs_proto_icmp.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * ip_vs_proto_icmp.c:	ICMP load balancing support for IP Virtual Server
- *
- * Authors:	Julian Anastasov <ja@ssi.bg>, March 2002
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		version 2 as published by the Free Software Foundation;
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/icmp.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4.h>
-
-#include <net/ip_vs.h>
-
-
-static int icmp_timeouts[1] =		{ 1*60*HZ };
-
-static char * icmp_state_name_table[1] = { "ICMP" };
-
-static struct ip_vs_conn *
-icmp_conn_in_get(const struct sk_buff *skb,
-		 struct ip_vs_protocol *pp,
-		 const struct iphdr *iph,
-		 unsigned int proto_off,
-		 int inverse)
-{
-#if 0
-	struct ip_vs_conn *cp;
-
-	if (likely(!inverse)) {
-		cp = ip_vs_conn_in_get(iph->protocol,
-			iph->saddr, 0,
-			iph->daddr, 0);
-	} else {
-		cp = ip_vs_conn_in_get(iph->protocol,
-			iph->daddr, 0,
-			iph->saddr, 0);
-	}
-
-	return cp;
-
-#else
-	return NULL;
-#endif
-}
-
-static struct ip_vs_conn *
-icmp_conn_out_get(const struct sk_buff *skb,
-		  struct ip_vs_protocol *pp,
-		  const struct iphdr *iph,
-		  unsigned int proto_off,
-		  int inverse)
-{
-#if 0
-	struct ip_vs_conn *cp;
-
-	if (likely(!inverse)) {
-		cp = ip_vs_conn_out_get(iph->protocol,
-			iph->saddr, 0,
-			iph->daddr, 0);
-	} else {
-		cp = ip_vs_conn_out_get(IPPROTO_UDP,
-			iph->daddr, 0,
-			iph->saddr, 0);
-	}
-
-	return cp;
-#else
-	return NULL;
-#endif
-}
-
-static int
-icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
-		   int *verdict, struct ip_vs_conn **cpp)
-{
-	*verdict = NF_ACCEPT;
-	return 0;
-}
-
-static int
-icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
-{
-	if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) {
-		if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
-			if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) {
-				IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for");
-				return 0;
-			}
-		}
-	}
-	return 1;
-}
-
-static void
-icmp_debug_packet(struct ip_vs_protocol *pp,
-		  const struct sk_buff *skb,
-		  int offset,
-		  const char *msg)
-{
-	char buf[256];
-	struct iphdr _iph, *ih;
-
-	ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
-	if (ih == NULL)
-		sprintf(buf, "%s TRUNCATED", pp->name);
-	else if (ih->frag_off & __constant_htons(IP_OFFSET))
-		sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag",
-			pp->name, NIPQUAD(ih->saddr),
-			NIPQUAD(ih->daddr));
-	else {
-		struct icmphdr _icmph, *ic;
-
-		ic = skb_header_pointer(skb, offset + ih->ihl*4,
-					sizeof(_icmph), &_icmph);
-		if (ic == NULL)
-			sprintf(buf, "%s TRUNCATED to %u bytes\n",
-				pp->name, skb->len - offset);
-		else
-			sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d",
-				pp->name, NIPQUAD(ih->saddr),
-				NIPQUAD(ih->daddr),
-				ic->type, ic->code);
-	}
-	printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
-}
-
-static int
-icmp_state_transition(struct ip_vs_conn *cp, int direction,
-		      const struct sk_buff *skb,
-		      struct ip_vs_protocol *pp)
-{
-	cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL];
-	return 1;
-}
-
-static int
-icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to)
-{
-	int num;
-	char **names;
-
-	num = IP_VS_ICMP_S_LAST;
-	names = icmp_state_name_table;
-	return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to);
-}
-
-
-static void icmp_init(struct ip_vs_protocol *pp)
-{
-	pp->timeout_table = icmp_timeouts;
-}
-
-static void icmp_exit(struct ip_vs_protocol *pp)
-{
-}
-
-struct ip_vs_protocol ip_vs_protocol_icmp = {
-	.name =			"ICMP",
-	.protocol =		IPPROTO_ICMP,
-	.dont_defrag =		0,
-	.init =			icmp_init,
-	.exit =			icmp_exit,
-	.conn_schedule =	icmp_conn_schedule,
-	.conn_in_get =		icmp_conn_in_get,
-	.conn_out_get =		icmp_conn_out_get,
-	.snat_handler =		NULL,
-	.dnat_handler =		NULL,
-	.csum_check =		icmp_csum_check,
-	.state_transition =	icmp_state_transition,
-	.register_app =		NULL,
-	.unregister_app =	NULL,
-	.app_conn_bind =	NULL,
-	.debug_packet =		icmp_debug_packet,
-	.timeout_change =	NULL,
-	.set_state_timeout =	icmp_set_state_timeout,
-};
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
index cf2e6bcf7973b99c8f0cd632c99bc2700ec19faa..c9cf8726051d7cae07a3d1278b0bea36b1c2eee5 100644
--- a/net/ipv4/multipath_drr.c
+++ b/net/ipv4/multipath_drr.c
@@ -31,6 +31,7 @@
 #include <linux/igmp.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <net/ip.h>
@@ -247,3 +248,4 @@ static void __exit drr_exit(void)
 
 module_init(drr_init);
 module_exit(drr_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
index 805a16e47de5ff9f35f2623dd0fc3e524aac18c5..5249dbe7c559f90fce4671405954a415aebb3b4c 100644
--- a/net/ipv4/multipath_random.c
+++ b/net/ipv4/multipath_random.c
@@ -31,6 +31,7 @@
 #include <linux/igmp.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <net/ip.h>
@@ -126,3 +127,4 @@ static void __exit random_exit(void)
 
 module_init(random_init);
 module_exit(random_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
index 061b6b253982d21192b6055de41b34a3878f927d..b6cd2870478f9db2700e5a49839f07782ac758da 100644
--- a/net/ipv4/multipath_rr.c
+++ b/net/ipv4/multipath_rr.c
@@ -31,6 +31,7 @@
 #include <linux/igmp.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <net/ip.h>
@@ -93,3 +94,4 @@ static void __exit rr_exit(void)
 
 module_init(rr_init);
 module_exit(rr_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index c3d2ca1a6781513bc7b2524aad96f61e7a4053a6..bd7d75b6abe0a6a7e1ed63d78b5d18becf3eb961 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -31,6 +31,7 @@
 #include <linux/igmp.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <net/ip.h>
@@ -342,3 +343,4 @@ static void __exit wrandom_exit(void)
 
 module_init(wrandom_init);
 module_exit(wrandom_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 46ca45f74d85b6e543304df6eb6f89b9db2098d4..bc59f7b3980585eacd0410a93de5722f8ccc299f 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -256,6 +256,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
  	struct list_head *e = v;
 
+	++*pos;
 	e = e->next;
 
 	if (e == &ip_conntrack_expect_list)
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 25ab9fabdcba3d66cb4bbf015514b6d671e6ed8f..2d44b07688af3794bfe51b4aa63bfb5417021aa7 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -223,7 +223,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned
 			curr_table->table[count].last_seen = 0;
 			curr_table->table[count].addr = 0;
 			curr_table->table[count].ttl = 0;
-			memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+			memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
 			curr_table->table[count].oldest_pkt = 0;
 			curr_table->table[count].time_pos = 0;
 			curr_table->time_info[count].position = count;
@@ -502,7 +502,7 @@ match(const struct sk_buff *skb,
 		location = time_info[curr_table->time_pos].position;
 		hash_table[r_list[location].hash_entry] = -1;
 		hash_table[hash_result] = location;
-		memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+		memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
 		r_list[location].time_pos = curr_table->time_pos;
 		r_list[location].addr = addr;
 		r_list[location].ttl = ttl;
@@ -631,7 +631,7 @@ match(const struct sk_buff *skb,
 			r_list[location].last_seen = 0;
 			r_list[location].addr = 0;
 			r_list[location].ttl = 0;
-			memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+			memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long));
 			r_list[location].oldest_pkt = 0;
 			ans = !info->invert;
 		}
@@ -734,10 +734,10 @@ checkentry(const char *tablename,
 	memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot);
 #ifdef DEBUG
 	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n",
-			sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+			sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);
 #endif
 
-	hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+	hold = vmalloc(sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);
 #ifdef DEBUG
 	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n");
 #endif
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 3aafb298c1c19691e26a2a599f53b8e7de4214f3..23068bddbf0bb6837edc01ff2f2f8cd34a12c357 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -23,6 +23,7 @@ extern int sysctl_ip_nonlocal_bind;
 extern int sysctl_icmp_echo_ignore_all;
 extern int sysctl_icmp_echo_ignore_broadcasts;
 extern int sysctl_icmp_ignore_bogus_error_responses;
+extern int sysctl_icmp_errors_use_inbound_ifaddr;
 
 /* From ip_fragment.c */
 extern int sysctl_ipfrag_low_thresh;
@@ -395,6 +396,14 @@ ctl_table ipv4_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
+		.procname	= "icmp_errors_use_inbound_ifaddr",
+		.data		= &sysctl_icmp_errors_use_inbound_ifaddr,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 	{
 		.ctl_name	= NET_IPV4_ROUTE,
 		.procname	= "route",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a037bafcba3c09234e7bfcfbf59f15acb71a8f95..0d9a4fd5f1a40cb568b691c19a571276b1c7a12d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2338,7 +2338,7 @@ void __init tcp_init(void)
 			(tcp_bhash_size * sizeof(struct tcp_bind_hashbucket));
 			order++)
 		;
-	if (order > 4) {
+	if (order >= 4) {
 		sysctl_local_port_range[0] = 32768;
 		sysctl_local_port_range[1] = 61000;
 		sysctl_tcp_max_tw_buckets = 180000;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7744a2592693ff9562f14b4fa0b0cb614f71fdd7..2720899d516c677231bd76cbb736d40f030494f0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -372,6 +372,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 		ndev->regen_timer.data = (unsigned long) ndev;
 		if ((dev->flags&IFF_LOOPBACK) ||
 		    dev->type == ARPHRD_TUNNEL ||
+		    dev->type == ARPHRD_NONE ||
 		    dev->type == ARPHRD_SIT) {
 			printk(KERN_INFO
 				"Disabled Privacy Extensions on device %p(%s)\n",
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 8e0f569b883e419acd311e79670d9ea916f0a034..ff3ec9822e36bb5e8c0100014c20bd8e3b14af50 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -277,8 +277,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 {
 	struct inet6_dev *idev = NULL;
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
-	struct sock *sk = icmpv6_socket->sk;
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sock *sk;
+	struct ipv6_pinfo *np;
 	struct in6_addr *saddr = NULL;
 	struct dst_entry *dst;
 	struct icmp6hdr tmp_hdr;
@@ -358,6 +358,9 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
 	if (icmpv6_xmit_lock())
 		return;
 
+	sk = icmpv6_socket->sk;
+	np = inet6_sk(sk);
+
 	if (!icmpv6_xrlim_allow(sk, type, &fl))
 		goto out;
 
@@ -423,9 +426,9 @@ out:
 
 static void icmpv6_echo_reply(struct sk_buff *skb)
 {
-	struct sock *sk = icmpv6_socket->sk;
+	struct sock *sk;
 	struct inet6_dev *idev;
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct ipv6_pinfo *np;
 	struct in6_addr *saddr = NULL;
 	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
 	struct icmp6hdr tmp_hdr;
@@ -454,6 +457,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	if (icmpv6_xmit_lock())
 		return;
 
+	sk = icmpv6_socket->sk;
+	np = inet6_sk(sk);
+
 	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3b1c9fa184ae68e81cf3d3ac8fd3c543317a2602..ba3b0c267f759565c3eab810e3ed8bbbaaa91bfd 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -882,6 +882,7 @@ ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p)
 	t->parms.hop_limit = p->hop_limit;
 	t->parms.encap_limit = p->encap_limit;
 	t->parms.flowinfo = p->flowinfo;
+	t->parms.link = p->link;
 	ip6ip6_tnl_link_config(t);
 	return 0;
 }
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 2f4c91ddc9a36c12d87cd57042a5d5d3644a1fd2..5ade5a5d199053dc20d349a8c8f313263a240260 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -37,5 +37,4 @@ EXPORT_SYMBOL(in6_dev_finish_destroy);
 EXPORT_SYMBOL(xfrm6_rcv);
 #endif
 EXPORT_SYMBOL(rt6_lookup);
-EXPORT_SYMBOL(fl6_sock_lookup);
 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index b0941186f867710a4f4ca4a9fdb486aa2d9b1455..b22c9beb604d78eb3dbf32809112802cb0b597ee 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -405,7 +405,7 @@ config NET_EMATCH_STACK
 	---help---
 	  Size of the local stack variable used while evaluating the tree of
 	  ematches. Limits the depth of the tree, i.e. the number of
-	  encapsulated precedences. Every level requires 4 bytes of addtional
+	  encapsulated precedences. Every level requires 4 bytes of additional
 	  stack space.
 
 config NET_EMATCH_CMP
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index cafcb084098d161d0d8d09ac64e8b067edb837f9..914c85ff8fe6c967bb30a1a99dba4ef58bd5c2da 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -881,7 +881,7 @@ static int __init tc_action_init(void)
 		link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
 	}
 
-	printk("TC classifier action (bugs to netdev@oss.sgi.com cc "
+	printk("TC classifier action (bugs to netdev@vger.kernel.org cc "
 	       "hadi@cyberus.ca)\n");
 	return 0;
 }
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 0d2d4415f334850b7006c110bc502736ae3f83b1..dfb300bb6baa067963a5e0e1e160087ae69d291d 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -261,6 +261,9 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
 	rta = (struct rtattr *) b;
 	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
 
+	if (f->res.classid)
+		RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
+
 	if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
 	    tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
 		goto rtattr_failure;
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index f1eeaf65cee5f833aabb493c53442ef80e983eef..48bb23c2a35a404aa5ef6e94a9160e2b346510ad 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -32,7 +32,7 @@
  * 	      +-----------+                           +-----------+
  * 	            |                                       |
  * 	            ---> meta_ops[INT][INDEV](...)          |
- *                            |                            |
+ *	                      |                             |
  * 	            -----------                             |
  * 	            V                                       V
  * 	      +-----------+                           +-----------+
@@ -70,6 +70,7 @@
 #include <net/dst.h>
 #include <net/route.h>
 #include <net/pkt_cls.h>
+#include <net/sock.h>
 
 struct meta_obj
 {
@@ -283,6 +284,214 @@ META_COLLECTOR(int_rtiif)
 		dst->value = ((struct rtable*) skb->dst)->fl.iif;
 }
 
+/**************************************************************************
+ * Socket Attributes
+ **************************************************************************/
+
+#define SKIP_NONLOCAL(skb)			\
+	if (unlikely(skb->sk == NULL)) {	\
+		*err = -1;			\
+		return;				\
+	}
+
+META_COLLECTOR(int_sk_family)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_family;
+}
+
+META_COLLECTOR(int_sk_state)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_state;
+}
+
+META_COLLECTOR(int_sk_reuse)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_reuse;
+}
+
+META_COLLECTOR(int_sk_bound_if)
+{
+	SKIP_NONLOCAL(skb);
+	/* No error if bound_dev_if is 0, legal userspace check */
+	dst->value = skb->sk->sk_bound_dev_if;
+}
+
+META_COLLECTOR(var_sk_bound_if)
+{
+	SKIP_NONLOCAL(skb);
+
+	 if (skb->sk->sk_bound_dev_if == 0) {
+		dst->value = (unsigned long) "any";
+		dst->len = 3;
+	 } else  {
+		struct net_device *dev;
+		
+		dev = dev_get_by_index(skb->sk->sk_bound_dev_if);
+		*err = var_dev(dev, dst);
+		if (dev)
+			dev_put(dev);
+	 }
+}
+
+META_COLLECTOR(int_sk_refcnt)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_refcnt);
+}
+
+META_COLLECTOR(int_sk_rcvbuf)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvbuf;
+}
+
+META_COLLECTOR(int_sk_shutdown)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_shutdown;
+}
+
+META_COLLECTOR(int_sk_proto)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_protocol;
+}
+
+META_COLLECTOR(int_sk_type)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_type;
+}
+
+META_COLLECTOR(int_sk_rmem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_rmem_alloc);
+}
+
+META_COLLECTOR(int_sk_wmem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_wmem_alloc);
+}
+
+META_COLLECTOR(int_sk_omem_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = atomic_read(&skb->sk->sk_omem_alloc);
+}
+
+META_COLLECTOR(int_sk_rcv_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_receive_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_snd_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_write_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_wmem_queued)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_wmem_queued;
+}
+
+META_COLLECTOR(int_sk_fwd_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_forward_alloc;
+}
+
+META_COLLECTOR(int_sk_sndbuf)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndbuf;
+}
+
+META_COLLECTOR(int_sk_alloc)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_allocation;
+}
+
+META_COLLECTOR(int_sk_route_caps)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_route_caps;
+}
+
+META_COLLECTOR(int_sk_hashent)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_hashent;
+}
+
+META_COLLECTOR(int_sk_lingertime)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_lingertime / HZ;
+}
+
+META_COLLECTOR(int_sk_err_qlen)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_error_queue.qlen;
+}
+
+META_COLLECTOR(int_sk_ack_bl)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_max_ack_bl)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_max_ack_backlog;
+}
+
+META_COLLECTOR(int_sk_prio)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_priority;
+}
+
+META_COLLECTOR(int_sk_rcvlowat)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvlowat;
+}
+
+META_COLLECTOR(int_sk_rcvtimeo)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_rcvtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sndtimeo)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndtimeo / HZ;
+}
+
+META_COLLECTOR(int_sk_sendmsg_off)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_sndmsg_off;
+}
+
+META_COLLECTOR(int_sk_write_pend)
+{
+	SKIP_NONLOCAL(skb);
+	dst->value = skb->sk->sk_write_pending;
+}
+
 /**************************************************************************
  * Meta value collectors assignment table
  **************************************************************************/
@@ -293,41 +502,75 @@ struct meta_ops
 			       struct meta_value *, struct meta_obj *, int *);
 };
 
+#define META_ID(name) TCF_META_ID_##name
+#define META_FUNC(name) { .get = meta_##name }
+
 /* Meta value operations table listing all meta value collectors and
  * assigns them to a type and meta id. */
 static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
 	[TCF_META_TYPE_VAR] = {
-		[TCF_META_ID_DEV]	= { .get = meta_var_dev },
-		[TCF_META_ID_INDEV]	= { .get = meta_var_indev },
-		[TCF_META_ID_REALDEV]	= { .get = meta_var_realdev }
+		[META_ID(DEV)]			= META_FUNC(var_dev),
+		[META_ID(INDEV)]		= META_FUNC(var_indev),
+		[META_ID(REALDEV)]		= META_FUNC(var_realdev),
+		[META_ID(SK_BOUND_IF)] 		= META_FUNC(var_sk_bound_if),
 	},
 	[TCF_META_TYPE_INT] = {
-		[TCF_META_ID_RANDOM]	= { .get = meta_int_random },
-		[TCF_META_ID_LOADAVG_0]	= { .get = meta_int_loadavg_0 },
-		[TCF_META_ID_LOADAVG_1]	= { .get = meta_int_loadavg_1 },
-		[TCF_META_ID_LOADAVG_2]	= { .get = meta_int_loadavg_2 },
-		[TCF_META_ID_DEV]	= { .get = meta_int_dev },
-		[TCF_META_ID_INDEV]	= { .get = meta_int_indev },
-		[TCF_META_ID_REALDEV]	= { .get = meta_int_realdev },
-		[TCF_META_ID_PRIORITY]	= { .get = meta_int_priority },
-		[TCF_META_ID_PROTOCOL]	= { .get = meta_int_protocol },
-		[TCF_META_ID_SECURITY]	= { .get = meta_int_security },
-		[TCF_META_ID_PKTTYPE]	= { .get = meta_int_pkttype },
-		[TCF_META_ID_PKTLEN]	= { .get = meta_int_pktlen },
-		[TCF_META_ID_DATALEN]	= { .get = meta_int_datalen },
-		[TCF_META_ID_MACLEN]	= { .get = meta_int_maclen },
+		[META_ID(RANDOM)]		= META_FUNC(int_random),
+		[META_ID(LOADAVG_0)]		= META_FUNC(int_loadavg_0),
+		[META_ID(LOADAVG_1)]		= META_FUNC(int_loadavg_1),
+		[META_ID(LOADAVG_2)]		= META_FUNC(int_loadavg_2),
+		[META_ID(DEV)]			= META_FUNC(int_dev),
+		[META_ID(INDEV)]		= META_FUNC(int_indev),
+		[META_ID(REALDEV)]		= META_FUNC(int_realdev),
+		[META_ID(PRIORITY)]		= META_FUNC(int_priority),
+		[META_ID(PROTOCOL)]		= META_FUNC(int_protocol),
+		[META_ID(SECURITY)]		= META_FUNC(int_security),
+		[META_ID(PKTTYPE)]		= META_FUNC(int_pkttype),
+		[META_ID(PKTLEN)]		= META_FUNC(int_pktlen),
+		[META_ID(DATALEN)]		= META_FUNC(int_datalen),
+		[META_ID(MACLEN)]		= META_FUNC(int_maclen),
 #ifdef CONFIG_NETFILTER
-		[TCF_META_ID_NFMARK]	= { .get = meta_int_nfmark },
+		[META_ID(NFMARK)]		= META_FUNC(int_nfmark),
 #endif
-		[TCF_META_ID_TCINDEX]	= { .get = meta_int_tcindex },
+		[META_ID(TCINDEX)]		= META_FUNC(int_tcindex),
 #ifdef CONFIG_NET_CLS_ACT
-		[TCF_META_ID_TCVERDICT]	= { .get = meta_int_tcverd },
-		[TCF_META_ID_TCCLASSID]	= { .get = meta_int_tcclassid },
+		[META_ID(TCVERDICT)]		= META_FUNC(int_tcverd),
+		[META_ID(TCCLASSID)]		= META_FUNC(int_tcclassid),
 #endif
 #ifdef CONFIG_NET_CLS_ROUTE
-		[TCF_META_ID_RTCLASSID]	= { .get = meta_int_rtclassid },
+		[META_ID(RTCLASSID)]		= META_FUNC(int_rtclassid),
 #endif
-		[TCF_META_ID_RTIIF]	= { .get = meta_int_rtiif }
+		[META_ID(RTIIF)]		= META_FUNC(int_rtiif),
+		[META_ID(SK_FAMILY)]		= META_FUNC(int_sk_family),
+		[META_ID(SK_STATE)]		= META_FUNC(int_sk_state),
+		[META_ID(SK_REUSE)]		= META_FUNC(int_sk_reuse),
+		[META_ID(SK_BOUND_IF)]		= META_FUNC(int_sk_bound_if),
+		[META_ID(SK_REFCNT)]		= META_FUNC(int_sk_refcnt),
+		[META_ID(SK_RCVBUF)]		= META_FUNC(int_sk_rcvbuf),
+		[META_ID(SK_SNDBUF)]		= META_FUNC(int_sk_sndbuf),
+		[META_ID(SK_SHUTDOWN)]		= META_FUNC(int_sk_shutdown),
+		[META_ID(SK_PROTO)]		= META_FUNC(int_sk_proto),
+		[META_ID(SK_TYPE)]		= META_FUNC(int_sk_type),
+		[META_ID(SK_RMEM_ALLOC)]	= META_FUNC(int_sk_rmem_alloc),
+		[META_ID(SK_WMEM_ALLOC)]	= META_FUNC(int_sk_wmem_alloc),
+		[META_ID(SK_OMEM_ALLOC)]	= META_FUNC(int_sk_omem_alloc),
+		[META_ID(SK_WMEM_QUEUED)]	= META_FUNC(int_sk_wmem_queued),
+		[META_ID(SK_RCV_QLEN)]		= META_FUNC(int_sk_rcv_qlen),
+		[META_ID(SK_SND_QLEN)]		= META_FUNC(int_sk_snd_qlen),
+		[META_ID(SK_ERR_QLEN)]		= META_FUNC(int_sk_err_qlen),
+		[META_ID(SK_FORWARD_ALLOCS)]	= META_FUNC(int_sk_fwd_alloc),
+		[META_ID(SK_ALLOCS)]		= META_FUNC(int_sk_alloc),
+		[META_ID(SK_ROUTE_CAPS)]	= META_FUNC(int_sk_route_caps),
+		[META_ID(SK_HASHENT)]		= META_FUNC(int_sk_hashent),
+		[META_ID(SK_LINGERTIME)]	= META_FUNC(int_sk_lingertime),
+		[META_ID(SK_ACK_BACKLOG)]	= META_FUNC(int_sk_ack_bl),
+		[META_ID(SK_MAX_ACK_BACKLOG)]	= META_FUNC(int_sk_max_ack_bl),
+		[META_ID(SK_PRIO)]		= META_FUNC(int_sk_prio),
+		[META_ID(SK_RCVLOWAT)]		= META_FUNC(int_sk_rcvlowat),
+		[META_ID(SK_RCVTIMEO)]		= META_FUNC(int_sk_rcvtimeo),
+		[META_ID(SK_SNDTIMEO)]		= META_FUNC(int_sk_sndtimeo),
+		[META_ID(SK_SENDMSG_OFF)]	= META_FUNC(int_sk_sendmsg_off),
+		[META_ID(SK_WRITE_PENDING)]	= META_FUNC(int_sk_write_pend),
 	}
 };
 
@@ -396,9 +639,9 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b)
 	/* Let gcc optimize it, the unlikely is not really based on
 	 * some numbers but jump free code for mismatches seems
 	 * more logical. */
-	if (unlikely(a == b))
+	if (unlikely(a->value == b->value))
 		return 0;
-	else if (a < b)
+	else if (a->value < b->value)
 		return -1;
 	else
 		return 1;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index b719a77d66b47e3a553672c1d712e8e53b93e99b..fffc880a646d9a027a690bef279ff81e1e1ee162 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -178,6 +178,37 @@ int sctp_rcv(struct sk_buff *skb)
 
 	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
 
+	if (!asoc)
+		ep = __sctp_rcv_lookup_endpoint(&dest);
+
+	/* Retrieve the common input handling substructure. */
+	rcvr = asoc ? &asoc->base : &ep->base;
+	sk = rcvr->sk;
+
+	/*
+	 * If a frame arrives on an interface and the receiving socket is
+	 * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB
+	 */
+	if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
+	{
+		sock_put(sk);
+		if (asoc) {
+			sctp_association_put(asoc);
+			asoc = NULL;
+		} else {
+			sctp_endpoint_put(ep);
+			ep = NULL;
+		}
+		sk = sctp_get_ctl_sock();
+		ep = sctp_sk(sk)->ep;
+		sctp_endpoint_hold(ep);
+		sock_hold(sk);
+		rcvr = &ep->base;
+	}
+
+	if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
+		goto discard_release;
+
 	/*
 	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
 	 * An SCTP packet is called an "out of the blue" (OOTB)
@@ -187,22 +218,12 @@ int sctp_rcv(struct sk_buff *skb)
 	 * packet belongs.
 	 */
 	if (!asoc) {
-		ep = __sctp_rcv_lookup_endpoint(&dest);
 		if (sctp_rcv_ootb(skb)) {
 			SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES);
 			goto discard_release;
 		}
 	}
 
-	/* Retrieve the common input handling substructure. */
-	rcvr = asoc ? &asoc->base : &ep->base;
-	sk = rcvr->sk;
-
-	if ((sk) && (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)) {
-		goto discard_release;
-	}
-
-
 	/* SCTP seems to always need a timestamp right now (FIXME) */
 	if (skb->stamp.tv_sec == 0) {
 		do_gettimeofday(&skb->stamp);
@@ -265,13 +286,11 @@ discard_it:
 
 discard_release:
 	/* Release any structures we may be holding. */
-	if (asoc) {
-		sock_put(asoc->base.sk);
+	sock_put(sk);
+	if (asoc)
 		sctp_association_put(asoc);
-	} else {
-		sock_put(ep->base.sk);
+	else
 		sctp_endpoint_put(ep);
-	}
 
 	goto discard_it;
 }
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index c9d9ea064734ad58e18c14e03055816b0c219dd7..c7e42d125b9cc544af46e640a725352c5ea1b6a1 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -812,26 +812,23 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 	if (addr->sa.sa_family != AF_INET6)
 		af = sctp_get_af_specific(addr->sa.sa_family);
 	else {
-		struct sock *sk;
 		int type = ipv6_addr_type(&addr->v6.sin6_addr);
-		sk = sctp_opt2sk(opt);
+		struct net_device *dev;
+
 		if (type & IPV6_ADDR_LINKLOCAL) {
-			/* Note: Behavior similar to af_inet6.c:
-			 *  1) Overrides previous bound_dev_if
-			 *  2) Destructive even if bind isn't successful.
-			 */
-
-			if (addr->v6.sin6_scope_id)
-				sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-			if (!sk->sk_bound_dev_if)
+			if (!addr->v6.sin6_scope_id)
+				return 0;
+			dev = dev_get_by_index(addr->v6.sin6_scope_id);
+			if (!dev)
 				return 0;
+			dev_put(dev);
 		}
 		af = opt->pf->af;
 	}
 	return af->available(addr, opt);
 }
 
-/* Verify that the provided sockaddr looks bindable.   Common verification,
+/* Verify that the provided sockaddr looks sendable.   Common verification,
  * has already been taken care of.
  */
 static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
@@ -842,19 +839,16 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
 	if (addr->sa.sa_family != AF_INET6)
 		af = sctp_get_af_specific(addr->sa.sa_family);
 	else {
-		struct sock *sk;
 		int type = ipv6_addr_type(&addr->v6.sin6_addr);
-		sk = sctp_opt2sk(opt);
+		struct net_device *dev;
+
 		if (type & IPV6_ADDR_LINKLOCAL) {
-			/* Note: Behavior similar to af_inet6.c:
-			 *  1) Overrides previous bound_dev_if
-			 *  2) Destructive even if bind isn't successful.
-			 */
-
-			if (addr->v6.sin6_scope_id)
-				sk->sk_bound_dev_if = addr->v6.sin6_scope_id;
-			if (!sk->sk_bound_dev_if)
+			if (!addr->v6.sin6_scope_id)
+				return 0;
+			dev = dev_get_by_index(addr->v6.sin6_scope_id);
+			if (!dev)
 				return 0;
+			dev_put(dev);
 		}
 		af = opt->pf->af;
 	}
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index e42fd8c2916b639fb1310dead4ef95a379936715..98d49ec9b74b93a4256f430e83838f2e911baf42 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -132,14 +132,25 @@ void sctp_snmp_proc_exit(void)
 static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
 {
 	struct list_head *pos;
+	struct sctp_association *asoc;
 	struct sctp_sockaddr_entry *laddr;
-	union sctp_addr *addr;
+	struct sctp_transport *peer;
+	union sctp_addr *addr, *primary = NULL;
 	struct sctp_af *af;
 
+	if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
+	    asoc = sctp_assoc(epb);
+	    peer = asoc->peer.primary_path;
+	    primary = &peer->saddr;
+	}
+
 	list_for_each(pos, &epb->bind_addr.address_list) {
 		laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 		addr = (union sctp_addr *)&laddr->a;
 		af = sctp_get_af_specific(addr->sa.sa_family);
+		if (primary && af->cmp_addr(addr, primary)) {
+			seq_printf(seq, "*");
+		}
 		af->seq_dump_addr(seq, addr);
 	}
 }
@@ -149,17 +160,54 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
 {
 	struct list_head *pos;
 	struct sctp_transport *transport;
-	union sctp_addr *addr;
+	union sctp_addr *addr, *primary;
 	struct sctp_af *af;
 
+	primary = &(assoc->peer.primary_addr);
 	list_for_each(pos, &assoc->peer.transport_addr_list) {
 		transport = list_entry(pos, struct sctp_transport, transports);
 		addr = (union sctp_addr *)&transport->ipaddr;
 		af = sctp_get_af_specific(addr->sa.sa_family);
+		if (af->cmp_addr(addr, primary)) {
+			seq_printf(seq, "*");
+		}
 		af->seq_dump_addr(seq, addr);
 	}
 }
 
+static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	if (*pos > sctp_ep_hashsize)
+		return NULL;
+
+	if (*pos < 0)
+		*pos = 0;
+
+	if (*pos == 0)
+		seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS\n");
+
+	++*pos;
+
+	return (void *)pos;
+}
+
+static void sctp_eps_seq_stop(struct seq_file *seq, void *v)
+{
+	return;
+}
+
+
+static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	if (*pos > sctp_ep_hashsize)
+		return NULL;
+
+	++*pos;
+
+	return pos;
+}
+
+
 /* Display sctp endpoints (/proc/net/sctp/eps). */
 static int sctp_eps_seq_show(struct seq_file *seq, void *v)
 {
@@ -167,38 +215,50 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
 	struct sctp_ep_common *epb;
 	struct sctp_endpoint *ep;
 	struct sock *sk;
-	int hash;
-
-	seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT LADDRS\n");
-	for (hash = 0; hash < sctp_ep_hashsize; hash++) {
-		head = &sctp_ep_hashtable[hash];
-		read_lock(&head->lock);
-		for (epb = head->chain; epb; epb = epb->next) {
-			ep = sctp_ep(epb);
-			sk = epb->sk;
-			seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk,
-				   sctp_sk(sk)->type, sk->sk_state, hash,
-				   epb->bind_addr.port);
-			sctp_seq_dump_local_addrs(seq, epb);
-			seq_printf(seq, "\n");
-		}
-		read_unlock(&head->lock);
+	int    hash = *(int *)v;
+
+	if (hash > sctp_ep_hashsize)
+		return -ENOMEM;
+
+	head = &sctp_ep_hashtable[hash-1];
+	sctp_local_bh_disable();
+	read_lock(&head->lock);
+	for (epb = head->chain; epb; epb = epb->next) {
+		ep = sctp_ep(epb);
+		sk = epb->sk;
+		seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
+			   sctp_sk(sk)->type, sk->sk_state, hash-1,
+			   epb->bind_addr.port,
+			   sock_i_uid(sk), sock_i_ino(sk));
+
+		sctp_seq_dump_local_addrs(seq, epb);
+		seq_printf(seq, "\n");
 	}
+	read_unlock(&head->lock);
+	sctp_local_bh_enable();
 
 	return 0;
 }
 
+static struct seq_operations sctp_eps_ops = {
+	.start = sctp_eps_seq_start,
+	.next  = sctp_eps_seq_next,
+	.stop  = sctp_eps_seq_stop,
+	.show  = sctp_eps_seq_show,
+};
+
+
 /* Initialize the seq file operations for 'eps' object. */
 static int sctp_eps_seq_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, sctp_eps_seq_show, NULL);
+	return seq_open(file, &sctp_eps_ops);
 }
 
 static struct file_operations sctp_eps_seq_fops = {
 	.open	 = sctp_eps_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = single_release,
+	.release = seq_release,
 };
 
 /* Set up the proc fs entry for 'eps' object. */
@@ -221,6 +281,40 @@ void sctp_eps_proc_exit(void)
 	remove_proc_entry("eps", proc_net_sctp);
 }
 
+
+static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	if (*pos > sctp_assoc_hashsize)
+		return NULL;
+
+	if (*pos < 0)
+		*pos = 0;
+
+	if (*pos == 0)
+		seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
+				"RPORT LADDRS <-> RADDRS\n");
+
+	++*pos;
+
+	return (void *)pos;
+}
+
+static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
+{
+	return;
+}
+
+
+static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	if (*pos > sctp_assoc_hashsize)
+		return NULL;
+
+	++*pos;
+
+	return pos;
+}
+
 /* Display sctp associations (/proc/net/sctp/assocs). */
 static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
 {
@@ -228,43 +322,57 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
 	struct sctp_ep_common *epb;
 	struct sctp_association *assoc;
 	struct sock *sk;
-	int hash;
-
-	seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT LPORT RPORT "
-			"LADDRS <-> RADDRS\n");
-	for (hash = 0; hash < sctp_assoc_hashsize; hash++) {
-		head = &sctp_assoc_hashtable[hash];
-		read_lock(&head->lock);
-		for (epb = head->chain; epb; epb = epb->next) {
-			assoc = sctp_assoc(epb);
-			sk = epb->sk;
-			seq_printf(seq,
-				   "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ",
-				   assoc, sk, sctp_sk(sk)->type, sk->sk_state,
-				   assoc->state, hash, epb->bind_addr.port,
-				   assoc->peer.port);
-			sctp_seq_dump_local_addrs(seq, epb);
-			seq_printf(seq, "<-> ");
-			sctp_seq_dump_remote_addrs(seq, assoc);
-			seq_printf(seq, "\n");
-		}
-		read_unlock(&head->lock);
+	int    hash = *(int *)v;
+
+	if (hash > sctp_assoc_hashsize)
+		return -ENOMEM;
+
+	head = &sctp_assoc_hashtable[hash-1];
+	sctp_local_bh_disable();
+	read_lock(&head->lock);
+	for (epb = head->chain; epb; epb = epb->next) {
+		assoc = sctp_assoc(epb);
+		sk = epb->sk;
+		seq_printf(seq,
+			   "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
+			   assoc, sk, sctp_sk(sk)->type, sk->sk_state,
+			   assoc->state, hash-1, assoc->assoc_id,
+			   (sk->sk_rcvbuf - assoc->rwnd),
+			   assoc->sndbuf_used,
+			   sock_i_uid(sk), sock_i_ino(sk),
+			   epb->bind_addr.port,
+			   assoc->peer.port);
+
+		seq_printf(seq, " ");
+		sctp_seq_dump_local_addrs(seq, epb);
+		seq_printf(seq, "<-> ");
+		sctp_seq_dump_remote_addrs(seq, assoc);
+		seq_printf(seq, "\n");
 	}
+	read_unlock(&head->lock);
+	sctp_local_bh_enable();
 
 	return 0;
 }
 
+static struct seq_operations sctp_assoc_ops = {
+	.start = sctp_assocs_seq_start,
+	.next  = sctp_assocs_seq_next,
+	.stop  = sctp_assocs_seq_stop,
+	.show  = sctp_assocs_seq_show,
+};
+
 /* Initialize the seq file operations for 'assocs' object. */
 static int sctp_assocs_seq_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, sctp_assocs_seq_show, NULL);
+	return seq_open(file, &sctp_assoc_ops);
 }
 
 static struct file_operations sctp_assocs_seq_fops = {
 	.open	 = sctp_assocs_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = single_release,
+	.release = seq_release,
 };
 
 /* Set up the proc fs entry for 'assocs' object. */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 2e1f9c3556f5922a9018c30055949f7a64f333be..5135e1a25d25c1413984520c7204f6df3d7d2df4 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -378,10 +378,13 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
 	int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
 
-	/* FIXME: ip_nonlocal_bind sysctl support. */
 
-	if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL)
+	if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
+	   ret != RTN_LOCAL &&
+	   !sp->inet.freebind &&
+	   !sysctl_ip_nonlocal_bind)
 		return 0;
+
 	return 1;
 }
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0b338eca6dc0b1559e2392af2964f5d7fcfe1820..2a3c0e08a090eedf7c9a41d96cc7f263e002730b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4686,6 +4686,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
 	struct sctp_endpoint *newep = newsp->ep;
 	struct sk_buff *skb, *tmp;
 	struct sctp_ulpevent *event;
+	int flags = 0;
 
 	/* Migrate socket buffer sizes and all the socket level options to the
 	 * new socket.
@@ -4707,6 +4708,17 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
 	sctp_sk(newsk)->bind_hash = pp;
 	inet_sk(newsk)->num = inet_sk(oldsk)->num;
 
+	/* Copy the bind_addr list from the original endpoint to the new
+	 * endpoint so that we can handle restarts properly
+	 */
+	if (assoc->peer.ipv4_address)
+		flags |= SCTP_ADDR4_PEERSUPP;
+	if (assoc->peer.ipv6_address)
+		flags |= SCTP_ADDR6_PEERSUPP;
+	sctp_bind_addr_copy(&newsp->ep->base.bind_addr,
+			     &oldsp->ep->base.bind_addr,
+			     SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags);
+
 	/* Move any messages in the old socket's receive queue that are for the
 	 * peeled off association to the new socket's receive queue.
 	 */
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 84b0bbddbd226f8716a06459aa9fa67892da6b6e..aae66144d411ce579eee7185b8e3cca84e730d9e 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3289,7 +3289,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
 		}
 		usb_chip[chip->index] = NULL;
 		up(&register_mutex);
-		snd_card_free_in_thread(card);
+		snd_card_free(card);
 	} else {
 		up(&register_mutex);
 	}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index b06a267e5dac22d5350942cdfa2cfcfdb74c62b2..89ee8b7320134fdf97b02a03f9e30457d32099f3 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -1,6 +1,11 @@
 /*
  * usbusy2y.c - ALSA USB US-428 Driver
  *
+2005-04-14 Karsten Wiese
+	Version 0.8.7.2:
+	Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom.
+	Tested ok with kernel 2.6.12-rc2.
+
 2004-12-14 Karsten Wiese
 	Version 0.8.7.1:
 	snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
@@ -143,7 +148,7 @@
 
 
 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1");
+MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
 
@@ -430,8 +435,6 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr)
 	if (ptr) {
 		usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr);
 		struct list_head* p;
-		if (usX2Y->chip_status == USX2Y_STAT_CHIP_HUP)	// on 2.6.1 kernel snd_usbmidi_disconnect()
-			return;					// calls us back. better leave :-) .
 		usX2Y->chip.shutdown = 1;
 		usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
 		usX2Y_unlinkSeq(&usX2Y->AS04);
@@ -443,7 +446,7 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr)
 		}
 		if (usX2Y->us428ctls_sharedmem) 
 			wake_up(&usX2Y->us428ctls_wait_queue_head);
-		snd_card_free_in_thread((snd_card_t*)ptr);
+		snd_card_free((snd_card_t*)ptr);
 	}
 }