[kernel] r8748 - in dists/sid/linux-2.6/debian: . patches/bugfix patches/series

Maximilian Attems maks at alioth.debian.org
Thu May 24 12:14:17 UTC 2007


Author: maks
Date: Thu May 24 12:14:17 2007
New Revision: 8748

Log:
add huge stable 2.6.21.2


Added:
   dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.2
Modified:
   dists/sid/linux-2.6/debian/changelog
   dists/sid/linux-2.6/debian/patches/series/3

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	(original)
+++ dists/sid/linux-2.6/debian/changelog	Thu May 24 12:14:17 2007
@@ -6,6 +6,80 @@
   [ maximilian attems ]
   * sparc64: enable USB_SERIAL. (closes: #412740)
   * Apply stable 2.6.21.1.
+  * Add stable release 2.6.21.2:
+    - slob: fix page order calculation on not 4KB page
+    - libata-sff: Undo bug introduced with pci_iomap changes
+    - kbuild: fixdep segfault on pathological string-o-death
+    - IPMI: fix SI address space settings
+    - IPV6: Reverse sense of promisc tests in ip6_mc_input
+    - iop: fix iop_getttimeoffset
+    - iop13xx: fix i/o address translation
+    - arm: fix handling of svc mode undefined instructions
+    - CPUFREQ: powernow-k7: fix MHz rounding issue with perflib
+    - CPUFREQ: Support rev H AMD64s in powernow-k8
+    - CPUFREQ: Correct revision mask for powernow-k8
+    - JFS: Fix race waking up jfsIO kernel thread
+    - IPV6: Send ICMPv6 error on scope violations.
+    - SPARC64: Add missing cpus_empty() check in hypervisor xcall handling.
+    - SPARC64: Fix recursion in PROM tree building.
+    - SERIAL SUNHV: Add an ID string.
+    - SPARC64: Bump PROMINTR_MAX to 32.
+    - SPARC64: Be more resiliant with PCI I/O space regs.
+    - oom: fix constraint deadlock
+    - fix for bugzilla 8426: massive slowdown on SCSI CD/DVD drive connected to
+      mptspi driver
+    - x86_64 : Fix vgettimeofday()
+    - IPV6: Fix slab corruption running ip6sic
+    - IPSEC: Check validity of direction in xfrm_policy_byid
+    - CRYPTO: api: Read module pointer before freeing algorithm
+    - NET_SCHED: prio qdisc boundary condition
+    - reiserfs: suppress lockdep warning
+    - USB HID: hiddev - fix race between hiddev_send_event() and
+      hiddev_release()
+    - NETFILTER: {ip,nf}_nat_proto_gre: do not modify/corrupt GREv0 packets
+      through NAT
+    - fix leaky resv_huge_pages when cpuset is in use
+    - ACPI: Fix 2.6.21 boot regression on P4/HT
+    - TG3: Fix TSO bugs.
+    - TG3: Remove reset during MAC address changes.
+    - TG3: Update version and reldate.
+    - BNX2: Fix TSO problem with small MSS.
+    - BNX2: Block MII access when ifdown.
+    - BNX2: Save PCI state during suspend.
+    - BNX2: Update version and reldate.
+    - sis900: Allocate rx replacement buffer before rx operation
+    - knfsd: Avoid use of unitialised variables on error path when nfs exports.
+    - knfsd: rpc: fix server-side wrapping of krb5i replies
+    - md: Avoid a possibility that a read error can wrongly propagate through
+    - md/raid1 to a filesystem.
+    - fat: fix VFAT compat ioctls on 64-bit systems
+    - NETFILTER: {ip,nf}_conntrack: fix use-after-free in helper destroy
+      callback invocation
+    - ppp: Fix ppp_deflate issues with recent zlib_inflate changes
+    - NETPOLL: Fix TX queue overflow in trapped mode.
+    - NETPOLL: Remove CONFIG_NETPOLL_RX
+    - cxacru: Fix infinite loop when trying to cancel polling task
+    - TCP: zero out rx_opt in tcp_disconnect()
+    - ipv6: track device renames in snmp6
+    - skge: default WOL should be magic only (rev2)
+    - skge: allow WOL except for known broken chips
+    - sky2: allow 88E8056
+    - sky2: 88e8071 support not ready
+    - skge: crash on shutdown/suspend
+    - sky2: fix oops on shutdown
+    - udf: decrement correct link count in udf_rmdir
+    - ALSA: hda-codec - Fix resume of STAC92xx codecs
+    - sata_via: add missing PM hooks
+    - driver-core: don't free devt_attr till the device is released
+    - pci-quirks: disable MSI on RS400-200 and RS480
+    - highres/dyntick: prevent xtime lock contention
+    - clocksource: fix resume logic
+    - smc911x: fix compilation breakage wjen debug is on
+    - SCTP: Fix sctp_getsockopt_local_addrs_old() to use local storage.
+    - SCTP: Correctly copy addresses in sctp_copy_laddrs
+    - SCTP: Prevent OOPS if hmac modules didn't load
+    - IPV6: Do no rely on skb->dst before it is assigned.
+    - IPV6 ROUTE: Assign rt6i_idev for ip6_{prohibit,blk_hole}_entry.
 
   [ Christian T. Steigies ]
   * m68k: enable ATARI_SCSI and ATARI_ROM_ISA
@@ -13,7 +87,7 @@
   [ Bastian Blank ]
   * Fix linux/version.h in linux-libc-dev.
 
- -- Bastian Blank <waldi at debian.org>  Tue, 22 May 2007 08:52:07 +0200
+ -- maximilian attems <maks at debian.org>  Thu, 24 May 2007 14:11:54 +0200
 
 linux-2.6 (2.6.21-2) unstable; urgency=low
 

Added: dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.2
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.2	Thu May 24 12:14:17 2007
@@ -0,0 +1,2566 @@
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index 2409560..7ed141f 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -273,6 +273,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
+ 	struct undef_hook *hook;
+ 	siginfo_t info;
+ 	void __user *pc;
++	unsigned long flags;
+ 
+ 	/*
+ 	 * According to the ARM ARM, PC is 2 or 4 bytes ahead,
+@@ -291,7 +292,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
+ 		get_user(instr, (u32 __user *)pc);
+ 	}
+ 
+-	spin_lock_irq(&undef_lock);
++	spin_lock_irqsave(&undef_lock, flags);
+ 	list_for_each_entry(hook, &undef_hook, node) {
+ 		if ((instr & hook->instr_mask) == hook->instr_val &&
+ 		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
+@@ -301,7 +302,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
+ 			}
+ 		}
+ 	}
+-	spin_unlock_irq(&undef_lock);
++	spin_unlock_irqrestore(&undef_lock, flags);
+ 
+ #ifdef CONFIG_DEBUG_USER
+ 	if (user_debug & UDBG_UNDEFINED) {
+diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
+index 89ec70e..d907a2a 100644
+--- a/arch/arm/mach-iop13xx/pci.c
++++ b/arch/arm/mach-iop13xx/pci.c
+@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
+ 				  << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
+ 		__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
+ 
+-		res[0].start = IOP13XX_PCIX_LOWER_IO_PA;
++		res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
+ 		res[0].end   = IOP13XX_PCIX_UPPER_IO_PA;
+ 		res[0].name  = "IQ81340 ATUX PCI I/O Space";
+ 		res[0].flags = IORESOURCE_IO;
+@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
+ 		res[1].name  = "IQ81340 ATUX PCI Memory Space";
+ 		res[1].flags = IORESOURCE_MEM;
+ 		sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
+-		sys->io_offset = IOP13XX_PCIX_IO_OFFSET;
++		sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
+ 		break;
+ 	case IOP13XX_INIT_ATU_ATUE:
+ 		/* Note: the function number field in the PCSR is ro */
+@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
+ 
+ 		__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
+ 
+-		res[0].start = IOP13XX_PCIE_LOWER_IO_PA;
++		res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
+ 		res[0].end   = IOP13XX_PCIE_UPPER_IO_PA;
+ 		res[0].name  = "IQ81340 ATUE PCI I/O Space";
+ 		res[0].flags = IORESOURCE_IO;
+@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
+ 		res[1].name  = "IQ81340 ATUE PCI Memory Space";
+ 		res[1].flags = IORESOURCE_MEM;
+ 		sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
+-		sys->io_offset = IOP13XX_PCIE_IO_OFFSET;
++		sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
+ 		sys->map_irq = iop13xx_pcie_map_irq;
+ 		break;
+ 	default:
+diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
+index 16300ad..0cc26da 100644
+--- a/arch/arm/plat-iop/time.c
++++ b/arch/arm/plat-iop/time.c
+@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time;
+ 
+ unsigned long iop_gettimeoffset(void)
+ {
+-	unsigned long offset, temp1, temp2;
++	unsigned long offset, temp;
+ 
+ 	/* enable cp6, if necessary, to avoid taking the overhead of an
+ 	 * undefined instruction trap
+ 	 */
+ 	asm volatile (
+ 	"mrc	p15, 0, %0, c15, c1, 0\n\t"
+-	"ands	%1, %0, #(1 << 6)\n\t"
++	"tst	%0, #(1 << 6)\n\t"
+ 	"orreq	%0, %0, #(1 << 6)\n\t"
+ 	"mcreq	p15, 0, %0, c15, c1, 0\n\t"
+-#ifdef CONFIG_XSCALE
++#ifdef CONFIG_CPU_XSCALE
+ 	"mrceq	p15, 0, %0, c15, c1, 0\n\t"
+ 	"moveq	%0, %0\n\t"
+ 	"subeq	pc, pc, #4\n\t"
+ #endif
+-	: "=r"(temp1), "=r"(temp2) : : "cc");
++	: "=r"(temp) : : "cc");
+ 
+ 	offset = next_jiffy_time - read_tcr1();
+ 
+diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+index 837b041..ca3e1d3 100644
+--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+@@ -341,15 +341,17 @@ static int powernow_acpi_init(void)
+ 	pc.val = (unsigned long) acpi_processor_perf->states[0].control;
+ 	for (i = 0; i < number_scales; i++) {
+ 		u8 fid, vid;
+-		unsigned int speed;
++		struct acpi_processor_px *state =
++			&acpi_processor_perf->states[i];
++		unsigned int speed, speed_mhz;
+ 
+-		pc.val = (unsigned long) acpi_processor_perf->states[i].control;
++		pc.val = (unsigned long) state->control;
+ 		dprintk ("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
+ 			 i,
+-			 (u32) acpi_processor_perf->states[i].core_frequency,
+-			 (u32) acpi_processor_perf->states[i].power,
+-			 (u32) acpi_processor_perf->states[i].transition_latency,
+-			 (u32) acpi_processor_perf->states[i].control,
++			 (u32) state->core_frequency,
++			 (u32) state->power,
++			 (u32) state->transition_latency,
++			 (u32) state->control,
+ 			 pc.bits.sgtc);
+ 
+ 		vid = pc.bits.vid;
+@@ -360,6 +362,18 @@ static int powernow_acpi_init(void)
+ 		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
+ 
+ 		speed = powernow_table[i].frequency;
++		speed_mhz = speed / 1000;
++
++		/* processor_perflib will multiply the MHz value by 1000 to
++		 * get a KHz value (e.g. 1266000). However, powernow-k7 works
++		 * with true KHz values (e.g. 1266768). To ensure that all
++		 * powernow frequencies are available, we must ensure that
++		 * ACPI doesn't restrict them, so we round up the MHz value
++		 * to ensure that perflib's computed KHz value is greater than
++		 * or equal to powernow's KHz value.
++		 */
++		if (speed % 1000 > 0)
++			speed_mhz++;
+ 
+ 		if ((fid_codes[fid] % 10)==5) {
+ 			if (have_a0 == 1)
+@@ -368,10 +382,16 @@ static int powernow_acpi_init(void)
+ 
+ 		dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
+ 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
+-			 fid_codes[fid] % 10, speed/1000, vid,
++			 fid_codes[fid] % 10, speed_mhz, vid,
+ 			 mobile_vid_table[vid]/1000,
+ 			 mobile_vid_table[vid]%1000);
+ 
++		if (state->core_frequency != speed_mhz) {
++			state->core_frequency = speed_mhz;
++			dprintk("   Corrected ACPI frequency to %d\n",
++				speed_mhz);
++		}
++
+ 		if (latency < pc.bits.sgtc)
+ 			latency = pc.bits.sgtc;
+ 
+@@ -602,7 +622,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
+ 			result = powernow_acpi_init();
+ 			if (result) {
+ 				printk (KERN_INFO PFX "ACPI and legacy methods failed\n");
+-				printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n");
++				printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n");
+ 			}
+ 		} else {
+ 			/* SGTC use the bus clock as timer */
+diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+index fe3b670..e295d87 100644
+--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+@@ -521,7 +521,7 @@ static int check_supported_cpu(unsigned int cpu)
+ 
+ 	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
+ 		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
+-		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
++		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
+ 			printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
+ 			goto out;
+ 		}
+diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+index 0fb2a30..575541f 100644
+--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+@@ -46,8 +46,8 @@ struct powernow_k8_data {
+ #define CPUID_XFAM			0x0ff00000	/* extended family */
+ #define CPUID_XFAM_K8			0
+ #define CPUID_XMOD			0x000f0000	/* extended model */
+-#define CPUID_XMOD_REV_G		0x00060000
+-#define CPUID_XFAM_10H 			0x00100000	/* family 0x10 */
++#define CPUID_XMOD_REV_MASK		0x00080000
++#define CPUID_XFAM_10H			0x00100000	/* family 0x10 */
+ #define CPUID_USE_XFAM_XMOD		0x00000f00
+ #define CPUID_GET_MAX_CAPABILITIES	0x80000000
+ #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
+diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
+index fb9bf1e..f56569f 100644
+--- a/arch/sparc64/kernel/of_device.c
++++ b/arch/sparc64/kernel/of_device.c
+@@ -508,6 +508,13 @@ static int __init build_one_resource(struct device_node *parent,
+ 			return 0;
+ 	}
+ 
++	/* When we miss an I/O space match on PCI, just pass it up
++	 * to the next PCI bridge and/or controller.
++	 */
++	if (!strcmp(bus->name, "pci") &&
++	    (addr[0] & 0x03000000) == 0x01000000)
++		return 0;
++
+ 	return 1;
+ }
+ 
+diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
+index 0917c24..3494adf 100644
+--- a/arch/sparc64/kernel/prom.c
++++ b/arch/sparc64/kernel/prom.c
+@@ -1555,10 +1555,21 @@ static struct device_node * __init create_node(phandle node, struct device_node
+ 
+ static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
+ {
++	struct device_node *ret = NULL, *prev_sibling = NULL;
+ 	struct device_node *dp;
+ 
+-	dp = create_node(node, parent);
+-	if (dp) {
++	while (1) {
++		dp = create_node(node, parent);
++		if (!dp)
++			break;
++
++		if (prev_sibling)
++			prev_sibling->sibling = dp;
++
++		if (!ret)
++			ret = dp;
++		prev_sibling = dp;
++
+ 		*(*nextp) = dp;
+ 		*nextp = &dp->allnext;
+ 
+@@ -1567,10 +1578,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl
+ 
+ 		dp->child = build_tree(dp, prom_getchild(node), nextp);
+ 
+-		dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
++		node = prom_getsibling(node);
+ 	}
+ 
+-	return dp;
++	return ret;
+ }
+ 
+ void __init prom_build_devicetree(void)
+diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
+index fc99f7b..8ad7bdb 100644
+--- a/arch/sparc64/kernel/smp.c
++++ b/arch/sparc64/kernel/smp.c
+@@ -566,6 +566,9 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t
+ 	unsigned long flags, status;
+ 	int cnt, retries, this_cpu, prev_sent, i;
+ 
++	if (cpus_empty(mask))
++		return;
++
+ 	/* We have to do this whole thing with interrupts fully disabled.
+ 	 * Otherwise if we send an xcall from interrupt context it will
+ 	 * corrupt both our mondo block and cpu list state.
+diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
+index b43c698..fc9f042 100644
+--- a/arch/x86_64/kernel/vsyscall.c
++++ b/arch/x86_64/kernel/vsyscall.c
+@@ -132,7 +132,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
+ 
+ 	/* convert to usecs and add to timespec: */
+ 	tv->tv_usec += nsec_delta / NSEC_PER_USEC;
+-	while (tv->tv_usec > USEC_PER_SEC) {
++	while (tv->tv_usec >= USEC_PER_SEC) {
+ 		tv->tv_sec += 1;
+ 		tv->tv_usec -= USEC_PER_SEC;
+ 	}
+diff --git a/crypto/api.c b/crypto/api.c
+index 55af8bb..33734fd 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -48,8 +48,10 @@ EXPORT_SYMBOL_GPL(crypto_mod_get);
+ 
+ void crypto_mod_put(struct crypto_alg *alg)
+ {
++	struct module *module = alg->cra_module;
++
+ 	crypto_alg_put(alg);
+-	module_put(alg->cra_module);
++	module_put(module);
+ }
+ EXPORT_SYMBOL_GPL(crypto_mod_put);
+ 
+diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
+index 807c711..d341491 100644
+--- a/drivers/acpi/tables/tbfadt.c
++++ b/drivers/acpi/tables/tbfadt.c
+@@ -347,6 +347,20 @@ static void acpi_tb_convert_fadt(void)
+ 		acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
+ 
+ 	}
++	/*
++	 * _CST object and C States change notification start with
++	 * ACPI 2.0 (FADT r3).  Although the field should be Reserved
++	 * and 0 before then, some pre-r3 FADT set this field and
++	 * it results in SMM-related boot failures.  For them, clear it.
++	 */
++	if ((acpi_gbl_FADT.header.revision < 3) &&
++		(acpi_gbl_FADT.cst_control != 0)) {
++			ACPI_WARNING((AE_INFO,
++				"Ignoring BIOS FADT r%u C-state control",
++				acpi_gbl_FADT.header.revision));
++		 	acpi_gbl_FADT.cst_control = 0;
++	}
++
+ }
+ 
+ /******************************************************************************
+diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
+index 2ffcca0..4d63974 100644
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -557,12 +557,30 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
+ 	int i, p = 0;
+ 	void __iomem * const *iomap;
+ 
++	/* Discard disabled ports. Some controllers show their
++	   unused channels this way */
++	if (ata_resources_present(pdev, 0) == 0)
++		ports &= ~ATA_PORT_PRIMARY;
++	if (ata_resources_present(pdev, 1) == 0)
++		ports &= ~ATA_PORT_SECONDARY;
++
+ 	/* iomap BARs */
+-	for (i = 0; i < 4; i++) {
+-		if (pcim_iomap(pdev, i, 0) == NULL) {
+-			dev_printk(KERN_ERR, &pdev->dev,
+-				   "failed to iomap PCI BAR %d\n", i);
+-			return NULL;
++	if (ports & ATA_PORT_PRIMARY) {
++		for (i = 0; i <= 1; i++) {
++			if (pcim_iomap(pdev, i, 0) == NULL) {
++				dev_printk(KERN_ERR, &pdev->dev,
++					   "failed to iomap PCI BAR %d\n", i);
++				return NULL;
++			}
++		}
++	}
++	if (ports & ATA_PORT_SECONDARY) {
++		for (i = 2; i <= 3; i++) {
++			if (pcim_iomap(pdev, i, 0) == NULL) {
++				dev_printk(KERN_ERR, &pdev->dev,
++					   "failed to iomap PCI BAR %d\n", i);
++				return NULL;
++			}
+ 		}
+ 	}
+ 
+@@ -577,13 +595,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
+ 	probe_ent->irq = pdev->irq;
+ 	probe_ent->irq_flags = IRQF_SHARED;
+ 
+-	/* Discard disabled ports. Some controllers show their
+-	   unused channels this way */
+-	if (ata_resources_present(pdev, 0) == 0)
+-		ports &= ~ATA_PORT_PRIMARY;
+-	if (ata_resources_present(pdev, 1) == 0)
+-		ports &= ~ATA_PORT_SECONDARY;
+-
+ 	if (ports & ATA_PORT_PRIMARY) {
+ 		probe_ent->port[p].cmd_addr = iomap[0];
+ 		probe_ent->port[p].altstatus_addr =
+diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
+index 598e6a2..ea6efca 100644
+--- a/drivers/ata/sata_via.c
++++ b/drivers/ata/sata_via.c
+@@ -97,6 +97,10 @@ static struct pci_driver svia_pci_driver = {
+ 	.name			= DRV_NAME,
+ 	.id_table		= svia_pci_tbl,
+ 	.probe			= svia_init_one,
++#ifdef CONFIG_PM
++	.suspend		= ata_pci_device_suspend,
++	.resume			= ata_pci_device_resume,
++#endif
+ 	.remove			= ata_pci_remove_one,
+ };
+ 
+@@ -116,6 +120,10 @@ static struct scsi_host_template svia_sht = {
+ 	.slave_configure	= ata_scsi_slave_config,
+ 	.slave_destroy		= ata_scsi_slave_destroy,
+ 	.bios_param		= ata_std_bios_param,
++#ifdef CONFIG_PM
++	.suspend		= ata_scsi_device_suspend,
++	.resume			= ata_scsi_device_resume,
++#endif
+ };
+ 
+ static const struct ata_port_operations vt6420_sata_ops = {
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index d7fcf82..a8dfee2 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -93,6 +93,9 @@ static void device_release(struct kobject * kobj)
+ {
+ 	struct device * dev = to_dev(kobj);
+ 
++	kfree(dev->devt_attr);
++	dev->devt_attr = NULL;
++
+ 	if (dev->release)
+ 		dev->release(dev);
+ 	else if (dev->type && dev->type->release)
+@@ -765,10 +768,8 @@ void device_del(struct device * dev)
+ 
+ 	if (parent)
+ 		klist_del(&dev->knode_parent);
+-	if (dev->devt_attr) {
++	if (dev->devt_attr)
+ 		device_remove_file(dev, dev->devt_attr);
+-		kfree(dev->devt_attr);
+-	}
+ 	if (dev->class) {
+ 		sysfs_remove_link(&dev->kobj, "subsystem");
+ 		/* If this is not a "fake" compatible device, remove the
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index e221465..cc13ebc 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -1859,10 +1859,10 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
+ 
+ 	if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+ 		info->io_setup = mem_setup;
+-		info->io.addr_type = IPMI_IO_ADDR_SPACE;
++		info->io.addr_type = IPMI_MEM_ADDR_SPACE;
+ 	} else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+ 		info->io_setup = port_setup;
+-		info->io.addr_type = IPMI_MEM_ADDR_SPACE;
++		info->io.addr_type = IPMI_IO_ADDR_SPACE;
+ 	} else {
+ 		kfree(info);
+ 		printk("ipmi_si: Unknown ACPI I/O Address type\n");
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 97ee870..3a95cc5 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -271,21 +271,25 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
+ 	 */
+ 	update_head_pos(mirror, r1_bio);
+ 
+-	if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) {
+-		/*
+-		 * Set R1BIO_Uptodate in our master bio, so that
+-		 * we will return a good error code for to the higher
+-		 * levels even if IO on some other mirrored buffer fails.
+-		 *
+-		 * The 'master' represents the composite IO operation to
+-		 * user-side. So if something waits for IO, then it will
+-		 * wait for the 'master' bio.
++	if (uptodate)
++		set_bit(R1BIO_Uptodate, &r1_bio->state);
++	else {
++		/* If all other devices have failed, we want to return
++		 * the error upwards rather than fail the last device.
++		 * Here we redefine "uptodate" to mean "Don't want to retry"
+ 		 */
+-		if (uptodate)
+-			set_bit(R1BIO_Uptodate, &r1_bio->state);
++		unsigned long flags;
++		spin_lock_irqsave(&conf->device_lock, flags);
++		if (r1_bio->mddev->degraded == conf->raid_disks ||
++		    (r1_bio->mddev->degraded == conf->raid_disks-1 &&
++		     !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)))
++			uptodate = 1;
++		spin_unlock_irqrestore(&conf->device_lock, flags);
++	}
+ 
++	if (uptodate)
+ 		raid_end_bio_io(r1_bio);
+-	} else {
++	else {
+ 		/*
+ 		 * oops, read error:
+ 		 */
+@@ -992,13 +996,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
+ 		unsigned long flags;
+ 		spin_lock_irqsave(&conf->device_lock, flags);
+ 		mddev->degraded++;
++		set_bit(Faulty, &rdev->flags);
+ 		spin_unlock_irqrestore(&conf->device_lock, flags);
+ 		/*
+ 		 * if recovery is running, make sure it aborts.
+ 		 */
+ 		set_bit(MD_RECOVERY_ERR, &mddev->recovery);
+-	}
+-	set_bit(Faulty, &rdev->flags);
++	} else
++		set_bit(Faulty, &rdev->flags);
+ 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ 	printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
+ 		"	Operation continuing on %d devices\n",
+diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
+index 85f21b5..2eb5741 100644
+--- a/drivers/message/fusion/mptspi.c
++++ b/drivers/message/fusion/mptspi.c
+@@ -726,13 +726,15 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
+ 	struct _MPT_SCSI_HOST *hd =
+ 		(struct _MPT_SCSI_HOST *)sdev->host->hostdata;
+ 	VirtTarget *vtarget = scsi_target(sdev)->hostdata;
+-	int ret = mptscsih_slave_configure(sdev);
++	int ret;
++
++	mptspi_initTarget(hd, vtarget, sdev);
++
++	ret = mptscsih_slave_configure(sdev);
+ 
+ 	if (ret)
+ 		return ret;
+ 
+-	mptspi_initTarget(hd, vtarget, sdev);
+-
+ 	ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x"
+ 		" max_offset=0x%02x max_width=%d\n", hd->ioc->name,
+ 		sdev->id, spi_min_period(scsi_target(sdev)),
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index a3d46ea..32a3003 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -2929,11 +2929,6 @@ endif #NETDEVICES
+ config NETPOLL
+ 	def_bool NETCONSOLE
+ 
+-config NETPOLL_RX
+-	bool "Netpoll support for trapping incoming packets"
+-	default n
+-	depends on NETPOLL
+-
+ config NETPOLL_TRAP
+ 	bool "Netpoll traffic trapping"
+ 	default n
+diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
+index e85f5ec..5006c67 100644
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -54,8 +54,8 @@
+ 
+ #define DRV_MODULE_NAME		"bnx2"
+ #define PFX DRV_MODULE_NAME	": "
+-#define DRV_MODULE_VERSION	"1.5.8"
+-#define DRV_MODULE_RELDATE	"April 24, 2007"
++#define DRV_MODULE_VERSION	"1.5.8.1"
++#define DRV_MODULE_RELDATE	"May 7, 2007"
+ 
+ #define RUN_AT(x) (jiffies + (x))
+ 
+@@ -4510,8 +4510,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		vlan_tag_flags |=
+ 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
+ 	}
+-	if ((mss = skb_shinfo(skb)->gso_size) &&
+-		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
++	if ((mss = skb_shinfo(skb)->gso_size)) {
+ 		u32 tcp_opt_len, ip_tcp_len;
+ 
+ 		if (skb_header_cloned(skb) &&
+@@ -5565,6 +5564,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ 	case SIOCGMIIREG: {
+ 		u32 mii_regval;
+ 
++		if (!netif_running(dev))
++			return -EAGAIN;
++
+ 		spin_lock_bh(&bp->phy_lock);
+ 		err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval);
+ 		spin_unlock_bh(&bp->phy_lock);
+@@ -5578,6 +5580,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ 		if (!capable(CAP_NET_ADMIN))
+ 			return -EPERM;
+ 
++		if (!netif_running(dev))
++			return -EAGAIN;
++
+ 		spin_lock_bh(&bp->phy_lock);
+ 		err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in);
+ 		spin_unlock_bh(&bp->phy_lock);
+@@ -6143,6 +6148,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
+ 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+ 	bnx2_reset_chip(bp, reset_code);
+ 	bnx2_free_skbs(bp);
++	pci_save_state(pdev);
+ 	bnx2_set_power_state(bp, pci_choose_state(pdev, state));
+ 	return 0;
+ }
+@@ -6156,6 +6162,7 @@ bnx2_resume(struct pci_dev *pdev)
+ 	if (!netif_running(dev))
+ 		return 0;
+ 
++	pci_restore_state(pdev);
+ 	bnx2_set_power_state(bp, PCI_D0);
+ 	netif_device_attach(dev);
+ 	bnx2_init_nic(bp);
+diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
+index b2a3b19..ce547af 100644
+--- a/drivers/net/sis900.c
++++ b/drivers/net/sis900.c
+@@ -1754,6 +1754,7 @@ static int sis900_rx(struct net_device *net_dev)
+ 			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
+ 		} else {
+ 			struct sk_buff * skb;
++			struct sk_buff * rx_skb;
+ 
+ 			pci_unmap_single(sis_priv->pci_dev,
+ 				sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
+@@ -1787,10 +1788,10 @@ static int sis900_rx(struct net_device *net_dev)
+ 			}
+ 
+ 			/* give the socket buffer to upper layers */
+-			skb = sis_priv->rx_skbuff[entry];
+-			skb_put(skb, rx_size);
+-			skb->protocol = eth_type_trans(skb, net_dev);
+-			netif_rx(skb);
++			rx_skb = sis_priv->rx_skbuff[entry];
++			skb_put(rx_skb, rx_size);
++			rx_skb->protocol = eth_type_trans(rx_skb, net_dev);
++			netif_rx(rx_skb);
+ 
+ 			/* some network statistics */
+ 			if ((rx_status & BCAST) == MCAST)
+diff --git a/drivers/net/skge.c b/drivers/net/skge.c
+index d476a3c..5ef9023 100644
+--- a/drivers/net/skge.c
++++ b/drivers/net/skge.c
+@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ /* Wake on Lan only supported on Yukon chips with rev 1 or above */
+ static u32 wol_supported(const struct skge_hw *hw)
+ {
+-	if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0)
+-		return WAKE_MAGIC | WAKE_PHY;
+-	else
++	if (hw->chip_id == CHIP_ID_GENESIS)
++		return 0;
++
++	if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
+ 		return 0;
++
++	return WAKE_MAGIC | WAKE_PHY;
+ }
+ 
+ static u32 pci_wake_enabled(struct pci_dev *dev)
+@@ -3583,7 +3586,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
+ 	skge->duplex = -1;
+ 	skge->speed = -1;
+ 	skge->advertising = skge_supported_modes(hw);
+-	skge->wol = pci_wake_enabled(hw->pdev) ? wol_supported(hw) : 0;
++
++	if (pci_wake_enabled(hw->pdev))
++		skge->wol = wol_supported(hw) & WAKE_MAGIC;
+ 
+ 	hw->dev[port] = dev;
+ 
+@@ -3789,6 +3794,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	struct skge_hw *hw  = pci_get_drvdata(pdev);
+ 	int i, err, wol = 0;
+ 
++	if (!hw)
++		return 0;
++
+ 	err = pci_save_state(pdev);
+ 	if (err)
+ 		return err;
+@@ -3817,6 +3825,9 @@ static int skge_resume(struct pci_dev *pdev)
+ 	struct skge_hw *hw  = pci_get_drvdata(pdev);
+ 	int i, err;
+ 
++	if (!hw)
++		return 0;
++
+ 	err = pci_set_power_state(pdev, PCI_D0);
+ 	if (err)
+ 		goto out;
+@@ -3855,6 +3866,9 @@ static void skge_shutdown(struct pci_dev *pdev)
+ 	struct skge_hw *hw  = pci_get_drvdata(pdev);
+ 	int i, wol = 0;
+ 
++	if (!hw)
++		return;
++
+ 	for (i = 0; i < hw->ports; i++) {
+ 		struct net_device *dev = hw->dev[i];
+ 		struct skge_port *skge = netdev_priv(dev);
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index ac36152..b6b444b 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -123,16 +123,13 @@ static const struct pci_device_id sky2_id_table[] = {
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
+-#ifdef broken
+-	/* This device causes data corruption problems that are not resolved */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
+-#endif
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
+-	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
++//	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+ 	{ 0 }
+ };
+ 
+@@ -3722,6 +3719,7 @@ err_out_free_regions:
+ 	pci_release_regions(pdev);
+ 	pci_disable_device(pdev);
+ err_out:
++	pci_set_drvdata(pdev, NULL);
+ 	return err;
+ }
+ 
+@@ -3774,6 +3772,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	struct sky2_hw *hw = pci_get_drvdata(pdev);
+ 	int i, wol = 0;
+ 
++	if (!hw)
++		return 0;
++
+ 	del_timer_sync(&hw->idle_timer);
+ 	netif_poll_disable(hw->dev[0]);
+ 
+@@ -3805,6 +3806,9 @@ static int sky2_resume(struct pci_dev *pdev)
+ 	struct sky2_hw *hw = pci_get_drvdata(pdev);
+ 	int i, err;
+ 
++	if (!hw)
++		return 0;
++
+ 	err = pci_set_power_state(pdev, PCI_D0);
+ 	if (err)
+ 		goto out;
+@@ -3851,6 +3855,9 @@ static void sky2_shutdown(struct pci_dev *pdev)
+ 	struct sky2_hw *hw = pci_get_drvdata(pdev);
+ 	int i, wol = 0;
+ 
++	if (!hw)
++		return;
++
+ 	del_timer_sync(&hw->idle_timer);
+ 	netif_poll_disable(hw->dev[0]);
+ 
+diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
+index c956141..0b89812 100644
+--- a/drivers/net/smc911x.c
++++ b/drivers/net/smc911x.c
+@@ -499,7 +499,7 @@ static inline void	 smc911x_rcv(struct net_device *dev)
+ 		SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_));
+ 		SMC_PULL_DATA(data, pkt_len+2+3);
+ 
+-		DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,);
++		DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name);
+ 		PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64);
+ 		dev->last_rx = jiffies;
+ 		skb->dev = dev;
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+index 256969e..3d20115 100644
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -64,8 +64,8 @@
+ 
+ #define DRV_MODULE_NAME		"tg3"
+ #define PFX DRV_MODULE_NAME	": "
+-#define DRV_MODULE_VERSION	"3.75"
+-#define DRV_MODULE_RELDATE	"March 23, 2007"
++#define DRV_MODULE_VERSION	"3.75.1"
++#define DRV_MODULE_RELDATE	"May 7, 2007"
+ 
+ #define TG3_DEF_MAC_MODE	0
+ #define TG3_DEF_RX_MODE		0
+@@ -3895,8 +3895,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	entry = tp->tx_prod;
+ 	base_flags = 0;
+ 	mss = 0;
+-	if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
+-	    (mss = skb_shinfo(skb)->gso_size) != 0) {
++	if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+ 		int tcp_opt_len, ip_tcp_len;
+ 
+ 		if (skb_header_cloned(skb) &&
+@@ -4053,8 +4052,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
+ 	if (skb->ip_summed == CHECKSUM_PARTIAL)
+ 		base_flags |= TXD_FLAG_TCPUDP_CSUM;
+ 	mss = 0;
+-	if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
+-	    (mss = skb_shinfo(skb)->gso_size) != 0) {
++	if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+ 		int tcp_opt_len, ip_tcp_len, hdr_len;
+ 
+ 		if (skb_header_cloned(skb) &&
+@@ -5936,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
+ 
+ 
+ /* tp->lock is held. */
+-static void __tg3_set_mac_addr(struct tg3 *tp)
++static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
+ {
+ 	u32 addr_high, addr_low;
+ 	int i;
+@@ -5948,6 +5946,8 @@ static void __tg3_set_mac_addr(struct tg3 *tp)
+ 		    (tp->dev->dev_addr[4] <<  8) |
+ 		    (tp->dev->dev_addr[5] <<  0));
+ 	for (i = 0; i < 4; i++) {
++		if (i == 1 && skip_mac_1)
++			continue;
+ 		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+ 		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
+ 	}
+@@ -5974,7 +5974,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
+ {
+ 	struct tg3 *tp = netdev_priv(dev);
+ 	struct sockaddr *addr = p;
+-	int err = 0;
++	int err = 0, skip_mac_1 = 0;
+ 
+ 	if (!is_valid_ether_addr(addr->sa_data))
+ 		return -EINVAL;
+@@ -5985,22 +5985,21 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
+ 		return 0;
+ 
+ 	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+-		/* Reset chip so that ASF can re-init any MAC addresses it
+-		 * needs.
+-		 */
+-		tg3_netif_stop(tp);
+-		tg3_full_lock(tp, 1);
++		u32 addr0_high, addr0_low, addr1_high, addr1_low;
+ 
+-		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+-		err = tg3_restart_hw(tp, 0);
+-		if (!err)
+-			tg3_netif_start(tp);
+-		tg3_full_unlock(tp);
+-	} else {
+-		spin_lock_bh(&tp->lock);
+-		__tg3_set_mac_addr(tp);
+-		spin_unlock_bh(&tp->lock);
++		addr0_high = tr32(MAC_ADDR_0_HIGH);
++		addr0_low = tr32(MAC_ADDR_0_LOW);
++		addr1_high = tr32(MAC_ADDR_1_HIGH);
++		addr1_low = tr32(MAC_ADDR_1_LOW);
++
++		/* Skip MAC addr 1 if ASF is using it. */
++		if ((addr0_high != addr1_high || addr0_low != addr1_low) &&
++		    !(addr1_high == 0 && addr1_low == 0))
++			skip_mac_1 = 1;
+ 	}
++	spin_lock_bh(&tp->lock);
++	__tg3_set_mac_addr(tp, skip_mac_1);
++	spin_unlock_bh(&tp->lock);
+ 
+ 	return err;
+ }
+@@ -6317,7 +6316,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
+ 		     tp->rx_jumbo_ptr);
+ 
+ 	/* Initialize MAC address and backoff seed. */
+-	__tg3_set_mac_addr(tp);
++	__tg3_set_mac_addr(tp, 0);
+ 
+ 	/* MTU + ethernet header + FCS + optional VLAN tag */
+ 	tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+@@ -6348,8 +6347,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
+ 	     tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
+ 	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) {
+ 		if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE &&
+-		    (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
+-		     tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
++		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+ 			rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128;
+ 		} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
+ 			   !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 65d6f23..5af9125 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1737,18 +1737,20 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+ 			quirk_nvidia_ck804_pcie_aer_ext_cap);
+ 
+ #ifdef CONFIG_PCI_MSI
+-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
+- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
+- * some other busses controlled by the chipset even if Linux is not aware of it.
+- * Instead of setting the flag on all busses in the machine, simply disable MSI
+- * globally.
++/* Some chipsets do not support MSI. We cannot easily rely on setting
++ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
++ * some other busses controlled by the chipset even if Linux is not
++ * aware of it.  Instead of setting the flag on all busses in the
++ * machine, simply disable MSI globally.
+  */
+-static void __init quirk_svw_msi(struct pci_dev *dev)
++static void __init quirk_disable_all_msi(struct pci_dev *dev)
+ {
+ 	pci_no_msi();
+ 	printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
+ }
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
+ 
+ /* Disable MSI on chipsets that are known to not support it */
+ static void __devinit quirk_disable_msi(struct pci_dev *dev)
+diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
+index 40d4856..c3a6bd2 100644
+--- a/drivers/serial/sunhv.c
++++ b/drivers/serial/sunhv.c
+@@ -493,6 +493,10 @@ static struct of_device_id hv_match[] = {
+ 		.name = "console",
+ 		.compatible = "qcn",
+ 	},
++	{
++		.name = "console",
++		.compatible = "SUNW,sun4v-console",
++	},
+ 	{},
+ };
+ MODULE_DEVICE_TABLE(of, hv_match);
+diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
+index 3dfa3e4..3257d94 100644
+--- a/drivers/usb/atm/cxacru.c
++++ b/drivers/usb/atm/cxacru.c
+@@ -146,6 +146,12 @@ enum cxacru_info_idx {
+ 	CXINF_MAX = 0x1c,
+ };
+ 
++enum poll_state {
++	CX_INIT,
++	CX_POLLING,
++	CX_ABORT
++};
++
+ struct cxacru_modem_type {
+ 	u32 pll_f_clk;
+ 	u32 pll_b_clk;
+@@ -159,6 +165,8 @@ struct cxacru_data {
+ 
+ 	int line_status;
+ 	struct delayed_work poll_work;
++	struct mutex poll_state_serialize;
++	enum poll_state poll_state;
+ 
+ 	/* contol handles */
+ 	struct mutex cm_serialize;
+@@ -356,7 +364,7 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
+ 	/*
+ 	struct atm_dev *atm_dev = usbatm_instance->atm_dev;
+ 	*/
+-	int ret;
++	int ret, start_polling = 1;
+ 
+ 	dbg("cxacru_atm_start");
+ 
+@@ -376,7 +384,15 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
+ 	}
+ 
+ 	/* Start status polling */
+-	cxacru_poll_status(&instance->poll_work.work);
++	mutex_lock(&instance->poll_state_serialize);
++	if (instance->poll_state == CX_INIT)
++		instance->poll_state = CX_POLLING;
++	else /* poll_state == CX_ABORT */
++		start_polling = 0;
++	mutex_unlock(&instance->poll_state_serialize);
++
++	if (start_polling)
++		cxacru_poll_status(&instance->poll_work.work);
+ 	return 0;
+ }
+ 
+@@ -685,6 +701,9 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
+ 	instance->usbatm = usbatm_instance;
+ 	instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
+ 
++	mutex_init(&instance->poll_state_serialize);
++	instance->poll_state = CX_INIT;
++
+ 	instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
+ 	if (!instance->rcv_buf) {
+ 		dbg("cxacru_bind: no memory for rcv_buf");
+@@ -744,6 +763,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
+ 		struct usb_interface *intf)
+ {
+ 	struct cxacru_data *instance = usbatm_instance->driver_data;
++	int stop_polling = 1;
+ 
+ 	dbg("cxacru_unbind entered");
+ 
+@@ -752,8 +772,20 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
+ 		return;
+ 	}
+ 
+-	while (!cancel_delayed_work(&instance->poll_work))
+-	       flush_scheduled_work();
++	mutex_lock(&instance->poll_state_serialize);
++	if (instance->poll_state != CX_POLLING) {
++		/* Polling hasn't started yet and with
++		 * the mutex locked it can be prevented
++		 * from starting.
++		 */
++		instance->poll_state = CX_ABORT;
++		stop_polling = 0;
++	}
++	mutex_unlock(&instance->poll_state_serialize);
++
++	if (stop_polling)
++		while (!cancel_delayed_work(&instance->poll_work))
++			flush_scheduled_work();
+ 
+ 	usb_kill_urb(instance->snd_urb);
+ 	usb_kill_urb(instance->rcv_urb);
+diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
+index a8b3d66..488d61b 100644
+--- a/drivers/usb/input/hiddev.c
++++ b/drivers/usb/input/hiddev.c
+@@ -51,6 +51,7 @@ struct hiddev {
+ 	wait_queue_head_t wait;
+ 	struct hid_device *hid;
+ 	struct list_head list;
++	spinlock_t list_lock;
+ };
+ 
+ struct hiddev_list {
+@@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid,
+ {
+ 	struct hiddev *hiddev = hid->hiddev;
+ 	struct hiddev_list *list;
++	unsigned long flags;
+ 
++	spin_lock_irqsave(&hiddev->list_lock, flags);
+ 	list_for_each_entry(list, &hiddev->list, node) {
+ 		if (uref->field_index != HID_FIELD_INDEX_NONE ||
+ 		    (list->flags & HIDDEV_FLAG_REPORT) != 0) {
+@@ -171,6 +174,7 @@ static void hiddev_send_event(struct hid_device *hid,
+ 			kill_fasync(&list->fasync, SIGIO, POLL_IN);
+ 		}
+ 	}
++	spin_unlock_irqrestore(&hiddev->list_lock, flags);
+ 
+ 	wake_up_interruptible(&hiddev->wait);
+ }
+@@ -235,9 +239,13 @@ static int hiddev_fasync(int fd, struct file *file, int on)
+ static int hiddev_release(struct inode * inode, struct file * file)
+ {
+ 	struct hiddev_list *list = file->private_data;
++	unsigned long flags;
+ 
+ 	hiddev_fasync(-1, file, 0);
++
++	spin_lock_irqsave(&list->hiddev->list_lock, flags);
+ 	list_del(&list->node);
++	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
+ 
+ 	if (!--list->hiddev->open) {
+ 		if (list->hiddev->exist)
+@@ -257,6 +265,7 @@ static int hiddev_release(struct inode * inode, struct file * file)
+ static int hiddev_open(struct inode *inode, struct file *file)
+ {
+ 	struct hiddev_list *list;
++	unsigned long flags;
+ 
+ 	int i = iminor(inode) - HIDDEV_MINOR_BASE;
+ 
+@@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file)
+ 		return -ENOMEM;
+ 
+ 	list->hiddev = hiddev_table[i];
++
++	spin_lock_irqsave(&list->hiddev->list_lock, flags);
+ 	list_add_tail(&list->node, &hiddev_table[i]->list);
++	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
++
+ 	file->private_data = list;
+ 
+ 	if (!list->hiddev->open++)
+@@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid)
+ 
+ 	init_waitqueue_head(&hiddev->wait);
+ 	INIT_LIST_HEAD(&hiddev->list);
++	spin_lock_init(&hiddev->list_lock);
+ 	hiddev->hid = hid;
+ 	hiddev->exist = 1;
+ 
+diff --git a/fs/fat/dir.c b/fs/fat/dir.c
+index c16af24..ccf161d 100644
+--- a/fs/fat/dir.c
++++ b/fs/fat/dir.c
+@@ -422,7 +422,7 @@ EODir:
+ EXPORT_SYMBOL_GPL(fat_search_long);
+ 
+ struct fat_ioctl_filldir_callback {
+-	struct dirent __user *dirent;
++	void __user *dirent;
+ 	int result;
+ 	/* for dir ioctl */
+ 	const char *longname;
+@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ 	return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
+ }
+ 
+-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
+-			     loff_t offset, u64 ino, unsigned int d_type)
++#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type)			   \
++static int func(void *__buf, const char *name, int name_len,		   \
++			     loff_t offset, u64 ino, unsigned int d_type)  \
++{									   \
++	struct fat_ioctl_filldir_callback *buf = __buf;			   \
++	struct dirent_type __user *d1 = buf->dirent;			   \
++	struct dirent_type __user *d2 = d1 + 1;				   \
++									   \
++	if (buf->result)						   \
++		return -EINVAL;						   \
++	buf->result++;							   \
++									   \
++	if (name != NULL) {						   \
++		/* dirent has only short name */			   \
++		if (name_len >= sizeof(d1->d_name))			   \
++			name_len = sizeof(d1->d_name) - 1;		   \
++									   \
++		if (put_user(0, d2->d_name)			||	   \
++		    put_user(0, &d2->d_reclen)			||	   \
++		    copy_to_user(d1->d_name, name, name_len)	||	   \
++		    put_user(0, d1->d_name + name_len)		||	   \
++		    put_user(name_len, &d1->d_reclen))			   \
++			goto efault;					   \
++	} else {							   \
++		/* dirent has short and long name */			   \
++		const char *longname = buf->longname;			   \
++		int long_len = buf->long_len;				   \
++		const char *shortname = buf->shortname;			   \
++		int short_len = buf->short_len;				   \
++									   \
++		if (long_len >= sizeof(d1->d_name))			   \
++			long_len = sizeof(d1->d_name) - 1;		   \
++		if (short_len >= sizeof(d1->d_name))			   \
++			short_len = sizeof(d1->d_name) - 1;		   \
++									   \
++		if (copy_to_user(d2->d_name, longname, long_len)	|| \
++		    put_user(0, d2->d_name + long_len)			|| \
++		    put_user(long_len, &d2->d_reclen)			|| \
++		    put_user(ino, &d2->d_ino)				|| \
++		    put_user(offset, &d2->d_off)			|| \
++		    copy_to_user(d1->d_name, shortname, short_len)	|| \
++		    put_user(0, d1->d_name + short_len)			|| \
++		    put_user(short_len, &d1->d_reclen))			   \
++			goto efault;					   \
++	}								   \
++	return 0;							   \
++efault:									   \
++	buf->result = -EFAULT;						   \
++	return -EFAULT;							   \
++}
++
++FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent)
++
++static int fat_ioctl_readdir(struct inode *inode, struct file *filp,
++			     void __user *dirent, filldir_t filldir,
++			     int short_only, int both)
+ {
+-	struct fat_ioctl_filldir_callback *buf = __buf;
+-	struct dirent __user *d1 = buf->dirent;
+-	struct dirent __user *d2 = d1 + 1;
+-
+-	if (buf->result)
+-		return -EINVAL;
+-	buf->result++;
+-
+-	if (name != NULL) {
+-		/* dirent has only short name */
+-		if (name_len >= sizeof(d1->d_name))
+-			name_len = sizeof(d1->d_name) - 1;
+-
+-		if (put_user(0, d2->d_name)			||
+-		    put_user(0, &d2->d_reclen)			||
+-		    copy_to_user(d1->d_name, name, name_len)	||
+-		    put_user(0, d1->d_name + name_len)		||
+-		    put_user(name_len, &d1->d_reclen))
+-			goto efault;
+-	} else {
+-		/* dirent has short and long name */
+-		const char *longname = buf->longname;
+-		int long_len = buf->long_len;
+-		const char *shortname = buf->shortname;
+-		int short_len = buf->short_len;
+-
+-		if (long_len >= sizeof(d1->d_name))
+-			long_len = sizeof(d1->d_name) - 1;
+-		if (short_len >= sizeof(d1->d_name))
+-			short_len = sizeof(d1->d_name) - 1;
+-
+-		if (copy_to_user(d2->d_name, longname, long_len)	||
+-		    put_user(0, d2->d_name + long_len)			||
+-		    put_user(long_len, &d2->d_reclen)			||
+-		    put_user(ino, &d2->d_ino)				||
+-		    put_user(offset, &d2->d_off)			||
+-		    copy_to_user(d1->d_name, shortname, short_len)	||
+-		    put_user(0, d1->d_name + short_len)			||
+-		    put_user(short_len, &d1->d_reclen))
+-			goto efault;
++	struct fat_ioctl_filldir_callback buf;
++	int ret;
++
++	buf.dirent = dirent;
++	buf.result = 0;
++	mutex_lock(&inode->i_mutex);
++	ret = -ENOENT;
++	if (!IS_DEADDIR(inode)) {
++		ret = __fat_readdir(inode, filp, &buf, filldir,
++				    short_only, both);
+ 	}
+-	return 0;
+-efault:
+-	buf->result = -EFAULT;
+-	return -EFAULT;
++	mutex_unlock(&inode->i_mutex);
++	if (ret >= 0)
++		ret = buf.result;
++	return ret;
+ }
+ 
+-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
+-		  unsigned int cmd, unsigned long arg)
++static int fat_dir_ioctl(struct inode *inode, struct file *filp,
++			 unsigned int cmd, unsigned long arg)
+ {
+-	struct fat_ioctl_filldir_callback buf;
+-	struct dirent __user *d1;
+-	int ret, short_only, both;
++	struct dirent __user *d1 = (struct dirent __user *)arg;
++	int short_only, both;
+ 
+ 	switch (cmd) {
+ 	case VFAT_IOCTL_READDIR_SHORT:
+@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
+ 		return fat_generic_ioctl(inode, filp, cmd, arg);
+ 	}
+ 
+-	d1 = (struct dirent __user *)arg;
+ 	if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
+ 		return -EFAULT;
+ 	/*
+@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
+ 	if (put_user(0, &d1->d_reclen))
+ 		return -EFAULT;
+ 
+-	buf.dirent = d1;
+-	buf.result = 0;
+-	mutex_lock(&inode->i_mutex);
+-	ret = -ENOENT;
+-	if (!IS_DEADDIR(inode)) {
+-		ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
+-				    short_only, both);
+-	}
+-	mutex_unlock(&inode->i_mutex);
+-	if (ret >= 0)
+-		ret = buf.result;
+-	return ret;
++	return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir,
++				 short_only, both);
+ }
+ 
+ #ifdef CONFIG_COMPAT
+ #define	VFAT_IOCTL_READDIR_BOTH32	_IOR('r', 1, struct compat_dirent[2])
+ #define	VFAT_IOCTL_READDIR_SHORT32	_IOR('r', 2, struct compat_dirent[2])
+ 
+-static long fat_compat_put_dirent32(struct dirent *d,
+-				    struct compat_dirent __user *d32)
+-{
+-        if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
+-                return -EFAULT;
+-
+-        __put_user(d->d_ino, &d32->d_ino);
+-        __put_user(d->d_off, &d32->d_off);
+-        __put_user(d->d_reclen, &d32->d_reclen);
+-        if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
+-		return -EFAULT;
++FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent)
+ 
+-        return 0;
+-}
+-
+-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
++static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
+ 				 unsigned long arg)
+ {
+-	struct compat_dirent __user *p = compat_ptr(arg);
+-	int ret;
+-	mm_segment_t oldfs = get_fs();
+-	struct dirent d[2];
++	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct compat_dirent __user *d1 = compat_ptr(arg);
++	int short_only, both;
+ 
+ 	switch (cmd) {
+-	case VFAT_IOCTL_READDIR_BOTH32:
+-		cmd = VFAT_IOCTL_READDIR_BOTH;
+-		break;
+ 	case VFAT_IOCTL_READDIR_SHORT32:
+-		cmd = VFAT_IOCTL_READDIR_SHORT;
++		short_only = 1;
++		both = 0;
++		break;
++	case VFAT_IOCTL_READDIR_BOTH32:
++		short_only = 0;
++		both = 1;
+ 		break;
+ 	default:
+ 		return -ENOIOCTLCMD;
+ 	}
+ 
+-	set_fs(KERNEL_DS);
+-	lock_kernel();
+-	ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file,
+-			    cmd, (unsigned long) &d);
+-	unlock_kernel();
+-	set_fs(oldfs);
+-	if (ret >= 0) {
+-		ret |= fat_compat_put_dirent32(&d[0], p);
+-		ret |= fat_compat_put_dirent32(&d[1], p + 1);
+-	}
+-	return ret;
++	if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2])))
++		return -EFAULT;
++	/*
++	 * Yes, we don't need this put_user() absolutely. However old
++	 * code didn't return the right value. So, app use this value,
++	 * in order to check whether it is EOF.
++	 */
++	if (put_user(0, &d1->d_reclen))
++		return -EFAULT;
++
++	return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir,
++				 short_only, both);
+ }
+ #endif /* CONFIG_COMPAT */
+ 
+diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
+index 5065baa..3760d02 100644
+--- a/fs/jfs/jfs_logmgr.c
++++ b/fs/jfs/jfs_logmgr.c
+@@ -2354,12 +2354,13 @@ int jfsIOWait(void *arg)
+ 			lbmStartIO(bp);
+ 			spin_lock_irq(&log_redrive_lock);
+ 		}
+-		spin_unlock_irq(&log_redrive_lock);
+ 
+ 		if (freezing(current)) {
++			spin_unlock_irq(&log_redrive_lock);
+ 			refrigerator();
+ 		} else {
+ 			set_current_state(TASK_INTERRUPTIBLE);
++			spin_unlock_irq(&log_redrive_lock);
+ 			schedule();
+ 			current->state = TASK_RUNNING;
+ 		}
+diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
+index 6f24768..79bd03b 100644
+--- a/fs/nfsd/export.c
++++ b/fs/nfsd/export.c
+@@ -469,6 +469,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 	nd.dentry = NULL;
+ 	exp.ex_path = NULL;
+ 
++	/* fs locations */
++	exp.ex_fslocs.locations = NULL;
++	exp.ex_fslocs.locations_count = 0;
++	exp.ex_fslocs.migrated = 0;
++
++	exp.ex_uuid = NULL;
++
+ 	if (mesg[mlen-1] != '\n')
+ 		return -EINVAL;
+ 	mesg[mlen-1] = 0;
+@@ -509,13 +516,6 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
+ 	if (exp.h.expiry_time == 0)
+ 		goto out;
+ 
+-	/* fs locations */
+-	exp.ex_fslocs.locations = NULL;
+-	exp.ex_fslocs.locations_count = 0;
+-	exp.ex_fslocs.migrated = 0;
+-
+-	exp.ex_uuid = NULL;
+-
+ 	/* flags */
+ 	err = get_int(&mesg, &an_int);
+ 	if (err == -ENOENT)
+diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
+index c8178b7..2cac562 100644
+--- a/fs/reiserfs/xattr.c
++++ b/fs/reiserfs/xattr.c
+@@ -68,7 +68,7 @@ static struct dentry *get_xa_root(struct super_block *sb, int flags)
+ 	if (!privroot)
+ 		return ERR_PTR(-ENODATA);
+ 
+-	mutex_lock(&privroot->d_inode->i_mutex);
++	mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR);
+ 	if (REISERFS_SB(sb)->xattr_root) {
+ 		xaroot = dget(REISERFS_SB(sb)->xattr_root);
+ 		goto out;
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index fe361cd..b254375 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -878,7 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
+ 			inode->i_nlink);
+ 	clear_nlink(inode);
+ 	inode->i_size = 0;
+-	inode_dec_link_count(inode);
++	inode_dec_link_count(dir);
+ 	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
+ 	mark_inode_dirty(dir);
+ 
+diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h
+index d26b755..74d7498 100644
+--- a/include/asm-arm/arch-iop13xx/iop13xx.h
++++ b/include/asm-arm/arch-iop13xx/iop13xx.h
+@@ -27,19 +27,24 @@ static inline int iop13xx_cpu_id(void)
+ #define IOP13XX_PCI_OFFSET	 IOP13XX_MAX_RAM_SIZE
+ 
+ /* PCI MAP
+- * 0x0000.0000 - 0x8000.0000           1:1 mapping with Physical RAM
+- * 0x8000.0000 - 0x8800.0000           PCIX/PCIE memory window (128MB)
+-*/
++ * bus range		cpu phys	cpu virt	note
++ * 0x0000.0000 + 2GB	(n/a)		(n/a)		inbound, 1:1 mapping with Physical RAM
++ * 0x8000.0000 + 928M	0x1.8000.0000   (ioremap)	PCIX outbound memory window
++ * 0x8000.0000 + 928M	0x2.8000.0000   (ioremap)	PCIE outbound memory window
++ * 
++ * IO MAP
++ * 0x1000 + 64K	0x0.fffb.1000	0xfec6.1000	PCIX outbound i/o window
++ * 0x1000 + 64K	0x0.fffd.1000	0xfed7.1000	PCIE outbound i/o window
++ */
+ #define IOP13XX_PCIX_IO_WINDOW_SIZE   0x10000UL
+ #define IOP13XX_PCIX_LOWER_IO_PA      0xfffb0000UL
+ #define IOP13XX_PCIX_LOWER_IO_VA      0xfec60000UL
+-#define IOP13XX_PCIX_LOWER_IO_BA      0x0fff0000UL
++#define IOP13XX_PCIX_LOWER_IO_BA      0x0UL /* OIOTVR */
++#define IOP13XX_PCIX_IO_BUS_OFFSET    0x1000UL
+ #define IOP13XX_PCIX_UPPER_IO_PA      (IOP13XX_PCIX_LOWER_IO_PA +\
+ 				       IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
+ #define IOP13XX_PCIX_UPPER_IO_VA      (IOP13XX_PCIX_LOWER_IO_VA +\
+ 				       IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
+-#define IOP13XX_PCIX_IO_OFFSET        (IOP13XX_PCIX_LOWER_IO_VA -\
+-				       IOP13XX_PCIX_LOWER_IO_BA)
+ #define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+ 					   (IOP13XX_PCIX_LOWER_IO_PA\
+ 					   - IOP13XX_PCIX_LOWER_IO_VA))
+@@ -65,15 +70,14 @@ static inline int iop13xx_cpu_id(void)
+ #define IOP13XX_PCIE_IO_WINDOW_SIZE   	 0x10000UL
+ #define IOP13XX_PCIE_LOWER_IO_PA      	 0xfffd0000UL
+ #define IOP13XX_PCIE_LOWER_IO_VA      	 0xfed70000UL
+-#define IOP13XX_PCIE_LOWER_IO_BA      	 0x0fff0000UL
++#define IOP13XX_PCIE_LOWER_IO_BA      	 0x0UL  /* OIOTVR */
++#define IOP13XX_PCIE_IO_BUS_OFFSET	 0x1000UL
+ #define IOP13XX_PCIE_UPPER_IO_PA      	 (IOP13XX_PCIE_LOWER_IO_PA +\
+ 					 IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+ #define IOP13XX_PCIE_UPPER_IO_VA      	 (IOP13XX_PCIE_LOWER_IO_VA +\
+ 					 IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+ #define IOP13XX_PCIE_UPPER_IO_BA      	 (IOP13XX_PCIE_LOWER_IO_BA +\
+ 					 IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+-#define IOP13XX_PCIE_IO_OFFSET        	 (IOP13XX_PCIE_LOWER_IO_VA -\
+-					 IOP13XX_PCIE_LOWER_IO_BA)
+ #define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+ 					   (IOP13XX_PCIE_LOWER_IO_PA\
+ 					   - IOP13XX_PCIE_LOWER_IO_VA))
+diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h
+index e01b805..26ec046 100644
+--- a/include/asm-sparc64/openprom.h
++++ b/include/asm-sparc64/openprom.h
+@@ -177,7 +177,7 @@ struct linux_nodeops {
+ /* More fun PROM structures for device probing. */
+ #define PROMREG_MAX     24
+ #define PROMVADDR_MAX   16
+-#define PROMINTR_MAX    15
++#define PROMINTR_MAX    32
+ 
+ struct linux_prom_registers {
+ 	unsigned which_io;	/* hi part of physical address			*/
+diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
+index daa4940..bf92c26 100644
+--- a/include/linux/clocksource.h
++++ b/include/linux/clocksource.h
+@@ -48,6 +48,7 @@ struct clocksource;
+  * @shift:		cycle to nanosecond divisor (power of two)
+  * @flags:		flags describing special properties
+  * @vread:		vsyscall based read
++ * @resume:		resume function for the clocksource, if necessary
+  * @cycle_interval:	Used internally by timekeeping core, please ignore.
+  * @xtime_interval:	Used internally by timekeeping core, please ignore.
+  */
+@@ -61,6 +62,7 @@ struct clocksource {
+ 	u32 shift;
+ 	unsigned long flags;
+ 	cycle_t (*vread)(void);
++	void (*resume)(void);
+ 
+ 	/* timekeeping specific data, ignore */
+ 	cycle_t cycle_last, cycle_interval;
+@@ -198,6 +200,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c,
+ extern int clocksource_register(struct clocksource*);
+ extern struct clocksource* clocksource_get_next(void);
+ extern void clocksource_change_rating(struct clocksource *cs, int rating);
++extern void clocksource_resume(void);
+ 
+ #ifdef CONFIG_GENERIC_TIME_VSYSCALL
+ extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 1a52854..b1b0f68 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -647,8 +647,10 @@ static inline void netif_start_queue(struct net_device *dev)
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
+ #ifdef CONFIG_NETPOLL_TRAP
+-	if (netpoll_trap())
++	if (netpoll_trap()) {
++		clear_bit(__LINK_STATE_XOFF, &dev->state);
+ 		return;
++	}
+ #endif
+ 	if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+ 		__netif_schedule(dev);
+@@ -656,10 +658,6 @@ static inline void netif_wake_queue(struct net_device *dev)
+ 
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
+-#ifdef CONFIG_NETPOLL_TRAP
+-	if (netpoll_trap())
+-		return;
+-#endif
+ 	set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+ 
+diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h
+index 4e6bbce..535e421 100644
+--- a/include/linux/netfilter/nf_conntrack_proto_gre.h
++++ b/include/linux/netfilter/nf_conntrack_proto_gre.h
+@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
+ /* delete keymap entries */
+ void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
+ 
+-/* get pointer to gre key, if present */
+-static inline __be32 *gre_key(struct gre_hdr *greh)
+-{
+-	if (!greh->key)
+-		return NULL;
+-	if (greh->csum || greh->routing)
+-		return (__be32 *)(greh+sizeof(*greh)+4);
+-	return (__be32 *)(greh+sizeof(*greh));
+-}
+-
+-/* get pointer ot gre csum, if present */
+-static inline __sum16 *gre_csum(struct gre_hdr *greh)
+-{
+-	if (!greh->csum)
+-		return NULL;
+-	return (__sum16 *)(greh+sizeof(*greh));
+-}
+-
+ extern void nf_ct_gre_keymap_flush(void);
+ extern void nf_nat_need_gre(void);
+ 
+diff --git a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
+index e371e0f..d0f36f5 100644
+--- a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
++++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h
+@@ -90,25 +90,6 @@ int ip_ct_gre_keymap_add(struct ip_conntrack *ct,
+ /* delete keymap entries */
+ void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct);
+ 
+-
+-/* get pointer to gre key, if present */
+-static inline __be32 *gre_key(struct gre_hdr *greh)
+-{
+-	if (!greh->key)
+-		return NULL;
+-	if (greh->csum || greh->routing)
+-		return (__be32 *) (greh+sizeof(*greh)+4);
+-	return (__be32 *) (greh+sizeof(*greh));
+-}
+-
+-/* get pointer ot gre csum, if present */
+-static inline __sum16 *gre_csum(struct gre_hdr *greh)
+-{
+-	if (!greh->csum)
+-		return NULL;
+-	return (__sum16 *) (greh+sizeof(*greh));
+-}
+-
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _CONNTRACK_PROTO_GRE_H */
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index fe5c7db..5baee91 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -74,6 +74,8 @@ static struct clocksource *watchdog;
+ static struct timer_list watchdog_timer;
+ static DEFINE_SPINLOCK(watchdog_lock);
+ static cycle_t watchdog_last;
++static int watchdog_resumed;
++
+ /*
+  * Interval: 0.5sec Treshold: 0.0625s
+  */
+@@ -98,15 +100,26 @@ static void clocksource_watchdog(unsigned long data)
+ 	struct clocksource *cs, *tmp;
+ 	cycle_t csnow, wdnow;
+ 	int64_t wd_nsec, cs_nsec;
++	int resumed;
+ 
+ 	spin_lock(&watchdog_lock);
+ 
++	resumed = watchdog_resumed;
++	if (unlikely(resumed))
++		watchdog_resumed = 0;
++
+ 	wdnow = watchdog->read();
+ 	wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask);
+ 	watchdog_last = wdnow;
+ 
+ 	list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
+ 		csnow = cs->read();
++
++		if (unlikely(resumed)) {
++			cs->wd_last = csnow;
++			continue;
++		}
++
+ 		/* Initialized ? */
+ 		if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
+ 			if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
+@@ -136,6 +149,13 @@ static void clocksource_watchdog(unsigned long data)
+ 	}
+ 	spin_unlock(&watchdog_lock);
+ }
++static void clocksource_resume_watchdog(void)
++{
++	spin_lock(&watchdog_lock);
++	watchdog_resumed = 1;
++	spin_unlock(&watchdog_lock);
++}
++
+ static void clocksource_check_watchdog(struct clocksource *cs)
+ {
+ 	struct clocksource *cse;
+@@ -182,9 +202,34 @@ static void clocksource_check_watchdog(struct clocksource *cs)
+ 	if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
+ 		cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
+ }
++
++static inline void clocksource_resume_watchdog(void) { }
+ #endif
+ 
+ /**
++ * clocksource_resume - resume the clocksource(s)
++ */
++void clocksource_resume(void)
++{
++	struct list_head *tmp;
++	unsigned long flags;
++
++	spin_lock_irqsave(&clocksource_lock, flags);
++
++	list_for_each(tmp, &clocksource_list) {
++		struct clocksource *cs;
++
++		cs = list_entry(tmp, struct clocksource, list);
++		if (cs->resume)
++			cs->resume();
++	}
++
++	clocksource_resume_watchdog();
++
++	spin_unlock_irqrestore(&clocksource_lock, flags);
++}
++
++/**
+  * clocksource_get_next - Returns the selected clocksource
+  *
+  */
+diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
+index bfda3f7..a96ec9a 100644
+--- a/kernel/time/tick-common.c
++++ b/kernel/time/tick-common.c
+@@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
+  */
+ ktime_t tick_next_period;
+ ktime_t tick_period;
+-static int tick_do_timer_cpu = -1;
++int tick_do_timer_cpu __read_mostly = -1;
+ DEFINE_SPINLOCK(tick_device_lock);
+ 
+ /*
+@@ -295,6 +295,12 @@ static void tick_shutdown(unsigned int *cpup)
+ 		clockevents_exchange_device(dev, NULL);
+ 		td->evtdev = NULL;
+ 	}
++	/* Transfer the do_timer job away from this cpu */
++	if (*cpup == tick_do_timer_cpu) {
++		int cpu = first_cpu(cpu_online_map);
++
++		tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
++	}
+ 	spin_unlock_irqrestore(&tick_device_lock, flags);
+ }
+ 
+diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
+index c9d203b..bb13f27 100644
+--- a/kernel/time/tick-internal.h
++++ b/kernel/time/tick-internal.h
+@@ -5,6 +5,7 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
+ extern spinlock_t tick_device_lock;
+ extern ktime_t tick_next_period;
+ extern ktime_t tick_period;
++extern int tick_do_timer_cpu __read_mostly;
+ 
+ extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
+ extern void tick_handle_periodic(struct clock_event_device *dev);
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index 51556b9..f4fc867 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -221,6 +221,18 @@ void tick_nohz_stop_sched_tick(void)
+ 			ts->tick_stopped = 1;
+ 			ts->idle_jiffies = last_jiffies;
+ 		}
++
++		/*
++		 * If this cpu is the one which updates jiffies, then
++		 * give up the assignment and let it be taken by the
++		 * cpu which runs the tick timer next, which might be
++		 * this cpu as well. If we don't drop this here the
++		 * jiffies might be stale and do_timer() never
++		 * invoked.
++		 */
++		if (cpu == tick_do_timer_cpu)
++			tick_do_timer_cpu = -1;
++
+ 		/*
+ 		 * calculate the expiry time for the next timer wheel
+ 		 * timer
+@@ -338,12 +350,24 @@ static void tick_nohz_handler(struct clock_event_device *dev)
+ {
+ 	struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
+ 	struct pt_regs *regs = get_irq_regs();
++	int cpu = smp_processor_id();
+ 	ktime_t now = ktime_get();
+ 
+ 	dev->next_event.tv64 = KTIME_MAX;
+ 
++	/*
++	 * Check if the do_timer duty was dropped. We don't care about
++	 * concurrency: This happens only when the cpu in charge went
++	 * into a long sleep. If two cpus happen to assign themself to
++	 * this duty, then the jiffies update is still serialized by
++	 * xtime_lock.
++	 */
++	if (unlikely(tick_do_timer_cpu == -1))
++		tick_do_timer_cpu = cpu;
++
+ 	/* Check, if the jiffies need an update */
+-	tick_do_update_jiffies64(now);
++	if (tick_do_timer_cpu == cpu)
++		tick_do_update_jiffies64(now);
+ 
+ 	/*
+ 	 * When we are idle and the tick is stopped, we have to touch
+@@ -431,9 +455,23 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
+ 	struct hrtimer_cpu_base *base = timer->base->cpu_base;
+ 	struct pt_regs *regs = get_irq_regs();
+ 	ktime_t now = ktime_get();
++	int cpu = smp_processor_id();
++
++#ifdef CONFIG_NO_HZ
++	/*
++	 * Check if the do_timer duty was dropped. We don't care about
++	 * concurrency: This happens only when the cpu in charge went
++	 * into a long sleep. If two cpus happen to assign themself to
++	 * this duty, then the jiffies update is still serialized by
++	 * xtime_lock.
++	 */
++	if (unlikely(tick_do_timer_cpu == -1))
++		tick_do_timer_cpu = cpu;
++#endif
+ 
+ 	/* Check, if the jiffies need an update */
+-	tick_do_update_jiffies64(now);
++	if (tick_do_timer_cpu == cpu)
++		tick_do_update_jiffies64(now);
+ 
+ 	/*
+ 	 * Do not call, when we are not in irq context and have
+diff --git a/kernel/timer.c b/kernel/timer.c
+index dd6c2c1..e045774 100644
+--- a/kernel/timer.c
++++ b/kernel/timer.c
+@@ -1903,6 +1903,8 @@ unregister_time_interpolator(struct time_interpolator *ti)
+ 		prev = &curr->next;
+ 	}
+ 
++	clocksource_resume();
++
+ 	write_seqlock_irqsave(&xtime_lock, flags);
+ 	if (ti == time_interpolator) {
+ 		/* we lost the best time-interpolator: */
+diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
+index fceb97c..7e1e311 100644
+--- a/lib/zlib_inflate/inflate.c
++++ b/lib/zlib_inflate/inflate.c
+@@ -743,12 +743,14 @@ int zlib_inflate(z_streamp strm, int flush)
+ 
+     strm->data_type = state->bits + (state->last ? 64 : 0) +
+                       (state->mode == TYPE ? 128 : 0);
+-    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+-        ret = Z_BUF_ERROR;
+ 
+     if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
+-            (strm->avail_out != 0 || strm->avail_in == 0))
++            strm->avail_out != 0 && strm->avail_in == 0)
+ 		return zlib_inflateSyncPacket(strm);
++
++    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
++        ret = Z_BUF_ERROR;
++
+     return ret;
+ }
+ 
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 36db012..88e708b 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -140,6 +140,8 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
+ 	return page;
+ 
+ fail:
++	if (vma->vm_flags & VM_MAYSHARE)
++		resv_huge_pages++;
+ 	spin_unlock(&hugetlb_lock);
+ 	return NULL;
+ }
+diff --git a/mm/oom_kill.c b/mm/oom_kill.c
+index 3791edf..b3a3dd6 100644
+--- a/mm/oom_kill.c
++++ b/mm/oom_kill.c
+@@ -397,6 +397,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
+ 	struct task_struct *p;
+ 	unsigned long points = 0;
+ 	unsigned long freed = 0;
++	int constraint;
+ 
+ 	blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
+ 	if (freed > 0)
+@@ -411,14 +412,15 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
+ 		show_mem();
+ 	}
+ 
+-	cpuset_lock();
+-	read_lock(&tasklist_lock);
+-
+ 	/*
+ 	 * Check if there were limitations on the allocation (only relevant for
+ 	 * NUMA) that may require different handling.
+ 	 */
+-	switch (constrained_alloc(zonelist, gfp_mask)) {
++	constraint = constrained_alloc(zonelist, gfp_mask);
++	cpuset_lock();
++	read_lock(&tasklist_lock);
++
++	switch (constraint) {
+ 	case CONSTRAINT_MEMORY_POLICY:
+ 		oom_kill_process(current, points,
+ 				"No available memory (MPOL_BIND)");
+diff --git a/mm/slob.c b/mm/slob.c
+index 5adc29c..c683d35 100644
+--- a/mm/slob.c
++++ b/mm/slob.c
+@@ -150,15 +150,6 @@ static void slob_free(void *block, int size)
+ 	spin_unlock_irqrestore(&slob_lock, flags);
+ }
+ 
+-static int FASTCALL(find_order(int size));
+-static int fastcall find_order(int size)
+-{
+-	int order = 0;
+-	for ( ; size > 4096 ; size >>=1)
+-		order++;
+-	return order;
+-}
+-
+ void *__kmalloc(size_t size, gfp_t gfp)
+ {
+ 	slob_t *m;
+@@ -174,7 +165,7 @@ void *__kmalloc(size_t size, gfp_t gfp)
+ 	if (!bb)
+ 		return 0;
+ 
+-	bb->order = find_order(size);
++	bb->order = get_order(size);
+ 	bb->pages = (void *)__get_free_pages(gfp, bb->order);
+ 
+ 	if (bb->pages) {
+@@ -284,7 +275,7 @@ void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
+ 	if (c->size < PAGE_SIZE)
+ 		b = slob_alloc(c->size, flags, c->align);
+ 	else
+-		b = (void *)__get_free_pages(flags, find_order(c->size));
++		b = (void *)__get_free_pages(flags, get_order(c->size));
+ 
+ 	if (c->ctor)
+ 		c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR);
+@@ -311,7 +302,7 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
+ 	if (c->size < PAGE_SIZE)
+ 		slob_free(b, c->size);
+ 	else
+-		free_pages((unsigned long)b, find_order(c->size));
++		free_pages((unsigned long)b, get_order(c->size));
+ }
+ EXPORT_SYMBOL(kmem_cache_free);
+ 
+diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+index 23b99ae..75bd597 100644
+--- a/net/ipv4/netfilter/ip_conntrack_core.c
++++ b/net/ipv4/netfilter/ip_conntrack_core.c
+@@ -302,7 +302,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
+ {
+ 	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
+ 	struct ip_conntrack_protocol *proto;
+-	struct ip_conntrack_helper *helper;
+ 	typeof(ip_conntrack_destroyed) destroyed;
+ 
+ 	DEBUGP("destroy_conntrack(%p)\n", ct);
+@@ -312,10 +311,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
+ 	ip_conntrack_event(IPCT_DESTROY, ct);
+ 	set_bit(IPS_DYING_BIT, &ct->status);
+ 
+-	helper = ct->helper;
+-	if (helper && helper->destroy)
+-		helper->destroy(ct);
+-
+ 	/* To make sure we don't get any weird locking issues here:
+ 	 * destroy_conntrack() MUST NOT be called with a write lock
+ 	 * to ip_conntrack_lock!!! -HW */
+@@ -356,6 +351,11 @@ destroy_conntrack(struct nf_conntrack *nfct)
+ static void death_by_timeout(unsigned long ul_conntrack)
+ {
+ 	struct ip_conntrack *ct = (void *)ul_conntrack;
++	struct ip_conntrack_helper *helper;
++
++	helper = ct->helper;
++	if (helper && helper->destroy)
++		helper->destroy(ct);
+ 
+ 	write_lock_bh(&ip_conntrack_lock);
+ 	/* Inside lock so preempt is disabled on module removal path.
+diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
+index 9581020..e3146a3 100644
+--- a/net/ipv4/netfilter/ip_nat_proto_gre.c
++++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
+@@ -70,6 +70,11 @@ gre_unique_tuple(struct ip_conntrack_tuple *tuple,
+ 	__be16 *keyptr;
+ 	unsigned int min, i, range_size;
+ 
++	/* If there is no master conntrack we are not PPTP,
++	   do not change tuples */
++	if (!conntrack->master)
++		return 0;
++		
+ 	if (maniptype == IP_NAT_MANIP_SRC)
+ 		keyptr = &tuple->src.u.gre.key;
+ 	else
+@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb,
+ 	if (maniptype == IP_NAT_MANIP_DST) {
+ 		/* key manipulation is always dest */
+ 		switch (greh->version) {
+-		case 0:
+-			if (!greh->key) {
+-				DEBUGP("can't nat GRE w/o key\n");
+-				break;
+-			}
+-			if (greh->csum) {
+-				/* FIXME: Never tested this code... */
+-				nf_proto_csum_replace4(gre_csum(greh), *pskb,
+-							*(gre_key(greh)),
+-							tuple->dst.u.gre.key, 0);
+-			}
+-			*(gre_key(greh)) = tuple->dst.u.gre.key;
++		case GRE_VERSION_1701:
++			/* We do not currently NAT any GREv0 packets.
++			 * Try to behave like "ip_nat_proto_unknown" */
+ 			break;
+ 		case GRE_VERSION_PPTP:
+ 			DEBUGP("call_id -> 0x%04x\n",
+diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
+index e5a34c1..ca3ff84 100644
+--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
++++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
+@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
+ 	__be16 *keyptr;
+ 	unsigned int min, i, range_size;
+ 
++	/* If there is no master conntrack we are not PPTP,
++	   do not change tuples */
++	if (!conntrack->master)
++		return 0;
++		
+ 	if (maniptype == IP_NAT_MANIP_SRC)
+ 		keyptr = &tuple->src.u.gre.key;
+ 	else
+@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
+ 	if (maniptype != IP_NAT_MANIP_DST)
+ 		return 1;
+ 	switch (greh->version) {
+-	case 0:
+-		if (!greh->key) {
+-			DEBUGP("can't nat GRE w/o key\n");
+-			break;
+-		}
+-		if (greh->csum) {
+-			/* FIXME: Never tested this code... */
+-			nf_proto_csum_replace4(gre_csum(greh), *pskb,
+-					       *(gre_key(greh)),
+-					       tuple->dst.u.gre.key, 0);
+-		}
+-		*(gre_key(greh)) = tuple->dst.u.gre.key;
++	case GRE_VERSION_1701:
++		/* We do not currently NAT any GREv0 packets.
++		 * Try to behave like "nf_nat_proto_unknown" */
+ 		break;
+ 	case GRE_VERSION_PPTP:
+ 		DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 3834b10..824c6b9 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1759,8 +1759,7 @@ int tcp_disconnect(struct sock *sk, int flags)
+ 	tcp_clear_retrans(tp);
+ 	inet_csk_delack_init(sk);
+ 	sk->sk_send_head = NULL;
+-	tp->rx_opt.saw_tstamp = 0;
+-	tcp_sack_reset(&tp->rx_opt);
++	memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
+ 	__sk_dst_reset(sk);
+ 
+ 	BUG_TRAP(!inet->num || icsk->icsk_bind_hash);
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 452a82c..a541137 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -2281,8 +2281,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
+ 		break;
+ 
+ 	case NETDEV_CHANGENAME:
+-#ifdef CONFIG_SYSCTL
+ 		if (idev) {
++			snmp6_unregister_dev(idev);
++#ifdef CONFIG_SYSCTL
+ 			addrconf_sysctl_unregister(&idev->cnf);
+ 			neigh_sysctl_unregister(idev->nd_parms);
+ 			neigh_sysctl_register(dev, idev->nd_parms,
+@@ -2290,8 +2291,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
+ 					      &ndisc_ifinfo_sysctl_change,
+ 					      NULL);
+ 			addrconf_sysctl_register(idev, &idev->cnf);
+-		}
+ #endif
++			snmp6_register_dev(idev);
++		}
+ 		break;
+ 	};
+ 
+@@ -4060,6 +4062,10 @@ int __init addrconf_init(void)
+ 		return err;
+ 
+ 	ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
++#ifdef CONFIG_IPV6_MULTIPLE_TABLES
++	ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
++	ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
++#endif
+ 
+ 	register_netdevice_notifier(&ipv6_dev_notf);
+ 
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 3205ec9..794b930 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -652,6 +652,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
+   Hop-by-hop options.
+  **********************************/
+ 
++/*
++ * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
++ */
++static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
++{
++	return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
++}
++
+ /* Router Alert as of RFC 2711 */
+ 
+ static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
+@@ -678,25 +686,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
+ 	if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
+ 		LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
+ 			       skb->nh.raw[optoff+1]);
+-		IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
++		IP6_INC_STATS_BH(ipv6_skb_idev(skb),
+ 				 IPSTATS_MIB_INHDRERRORS);
+ 		goto drop;
+ 	}
+ 
+ 	pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
+ 	if (pkt_len <= IPV6_MAXPLEN) {
+-		IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
++		IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
+ 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
+ 		return 0;
+ 	}
+ 	if (skb->nh.ipv6h->payload_len) {
+-		IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
++		IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
+ 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
+ 		return 0;
+ 	}
+ 
+ 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
+-		IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
++		IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS);
+ 		goto drop;
+ 	}
+ 
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index 61e7a6c..1b34ee5 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb)
+ 	IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
+ 
+ 	hdr = skb->nh.ipv6h;
+-	deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
++	deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) ||
+ 	    ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
+ 
+ 	/*
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 3055169..9fa3ffb 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -449,10 +449,17 @@ int ip6_forward(struct sk_buff *skb)
+ 		 */
+ 		if (xrlim_allow(dst, 1*HZ))
+ 			ndisc_send_redirect(skb, n, target);
+-	} else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
+-						|IPV6_ADDR_LINKLOCAL)) {
++	} else {
++		int addrtype = ipv6_addr_type(&hdr->saddr);
++
+ 		/* This check is security critical. */
+-		goto error;
++		if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK))
++			goto error;
++		if (addrtype & IPV6_ADDR_LINKLOCAL) {
++			icmpv6_send(skb, ICMPV6_DEST_UNREACH,
++				ICMPV6_NOT_NEIGHBOUR, 0, skb->dev);
++			goto error;
++		}
+ 	}
+ 
+ 	if (skb->len > dst_mtu(dst)) {
+diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
+index fa3fb50..d57853d 100644
+--- a/net/ipv6/proc.c
++++ b/net/ipv6/proc.c
+@@ -236,6 +236,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
+ 		return -EINVAL;
+ 	remove_proc_entry(idev->stats.proc_dir_entry->name,
+ 			  proc_net_devsnmp6);
++	idev->stats.proc_dir_entry = NULL;
+ 	return 0;
+ }
+ 
+diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
+index 93c4223..dff33cc 100644
+--- a/net/ipv6/xfrm6_tunnel.c
++++ b/net/ipv6/xfrm6_tunnel.c
+@@ -261,7 +261,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
+ 	__be32 spi;
+ 
+ 	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
+-	return xfrm6_rcv_spi(skb, spi);
++	return xfrm6_rcv_spi(skb, spi) > 0 ? : 0;
+ }
+ 
+ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index b3a70eb..ce28fdd 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -315,7 +315,6 @@ static void
+ destroy_conntrack(struct nf_conntrack *nfct)
+ {
+ 	struct nf_conn *ct = (struct nf_conn *)nfct;
+-	struct nf_conn_help *help = nfct_help(ct);
+ 	struct nf_conntrack_l3proto *l3proto;
+ 	struct nf_conntrack_l4proto *l4proto;
+ 	typeof(nf_conntrack_destroyed) destroyed;
+@@ -327,9 +326,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
+ 	nf_conntrack_event(IPCT_DESTROY, ct);
+ 	set_bit(IPS_DYING_BIT, &ct->status);
+ 
+-	if (help && help->helper && help->helper->destroy)
+-		help->helper->destroy(ct);
+-
+ 	/* To make sure we don't get any weird locking issues here:
+ 	 * destroy_conntrack() MUST NOT be called with a write lock
+ 	 * to nf_conntrack_lock!!! -HW */
+@@ -375,6 +371,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
+ static void death_by_timeout(unsigned long ul_conntrack)
+ {
+ 	struct nf_conn *ct = (void *)ul_conntrack;
++	struct nf_conn_help *help = nfct_help(ct);
++
++	if (help && help->helper && help->helper->destroy)
++		help->helper->destroy(ct);
+ 
+ 	write_lock_bh(&nf_conntrack_lock);
+ 	/* Inside lock so preempt is disabled on module removal path.
+diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
+index de889f2..a86f36b 100644
+--- a/net/sched/sch_prio.c
++++ b/net/sched/sch_prio.c
+@@ -74,7 +74,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ 		band = res.classid;
+ 	}
+ 	band = TC_H_MIN(band) - 1;
+-	if (band > q->bands)
++	if (band >= q->bands)
+ 		return q->queues[q->prio2band[0]];
+ 
+ 	return q->queues[band];
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index a1d026f..843c928 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -3847,7 +3847,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+ 		memcpy(&temp, &from->ipaddr, sizeof(temp));
+ 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+ 		addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+-		if(space_left < addrlen)
++		if (space_left < addrlen)
+ 			return -ENOMEM;
+ 		if (copy_to_user(to, &temp, addrlen))
+ 			return -EFAULT;
+@@ -3936,8 +3936,9 @@ done:
+ /* Helper function that copies local addresses to user and returns the number
+  * of addresses copied.
+  */
+-static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs,
+-					void __user *to)
++static int sctp_copy_laddrs_old(struct sock *sk, __u16 port,
++					int max_addrs, void *to,
++					int *bytes_copied)
+ {
+ 	struct list_head *pos, *next;
+ 	struct sctp_sockaddr_entry *addr;
+@@ -3954,10 +3955,10 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
+ 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+ 								&temp);
+ 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+-		if (copy_to_user(to, &temp, addrlen))
+-			return -EFAULT;
++		memcpy(to, &temp, addrlen);
+ 
+ 		to += addrlen;
++		*bytes_copied += addrlen;
+ 		cnt ++;
+ 		if (cnt >= max_addrs) break;
+ 	}
+@@ -3965,8 +3966,8 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
+ 	return cnt;
+ }
+ 
+-static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
+-				    void __user **to, size_t space_left)
++static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
++			    size_t space_left, int *bytes_copied)
+ {
+ 	struct list_head *pos, *next;
+ 	struct sctp_sockaddr_entry *addr;
+@@ -3983,14 +3984,14 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
+ 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+ 								&temp);
+ 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+-		if(space_left<addrlen)
++		if (space_left < addrlen)
+ 			return -ENOMEM;
+-		if (copy_to_user(*to, &temp, addrlen))
+-			return -EFAULT;
++		memcpy(to, &temp, addrlen);
+ 
+-		*to += addrlen;
++		to += addrlen;
+ 		cnt ++;
+ 		space_left -= addrlen;
++		bytes_copied += addrlen;
+ 	}
+ 
+ 	return cnt;
+@@ -4014,6 +4015,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
+ 	int addrlen;
+ 	rwlock_t *addr_lock;
+ 	int err = 0;
++	void *addrs;
++	void *buf;
++	int bytes_copied = 0;
+ 
+ 	if (len != sizeof(struct sctp_getaddrs_old))
+ 		return -EINVAL;
+@@ -4041,6 +4045,15 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
+ 
+ 	to = getaddrs.addrs;
+ 
++	/* Allocate space for a local instance of packed array to hold all
++	 * the data.  We store addresses here first and then put write them
++	 * to the user in one shot.
++	 */
++	addrs = kmalloc(sizeof(union sctp_addr) * getaddrs.addr_num,
++			GFP_KERNEL);
++	if (!addrs)
++		return -ENOMEM;
++
+ 	sctp_read_lock(addr_lock);
+ 
+ 	/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+@@ -4050,38 +4063,42 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
+ 		addr = list_entry(bp->address_list.next,
+ 				  struct sctp_sockaddr_entry, list);
+ 		if (sctp_is_any(&addr->a)) {
+-			cnt = sctp_copy_laddrs_to_user_old(sk, bp->port,
+-							   getaddrs.addr_num,
+-							   to);
+-			if (cnt < 0) {
+-				err = cnt;
+-				goto unlock;
+-			}
++			cnt = sctp_copy_laddrs_old(sk, bp->port,
++						   getaddrs.addr_num,
++						   addrs, &bytes_copied);
+ 			goto copy_getaddrs;
+ 		}
+ 	}
+ 
++	buf = addrs;
+ 	list_for_each(pos, &bp->address_list) {
+ 		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ 		memcpy(&temp, &addr->a, sizeof(temp));
+ 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+ 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+-		if (copy_to_user(to, &temp, addrlen)) {
+-			err = -EFAULT;
+-			goto unlock;
+-		}
+-		to += addrlen;
++		memcpy(buf, &temp, addrlen);
++		buf += addrlen;
++		bytes_copied += addrlen;
+ 		cnt ++;
+ 		if (cnt >= getaddrs.addr_num) break;
+ 	}
+ 
+ copy_getaddrs:
++	sctp_read_unlock(addr_lock);
++
++	/* copy the entire address list into the user provided space */
++	if (copy_to_user(to, addrs, bytes_copied)) {
++		err = -EFAULT;
++		goto error;
++	}
++
++	/* copy the leading structure back to user */
+ 	getaddrs.addr_num = cnt;
+ 	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old)))
+ 		err = -EFAULT;
+ 
+-unlock:
+-	sctp_read_unlock(addr_lock);
++error:
++	kfree(addrs);
+ 	return err;
+ }
+ 
+@@ -4101,7 +4118,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+ 	rwlock_t *addr_lock;
+ 	int err = 0;
+ 	size_t space_left;
+-	int bytes_copied;
++	int bytes_copied = 0;
++	void *addrs;
++	void *buf;
+ 
+ 	if (len <= sizeof(struct sctp_getaddrs))
+ 		return -EINVAL;
+@@ -4129,6 +4148,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+ 	to = optval + offsetof(struct sctp_getaddrs,addrs);
+ 	space_left = len - sizeof(struct sctp_getaddrs) -
+ 			 offsetof(struct sctp_getaddrs,addrs);
++	addrs = kmalloc(space_left, GFP_KERNEL);
++	if (!addrs)
++		return -ENOMEM;
+ 
+ 	sctp_read_lock(addr_lock);
+ 
+@@ -4139,41 +4161,47 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+ 		addr = list_entry(bp->address_list.next,
+ 				  struct sctp_sockaddr_entry, list);
+ 		if (sctp_is_any(&addr->a)) {
+-			cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+-						       &to, space_left);
++			cnt = sctp_copy_laddrs(sk, bp->port, addrs,
++						space_left, &bytes_copied);
+ 			if (cnt < 0) {
+ 				err = cnt;
+-				goto unlock;
++				goto error;
+ 			}
+ 			goto copy_getaddrs;
+ 		}
+ 	}
+ 
++	buf = addrs;
+ 	list_for_each(pos, &bp->address_list) {
+ 		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ 		memcpy(&temp, &addr->a, sizeof(temp));
+ 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+ 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+-		if(space_left < addrlen)
+-			return -ENOMEM; /*fixme: right error?*/
+-		if (copy_to_user(to, &temp, addrlen)) {
+-			err = -EFAULT;
+-			goto unlock;
++		if (space_left < addrlen) {
++			err =  -ENOMEM; /*fixme: right error?*/
++			goto error;
+ 		}
+-		to += addrlen;
++		memcpy(buf, &temp, addrlen);
++		buf += addrlen;
++		bytes_copied += addrlen;
+ 		cnt ++;
+ 		space_left -= addrlen;
+ 	}
+ 
+ copy_getaddrs:
++	sctp_read_unlock(addr_lock);
++
++	if (copy_to_user(to, addrs, bytes_copied)) {
++		err = -EFAULT;
++		goto error;
++	}
+ 	if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
+ 		return -EFAULT;
+-	bytes_copied = ((char __user *)to) - optval;
+ 	if (put_user(bytes_copied, optlen))
+ 		return -EFAULT;
+ 
+-unlock:
+-	sctp_read_unlock(addr_lock);
++error:
++	kfree(addrs);
+ 	return err;
+ }
+ 
+@@ -4961,7 +4989,12 @@ int sctp_inet_listen(struct socket *sock, int backlog)
+ 	/* Allocate HMAC for generating cookie. */
+ 	if (sctp_hmac_alg) {
+ 		tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
+-		if (!tfm) {
++		if (IS_ERR(tfm)) {
++			if (net_ratelimit()) {
++				printk(KERN_INFO
++				       "SCTP: failed to load transform for %s: %ld\n",
++					sctp_hmac_alg, PTR_ERR(tfm));
++			}
+ 			err = -ENOSYS;
+ 			goto out;
+ 		}
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index db298b5..c678f5f 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -1196,13 +1196,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
+ 	if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset,
+ 				integ_len))
+ 		BUG();
+-	if (resbuf->page_len == 0
+-			&& resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE
+-			< PAGE_SIZE) {
+-		BUG_ON(resbuf->tail[0].iov_len);
+-		/* Use head for everything */
+-		resv = &resbuf->head[0];
+-	} else if (resbuf->tail[0].iov_base == NULL) {
++	if (resbuf->tail[0].iov_base == NULL) {
+ 		if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE)
+ 			goto out_err;
+ 		resbuf->tail[0].iov_base = resbuf->head[0].iov_base
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 785c3e3..ba89293 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -782,6 +782,10 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
+ 	struct hlist_head *chain;
+ 	struct hlist_node *entry;
+ 
++	*err = -ENOENT;
++	if (xfrm_policy_id2dir(id) != dir)
++		return NULL;
++
+ 	*err = 0;
+ 	write_lock_bh(&xfrm_policy_lock);
+ 	chain = xfrm_policy_byidx + idx_hash(id);
+diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
+index 6bc7e7c..8912c0f 100644
+--- a/scripts/basic/fixdep.c
++++ b/scripts/basic/fixdep.c
+@@ -249,6 +249,8 @@ void parse_config_file(char *map, size_t len)
+ 	found:
+ 		if (!memcmp(q - 7, "_MODULE", 7))
+ 			q -= 7;
++		if( (q-p-7) < 0 )
++			continue;
+ 		use_config(p+7, q-p-7);
+ 	}
+ }
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index c94291b..a6f8992 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -1751,6 +1751,7 @@ static int stac92xx_resume(struct hda_codec *codec)
+ 
+ 	stac92xx_init(codec);
+ 	stac92xx_set_config_regs(codec);
++	snd_hda_resume_ctls(codec, spec->mixer);
+ 	for (i = 0; i < spec->num_mixers; i++)
+ 		snd_hda_resume_ctls(codec, spec->mixers[i]);
+ 	if (spec->multiout.dig_out_nid)

Modified: dists/sid/linux-2.6/debian/patches/series/3
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/3	(original)
+++ dists/sid/linux-2.6/debian/patches/series/3	Thu May 24 12:14:17 2007
@@ -1,2 +1,3 @@
 + features/arm/nslu2-freq-fixup.patch
 + bugfix/2.6.21.1
++ bugfix/2.6.21.2



More information about the Kernel-svn-changes mailing list