Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 8309a7b..79577f0 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -44,6 +44,9 @@
 extern int gsi_irq_sharing(int gsi);
 #include <asm/proto.h>
 
+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
+
+
 #else				/* X86 */
 
 #ifdef	CONFIG_X86_LOCAL_APIC
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 5f68b22..e00e5f6 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -161,60 +161,6 @@
 	return error;
 }
 
-struct dirent32 {
-	unsigned int	d_ino;
-	unsigned int	d_off;
-	unsigned short	d_reclen;
-	char		d_name[NAME_MAX + 1];
-};
-
-static void
-xlate_dirent(void *dirent64, void *dirent32, long n)
-{
-	long off;
-	struct dirent *dirp;
-	struct dirent32 *dirp32;
-
-	off = 0;
-	while (off < n) {
-		dirp = (struct dirent *)(dirent64 + off);
-		dirp32 = (struct dirent32 *)(dirent32 + off);
-		off += dirp->d_reclen;
-		dirp32->d_ino = dirp->d_ino;
-		dirp32->d_off = (unsigned int)dirp->d_off;
-		dirp32->d_reclen = dirp->d_reclen;
-		strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
-	}
-	return;
-}
-
-asmlinkage long
-sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
-{
-	long n;
-	void *dirent64;
-
-	dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
-	if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
-		return(n);
-	xlate_dirent(dirent64, dirent32, n);
-	return(n);
-}
-
-asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);
-
-asmlinkage int
-sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
-{
-	int n;
-	struct dirent dirent64;
-
-	if ((n = old_readdir(fd, &dirent64, count)) < 0)
-		return(n);
-	xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
-	return(n);
-}
-
 asmlinkage int
 sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
 {
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index d87b544..02c8267 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -195,7 +195,7 @@
 	PTR	sys_fdatasync
 	PTR	sys_truncate
 	PTR	sys_ftruncate			/* 6075 */
-	PTR	sys32_getdents
+	PTR	compat_sys_getdents
 	PTR	sys_getcwd
 	PTR	sys_chdir
 	PTR	sys_fchdir
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 5b04140..797e0d8 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -293,7 +293,7 @@
 	PTR	sys_uselib
 	PTR	sys_swapon
 	PTR	sys_reboot
-	PTR	sys32_readdir
+	PTR	compat_sys_old_readdir
 	PTR	old_mmap			/* 4090 */
 	PTR	sys_munmap
 	PTR	sys_truncate
@@ -345,7 +345,7 @@
 	PTR	sys_setfsuid
 	PTR	sys_setfsgid
 	PTR	sys32_llseek			/* 4140 */
-	PTR	sys32_getdents
+	PTR	compat_sys_getdents
 	PTR	compat_sys_select
 	PTR	sys_flock
 	PTR	sys_msync
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index d86affa..d9293c5 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -540,6 +540,9 @@
 	sparse_init();
 	paging_init();
 	resource_init();
+#ifdef CONFIG_SMP
+	plat_smp_setup();
+#endif
 }
 
 int __init fpu_disable(char *s)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 5e18986..06ed907 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -236,7 +236,7 @@
 	init_new_context(current, &init_mm);
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
-	prom_prepare_cpus(max_cpus);
+	plat_prepare_cpus(max_cpus);
 }
 
 /* preload SMP state for boot cpu */
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
index c930364..993b8bf 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp_mt.c
@@ -143,7 +143,7 @@
  * Make sure all CPU's are in a sensible state before we boot any of the
  * secondarys
  */
-void prom_prepare_cpus(unsigned int max_cpus)
+void plat_smp_setup(void)
 {
 	unsigned long val;
 	int i, num;
@@ -179,11 +179,9 @@
 				write_vpe_c0_vpeconf0(tmp);
 
 				/* Record this as available CPU */
-				if (i < max_cpus) {
-					cpu_set(i, phys_cpu_present_map);
-					__cpu_number_map[i]	= ++num;
-					__cpu_logical_map[num]	= i;
-				}
+				cpu_set(i, phys_cpu_present_map);
+				__cpu_number_map[i]	= ++num;
+				__cpu_logical_map[num]	= i;
 			}
 
 			/* disable multi-threading with TC's */
@@ -241,7 +239,10 @@
 		set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
 		set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
 	}
+}
 
+void __init plat_prepare_cpus(unsigned int max_cpus)
+{
 	cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
 	cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
 
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 7f8fda9..c197311 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -50,37 +50,25 @@
  * We don't want to start the secondary CPU yet nor do we have a nice probing
  * feature in PMON so we just assume presence of the secondary core.
  */
-static char maxcpus_string[] __initdata =
-	KERN_WARNING "max_cpus set to 0; using 1 instead\n";
-
-void __init prom_prepare_cpus(unsigned int max_cpus)
+void __init plat_smp_setup(void)
 {
-	int enabled = 0, i;
-
-	if (max_cpus == 0) {
-		printk(maxcpus_string);
-		max_cpus = 1;
-	}
+	int i;
 
 	cpus_clear(phys_cpu_present_map);
 
 	for (i = 0; i < 2; i++) {
-		if (i == max_cpus)
-			break;
-
-		/*
-		 * The boot CPU
-		 */
 		cpu_set(i, phys_cpu_present_map);
 		__cpu_number_map[i]	= i;
 		__cpu_logical_map[i]	= i;
-		enabled++;
 	}
+}
 
+void __init plat_prepare_cpus(unsigned int max_cpus)
+{
 	/*
 	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
 	 */
-	if (enabled > 1)
+	if (cpus_weight(cpu_possible_map))
 		set_c0_status(STATUSF_IP5);
 }
 
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index dbef3f6..09fa7f5 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -140,7 +140,7 @@
 		REMOTE_HUB_CLR_INTR(nasid, i);
 }
 
-void __init prom_prepare_cpus(unsigned int max_cpus)
+void __init plat_smp_setup(void)
 {
 	cnodeid_t	cnode;
 
@@ -161,6 +161,11 @@
 	alloc_cpupda(0, 0);
 }
 
+void __init plat_prepare_cpus(unsigned int max_cpus)
+{
+	/* We already did everything necessary earlier */
+}
+
 /*
  * Launch a slave into smp_bootstrap().  It doesn't take an argument, and we
  * set sp to the kernel stack of the newly created idle process, gp to the proc
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
index 4477af3..eab20e2 100644
--- a/arch/mips/sibyte/cfe/smp.c
+++ b/arch/mips/sibyte/cfe/smp.c
@@ -31,7 +31,7 @@
  *
  * Common setup before any secondaries are started
  */
-void __init prom_prepare_cpus(unsigned int max_cpus)
+void __init plat_smp_setup(void)
 {
 	int i, num;
 
@@ -40,14 +40,18 @@
 	__cpu_number_map[0] = 0;
 	__cpu_logical_map[0] = 0;
 
-	for (i=1, num=0; i<NR_CPUS; i++) {
+	for (i = 1, num = 0; i < NR_CPUS; i++) {
 		if (cfe_cpu_stop(i) == 0) {
 			cpu_set(i, phys_cpu_present_map);
 			__cpu_number_map[i] = ++num;
 			__cpu_logical_map[num] = i;
 		}
 	}
-	printk("Detected %i available secondary CPU(s)\n", num);
+	printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+}
+
+void __init plat_prepare_cpus(unsigned int max_cpus)
+{
 }
 
 /*
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index d70605e..e5b14c5 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -962,14 +962,12 @@
 	irq_exit();
 }
 
-int __initdata unsync_tsc_on_multicluster;
-
 /*
  * oem_force_hpet_timer -- force HPET mode for some boxes.
  *
  * Thus far, the major user of this is IBM's Summit2 series:
  *
- * Some clustered boxes may have unsynced TSC problems if they are
+ * Clustered boxes may have unsynced TSC problems if they are
  * multi-chassis. Use available data to take a good guess.
  * If in doubt, go HPET.
  */
@@ -979,11 +977,6 @@
 	unsigned id;
 	DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
 
-	/* Only do this check on IBM machines - big Unisys systems
-	   use multiple clusters too, but have synchronized TSC */
-	if (!unsync_tsc_on_multicluster)
-		return 0;
-
 	bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
 
 	for (i = 0; i < NR_CPUS; i++) {
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 588e75e..a6b4f02 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1095,17 +1095,17 @@
 
 		sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); 
 
+		/* Don't copy past the end of the hardware receive buffer */
+		if (rx_op + c > 0x100) c = 0x100 - rx_op;
+
+		sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c);
+
 		/* Don't copy more bytes than there is room for in the buffer */
 
 		c = tty_prepare_flip_string(tty, &rp, c);
 
 		sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); 
 
-		/* Don't copy past the end of the hardware receive buffer */
-		if (rx_op + c > 0x100) c = 0x100 - rx_op;
-
-		sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c);
-
 		/* If for one reason or another, we can't copy more data, we're done! */
 		if (c == 0) break;
 
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e7dc653..e8e92c8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9408,6 +9408,15 @@
 			return 0;
 		if (venid == PCI_VENDOR_ID_SUN)
 			return 1;
+
+		/* TG3 chips onboard the SunBlade-2500 don't have the
+		 * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they
+		 * are distinguishable from non-Sun variants by being
+		 * named "network" by the firmware.  Non-Sun cards will
+		 * show up as being named "ethernet".
+		 */
+		if (!strcmp(pcp->prom_name, "network"))
+			return 1;
 	}
 	return 0;
 }
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 8f2beec..74d8be8 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -540,7 +540,7 @@
 
 	/* First sum forwards in this page */
 	do {
-		if (mapped != buffer_mapped(bh))
+		if (!buffer_uptodate(bh) || (mapped != buffer_mapped(bh)))
 			return total;
 		total += bh->b_size;
 	} while ((bh = bh->b_this_page) != head);
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 53a00fb2..7c0e39d 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -68,6 +68,9 @@
 kmem_zone_t	*qm_dqtrxzone;
 STATIC kmem_shaker_t	xfs_qm_shaker;
 
+STATIC cred_t	xfs_zerocr;
+STATIC xfs_inode_t	xfs_zeroino;
+
 STATIC void	xfs_qm_list_init(xfs_dqlist_t *, char *, int);
 STATIC void	xfs_qm_list_destroy(xfs_dqlist_t *);
 
@@ -1393,8 +1396,6 @@
 	xfs_trans_t	*tp;
 	int		error;
 	unsigned long	s;
-	cred_t		zerocr;
-	xfs_inode_t	zeroino;
 	int		committed;
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE);
@@ -1406,11 +1407,9 @@
 		xfs_trans_cancel(tp, 0);
 		return error;
 	}
-	memset(&zerocr, 0, sizeof(zerocr));
-	memset(&zeroino, 0, sizeof(zeroino));
 
-	if ((error = xfs_dir_ialloc(&tp, &zeroino, S_IFREG, 1, 0,
-				   &zerocr, 0, 1, ip, &committed))) {
+	if ((error = xfs_dir_ialloc(&tp, &xfs_zeroino, S_IFREG, 1, 0,
+				   &xfs_zerocr, 0, 1, ip, &committed))) {
 		xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
 				 XFS_TRANS_ABORT);
 		return error;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 06fc061..5b41394 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -130,7 +130,8 @@
 		/*
 		 * Lock the inode.
 		 */
-		if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL, &ip)))
+		if ((error = xfs_trans_iget(mp, tp, ino, 0,
+						XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		XFS_BMAP_INIT(&flist, &firstblock);
 		/*
@@ -170,8 +171,8 @@
 			/*
 			 * Lock the bitmap inode.
 			 */
-			if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL,
-					&ip)))
+			if ((error = xfs_trans_iget(mp, tp, ino, 0,
+							XFS_ILOCK_EXCL, &ip)))
 				goto error_exit;
 			/*
 			 * Get a buffer for the block.
@@ -2023,8 +2024,8 @@
 		/*
 		 * Lock out other callers by grabbing the bitmap inode lock.
 		 */
-		if ((error = xfs_trans_iget(mp, tp, 0, mp->m_sb.sb_rbmino,
-				XFS_ILOCK_EXCL, &ip)))
+		if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+						XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		ASSERT(ip == mp->m_rbmip);
 		/*
@@ -2037,8 +2038,8 @@
 		/*
 		 * Get the summary inode into the transaction.
 		 */
-		if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino,
-				0, XFS_ILOCK_EXCL, &ip)))
+		if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
+						XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		ASSERT(ip == mp->m_rsumip);
 		/*
@@ -2158,10 +2159,9 @@
 	/*
 	 * Lock out other callers by grabbing the bitmap inode lock.
 	 */
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-	if (error) {
+	if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+					XFS_ILOCK_EXCL, &ip)))
 		return error;
-	}
 	sumbp = NULL;
 	/*
 	 * Allocate by size, or near another block, or exactly at some block.
@@ -2221,10 +2221,9 @@
 	/*
 	 * Synchronize by locking the bitmap inode.
 	 */
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-	if (error) {
+	if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+					XFS_ILOCK_EXCL, &ip)))
 		return error;
-	}
 #if defined(__KERNEL__) && defined(DEBUG)
 	/*
 	 * Check to see that this whole range is currently allocated.
@@ -2365,8 +2364,8 @@
 	__uint64_t	seq;		/* sequence number of file creation */
 	__uint64_t	*seqp;		/* pointer to seqno in inode */
 
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
-	if (error)
+	if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
+					XFS_ILOCK_EXCL, &ip)))
 		return error;
 	ASSERT(ip == mp->m_rbmip);
 	seqp = (__uint64_t *)&ip->i_d.di_atime;
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 654b97d..2c8b853 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -250,7 +250,10 @@
 		"	subu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	sc	%0, %2					\n"
+		"	.set	noreorder				\n"
 		"	beqzl	%0, 1b					\n"
+		"	 subu	%0, %1, %3				\n"
+		"	.set	reorder					\n"
 		"	sync						\n"
 		"1:							\n"
 		"	.set	mips0					\n"
@@ -266,7 +269,10 @@
 		"	subu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	sc	%0, %2					\n"
+		"	.set	noreorder				\n"
 		"	beqz	%0, 1b					\n"
+		"	 subu	%0, %1, %3				\n"
+		"	.set	reorder					\n"
 		"	sync						\n"
 		"1:							\n"
 		"	.set	mips0					\n"
@@ -598,7 +604,10 @@
 		"	dsubu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	scd	%0, %2					\n"
+		"	.set	noreorder				\n"
 		"	beqzl	%0, 1b					\n"
+		"	 dsubu	%0, %1, %3				\n"
+		"	.set	reorder					\n"
 		"	sync						\n"
 		"1:							\n"
 		"	.set	mips0					\n"
@@ -614,7 +623,10 @@
 		"	dsubu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	scd	%0, %2					\n"
+		"	.set	noreorder				\n"
 		"	beqz	%0, 1b					\n"
+		"	 dsubu	%0, %1, %3				\n"
+		"	.set	reorder					\n"
 		"	sync						\n"
 		"1:							\n"
 		"	.set	mips0					\n"
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
index 5618f1e..75c6fe7c 100644
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -58,7 +58,9 @@
 	return cpus_weight(cpu_callout_map);
 }
 
-/* These are defined by the board-specific code. */
+/*
+ * These are defined by the board-specific code.
+ */
 
 /*
  * Cause the function described by call_data to be executed on the passed
@@ -79,7 +81,12 @@
 extern void prom_init_secondary(void);
 
 /*
- * Detect available CPUs, populate phys_cpu_present_map before smp_init
+ * Populate cpu_possible_map before smp_init, called from setup_arch.
+ */
+extern void plat_smp_setup(void);
+
+/*
+ * Called after init_IRQ but before __cpu_up.
  */
 extern void prom_prepare_cpus(unsigned int max_cpus);
 
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index e8e5d41..ddae9ba 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -322,7 +322,7 @@
 #endif
 		"2:							\n"
 		"	.set	pop					\n"
-		: "=&r" (retval), "=m" (*m)
+		: "=&r" (retval), "=R" (*m)
 		: "R" (*m), "Jr" (old), "Jr" (new)
 		: "memory");
 	} else if (cpu_has_llsc) {
@@ -342,7 +342,7 @@
 #endif
 		"2:							\n"
 		"	.set	pop					\n"
-		: "=&r" (retval), "=m" (*m)
+		: "=&r" (retval), "=R" (*m)
 		: "R" (*m), "Jr" (old), "Jr" (new)
 		: "memory");
 	} else {
@@ -379,7 +379,7 @@
 #endif
 		"2:							\n"
 		"	.set	pop					\n"
-		: "=&r" (retval), "=m" (*m)
+		: "=&r" (retval), "=R" (*m)
 		: "R" (*m), "Jr" (old), "Jr" (new)
 		: "memory");
 	} else if (cpu_has_llsc) {
@@ -397,7 +397,7 @@
 #endif
 		"2:							\n"
 		"	.set	pop					\n"
-		: "=&r" (retval), "=m" (*m)
+		: "=&r" (retval), "=R" (*m)
 		: "R" (*m), "Jr" (old), "Jr" (new)
 		: "memory");
 	} else {
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index e2b9923..aa1c7b2 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -164,20 +164,6 @@
 
 extern int acpi_skip_timer_override;
 
-extern int unsync_tsc_on_multicluster;
-
-static inline int acpi_madt_oem_check(char *oem, char *productid) 
-{ 
-	/* Copied from i386. Probably has too many entries. */
-	if (!strncmp(oem, "IBM ENSW", 8) && 
-        	(!strncmp(productid, "VIGIL SMP", 9) 
-             		|| !strncmp(productid, "EXA", 3)
-			|| !strncmp(productid, "RUTHLESS SMP", 12))) {
-		unsync_tsc_on_multicluster = 1;
-        }
-        return 0;
-}
-
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
diff --git a/include/linux/netfilter_bridge/ebt_log.h b/include/linux/netfilter_bridge/ebt_log.h
index 358fbc8..96e231a 100644
--- a/include/linux/netfilter_bridge/ebt_log.h
+++ b/include/linux/netfilter_bridge/ebt_log.h
@@ -3,6 +3,7 @@
 
 #define EBT_LOG_IP 0x01 /* if the frame is made by ip, log the ip information */
 #define EBT_LOG_ARP 0x02
+#define EBT_LOG_NFLOG 0x04
 #define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP)
 #define EBT_LOG_PREFIX_SIZE 30
 #define EBT_LOG_WATCHER "log"
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h
index 22d1617..892f9a3 100644
--- a/include/linux/netfilter_ipv4/ipt_LOG.h
+++ b/include/linux/netfilter_ipv4/ipt_LOG.h
@@ -6,7 +6,8 @@
 #define IPT_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IPT_LOG_IPOPT		0x04	/* Log IP options */
 #define IPT_LOG_UID		0x08	/* Log UID owning local socket */
-#define IPT_LOG_MASK		0x0f
+#define IPT_LOG_NFLOG		0x10	/* Log using nf_log backend */
+#define IPT_LOG_MASK		0x1f
 
 struct ipt_log_info {
 	unsigned char level;
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h
index 9008ff5..060c1a1 100644
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h
+++ b/include/linux/netfilter_ipv6/ip6t_LOG.h
@@ -6,7 +6,8 @@
 #define IP6T_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IP6T_LOG_IPOPT		0x04	/* Log IP options */
 #define IP6T_LOG_UID		0x08	/* Log UID owning local socket */
-#define IP6T_LOG_MASK		0x0f
+#define IP6T_LOG_NFLOG		0x10	/* Log using nf_log backend */
+#define IP6T_LOG_MASK		0x1f
 
 struct ip6t_log_info {
 	unsigned char level;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 004e645..8d362c4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -233,7 +233,6 @@
 	int			(*init_state)(struct xfrm_state *x);
 	void			(*destructor)(struct xfrm_state *);
 	int			(*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
-	int			(*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
 	/* Estimate maximal size of result of transformation of a dgram */
 	u32			(*get_max_size)(struct xfrm_state *, int size);
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 0128fbb..288ff1d 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -166,7 +166,12 @@
 	li.u.log.level = info->loglevel;
 	li.u.log.logflags = info->bitmask;
 
-	nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
+	if (info->bitmask & EBT_LOG_NFLOG)
+		nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
+		              info->prefix);
+	else
+		ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
+		               info->prefix);
 }
 
 static struct ebt_watcher log =
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index b8203de..98f0fc9 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -52,7 +52,6 @@
 	get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
 	rwlock_init(&queue->syn_wait_lock);
 	queue->rskq_accept_head = queue->rskq_accept_head = NULL;
-	queue->rskq_defer_accept = 0;
 	lopt->nr_table_entries = nr_table_entries;
 
 	write_lock_bh(&queue->syn_wait_lock);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 73bfcae..09590f3 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -12,13 +12,6 @@
 #include <net/protocol.h>
 #include <net/udp.h>
 
-/* decapsulation data for use when post-processing */
-struct esp_decap_data {
-	xfrm_address_t	saddr;
-	__u16		sport;
-	__u8		proto;
-};
-
 static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 {
 	int err;
@@ -150,6 +143,10 @@
 	int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
 	int nfrags;
 	int encap_len = 0;
+	u8 nexthdr[2];
+	struct scatterlist *sg;
+	u8 workbuf[60];
+	int padlen;
 
 	if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
 		goto out;
@@ -185,124 +182,84 @@
 	if (esp->conf.ivlen)
 		crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm));
 
-        {
-		u8 nexthdr[2];
-		struct scatterlist *sg = &esp->sgbuf[0];
-		u8 workbuf[60];
-		int padlen;
+	sg = &esp->sgbuf[0];
 
-		if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
-			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-			if (!sg)
-				goto out;
-		}
-		skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
-		crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
-		if (unlikely(sg != &esp->sgbuf[0]))
-			kfree(sg);
+	if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
+		sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
+		if (!sg)
+			goto out;
+	}
+	skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
+	crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
+	if (unlikely(sg != &esp->sgbuf[0]))
+		kfree(sg);
 
-		if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
-			BUG();
+	if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
+		BUG();
 
-		padlen = nexthdr[0];
-		if (padlen+2 >= elen)
+	padlen = nexthdr[0];
+	if (padlen+2 >= elen)
+		goto out;
+
+	/* ... check padding bits here. Silly. :-) */ 
+
+	if (x->encap) {
+		struct xfrm_encap_tmpl *encap = x->encap;
+		struct udphdr *uh;
+
+		if (encap->encap_type != decap->decap_type)
 			goto out;
 
-		/* ... check padding bits here. Silly. :-) */ 
+		uh = (struct udphdr *)(iph + 1);
+		encap_len = (void*)esph - (void*)uh;
 
-		if (x->encap && decap && decap->decap_type) {
-			struct esp_decap_data *encap_data;
-			struct udphdr *uh = (struct udphdr *) (iph+1);
+		/*
+		 * 1) if the NAT-T peer's IP or port changed then
+		 *    advertize the change to the keying daemon.
+		 *    This is an inbound SA, so just compare
+		 *    SRC ports.
+		 */
+		if (iph->saddr != x->props.saddr.a4 ||
+		    uh->source != encap->encap_sport) {
+			xfrm_address_t ipaddr;
 
-			encap_data = (struct esp_decap_data *) (decap->decap_data);
-			encap_data->proto = 0;
-
-			switch (decap->decap_type) {
-			case UDP_ENCAP_ESPINUDP:
-			case UDP_ENCAP_ESPINUDP_NON_IKE:
-				encap_data->proto = AF_INET;
-				encap_data->saddr.a4 = iph->saddr;
-				encap_data->sport = uh->source;
-				encap_len = (void*)esph - (void*)uh;
-				break;
-
-			default:
-				goto out;
-			}
+			ipaddr.a4 = iph->saddr;
+			km_new_mapping(x, &ipaddr, uh->source);
+				
+			/* XXX: perhaps add an extra
+			 * policy check here, to see
+			 * if we should allow or
+			 * reject a packet from a
+			 * different source
+			 * address/port.
+			 */
 		}
-
-		iph->protocol = nexthdr[1];
-		pskb_trim(skb, skb->len - alen - padlen - 2);
-		memcpy(workbuf, skb->nh.raw, iph->ihl*4);
-		skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
-		skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-		memcpy(skb->nh.raw, workbuf, iph->ihl*4);
-		skb->nh.iph->tot_len = htons(skb->len);
+	
+		/*
+		 * 2) ignore UDP/TCP checksums in case
+		 *    of NAT-T in Transport Mode, or
+		 *    perform other post-processing fixes
+		 *    as per draft-ietf-ipsec-udp-encaps-06,
+		 *    section 3.1.2
+		 */
+		if (!x->props.mode)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 
+	iph->protocol = nexthdr[1];
+	pskb_trim(skb, skb->len - alen - padlen - 2);
+	memcpy(workbuf, skb->nh.raw, iph->ihl*4);
+	skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
+	skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+	memcpy(skb->nh.raw, workbuf, iph->ihl*4);
+	skb->nh.iph->tot_len = htons(skb->len);
+
 	return 0;
 
 out:
 	return -EINVAL;
 }
 
-static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
-{
-  
-	if (x->encap) {
-		struct xfrm_encap_tmpl *encap;
-		struct esp_decap_data *decap_data;
-
-		encap = x->encap;
-		decap_data = (struct esp_decap_data *)(decap->decap_data);
-
-		/* first, make sure that the decap type == the encap type */
-		if (encap->encap_type != decap->decap_type)
-			return -EINVAL;
-
-		switch (encap->encap_type) {
-		default:
-		case UDP_ENCAP_ESPINUDP:
-		case UDP_ENCAP_ESPINUDP_NON_IKE:
-			/*
-			 * 1) if the NAT-T peer's IP or port changed then
-			 *    advertize the change to the keying daemon.
-			 *    This is an inbound SA, so just compare
-			 *    SRC ports.
-			 */
-			if (decap_data->proto == AF_INET &&
-			    (decap_data->saddr.a4 != x->props.saddr.a4 ||
-			     decap_data->sport != encap->encap_sport)) {
-				xfrm_address_t ipaddr;
-
-				ipaddr.a4 = decap_data->saddr.a4;
-				km_new_mapping(x, &ipaddr, decap_data->sport);
-					
-				/* XXX: perhaps add an extra
-				 * policy check here, to see
-				 * if we should allow or
-				 * reject a packet from a
-				 * different source
-				 * address/port.
-				 */
-			}
-		
-			/*
-			 * 2) ignore UDP/TCP checksums in case
-			 *    of NAT-T in Transport Mode, or
-			 *    perform other post-processing fixes
-			 *    as per * draft-ietf-ipsec-udp-encaps-06,
-			 *    section 3.1.2
-			 */
-			if (!x->props.mode)
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-			break;
-		}
-	}
-	return 0;
-}
-
 static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
 {
 	struct esp_data *esp = x->data;
@@ -458,7 +415,6 @@
 	.destructor	= esp_destroy,
 	.get_max_size	= esp4_get_max_size,
 	.input		= esp_input,
-	.post_input	= esp_post_input,
 	.output		= esp_output
 };
 
@@ -470,15 +426,6 @@
 
 static int __init esp4_init(void)
 {
-	struct xfrm_decap_state decap;
-
-	if (sizeof(struct esp_decap_data)  >
-	    sizeof(decap.decap_data)) {
-		extern void decap_data_too_small(void);
-
-		decap_data_too_small();
-	}
-
 	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
 		return -EAGAIN;
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 6606ddb..cc27545 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -425,7 +425,12 @@
 	li.u.log.level = loginfo->level;
 	li.u.log.logflags = loginfo->logflags;
 
-	nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix);
+	if (loginfo->logflags & IPT_LOG_NFLOG)
+		nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
+		              loginfo->prefix);
+	else
+		ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
+		               loginfo->prefix);
 
 	return IPT_CONTINUE;
 }
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 77c7258..6b930ef 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -436,7 +436,12 @@
 	li.u.log.level = loginfo->level;
 	li.u.log.logflags = loginfo->logflags;
 
-	nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix);
+	if (loginfo->logflags & IP6T_LOG_NFLOG)
+		nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
+		              loginfo->prefix);
+	else
+		ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
+		                loginfo->prefix);
 
 	return IP6T_CONTINUE;
 }
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index d3a4f30..d9f0d7e 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -6,6 +6,7 @@
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
 #include <linux/seq_file.h>
+#include <linux/rcupdate.h>
 #include <net/protocol.h>
 
 #include "nf_internals.h"
@@ -16,7 +17,7 @@
  * for queueing and must reinject all packets it receives, no matter what.
  */
 static struct nf_queue_handler *queue_handler[NPROTO];
-static struct nf_queue_rerouter *queue_rerouter;
+static struct nf_queue_rerouter *queue_rerouter[NPROTO];
 
 static DEFINE_RWLOCK(queue_handler_lock);
 
@@ -64,7 +65,7 @@
 		return -EINVAL;
 
 	write_lock_bh(&queue_handler_lock);
-	memcpy(&queue_rerouter[pf], rer, sizeof(queue_rerouter[pf]));
+	rcu_assign_pointer(queue_rerouter[pf], rer);
 	write_unlock_bh(&queue_handler_lock);
 
 	return 0;
@@ -77,8 +78,9 @@
 		return -EINVAL;
 
 	write_lock_bh(&queue_handler_lock);
-	memset(&queue_rerouter[pf], 0, sizeof(queue_rerouter[pf]));
+	rcu_assign_pointer(queue_rerouter[pf], NULL);
 	write_unlock_bh(&queue_handler_lock);
+	synchronize_rcu();
 	return 0;
 }
 EXPORT_SYMBOL_GPL(nf_unregister_queue_rerouter);
@@ -114,16 +116,17 @@
 	struct net_device *physindev = NULL;
 	struct net_device *physoutdev = NULL;
 #endif
+	struct nf_queue_rerouter *rerouter;
 
 	/* QUEUE == DROP if noone is waiting, to be safe. */
 	read_lock(&queue_handler_lock);
-	if (!queue_handler[pf] || !queue_handler[pf]->outfn) {
+	if (!queue_handler[pf]) {
 		read_unlock(&queue_handler_lock);
 		kfree_skb(*skb);
 		return 1;
 	}
 
-	info = kmalloc(sizeof(*info)+queue_rerouter[pf].rer_size, GFP_ATOMIC);
+	info = kmalloc(sizeof(*info)+queue_rerouter[pf]->rer_size, GFP_ATOMIC);
 	if (!info) {
 		if (net_ratelimit())
 			printk(KERN_ERR "OOM queueing packet %p\n",
@@ -155,15 +158,13 @@
 		if (physoutdev) dev_hold(physoutdev);
 	}
 #endif
-	if (queue_rerouter[pf].save)
-		queue_rerouter[pf].save(*skb, info);
+	rerouter = rcu_dereference(queue_rerouter[pf]);
+	if (rerouter)
+		rerouter->save(*skb, info);
 
 	status = queue_handler[pf]->outfn(*skb, info, queuenum,
 					  queue_handler[pf]->data);
 
-	if (status >= 0 && queue_rerouter[pf].reroute)
-		status = queue_rerouter[pf].reroute(skb, info);
-
 	read_unlock(&queue_handler_lock);
 
 	if (status < 0) {
@@ -189,6 +190,7 @@
 {
 	struct list_head *elem = &info->elem->list;
 	struct list_head *i;
+	struct nf_queue_rerouter *rerouter;
 
 	rcu_read_lock();
 
@@ -212,7 +214,7 @@
   			break;
   	}
   
-	if (elem == &nf_hooks[info->pf][info->hook]) {
+	if (i == &nf_hooks[info->pf][info->hook]) {
 		/* The module which sent it to userspace is gone. */
 		NFDEBUG("%s: module disappeared, dropping packet.\n",
 			__FUNCTION__);
@@ -226,6 +228,12 @@
 	}
 
 	if (verdict == NF_ACCEPT) {
+		rerouter = rcu_dereference(queue_rerouter[info->pf]);
+		if (rerouter && rerouter->reroute(&skb, info) < 0)
+			verdict = NF_DROP;
+	}
+
+	if (verdict == NF_ACCEPT) {
 	next_hook:
 		verdict = nf_iterate(&nf_hooks[info->pf][info->hook],
 				     &skb, info->hook, 
@@ -322,22 +330,12 @@
 {
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *pde;
-#endif
-	queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter),
-				 GFP_KERNEL);
-	if (!queue_rerouter)
-		return -ENOMEM;
 
-#ifdef CONFIG_PROC_FS
 	pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter);
-	if (!pde) {
-		kfree(queue_rerouter);
+	if (!pde)
 		return -1;
-	}
 	pde->proc_fops = &nfqueue_file_ops;
 #endif
-	memset(queue_rerouter, 0, NPROTO * sizeof(struct nf_queue_rerouter));
-
 	return 0;
 }
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 8206025..ae62054 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -996,13 +996,6 @@
 			struct sec_decap_state *xvec = &(skb->sp->x[i]);
 			if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
 				return 0;
-
-			/* If there is a post_input processor, try running it */
-			if (xvec->xvec->type->post_input &&
-			    (xvec->xvec->type->post_input)(xvec->xvec,
-							   &(xvec->decap),
-							   skb) != 0)
-				return 0;
 		}
 	}