[kernel] r14422 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all/stable patches/series

Ben Hutchings benh at alioth.debian.org
Fri Oct 23 01:13:43 UTC 2009


Author: benh
Date: Fri Oct 23 01:13:40 2009
New Revision: 14422

Log:
Add stable release 2.6.31.5

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.5.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/base

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Thu Oct 22 22:46:05 2009	(r14421)
+++ dists/trunk/linux-2.6/debian/changelog	Fri Oct 23 01:13:40 2009	(r14422)
@@ -3,6 +3,7 @@
   [ Ben Hutchings ]
   * Include aufs2, marked as staging (Closes: #541828)
   * Include speakup modules under staging
+  * Add stable release 2.6.31.5
 
   [ Martin Michlmayr ]
   * CPUidle: always return with interrupts enabled.

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.5.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.5.patch	Fri Oct 23 01:13:40 2009	(r14422)
@@ -0,0 +1,2585 @@
+diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
+index 6a5be5d..473c589 100644
+--- a/Documentation/connector/cn_test.c
++++ b/Documentation/connector/cn_test.c
+@@ -32,10 +32,8 @@ static char cn_test_name[] = "cn_test";
+ static struct sock *nls;
+ static struct timer_list cn_test_timer;
+ 
+-void cn_test_callback(void *data)
++static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = (struct cn_msg *)data;
+-
+ 	printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
+ 	       __func__, jiffies, msg->id.idx, msg->id.val,
+ 	       msg->seq, msg->ack, msg->len, (char *)msg->data);
+diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
+index ad6e0ba..3e6dcc7 100644
+--- a/Documentation/connector/connector.txt
++++ b/Documentation/connector/connector.txt
+@@ -23,7 +23,7 @@ handling...  Connector allows any kernelspace agents to use netlink
+ based networking for inter-process communication in a significantly
+ easier way:
+ 
+-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
++int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
+ void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);
+ 
+ struct cb_id
+@@ -53,15 +53,15 @@ struct cn_msg
+ Connector interfaces.
+ /*****************************************/
+ 
+-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
++int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
+ 
+ Registers new callback with connector core.
+ 
+ struct cb_id *id 		- unique connector's user identifier.
+ 			  	  It must be registered in connector.h for legal in-kernel users.
+ char *name 			- connector's callback symbolic name.
+-void (*callback) (void *)	- connector's callback.
+-				  Argument must be dereferenced to struct cn_msg *.
++void (*callback) (struct cn..)	- connector's callback.
++				  cn_msg and the sender's credentials
+ 
+ void cn_del_callback(struct cb_id *id);
+ 
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 2ccc21c..94138c4 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1992,7 +1992,7 @@ S:	Maintained
+ F:	fs/*
+ 
+ FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+-M:	Riku Voipio <riku.vipio at iki.fi>
++M:	Riku Voipio <riku.voipio at iki.fi>
+ L:	lm-sensors at lm-sensors.org
+ S:	Maintained
+ F:	drivers/hwmon/f75375s.c
+diff --git a/Makefile b/Makefile
+index 314a3aa..8190a1c 100644
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index c877d6d..41edaf2 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -14,7 +14,7 @@ LDFLAGS_vmlinux	:=-p --no-undefined -X
+ ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+ LDFLAGS_vmlinux	+= --be8
+ endif
+-CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
++
+ OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
+ GZFLAGS		:=-9
+ #KBUILD_CFLAGS	+=-pipe
+diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
+index ff89d0b..60be28d 100644
+--- a/arch/arm/kernel/Makefile
++++ b/arch/arm/kernel/Makefile
+@@ -2,7 +2,8 @@
+ # Makefile for the linux kernel.
+ #
+ 
+-AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
++CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
++AFLAGS_head.o        := -DTEXT_OFFSET=$(TEXT_OFFSET)
+ 
+ ifdef CONFIG_DYNAMIC_FTRACE
+ CFLAGS_REMOVE_ftrace.o = -pg
+diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+index 3a8ee22..983cc8c 100644
+--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
++++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+@@ -155,7 +155,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
+ 
+ static pxa_freqs_t pxa27x_freqs[] = {
+ 	{104000, 104000, PXA27x_CCCR(1,	 8, 2), 0, CCLKCFG2(1, 0, 1),  900000, 1705000 },
+-	{156000, 104000, PXA27x_CCCR(1,	 8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 },
++	{156000, 104000, PXA27x_CCCR(1,	 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
+ 	{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
+ 	{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
+ 	{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
+diff --git a/arch/cris/Makefile b/arch/cris/Makefile
+index 71e17d3..29c2ceb 100644
+--- a/arch/cris/Makefile
++++ b/arch/cris/Makefile
+@@ -42,8 +42,6 @@ LD = $(CROSS_COMPILE)ld -mcrislinux
+ 
+ OBJCOPYFLAGS := -O binary -R .note -R .comment -S
+ 
+-CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
+-
+ KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc)
+ KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc)
+ KBUILD_CPPFLAGS += $(inc)
+diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
+index ee7bcd4..b45640b 100644
+--- a/arch/cris/kernel/Makefile
++++ b/arch/cris/kernel/Makefile
+@@ -3,6 +3,7 @@
+ # Makefile for the linux kernel.
+ #
+ 
++CPPFLAGS_vmlinux.lds := -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
+ extra-y	:= vmlinux.lds
+ 
+ obj-y   := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o
+diff --git a/arch/mips/Makefile b/arch/mips/Makefile
+index 861da51..7d651d5 100644
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -615,16 +615,6 @@ endif
+ cflags-y			+= -I$(srctree)/arch/mips/include/asm/mach-generic
+ drivers-$(CONFIG_PCI)		+= arch/mips/pci/
+ 
+-ifdef CONFIG_32BIT
+-ifdef CONFIG_CPU_LITTLE_ENDIAN
+-JIFFIES			= jiffies_64
+-else
+-JIFFIES			= jiffies_64 + 4
+-endif
+-else
+-JIFFIES			= jiffies_64
+-endif
+-
+ #
+ # Automatically detect the build format. By default we choose
+ # the elf format according to the load address.
+@@ -648,8 +638,9 @@ ifdef CONFIG_64BIT
+ endif
+ 
+ KBUILD_AFLAGS	+= $(cflags-y)
+-KBUILD_CFLAGS	+= $(cflags-y) \
+-			-D"VMLINUX_LOAD_ADDRESS=$(load-y)"
++KBUILD_CFLAGS	+= $(cflags-y)
++KBUILD_CPPFLAGS += -D"VMLINUX_LOAD_ADDRESS=$(load-y)"
++KBUILD_CPPFLAGS += -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)"
+ 
+ LDFLAGS			+= -m $(ld-emul)
+ 
+@@ -664,18 +655,6 @@ endif
+ 
+ OBJCOPYFLAGS		+= --remove-section=.reginfo
+ 
+-#
+-# Choosing incompatible machines durings configuration will result in
+-# error messages during linking.  Select a default linkscript if
+-# none has been choosen above.
+-#
+-
+-CPPFLAGS_vmlinux.lds := \
+-	$(KBUILD_CFLAGS) \
+-	-D"LOADADDR=$(load-y)" \
+-	-D"JIFFIES=$(JIFFIES)" \
+-	-D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)"
+-
+ head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
+ 
+ libs-y			+= arch/mips/lib/
+diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
+index 58738c8..576f8fb 100644
+--- a/arch/mips/kernel/vmlinux.lds.S
++++ b/arch/mips/kernel/vmlinux.lds.S
+@@ -9,7 +9,16 @@ PHDRS {
+ 	text PT_LOAD FLAGS(7);	/* RWX */
+ 	note PT_NOTE FLAGS(4);	/* R__ */
+ }
+-jiffies = JIFFIES;
++
++ifdef CONFIG_32BIT
++	ifdef CONFIG_CPU_LITTLE_ENDIAN
++		jiffies  = jiffies_64;
++	else
++		jiffies  = jiffies_64 + 4;
++	endif
++else
++	jiffies  = jiffies_64;
++endif
+ 
+ SECTIONS
+ {
+@@ -28,7 +37,7 @@ SECTIONS
+ 	/* . = 0xa800000000300000; */
+ 	. = 0xffffffff80300000;
+ #endif
+-	. = LOADADDR;
++	. = VMLINUX_LOAD_ADDRESS;
+ 	/* read-only */
+ 	_text = .;	/* Text and read-only data */
+ 	.text : {
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index bc35f4e..39d44f7 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -158,8 +158,6 @@ drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
+ # Default to zImage, override when needed
+ all: zImage
+ 
+-CPPFLAGS_vmlinux.lds	:= -Upowerpc
+-
+ BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
+ 
+ PHONY += $(BOOT_TARGETS)
+diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
+index 2003ded..6c21179 100644
+--- a/arch/sparc/Makefile
++++ b/arch/sparc/Makefile
+@@ -31,7 +31,6 @@ export BITS    := 32
+ #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
+ KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+ KBUILD_AFLAGS += -m32
+-CPPFLAGS_vmlinux.lds += -m32
+ 
+ #LDFLAGS_vmlinux = -N -Ttext 0xf0004000
+ #  Since 2.5.40, the first stage is left not btfix-ed.
+@@ -49,9 +48,6 @@ else
+ 
+ CHECKFLAGS      += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
+ 
+-# Undefine sparc when processing vmlinux.lds - it is used
+-# And teach CPP we are doing 64 bit builds (for this case)
+-CPPFLAGS_vmlinux.lds += -m64 -Usparc
+ LDFLAGS              := -m elf64_sparc
+ export BITS          := 64
+ 
+diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
+index 475ce46..cbf5d0b 100644
+--- a/arch/sparc/kernel/Makefile
++++ b/arch/sparc/kernel/Makefile
+@@ -7,7 +7,11 @@ ccflags-y := -Werror
+ 
+ extra-y     := head_$(BITS).o
+ extra-y     += init_task.o
+-extra-y     += vmlinux.lds
++
++# Undefine sparc when processing vmlinux.lds - it is used
++# And teach CPP we are doing $(BITS) builds (for this case)
++CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
++extra-y              += vmlinux.lds
+ 
+ obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
+ obj-$(CONFIG_SPARC32)   += etrap_32.o
+diff --git a/arch/um/Makefile b/arch/um/Makefile
+index 0728def..fc633db 100644
+--- a/arch/um/Makefile
++++ b/arch/um/Makefile
+@@ -96,11 +96,10 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,)
+ 	$(call cc-option, -fno-stack-protector,) \
+ 	$(call cc-option, -fno-stack-protector-all,)
+ 
+-CONFIG_KERNEL_STACK_ORDER ?= 2
+-STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
+-
+-CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
+-	-DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)
++# Options used by linker script
++export LDS_START      := $(START)
++export LDS_ELF_ARCH   := $(ELF_ARCH)
++export LDS_ELF_FORMAT := $(ELF_FORMAT)
+ 
+ # The wrappers will select whether using "malloc" or the kernel allocator.
+ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
+index 388ec0a..1119233 100644
+--- a/arch/um/kernel/Makefile
++++ b/arch/um/kernel/Makefile
+@@ -3,6 +3,9 @@
+ # Licensed under the GPL
+ #
+ 
++CPPFLAGS_vmlinux.lds := -U$(SUBARCH) -DSTART=$(LDS_START) \
++                        -DELF_ARCH=$(LDS_ELF_ARCH)        \
++                        -DELF_FORMAT=$(LDS_ELF_FORMAT)
+ extra-y := vmlinux.lds
+ clean-files :=
+ 
+diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
+index f8aeb44..16e49bf 100644
+--- a/arch/um/kernel/vmlinux.lds.S
++++ b/arch/um/kernel/vmlinux.lds.S
+@@ -1,3 +1,6 @@
++
++KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER);
++
+ #ifdef CONFIG_LD_SCRIPT_STATIC
+ #include "uml.lds.S"
+ #else
+diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
+index 4fb37c8..43b8adb 100644
+--- a/arch/x86/include/asm/paravirt.h
++++ b/arch/x86/include/asm/paravirt.h
+@@ -528,10 +528,11 @@ int paravirt_disable_iospace(void);
+ #define EXTRA_CLOBBERS
+ #define VEXTRA_CLOBBERS
+ #else  /* CONFIG_X86_64 */
++/* [re]ax isn't an arg, but the return val */
+ #define PVOP_VCALL_ARGS					\
+ 	unsigned long __edi = __edi, __esi = __esi,	\
+-		__edx = __edx, __ecx = __ecx
+-#define PVOP_CALL_ARGS		PVOP_VCALL_ARGS, __eax
++		__edx = __edx, __ecx = __ecx, __eax = __eax
++#define PVOP_CALL_ARGS		PVOP_VCALL_ARGS
+ 
+ #define PVOP_CALL_ARG1(x)		"D" ((unsigned long)(x))
+ #define PVOP_CALL_ARG2(x)		"S" ((unsigned long)(x))
+@@ -543,6 +544,7 @@ int paravirt_disable_iospace(void);
+ 				"=c" (__ecx)
+ #define PVOP_CALL_CLOBBERS	PVOP_VCALL_CLOBBERS, "=a" (__eax)
+ 
++/* void functions are still allowed [re]ax for scratch */
+ #define PVOP_VCALLEE_CLOBBERS	"=a" (__eax)
+ #define PVOP_CALLEE_CLOBBERS	PVOP_VCALLEE_CLOBBERS
+ 
+@@ -617,8 +619,8 @@ int paravirt_disable_iospace(void);
+ 		       VEXTRA_CLOBBERS,					\
+ 		       pre, post, ##__VA_ARGS__)
+ 
+-#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...)			\
+-	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
++#define __PVOP_VCALLEESAVE(op, pre, post, ...)				\
++	____PVOP_VCALL(op.func, CLBR_RET_REG,				\
+ 		      PVOP_VCALLEE_CLOBBERS, ,				\
+ 		      pre, post, ##__VA_ARGS__)
+ 
+@@ -1565,42 +1567,22 @@ extern struct paravirt_patch_site __parainstructions[],
+ 
+ static inline unsigned long __raw_local_save_flags(void)
+ {
+-	unsigned long f;
+-
+-	asm volatile(paravirt_alt(PARAVIRT_CALL)
+-		     : "=a"(f)
+-		     : paravirt_type(pv_irq_ops.save_fl),
+-		       paravirt_clobber(CLBR_EAX)
+-		     : "memory", "cc");
+-	return f;
++	return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
+ }
+ 
+ static inline void raw_local_irq_restore(unsigned long f)
+ {
+-	asm volatile(paravirt_alt(PARAVIRT_CALL)
+-		     : "=a"(f)
+-		     : PV_FLAGS_ARG(f),
+-		       paravirt_type(pv_irq_ops.restore_fl),
+-		       paravirt_clobber(CLBR_EAX)
+-		     : "memory", "cc");
++	PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
+ }
+ 
+ static inline void raw_local_irq_disable(void)
+ {
+-	asm volatile(paravirt_alt(PARAVIRT_CALL)
+-		     :
+-		     : paravirt_type(pv_irq_ops.irq_disable),
+-		       paravirt_clobber(CLBR_EAX)
+-		     : "memory", "eax", "cc");
++	PVOP_VCALLEE0(pv_irq_ops.irq_disable);
+ }
+ 
+ static inline void raw_local_irq_enable(void)
+ {
+-	asm volatile(paravirt_alt(PARAVIRT_CALL)
+-		     :
+-		     : paravirt_type(pv_irq_ops.irq_enable),
+-		       paravirt_clobber(CLBR_EAX)
+-		     : "memory", "eax", "cc");
++	PVOP_VCALLEE0(pv_irq_ops.irq_enable);
+ }
+ 
+ static inline unsigned long __raw_local_irq_save(void)
+diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
+index fe3186d..6f56d95 100644
+--- a/arch/xtensa/kernel/Makefile
++++ b/arch/xtensa/kernel/Makefile
+@@ -27,7 +27,8 @@ sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g'	\
+ 	-e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g'
+ 
+ quiet_cmd__cpp_lds_S = LDS     $@
+-      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ $< | sed $(sed-y) >$@
++      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \
++                       | sed $(sed-y) >$@
+ 
+ $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
+ 	$(call if_changed_dep,_cpp_lds_S)
+diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
+index b0603b2..47c2d27 100644
+--- a/drivers/char/tpm/tpm.c
++++ b/drivers/char/tpm/tpm.c
+@@ -696,8 +696,7 @@ int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+ 
+ 	cmd.header.in = pcrread_header;
+ 	cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+-	BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
+-	rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
++	rc = transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
+ 			  "attempting to read a pcr value");
+ 
+ 	if (rc == 0)
+@@ -742,7 +741,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
+  * the module usage count.
+  */
+ #define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
+-#define EXTEND_PCR_SIZE 34
++#define EXTEND_PCR_RESULT_SIZE 34
+ static struct tpm_input_header pcrextend_header = {
+ 	.tag = TPM_TAG_RQU_COMMAND,
+ 	.length = cpu_to_be32(34),
+@@ -760,10 +759,9 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+ 		return -ENODEV;
+ 
+ 	cmd.header.in = pcrextend_header;
+-	BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
+ 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+ 	memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+-	rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
++	rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+ 			  "attempting extend a PCR value");
+ 
+ 	module_put(chip->dev->driver->owner);
+diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
+index 3108991..0296612 100644
+--- a/drivers/char/tty_buffer.c
++++ b/drivers/char/tty_buffer.c
+@@ -402,28 +402,26 @@ static void flush_to_ldisc(struct work_struct *work)
+ 		container_of(work, struct tty_struct, buf.work.work);
+ 	unsigned long 	flags;
+ 	struct tty_ldisc *disc;
+-	struct tty_buffer *tbuf, *head;
+-	char *char_buf;
+-	unsigned char *flag_buf;
+ 
+ 	disc = tty_ldisc_ref(tty);
+ 	if (disc == NULL)	/*  !TTY_LDISC */
+ 		return;
+ 
+ 	spin_lock_irqsave(&tty->buf.lock, flags);
+-	/* So we know a flush is running */
+-	set_bit(TTY_FLUSHING, &tty->flags);
+-	head = tty->buf.head;
+-	if (head != NULL) {
+-		tty->buf.head = NULL;
+-		for (;;) {
+-			int count = head->commit - head->read;
++
++	if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
++		struct tty_buffer *head;
++		while ((head = tty->buf.head) != NULL) {
++			int count;
++			char *char_buf;
++			unsigned char *flag_buf;
++
++			count = head->commit - head->read;
+ 			if (!count) {
+ 				if (head->next == NULL)
+ 					break;
+-				tbuf = head;
+-				head = head->next;
+-				tty_buffer_free(tty, tbuf);
++				tty->buf.head = head->next;
++				tty_buffer_free(tty, head);
+ 				continue;
+ 			}
+ 			/* Ldisc or user is trying to flush the buffers
+@@ -445,9 +443,9 @@ static void flush_to_ldisc(struct work_struct *work)
+ 							flag_buf, count);
+ 			spin_lock_irqsave(&tty->buf.lock, flags);
+ 		}
+-		/* Restore the queue head */
+-		tty->buf.head = head;
++		clear_bit(TTY_FLUSHING, &tty->flags);
+ 	}
++
+ 	/* We may have a deferred request to flush the input buffer,
+ 	   if so pull the chain under the lock and empty the queue */
+ 	if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
+@@ -455,7 +453,6 @@ static void flush_to_ldisc(struct work_struct *work)
+ 		clear_bit(TTY_FLUSHPENDING, &tty->flags);
+ 		wake_up(&tty->read_wait);
+ 	}
+-	clear_bit(TTY_FLUSHING, &tty->flags);
+ 	spin_unlock_irqrestore(&tty->buf.lock, flags);
+ 
+ 	tty_ldisc_deref(disc);
+diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
+index c5afc98..9ca20d0 100644
+--- a/drivers/connector/cn_proc.c
++++ b/drivers/connector/cn_proc.c
+@@ -202,9 +202,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+  * cn_proc_mcast_ctl
+  * @data: message sent from userspace via the connector
+  */
+-static void cn_proc_mcast_ctl(void *data)
++static void cn_proc_mcast_ctl(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = data;
+ 	enum proc_cn_mcast_op *mc_op = NULL;
+ 	int err = 0;
+ 
+diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
+index 408c2af..210338e 100644
+--- a/drivers/connector/cn_queue.c
++++ b/drivers/connector/cn_queue.c
+@@ -78,16 +78,20 @@ void cn_queue_wrapper(struct work_struct *work)
+ 	struct cn_callback_entry *cbq =
+ 		container_of(work, struct cn_callback_entry, work);
+ 	struct cn_callback_data *d = &cbq->data;
++	struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
++	struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
+ 
+-	d->callback(d->callback_priv);
++	d->callback(msg, nsp);
+ 
+-	d->destruct_data(d->ddata);
+-	d->ddata = NULL;
++	kfree_skb(d->skb);
++	d->skb = NULL;
+ 
+ 	kfree(d->free);
+ }
+ 
+-static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *))
++static struct cn_callback_entry *
++cn_queue_alloc_callback_entry(char *name, struct cb_id *id,
++			      void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
+ {
+ 	struct cn_callback_entry *cbq;
+ 
+@@ -120,7 +124,8 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
+ 	return ((i1->idx == i2->idx) && (i1->val == i2->val));
+ }
+ 
+-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *))
++int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id,
++			  void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
+ {
+ 	struct cn_callback_entry *cbq, *__cbq;
+ 	int found = 0;
+diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
+index 08b2500..f060246 100644
+--- a/drivers/connector/connector.c
++++ b/drivers/connector/connector.c
+@@ -129,21 +129,19 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
+ /*
+  * Callback helper - queues work and setup destructor for given data.
+  */
+-static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
++static int cn_call_callback(struct sk_buff *skb)
+ {
+ 	struct cn_callback_entry *__cbq, *__new_cbq;
+ 	struct cn_dev *dev = &cdev;
++	struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
+ 	int err = -ENODEV;
+ 
+ 	spin_lock_bh(&dev->cbdev->queue_lock);
+ 	list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
+ 		if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
+ 			if (likely(!work_pending(&__cbq->work) &&
+-					__cbq->data.ddata == NULL)) {
+-				__cbq->data.callback_priv = msg;
+-
+-				__cbq->data.ddata = data;
+-				__cbq->data.destruct_data = destruct_data;
++					__cbq->data.skb == NULL)) {
++				__cbq->data.skb = skb;
+ 
+ 				if (queue_cn_work(__cbq, &__cbq->work))
+ 					err = 0;
+@@ -156,10 +154,8 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
+ 				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
+ 				if (__new_cbq) {
+ 					d = &__new_cbq->data;
+-					d->callback_priv = msg;
++					d->skb = skb;
+ 					d->callback = __cbq->data.callback;
+-					d->ddata = data;
+-					d->destruct_data = destruct_data;
+ 					d->free = __new_cbq;
+ 
+ 					__new_cbq->pdev = __cbq->pdev;
+@@ -191,7 +187,6 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
+  */
+ static void cn_rx_skb(struct sk_buff *__skb)
+ {
+-	struct cn_msg *msg;
+ 	struct nlmsghdr *nlh;
+ 	int err;
+ 	struct sk_buff *skb;
+@@ -208,8 +203,7 @@ static void cn_rx_skb(struct sk_buff *__skb)
+ 			return;
+ 		}
+ 
+-		msg = NLMSG_DATA(nlh);
+-		err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
++		err = cn_call_callback(skb);
+ 		if (err < 0)
+ 			kfree_skb(skb);
+ 	}
+@@ -269,7 +263,8 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
+  *
+  * May sleep.
+  */
+-int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
++int cn_add_callback(struct cb_id *id, char *name,
++		    void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
+ {
+ 	int err;
+ 	struct cn_dev *dev = &cdev;
+@@ -351,9 +346,8 @@ static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
+  *
+  * Used for notification of a request's processing.
+  */
+-static void cn_callback(void *data)
++static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = data;
+ 	struct cn_ctl_msg *ctl;
+ 	struct cn_ctl_entry *ent;
+ 	u32 size;
+diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
+index f7d6fe9..8f0b90e 100644
+--- a/drivers/i2c/busses/i2c-amd756.c
++++ b/drivers/i2c/busses/i2c-amd756.c
+@@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
+ 	error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
+ 				  amd756_driver.name);
+ 	if (error)
+-		return error;
++		return -ENODEV;
+ 
+ 	if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
+ 		dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
+diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
+index a7c5990..5b4ad86 100644
+--- a/drivers/i2c/busses/i2c-amd8111.c
++++ b/drivers/i2c/busses/i2c-amd8111.c
+@@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
+ 	smbus->size = pci_resource_len(dev, 0);
+ 
+ 	error = acpi_check_resource_conflict(&dev->resource[0]);
+-	if (error)
++	if (error) {
++		error = -ENODEV;
+ 		goto out_kfree;
++	}
+ 
+ 	if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
+ 		error = -EBUSY;
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index 9d2c5ad..55edcfe 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
+ 	}
+ 
+ 	err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
+-	if (err)
++	if (err) {
++		err = -ENODEV;
+ 		goto exit;
++	}
+ 
+ 	err = pci_request_region(dev, SMBBAR, i801_driver.name);
+ 	if (err) {
+diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
+index 9f6b8e0..dba6eb0 100644
+--- a/drivers/i2c/busses/i2c-isch.c
++++ b/drivers/i2c/busses/i2c-isch.c
+@@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev,
+ 		return -ENODEV;
+ 	}
+ 	if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
+-		return -EBUSY;
++		return -ENODEV;
+ 	if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
+ 		dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
+ 			sch_smba);
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index 0249a7d..808e49e 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -168,7 +168,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
+ 	}
+ 
+ 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
+-		return -EBUSY;
++		return -ENODEV;
+ 
+ 	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+ 		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
+@@ -259,7 +259,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
+ 
+ 	piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+ 	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
+-		return -EBUSY;
++		return -ENODEV;
+ 
+ 	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+ 		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
+diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
+index 8295885..1649963 100644
+--- a/drivers/i2c/busses/i2c-sis96x.c
++++ b/drivers/i2c/busses/i2c-sis96x.c
+@@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
+ 
+ 	retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
+ 	if (retval)
+-		return retval;
++		return -ENODEV;
+ 
+ 	/* Everything is happy, let's grab the memory and set things up. */
+ 	if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
+diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
+index 54d810a..e4b1543 100644
+--- a/drivers/i2c/busses/i2c-viapro.c
++++ b/drivers/i2c/busses/i2c-viapro.c
+@@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
+ found:
+ 	error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
+ 	if (error)
+-		return error;
++		return -ENODEV;
+ 
+ 	if (!request_region(vt596_smba, 8, vt596_driver.name)) {
+ 		dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
+diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
+index fde377c..556f0fe 100644
+--- a/drivers/macintosh/therm_adt746x.c
++++ b/drivers/macintosh/therm_adt746x.c
+@@ -124,6 +124,8 @@ read_reg(struct thermostat* th, int reg)
+ 	return data;
+ }
+ 
++static struct i2c_driver thermostat_driver;
++
+ static int
+ attach_thermostat(struct i2c_adapter *adapter)
+ {
+@@ -148,7 +150,7 @@ attach_thermostat(struct i2c_adapter *adapter)
+ 	 * Let i2c-core delete that device on driver removal.
+ 	 * This is safe because i2c-core holds the core_lock mutex for us.
+ 	 */
+-	list_add_tail(&client->detected, &client->driver->clients);
++	list_add_tail(&client->detected, &thermostat_driver.clients);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
+index a028598..ea32c7e 100644
+--- a/drivers/macintosh/therm_pm72.c
++++ b/drivers/macintosh/therm_pm72.c
+@@ -286,6 +286,8 @@ struct fcu_fan_table	fcu_fans[] = {
+ 	},
+ };
+ 
++static struct i2c_driver therm_pm72_driver;
++
+ /*
+  * Utility function to create an i2c_client structure and
+  * attach it to one of u3 adapters
+@@ -318,7 +320,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
+ 	 * Let i2c-core delete that device on driver removal.
+ 	 * This is safe because i2c-core holds the core_lock mutex for us.
+ 	 */
+-	list_add_tail(&clt->detected, &clt->driver->clients);
++	list_add_tail(&clt->detected, &therm_pm72_driver.clients);
+ 	return clt;
+ }
+ 
+diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
+index 529886c..ed6426a 100644
+--- a/drivers/macintosh/windfarm_lm75_sensor.c
++++ b/drivers/macintosh/windfarm_lm75_sensor.c
+@@ -115,6 +115,8 @@ static int wf_lm75_probe(struct i2c_client *client,
+ 	return rc;
+ }
+ 
++static struct i2c_driver wf_lm75_driver;
++
+ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
+ 					     u8 addr, int ds1775,
+ 					     const char *loc)
+@@ -157,7 +159,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
+ 	 * Let i2c-core delete that device on driver removal.
+ 	 * This is safe because i2c-core holds the core_lock mutex for us.
+ 	 */
+-	list_add_tail(&client->detected, &client->driver->clients);
++	list_add_tail(&client->detected, &wf_lm75_driver.clients);
+ 	return client;
+  fail:
+ 	return NULL;
+diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
+index e2a55ec..a67b349 100644
+--- a/drivers/macintosh/windfarm_max6690_sensor.c
++++ b/drivers/macintosh/windfarm_max6690_sensor.c
+@@ -88,6 +88,8 @@ static int wf_max6690_probe(struct i2c_client *client,
+ 	return rc;
+ }
+ 
++static struct i2c_driver wf_max6690_driver;
++
+ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
+ 					    u8 addr, const char *loc)
+ {
+@@ -119,7 +121,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
+ 	 * Let i2c-core delete that device on driver removal.
+ 	 * This is safe because i2c-core holds the core_lock mutex for us.
+ 	 */
+-	list_add_tail(&client->detected, &client->driver->clients);
++	list_add_tail(&client->detected, &wf_max6690_driver.clients);
+ 	return client;
+ 
+  fail:
+diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
+index 5da729e..e20330a 100644
+--- a/drivers/macintosh/windfarm_smu_sat.c
++++ b/drivers/macintosh/windfarm_smu_sat.c
+@@ -194,6 +194,8 @@ static struct wf_sensor_ops wf_sat_ops = {
+ 	.owner		= THIS_MODULE,
+ };
+ 
++static struct i2c_driver wf_sat_driver;
++
+ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
+ {
+ 	struct i2c_board_info info;
+@@ -222,7 +224,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
+ 	 * Let i2c-core delete that device on driver removal.
+ 	 * This is safe because i2c-core holds the core_lock mutex for us.
+ 	 */
+-	list_add_tail(&client->detected, &client->driver->clients);
++	list_add_tail(&client->detected, &wf_sat_driver.clients);
+ }
+ 
+ static int wf_sat_probe(struct i2c_client *client,
+diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
+index ba0edad..54abf9e 100644
+--- a/drivers/md/dm-log-userspace-transfer.c
++++ b/drivers/md/dm-log-userspace-transfer.c
+@@ -129,11 +129,13 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
+  * This is the connector callback that delivers data
+  * that was sent from userspace.
+  */
+-static void cn_ulog_callback(void *data)
++static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = (struct cn_msg *)data;
+ 	struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
+ 
++	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
++		return;
++
+ 	spin_lock(&receiving_list_lock);
+ 	if (msg->len == 0)
+ 		fill_pkg(msg, NULL);
+diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
+index b53b40b..d1e0563 100644
+--- a/drivers/net/e1000e/82571.c
++++ b/drivers/net/e1000e/82571.c
+@@ -1803,7 +1803,7 @@ struct e1000_info e1000_82574_info = {
+ 				  | FLAG_HAS_AMT
+ 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
+ 	.pba			= 20,
+-	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
++	.max_hw_frame_size	= DEFAULT_JUMBO,
+ 	.get_variants		= e1000_get_variants_82571,
+ 	.mac_ops		= &e82571_mac_ops,
+ 	.phy_ops		= &e82_phy_ops_bm,
+@@ -1820,7 +1820,7 @@ struct e1000_info e1000_82583_info = {
+ 				  | FLAG_HAS_AMT
+ 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
+ 	.pba			= 20,
+-	.max_hw_frame_size	= DEFAULT_JUMBO,
++	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
+ 	.get_variants		= e1000_get_variants_82571,
+ 	.mac_ops		= &e82571_mac_ops,
+ 	.phy_ops		= &e82_phy_ops_bm,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+index e8c0e82..eabe48a 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+@@ -335,7 +335,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
+ 					u16 *validblockaddr)
+ {
+ 	u16 next_link_addr = 0, link_value = 0, valid_addr;
+-	int ret = 0;
+ 	int usedblocks = 0;
+ 
+ 	/* set addressing mode to absolute to traverse the link list */
+@@ -355,29 +354,29 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
+ 		 * check for more block on the link list
+ 		 */
+ 		valid_addr = next_link_addr;
+-		next_link_addr = link_value;
++		next_link_addr = link_value * sizeof(u16);
+ 		IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
+ 			       usedblocks, next_link_addr);
+ 		if (iwl_read_otp_word(priv, next_link_addr, &link_value))
+ 			return -EINVAL;
+ 		if (!link_value) {
+ 			/*
+-			 * reach the end of link list,
++			 * reach the end of link list, return success and
+ 			 * set address point to the starting address
+ 			 * of the image
+ 			 */
+-			goto done;
++			*validblockaddr = valid_addr;
++			/* skip first 2 bytes (link list pointer) */
++			*validblockaddr += 2;
++			return 0;
+ 		}
+ 		/* more in the link list, continue */
+ 		usedblocks++;
+-	} while (usedblocks < priv->cfg->max_ll_items);
+-	/* OTP full, use last block */
+-	IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
+-done:
+-	*validblockaddr = valid_addr;
+-	/* skip first 2 bytes (link list pointer) */
+-	*validblockaddr += 2;
+-	return ret;
++	} while (usedblocks <= priv->cfg->max_ll_items);
++
++	/* OTP has no valid blocks */
++	IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
++	return -EINVAL;
+ }
+ 
+ /**
+diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
+index 7b287cb..380b60e 100644
+--- a/drivers/pci/dmar.c
++++ b/drivers/pci/dmar.c
+@@ -632,20 +632,31 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
+ 	iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
+ 	iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+ 
++	if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
++		/* Promote an attitude of violence to a BIOS engineer today */
++		WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
++		     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
++		     drhd->reg_base_addr,
++		     dmi_get_system_info(DMI_BIOS_VENDOR),
++		     dmi_get_system_info(DMI_BIOS_VERSION),
++		     dmi_get_system_info(DMI_PRODUCT_VERSION));
++		goto err_unmap;
++	}
++
+ #ifdef CONFIG_DMAR
+ 	agaw = iommu_calculate_agaw(iommu);
+ 	if (agaw < 0) {
+ 		printk(KERN_ERR
+ 		       "Cannot get a valid agaw for iommu (seq_id = %d)\n",
+ 		       iommu->seq_id);
+-		goto error;
++		goto err_unmap;
+ 	}
+ 	msagaw = iommu_calculate_max_sagaw(iommu);
+ 	if (msagaw < 0) {
+ 		printk(KERN_ERR
+ 			"Cannot get a valid max agaw for iommu (seq_id = %d)\n",
+ 			iommu->seq_id);
+-		goto error;
++		goto err_unmap;
+ 	}
+ #endif
+ 	iommu->agaw = agaw;
+@@ -665,7 +676,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
+ 	}
+ 
+ 	ver = readl(iommu->reg + DMAR_VER_REG);
+-	pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
++	pr_info("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
+ 		(unsigned long long)drhd->reg_base_addr,
+ 		DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
+ 		(unsigned long long)iommu->cap,
+@@ -675,7 +686,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
+ 
+ 	drhd->iommu = iommu;
+ 	return 0;
+-error:
++
++ err_unmap:
++	iounmap(iommu->reg);
++ error:
+ 	kfree(iommu);
+ 	return -1;
+ }
+diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
+index 2de5f3a..69397bb 100644
+--- a/drivers/scsi/scsi.c
++++ b/drivers/scsi/scsi.c
+@@ -241,10 +241,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
+  */
+ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
+ {
+-	struct scsi_cmnd *cmd;
+-	unsigned char *buf;
+-
+-	cmd = scsi_host_alloc_command(shost, gfp_mask);
++	struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask);
+ 
+ 	if (unlikely(!cmd)) {
+ 		unsigned long flags;
+@@ -258,9 +255,15 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
+ 		spin_unlock_irqrestore(&shost->free_list_lock, flags);
+ 
+ 		if (cmd) {
++			void *buf, *prot;
++
+ 			buf = cmd->sense_buffer;
++			prot = cmd->prot_sdb;
++
+ 			memset(cmd, 0, sizeof(*cmd));
++
+ 			cmd->sense_buffer = buf;
++			cmd->prot_sdb = prot;
+ 		}
+ 	}
+ 
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index a168935..c253e9c 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -721,6 +721,9 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
+ 		case NEEDS_RETRY:
+ 		case FAILED:
+ 			break;
++		case ADD_TO_MLQUEUE:
++			rtn = NEEDS_RETRY;
++			break;
+ 		default:
+ 			rtn = FAILED;
+ 			break;
+diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
+index 4968c4c..dc0e3d4 100644
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1708,11 +1708,6 @@ static int sg_finish_rem_req(Sg_request * srp)
+ 	Sg_scatter_hold *req_schp = &srp->data;
+ 
+ 	SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used));
+-	if (srp->res_used)
+-		sg_unlink_reserve(sfp, srp);
+-	else
+-		sg_remove_scat(req_schp);
+-
+ 	if (srp->rq) {
+ 		if (srp->bio)
+ 			ret = blk_rq_unmap_user(srp->bio);
+@@ -1720,6 +1715,11 @@ static int sg_finish_rem_req(Sg_request * srp)
+ 		blk_put_request(srp->rq);
+ 	}
+ 
++	if (srp->res_used)
++		sg_unlink_reserve(sfp, srp);
++	else
++		sg_remove_scat(req_schp);
++
+ 	sg_remove_request(sfp, srp);
+ 
+ 	return ret;
+diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
+index fad25b7..5546898 100644
+--- a/drivers/staging/dst/dcore.c
++++ b/drivers/staging/dst/dcore.c
+@@ -846,15 +846,19 @@ static dst_command_func dst_commands[] = {
+ /*
+  * Configuration parser.
+  */
+-static void cn_dst_callback(void *data)
++static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+ 	struct dst_ctl *ctl;
+-	struct cn_msg *msg = data;
+ 	int err;
+ 	struct dst_ctl_ack ack;
+ 	struct dst_node *n = NULL, *tmp;
+ 	unsigned int hash;
+ 
++	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
++		err = -EPERM;
++		goto out;
++	}
++
+ 	if (msg->len < sizeof(struct dst_ctl)) {
+ 		err = -EBADMSG;
+ 		goto out;
+diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
+index a6eaa42..d8ec47a 100644
+--- a/drivers/staging/pohmelfs/config.c
++++ b/drivers/staging/pohmelfs/config.c
+@@ -446,11 +446,13 @@ out_unlock:
+ 	return err;
+ }
+ 
+-static void pohmelfs_cn_callback(void *data)
++static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = data;
+ 	int err;
+ 
++	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
++		return;
++
+ 	switch (msg->flags) {
+ 		case POHMELFS_FLAGS_ADD:
+ 		case POHMELFS_FLAGS_DEL:
+diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
+index fb17355..857ff45 100644
+--- a/drivers/staging/rt2860/common/cmm_data_2860.c
++++ b/drivers/staging/rt2860/common/cmm_data_2860.c
+@@ -363,6 +363,8 @@ int RtmpPCIMgmtKickOut(
+ 	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
+ 
+ 	pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
++	if (!pTxD)
++		return 0;
+ 
+ 	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
+ 	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index b5275c4..a69457f 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -114,6 +114,7 @@ static struct usb_device_id id_table [] = {
+ 	{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
+ 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+ 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
++	{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
+ 	{ } /* Terminating Entry */
+ };
+ 
+diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
+index f480809..9bd82b4 100644
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -899,16 +899,16 @@ static void digi_rx_unthrottle(struct tty_struct *tty)
+ 
+ 	spin_lock_irqsave(&priv->dp_port_lock, flags);
+ 
+-	/* turn throttle off */
+-	priv->dp_throttled = 0;
+-	priv->dp_throttle_restart = 0;
+-
+ 	/* restart read chain */
+ 	if (priv->dp_throttle_restart) {
+ 		port->read_urb->dev = port->serial->dev;
+ 		ret = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ 	}
+ 
++	/* turn throttle off */
++	priv->dp_throttled = 0;
++	priv->dp_throttle_restart = 0;
++
+ 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
+ 
+ 	if (ret)
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 0cc78f9..048b563 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -76,13 +76,7 @@ struct ftdi_private {
+ 	unsigned long last_dtr_rts;	/* saved modem control outputs */
+ 	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ 	char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+-	__u8 rx_flags;		/* receive state flags (throttling) */
+-	spinlock_t rx_lock;	/* spinlock for receive state */
+-	struct delayed_work rx_work;
+ 	struct usb_serial_port *port;
+-	int rx_processed;
+-	unsigned long rx_bytes;
+-
+ 	__u16 interface;	/* FT2232C, FT2232H or FT4232H port interface
+ 				   (0 for FT232/245) */
+ 
+@@ -737,10 +731,6 @@ static const char *ftdi_chip_name[] = {
+ /* Constants for read urb and write urb */
+ #define BUFSZ 512
+ 
+-/* rx_flags */
+-#define THROTTLED		0x01
+-#define ACTUALLY_THROTTLED	0x02
+-
+ /* Used for TIOCMIWAIT */
+ #define FTDI_STATUS_B0_MASK	(FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
+ #define FTDI_STATUS_B1_MASK	(FTDI_RS_BI)
+@@ -764,7 +754,7 @@ static int  ftdi_write_room(struct tty_struct *tty);
+ static int  ftdi_chars_in_buffer(struct tty_struct *tty);
+ static void ftdi_write_bulk_callback(struct urb *urb);
+ static void ftdi_read_bulk_callback(struct urb *urb);
+-static void ftdi_process_read(struct work_struct *work);
++static void ftdi_process_read(struct usb_serial_port *port);
+ static void ftdi_set_termios(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct ktermios *old);
+ static int  ftdi_tiocmget(struct tty_struct *tty, struct file *file);
+@@ -1235,7 +1225,6 @@ static int set_serial_info(struct tty_struct *tty,
+ 					(new_serial.flags & ASYNC_FLAGS));
+ 	priv->custom_divisor = new_serial.custom_divisor;
+ 
+-	tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ 	write_latency_timer(port);
+ 
+ check_and_exit:
+@@ -1528,7 +1517,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ 	}
+ 
+ 	kref_init(&priv->kref);
+-	spin_lock_init(&priv->rx_lock);
+ 	spin_lock_init(&priv->tx_lock);
+ 	init_waitqueue_head(&priv->delta_msr_wait);
+ 	/* This will push the characters through immediately rather
+@@ -1550,7 +1538,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ 		port->read_urb->transfer_buffer_length = BUFSZ;
+ 	}
+ 
+-	INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read);
+ 	priv->port = port;
+ 
+ 	/* Free port's existing write urb and transfer buffer. */
+@@ -1687,6 +1674,26 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+ 	return 0;
+ }
+ 
++static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
++{
++	struct urb *urb = port->read_urb;
++	struct usb_serial *serial = port->serial;
++	int result;
++
++	usb_fill_bulk_urb(urb, serial->dev,
++			   usb_rcvbulkpipe(serial->dev,
++					port->bulk_in_endpointAddress),
++			   urb->transfer_buffer,
++			   urb->transfer_buffer_length,
++			   ftdi_read_bulk_callback, port);
++	result = usb_submit_urb(urb, mem_flags);
++	if (result)
++		dev_err(&port->dev,
++			"%s - failed submitting read urb, error %d\n",
++							__func__, result);
++	return result;
++}
++
+ static int ftdi_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp)
+ { /* ftdi_open */
+@@ -1702,12 +1709,6 @@ static int ftdi_open(struct tty_struct *tty,
+ 	spin_lock_irqsave(&priv->tx_lock, flags);
+ 	priv->tx_bytes = 0;
+ 	spin_unlock_irqrestore(&priv->tx_lock, flags);
+-	spin_lock_irqsave(&priv->rx_lock, flags);
+-	priv->rx_bytes = 0;
+-	spin_unlock_irqrestore(&priv->rx_lock, flags);
+-
+-	if (tty)
+-		tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ 
+ 	write_latency_timer(port);
+ 
+@@ -1727,23 +1728,14 @@ static int ftdi_open(struct tty_struct *tty,
+ 		ftdi_set_termios(tty, port, tty->termios);
+ 
+ 	/* Not throttled */
+-	spin_lock_irqsave(&priv->rx_lock, flags);
+-	priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
+-	spin_unlock_irqrestore(&priv->rx_lock, flags);
++	spin_lock_irqsave(&port->lock, flags);
++	port->throttled = 0;
++	port->throttle_req = 0;
++	spin_unlock_irqrestore(&port->lock, flags);
+ 
+ 	/* Start reading from the device */
+-	priv->rx_processed = 0;
+-	usb_fill_bulk_urb(port->read_urb, dev,
+-			usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
+-			port->read_urb->transfer_buffer,
+-				port->read_urb->transfer_buffer_length,
+-			ftdi_read_bulk_callback, port);
+-	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+-	if (result)
+-		dev_err(&port->dev,
+-			"%s - failed submitting read urb, error %d\n",
+-			__func__, result);
+-	else
++	result = ftdi_submit_read_urb(port, GFP_KERNEL);
++	if (!result)
+ 		kref_get(&priv->kref);
+ 
+ 	return result;
+@@ -1789,10 +1781,6 @@ static void ftdi_close(struct usb_serial_port *port)
+ 
+ 	dbg("%s", __func__);
+ 
+-
+-	/* cancel any scheduled reading */
+-	cancel_delayed_work_sync(&priv->rx_work);
+-
+ 	/* shutdown our bulk read */
+ 	usb_kill_urb(port->read_urb);
+ 	kref_put(&priv->kref, ftdi_sio_priv_release);
+@@ -2015,271 +2003,121 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty)
+ 	return buffered;
+ }
+ 
+-static void ftdi_read_bulk_callback(struct urb *urb)
++static int ftdi_process_packet(struct tty_struct *tty,
++		struct usb_serial_port *port, struct ftdi_private *priv,
++		char *packet, int len)
+ {
+-	struct usb_serial_port *port = urb->context;
+-	struct tty_struct *tty;
+-	struct ftdi_private *priv;
+-	unsigned long countread;
+-	unsigned long flags;
+-	int status = urb->status;
+-
+-	if (urb->number_of_packets > 0) {
+-		dev_err(&port->dev, "%s transfer_buffer_length %d "
+-			"actual_length %d number of packets %d\n", __func__,
+-			urb->transfer_buffer_length,
+-			urb->actual_length, urb->number_of_packets);
+-		dev_err(&port->dev, "%s transfer_flags %x\n", __func__,
+-			urb->transfer_flags);
+-	}
++	int i;
++	char status;
++	char flag;
++	char *ch;
+ 
+ 	dbg("%s - port %d", __func__, port->number);
+ 
+-	if (port->port.count <= 0)
+-		return;
+-
+-	tty = tty_port_tty_get(&port->port);
+-	if (!tty) {
+-		dbg("%s - bad tty pointer - exiting", __func__);
+-		return;
++	if (len < 2) {
++		dbg("malformed packet");
++		return 0;
+ 	}
+ 
+-	priv = usb_get_serial_port_data(port);
+-	if (!priv) {
+-		dbg("%s - bad port private data pointer - exiting", __func__);
+-		goto out;
++	/* Compare new line status to the old one, signal if different/
++	   N.B. packet may be processed more than once, but differences
++	   are only processed once.  */
++	status = packet[0] & FTDI_STATUS_B0_MASK;
++	if (status != priv->prev_status) {
++		priv->diff_status |= status ^ priv->prev_status;
++		wake_up_interruptible(&priv->delta_msr_wait);
++		priv->prev_status = status;
+ 	}
+ 
+-	if (urb != port->read_urb)
+-		dev_err(&port->dev, "%s - Not my urb!\n", __func__);
+-
+-	if (status) {
+-		/* This will happen at close every time so it is a dbg not an
+-		   err */
+-		dbg("(this is ok on close) nonzero read bulk status received: %d", status);
+-		goto out;
++	/*
++	 * Although the device uses a bitmask and hence can have multiple
++	 * errors on a packet - the order here sets the priority the error is
++	 * returned to the tty layer.
++	 */
++	flag = TTY_NORMAL;
++	if (packet[1] & FTDI_RS_OE) {
++		flag = TTY_OVERRUN;
++		dbg("OVERRRUN error");
++	}
++	if (packet[1] & FTDI_RS_BI) {
++		flag = TTY_BREAK;
++		dbg("BREAK received");
++		usb_serial_handle_break(port);
++	}
++	if (packet[1] & FTDI_RS_PE) {
++		flag = TTY_PARITY;
++		dbg("PARITY error");
++	}
++	if (packet[1] & FTDI_RS_FE) {
++		flag = TTY_FRAME;
++		dbg("FRAMING error");
+ 	}
+ 
+-	/* count data bytes, but not status bytes */
+-	countread = urb->actual_length;
+-	countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size);
+-	spin_lock_irqsave(&priv->rx_lock, flags);
+-	priv->rx_bytes += countread;
+-	spin_unlock_irqrestore(&priv->rx_lock, flags);
+-
+-	ftdi_process_read(&priv->rx_work.work);
+-out:
+-	tty_kref_put(tty);
+-} /* ftdi_read_bulk_callback */
+-
++	len -= 2;
++	if (!len)
++		return 0;	/* status only */
++	ch = packet + 2;
++
++	if (!(port->console && port->sysrq) && flag == TTY_NORMAL)
++		tty_insert_flip_string(tty, ch, len);
++	else {
++		for (i = 0; i < len; i++, ch++) {
++			if (!usb_serial_handle_sysrq_char(tty, port, *ch))
++				tty_insert_flip_char(tty, *ch, flag);
++		}
++	}
++	return len;
++}
+ 
+-static void ftdi_process_read(struct work_struct *work)
+-{ /* ftdi_process_read */
+-	struct ftdi_private *priv =
+-		container_of(work, struct ftdi_private, rx_work.work);
+-	struct usb_serial_port *port = priv->port;
+-	struct urb *urb;
++static void ftdi_process_read(struct usb_serial_port *port)
++{
++	struct urb *urb = port->read_urb;
+ 	struct tty_struct *tty;
+-	char error_flag;
+-	unsigned char *data;
+-
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++	char *data = (char *)urb->transfer_buffer;
+ 	int i;
+-	int result;
+-	int need_flip;
+-	int packet_offset;
+-	unsigned long flags;
+-
+-	dbg("%s - port %d", __func__, port->number);
+-
+-	if (port->port.count <= 0)
+-		return;
++	int len;
++	int count = 0;
+ 
+ 	tty = tty_port_tty_get(&port->port);
+-	if (!tty) {
+-		dbg("%s - bad tty pointer - exiting", __func__);
++	if (!tty)
+ 		return;
+-	}
+-
+-	priv = usb_get_serial_port_data(port);
+-	if (!priv) {
+-		dbg("%s - bad port private data pointer - exiting", __func__);
+-		goto out;
+-	}
+-
+-	urb = port->read_urb;
+-	if (!urb) {
+-		dbg("%s - bad read_urb pointer - exiting", __func__);
+-		goto out;
+-	}
+-
+-	data = urb->transfer_buffer;
+ 
+-	if (priv->rx_processed) {
+-		dbg("%s - already processed: %d bytes, %d remain", __func__,
+-				priv->rx_processed,
+-				urb->actual_length - priv->rx_processed);
+-	} else {
+-		/* The first two bytes of every read packet are status */
+-		if (urb->actual_length > 2)
+-			usb_serial_debug_data(debug, &port->dev, __func__,
+-						urb->actual_length, data);
+-		else
+-			dbg("Status only: %03oo %03oo", data[0], data[1]);
++	for (i = 0; i < urb->actual_length; i += priv->max_packet_size) {
++		len = min_t(int, urb->actual_length - i, priv->max_packet_size);
++		count += ftdi_process_packet(tty, port, priv, &data[i], len);
+ 	}
+ 
+-
+-	/* TO DO -- check for hung up line and handle appropriately: */
+-	/*   send hangup  */
+-	/* See acm.c - you do a tty_hangup  - eg tty_hangup(tty) */
+-	/* if CD is dropped and the line is not CLOCAL then we should hangup */
+-
+-	need_flip = 0;
+-	for (packet_offset = priv->rx_processed;
+-		packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) {
+-		int length;
+-
+-		/* Compare new line status to the old one, signal if different/
+-		   N.B. packet may be processed more than once, but differences
+-		   are only processed once.  */
+-		char new_status = data[packet_offset + 0] &
+-						FTDI_STATUS_B0_MASK;
+-		if (new_status != priv->prev_status) {
+-			priv->diff_status |=
+-				new_status ^ priv->prev_status;
+-			wake_up_interruptible(&priv->delta_msr_wait);
+-			priv->prev_status = new_status;
+-		}
+-
+-		length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2;
+-		if (length < 0) {
+-			dev_err(&port->dev, "%s - bad packet length: %d\n",
+-				__func__, length+2);
+-			length = 0;
+-		}
+-
+-		if (priv->rx_flags & THROTTLED) {
+-			dbg("%s - throttled", __func__);
+-			break;
+-		}
+-		if (tty_buffer_request_room(tty, length) < length) {
+-			/* break out & wait for throttling/unthrottling to
+-			   happen */
+-			dbg("%s - receive room low", __func__);
+-			break;
+-		}
+-
+-		/* Handle errors and break */
+-		error_flag = TTY_NORMAL;
+-		/* Although the device uses a bitmask and hence can have
+-		   multiple errors on a packet - the order here sets the
+-		   priority the error is returned to the tty layer  */
+-
+-		if (data[packet_offset+1] & FTDI_RS_OE) {
+-			error_flag = TTY_OVERRUN;
+-			dbg("OVERRRUN error");
+-		}
+-		if (data[packet_offset+1] & FTDI_RS_BI) {
+-			error_flag = TTY_BREAK;
+-			dbg("BREAK received");
+-			usb_serial_handle_break(port);
+-		}
+-		if (data[packet_offset+1] & FTDI_RS_PE) {
+-			error_flag = TTY_PARITY;
+-			dbg("PARITY error");
+-		}
+-		if (data[packet_offset+1] & FTDI_RS_FE) {
+-			error_flag = TTY_FRAME;
+-			dbg("FRAMING error");
+-		}
+-		if (length > 0) {
+-			for (i = 2; i < length+2; i++) {
+-				/* Note that the error flag is duplicated for
+-				   every character received since we don't know
+-				   which character it applied to */
+-				if (!usb_serial_handle_sysrq_char(tty, port,
+-						data[packet_offset + i]))
+-					tty_insert_flip_char(tty,
+-						data[packet_offset + i],
+-						error_flag);
+-			}
+-			need_flip = 1;
+-		}
+-
+-#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
+-		/* if a parity error is detected you get status packets forever
+-		   until a character is sent without a parity error.
+-		   This doesn't work well since the application receives a
+-		   never ending stream of bad data - even though new data
+-		   hasn't been sent. Therefore I (bill) have taken this out.
+-		   However - this might make sense for framing errors and so on
+-		   so I am leaving the code in for now.
+-		*/
+-		else {
+-			if (error_flag != TTY_NORMAL) {
+-				dbg("error_flag is not normal");
+-				/* In this case it is just status - if that is
+-				   an error send a bad character */
+-				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+-					tty_flip_buffer_push(tty);
+-				tty_insert_flip_char(tty, 0xff, error_flag);
+-				need_flip = 1;
+-			}
+-		}
+-#endif
+-	} /* "for(packet_offset=0..." */
+-
+-	/* Low latency */
+-	if (need_flip)
++	if (count)
+ 		tty_flip_buffer_push(tty);
++	tty_kref_put(tty);
++}
+ 
+-	if (packet_offset < urb->actual_length) {
+-		/* not completely processed - record progress */
+-		priv->rx_processed = packet_offset;
+-		dbg("%s - incomplete, %d bytes processed, %d remain",
+-				__func__, packet_offset,
+-				urb->actual_length - packet_offset);
+-		/* check if we were throttled while processing */
+-		spin_lock_irqsave(&priv->rx_lock, flags);
+-		if (priv->rx_flags & THROTTLED) {
+-			priv->rx_flags |= ACTUALLY_THROTTLED;
+-			spin_unlock_irqrestore(&priv->rx_lock, flags);
+-			dbg("%s - deferring remainder until unthrottled",
+-					__func__);
+-			goto out;
+-		}
+-		spin_unlock_irqrestore(&priv->rx_lock, flags);
+-		/* if the port is closed stop trying to read */
+-		if (port->port.count > 0)
+-			/* delay processing of remainder */
+-			schedule_delayed_work(&priv->rx_work, 1);
+-		else
+-			dbg("%s - port is closed", __func__);
+-		goto out;
+-	}
+-
+-	/* urb is completely processed */
+-	priv->rx_processed = 0;
++static void ftdi_read_bulk_callback(struct urb *urb)
++{
++	struct usb_serial_port *port = urb->context;
++	unsigned long flags;
+ 
+-	/* if the port is closed stop trying to read */
+-	if (port->port.count > 0) {
+-		/* Continue trying to always read  */
+-		usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+-			usb_rcvbulkpipe(port->serial->dev,
+-					port->bulk_in_endpointAddress),
+-			port->read_urb->transfer_buffer,
+-			port->read_urb->transfer_buffer_length,
+-			ftdi_read_bulk_callback, port);
++	dbg("%s - port %d", __func__, port->number);
+ 
+-		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+-		if (result)
+-			dev_err(&port->dev,
+-				"%s - failed resubmitting read urb, error %d\n",
+-				__func__, result);
++	if (urb->status) {
++		dbg("%s - nonzero read bulk status received: %d",
++						__func__, urb->status);
++		return;
+ 	}
+-out:
+-	tty_kref_put(tty);
+-} /* ftdi_process_read */
+ 
++	usb_serial_debug_data(debug, &port->dev, __func__,
++				urb->actual_length, urb->transfer_buffer);
++	ftdi_process_read(port);
++
++	spin_lock_irqsave(&port->lock, flags);
++	port->throttled = port->throttle_req;
++	if (!port->throttled) {
++		spin_unlock_irqrestore(&port->lock, flags);
++		ftdi_submit_read_urb(port, GFP_ATOMIC);
++	} else
++		spin_unlock_irqrestore(&port->lock, flags);
++}
+ 
+ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
+ {
+@@ -2611,33 +2449,31 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
+ static void ftdi_throttle(struct tty_struct *tty)
+ {
+ 	struct usb_serial_port *port = tty->driver_data;
+-	struct ftdi_private *priv = usb_get_serial_port_data(port);
+ 	unsigned long flags;
+ 
+ 	dbg("%s - port %d", __func__, port->number);
+ 
+-	spin_lock_irqsave(&priv->rx_lock, flags);
+-	priv->rx_flags |= THROTTLED;
+-	spin_unlock_irqrestore(&priv->rx_lock, flags);
++	spin_lock_irqsave(&port->lock, flags);
++	port->throttle_req = 1;
++	spin_unlock_irqrestore(&port->lock, flags);
+ }
+ 
+-
+-static void ftdi_unthrottle(struct tty_struct *tty)
++void ftdi_unthrottle(struct tty_struct *tty)
+ {
+ 	struct usb_serial_port *port = tty->driver_data;
+-	struct ftdi_private *priv = usb_get_serial_port_data(port);
+-	int actually_throttled;
++	int was_throttled;
+ 	unsigned long flags;
+ 
+ 	dbg("%s - port %d", __func__, port->number);
+ 
+-	spin_lock_irqsave(&priv->rx_lock, flags);
+-	actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
+-	priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
+-	spin_unlock_irqrestore(&priv->rx_lock, flags);
++	spin_lock_irqsave(&port->lock, flags);
++	was_throttled = port->throttled;
++	port->throttled = port->throttle_req = 0;
++	spin_unlock_irqrestore(&port->lock, flags);
+ 
+-	if (actually_throttled)
+-		schedule_delayed_work(&priv->rx_work, 0);
++	/* Resubmit urb if throttled and open. */
++	if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags))
++		ftdi_submit_read_urb(port, GFP_KERNEL);
+ }
+ 
+ static int __init ftdi_init(void)
+diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
+index ce57f6a..7170b69 100644
+--- a/drivers/usb/serial/generic.c
++++ b/drivers/usb/serial/generic.c
+@@ -530,7 +530,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
+ 
+ 	if (was_throttled) {
+ 		/* Resume reading from device */
+-		usb_serial_generic_resubmit_read_urb(port, GFP_KERNEL);
++		flush_and_resubmit_read_urb(port);
+ 	}
+ }
+ 
+diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
+index 2545d45..c4d0206 100644
+--- a/drivers/usb/serial/ipaq.c
++++ b/drivers/usb/serial/ipaq.c
+@@ -971,6 +971,15 @@ static int ipaq_calc_num_ports(struct usb_serial *serial)
+ static int ipaq_startup(struct usb_serial *serial)
+ {
+ 	dbg("%s", __func__);
++
++	/* Some of the devices in ipaq_id_table[] are composite, and we
++	 * shouldn't bind to all the interfaces.  This test will rule out
++	 * some obviously invalid possibilities.
++	 */
++	if (serial->num_bulk_in < serial->num_ports ||
++			serial->num_bulk_out < serial->num_ports)
++		return -ENODEV;
++
+ 	if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
+ 		/*
+ 		 * FIXME: HP iPaq rx3715, possibly others, have 1 config that
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 0101548..20b0788 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -319,6 +319,7 @@ static int  option_resume(struct usb_serial *serial);
+ /* TOSHIBA PRODUCTS */
+ #define TOSHIBA_VENDOR_ID			0x0930
+ #define TOSHIBA_PRODUCT_HSDPA_MINICARD		0x1302
++#define TOSHIBA_PRODUCT_G450			0x0d45
+ 
+ #define ALINK_VENDOR_ID				0x1e0e
+ #define ALINK_PRODUCT_3GU			0x9200
+@@ -582,6 +583,7 @@ static struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
+ 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
+ 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
++	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
+ 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
+ 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index 124d5ae..600097d 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -995,13 +995,15 @@ static void pl2303_push_data(struct tty_struct *tty,
+ 	/* overrun is special, not associated with a char */
+ 	if (line_status & UART_OVERRUN_ERROR)
+ 		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+-	if (port->console && port->sysrq) {
++
++	if (tty_flag == TTY_NORMAL && !(port->console && port->sysrq))
++		tty_insert_flip_string(tty, data, urb->actual_length);
++	else {
+ 		int i;
+ 		for (i = 0; i < urb->actual_length; ++i)
+ 			if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
+ 				tty_insert_flip_char(tty, data[i], tty_flag);
+-	} else
+-		tty_insert_flip_string(tty, data, urb->actual_length);
++	}
+ 	tty_flip_buffer_push(tty);
+ }
+ 
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index a0702db..3292e03 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -155,7 +155,8 @@ static void destroy_serial(struct kref *kref)
+ 	if (serial->minor != SERIAL_TTY_NO_MINOR)
+ 		return_serial(serial);
+ 
+-	serial->type->release(serial);
++	if (serial->attached)
++		serial->type->release(serial);
+ 
+ 	/* Now that nothing is using the ports, they can be freed */
+ 	for (i = 0; i < serial->num_port_pointers; ++i) {
+@@ -1060,12 +1061,15 @@ int usb_serial_probe(struct usb_interface *interface,
+ 		module_put(type->driver.owner);
+ 		if (retval < 0)
+ 			goto probe_error;
++		serial->attached = 1;
+ 		if (retval > 0) {
+ 			/* quietly accept this device, but don't bind to a
+ 			   serial port as it's about to disappear */
+ 			serial->num_ports = 0;
+ 			goto exit;
+ 		}
++	} else {
++		serial->attached = 1;
+ 	}
+ 
+ 	if (get_free_serial(serial, num_ports, &minor) == NULL) {
+diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
+index e20dc52..589f6b4 100644
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+ 		/* device supports and needs bigger sense buffer */
+ 		if (us->fflags & US_FL_SANE_SENSE)
+ 			sense_size = ~0;
+-
++Retry_Sense:
+ 		US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
+ 
+ 		scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
+@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+ 			srb->result = DID_ABORT << 16;
+ 			goto Handle_Errors;
+ 		}
++
++		/* Some devices claim to support larger sense but fail when
++		 * trying to request it. When a transport failure happens
++		 * using US_FS_SANE_SENSE, we always retry with a standard
++		 * (small) sense request. This fixes some USB GSM modems
++		 */
++		if (temp_result == USB_STOR_TRANSPORT_FAILED &&
++		    (us->fflags & US_FL_SANE_SENSE) &&
++		    sense_size != US_SENSE_SIZE) {
++			US_DEBUGP("-- auto-sense failure, retry small sense\n");
++			sense_size = US_SENSE_SIZE;
++			goto Retry_Sense;
++		}
++
++		/* Other failures */
+ 		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
+ 			US_DEBUGP("-- auto-sense failure\n");
+ 
+@@ -768,17 +783,32 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+ 		/* set the result so the higher layers expect this data */
+ 		srb->result = SAM_STAT_CHECK_CONDITION;
+ 
+-		/* If things are really okay, then let's show that.  Zero
+-		 * out the sense buffer so the higher layers won't realize
+-		 * we did an unsolicited auto-sense. */
+-		if (result == USB_STOR_TRANSPORT_GOOD &&
+-			/* Filemark 0, ignore EOM, ILI 0, no sense */
++		/* We often get empty sense data.  This could indicate that
++		 * everything worked or that there was an unspecified
++		 * problem.  We have to decide which.
++		 */
++		if (	/* Filemark 0, ignore EOM, ILI 0, no sense */
+ 				(srb->sense_buffer[2] & 0xaf) == 0 &&
+ 			/* No ASC or ASCQ */
+ 				srb->sense_buffer[12] == 0 &&
+ 				srb->sense_buffer[13] == 0) {
+-			srb->result = SAM_STAT_GOOD;
+-			srb->sense_buffer[0] = 0x0;
++
++			/* If things are really okay, then let's show that.
++			 * Zero out the sense buffer so the higher layers
++			 * won't realize we did an unsolicited auto-sense.
++			 */
++			if (result == USB_STOR_TRANSPORT_GOOD) {
++				srb->result = SAM_STAT_GOOD;
++				srb->sense_buffer[0] = 0x0;
++
++			/* If there was a problem, report an unspecified
++			 * hardware error to prevent the higher layers from
++			 * entering an infinite retry loop.
++			 */
++			} else {
++				srb->result = DID_ERROR << 16;
++				srb->sense_buffer[2] = HARDWARE_ERROR;
++			}
+ 		}
+ 	}
+ 
+diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
+index ca5b464..e35232a 100644
+--- a/drivers/video/uvesafb.c
++++ b/drivers/video/uvesafb.c
+@@ -67,12 +67,14 @@ static DEFINE_MUTEX(uvfb_lock);
+  * find the kernel part of the task struct, copy the registers and
+  * the buffer contents and then complete the task.
+  */
+-static void uvesafb_cn_callback(void *data)
++static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = data;
+ 	struct uvesafb_task *utask;
+ 	struct uvesafb_ktask *task;
+ 
++	if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
++		return;
++
+ 	if (msg->seq >= UVESAFB_TASKS_MAX)
+ 		return;
+ 
+diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
+index fdf7285..45c126f 100644
+--- a/drivers/w1/w1_netlink.c
++++ b/drivers/w1/w1_netlink.c
+@@ -306,9 +306,8 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
+ 	return error;
+ }
+ 
+-static void w1_cn_callback(void *data)
++static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
+ {
+-	struct cn_msg *msg = data;
+ 	struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
+ 	struct w1_netlink_cmd *cmd;
+ 	struct w1_slave *sl;
+diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
+index 561a9c0..f5ea468 100644
+--- a/fs/sysfs/file.c
++++ b/fs/sysfs/file.c
+@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
+ 	struct sysfs_open_dirent *od, *new_od = NULL;
+ 
+  retry:
+-	spin_lock(&sysfs_open_dirent_lock);
++	spin_lock_irq(&sysfs_open_dirent_lock);
+ 
+ 	if (!sd->s_attr.open && new_od) {
+ 		sd->s_attr.open = new_od;
+@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
+ 		list_add_tail(&buffer->list, &od->buffers);
+ 	}
+ 
+-	spin_unlock(&sysfs_open_dirent_lock);
++	spin_unlock_irq(&sysfs_open_dirent_lock);
+ 
+ 	if (od) {
+ 		kfree(new_od);
+@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
+ 				  struct sysfs_buffer *buffer)
+ {
+ 	struct sysfs_open_dirent *od = sd->s_attr.open;
++	unsigned long flags;
+ 
+-	spin_lock(&sysfs_open_dirent_lock);
++	spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
+ 
+ 	list_del(&buffer->list);
+ 	if (atomic_dec_and_test(&od->refcnt))
+@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
+ 	else
+ 		od = NULL;
+ 
+-	spin_unlock(&sysfs_open_dirent_lock);
++	spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
+ 
+ 	kfree(od);
+ }
+@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
+ void sysfs_notify_dirent(struct sysfs_dirent *sd)
+ {
+ 	struct sysfs_open_dirent *od;
++	unsigned long flags;
+ 
+-	spin_lock(&sysfs_open_dirent_lock);
++	spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
+ 
+ 	od = sd->s_attr.open;
+ 	if (od) {
+@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
+ 		wake_up_interruptible(&od->poll);
+ 	}
+ 
+-	spin_unlock(&sysfs_open_dirent_lock);
++	spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
+ 
+diff --git a/include/linux/connector.h b/include/linux/connector.h
+index b68d278..3a14615 100644
+--- a/include/linux/connector.h
++++ b/include/linux/connector.h
+@@ -132,11 +132,8 @@ struct cn_callback_id {
+ };
+ 
+ struct cn_callback_data {
+-	void (*destruct_data) (void *);
+-	void *ddata;
+-	
+-	void *callback_priv;
+-	void (*callback) (void *);
++	struct sk_buff *skb;
++	void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
+ 
+ 	void *free;
+ };
+@@ -167,11 +164,11 @@ struct cn_dev {
+ 	struct cn_queue_dev *cbdev;
+ };
+ 
+-int cn_add_callback(struct cb_id *, char *, void (*callback) (void *));
++int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
+ void cn_del_callback(struct cb_id *);
+ int cn_netlink_send(struct cn_msg *, u32, gfp_t);
+ 
+-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *));
++int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
+ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
+ 
+ int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
+diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
+index 73f121e..20b12f3 100644
+--- a/include/linux/usb/serial.h
++++ b/include/linux/usb/serial.h
+@@ -148,6 +148,7 @@ struct usb_serial {
+ 	struct usb_interface		*interface;
+ 	unsigned char			disconnected:1;
+ 	unsigned char			suspending:1;
++	unsigned char			attached:1;
+ 	unsigned char			minor;
+ 	unsigned char			num_ports;
+ 	unsigned char			num_port_pointers;
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index c4ca422..25b8a03 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -187,6 +187,7 @@ struct hci_conn {
+ 	struct work_struct work_del;
+ 
+ 	struct device	dev;
++	atomic_t	devref;
+ 
+ 	struct hci_dev	*hdev;
+ 	void		*l2cap_data;
+@@ -339,6 +340,9 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
+ void hci_conn_enter_active_mode(struct hci_conn *conn);
+ void hci_conn_enter_sniff_mode(struct hci_conn *conn);
+ 
++void hci_conn_hold_device(struct hci_conn *conn);
++void hci_conn_put_device(struct hci_conn *conn);
++
+ static inline void hci_conn_hold(struct hci_conn *conn)
+ {
+ 	atomic_inc(&conn->refcnt);
+diff --git a/kernel/acct.c b/kernel/acct.c
+index 9f33910..9a4715a 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -491,13 +491,17 @@ static void do_acct_process(struct bsd_acct_struct *acct,
+ 	u64 run_time;
+ 	struct timespec uptime;
+ 	struct tty_struct *tty;
++	const struct cred *orig_cred;
++
++	/* Perform file operations on behalf of whoever enabled accounting */
++	orig_cred = override_creds(file->f_cred);
+ 
+ 	/*
+ 	 * First check to see if there is enough free_space to continue
+ 	 * the process accounting system.
+ 	 */
+ 	if (!check_free_space(acct, file))
+-		return;
++		goto out;
+ 
+ 	/*
+ 	 * Fill the accounting struct with the needed info as recorded
+@@ -578,6 +582,8 @@ static void do_acct_process(struct bsd_acct_struct *acct,
+ 			       sizeof(acct_t), &file->f_pos);
+ 	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
+ 	set_fs(fs);
++out:
++	revert_creds(orig_cred);
+ }
+ 
+ /**
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 2362d06..59a2f4d 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -115,6 +115,9 @@ struct futex_q {
+ 	/* rt_waiter storage for requeue_pi: */
+ 	struct rt_mutex_waiter *rt_waiter;
+ 
++	/* The expected requeue pi target futex key: */
++	union futex_key *requeue_pi_key;
++
+ 	/* Bitset for the optional bitmasked wakeup */
+ 	u32 bitset;
+ };
+@@ -1089,6 +1092,10 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
+ 	if (!top_waiter)
+ 		return 0;
+ 
++	/* Ensure we requeue to the expected futex. */
++	if (!match_futex(top_waiter->requeue_pi_key, key2))
++		return -EINVAL;
++
+ 	/*
+ 	 * Try to take the lock for top_waiter.  Set the FUTEX_WAITERS bit in
+ 	 * the contended case or if set_waiters is 1.  The pi_state is returned
+@@ -1276,6 +1283,12 @@ retry_private:
+ 			continue;
+ 		}
+ 
++		/* Ensure we requeue to the expected futex for requeue_pi. */
++		if (requeue_pi && !match_futex(this->requeue_pi_key, &key2)) {
++			ret = -EINVAL;
++			break;
++		}
++
+ 		/*
+ 		 * Requeue nr_requeue waiters and possibly one more in the case
+ 		 * of requeue_pi if we couldn't acquire the lock atomically.
+@@ -1625,17 +1638,8 @@ out:
+ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
+ 				struct hrtimer_sleeper *timeout)
+ {
+-	queue_me(q, hb);
+-
+-	/*
+-	 * There might have been scheduling since the queue_me(), as we
+-	 * cannot hold a spinlock across the get_user() in case it
+-	 * faults, and we cannot just set TASK_INTERRUPTIBLE state when
+-	 * queueing ourselves into the futex hash. This code thus has to
+-	 * rely on the futex_wake() code removing us from hash when it
+-	 * wakes us up.
+-	 */
+ 	set_current_state(TASK_INTERRUPTIBLE);
++	queue_me(q, hb);
+ 
+ 	/* Arm the timer */
+ 	if (timeout) {
+@@ -1645,8 +1649,8 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
+ 	}
+ 
+ 	/*
+-	 * !plist_node_empty() is safe here without any lock.
+-	 * q.lock_ptr != 0 is not safe, because of ordering against wakeup.
++	 * If we have been removed from the hash list, then another task
++	 * has tried to wake us, and we can skip the call to schedule().
+ 	 */
+ 	if (likely(!plist_node_empty(&q->list))) {
+ 		/*
+@@ -1751,6 +1755,7 @@ static int futex_wait(u32 __user *uaddr, int fshared,
+ 	q.pi_state = NULL;
+ 	q.bitset = bitset;
+ 	q.rt_waiter = NULL;
++	q.requeue_pi_key = NULL;
+ 
+ 	if (abs_time) {
+ 		to = &timeout;
+@@ -1858,6 +1863,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
+ 
+ 	q.pi_state = NULL;
+ 	q.rt_waiter = NULL;
++	q.requeue_pi_key = NULL;
+ retry:
+ 	q.key = FUTEX_KEY_INIT;
+ 	ret = get_futex_key(uaddr, fshared, &q.key, VERIFY_WRITE);
+@@ -2168,15 +2174,16 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared,
+ 	debug_rt_mutex_init_waiter(&rt_waiter);
+ 	rt_waiter.task = NULL;
+ 
+-	q.pi_state = NULL;
+-	q.bitset = bitset;
+-	q.rt_waiter = &rt_waiter;
+-
+ 	key2 = FUTEX_KEY_INIT;
+ 	ret = get_futex_key(uaddr2, fshared, &key2, VERIFY_WRITE);
+ 	if (unlikely(ret != 0))
+ 		goto out;
+ 
++	q.pi_state = NULL;
++	q.bitset = bitset;
++	q.rt_waiter = &rt_waiter;
++	q.requeue_pi_key = &key2;
++
+ 	/* Prepare to wait on uaddr. */
+ 	ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
+ 	if (ret)
+diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
+index f32dc9d..a6b0d73 100644
+--- a/kernel/trace/trace_events_filter.c
++++ b/kernel/trace/trace_events_filter.c
+@@ -844,8 +844,9 @@ static void postfix_clear(struct filter_parse_state *ps)
+ 
+ 	while (!list_empty(&ps->postfix)) {
+ 		elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
+-		kfree(elt->operand);
+ 		list_del(&elt->list);
++		kfree(elt->operand);
++		kfree(elt);
+ 	}
+ }
+ 
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index fa47d5d..a975098 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -246,6 +246,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
+ 	if (hdev->notify)
+ 		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
+ 
++	atomic_set(&conn->devref, 0);
++
+ 	hci_conn_init_sysfs(conn);
+ 
+ 	tasklet_enable(&hdev->tx_task);
+@@ -288,7 +290,7 @@ int hci_conn_del(struct hci_conn *conn)
+ 
+ 	skb_queue_purge(&conn->data_q);
+ 
+-	hci_conn_del_sysfs(conn);
++	hci_conn_put_device(conn);
+ 
+ 	hci_dev_put(hdev);
+ 
+@@ -583,6 +585,19 @@ void hci_conn_check_pending(struct hci_dev *hdev)
+ 	hci_dev_unlock(hdev);
+ }
+ 
++void hci_conn_hold_device(struct hci_conn *conn)
++{
++	atomic_inc(&conn->devref);
++}
++EXPORT_SYMBOL(hci_conn_hold_device);
++
++void hci_conn_put_device(struct hci_conn *conn)
++{
++	if (atomic_dec_and_test(&conn->devref))
++		hci_conn_del_sysfs(conn);
++}
++EXPORT_SYMBOL(hci_conn_put_device);
++
+ int hci_get_conn_list(void __user *arg)
+ {
+ 	struct hci_conn_list_req req, *cl;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 184ba0a..e99fe38 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -887,6 +887,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
+ 		} else
+ 			conn->state = BT_CONNECTED;
+ 
++		hci_conn_hold_device(conn);
+ 		hci_conn_add_sysfs(conn);
+ 
+ 		if (test_bit(HCI_AUTH, &hdev->flags))
+@@ -1693,6 +1694,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
+ 		conn->handle = __le16_to_cpu(ev->handle);
+ 		conn->state  = BT_CONNECTED;
+ 
++		hci_conn_hold_device(conn);
+ 		hci_conn_add_sysfs(conn);
+ 		break;
+ 
+diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
+index b186768..9f1e765 100644
+--- a/net/bluetooth/hidp/core.c
++++ b/net/bluetooth/hidp/core.c
+@@ -40,6 +40,7 @@
+ 
+ #include <linux/input.h>
+ #include <linux/hid.h>
++#include <linux/hidraw.h>
+ 
+ #include <net/bluetooth/bluetooth.h>
+ #include <net/bluetooth/hci_core.h>
+@@ -92,10 +93,14 @@ static void __hidp_link_session(struct hidp_session *session)
+ {
+ 	__module_get(THIS_MODULE);
+ 	list_add(&session->list, &hidp_session_list);
++
++	hci_conn_hold_device(session->conn);
+ }
+ 
+ static void __hidp_unlink_session(struct hidp_session *session)
+ {
++	hci_conn_put_device(session->conn);
++
+ 	list_del(&session->list);
+ 	module_put(THIS_MODULE);
+ }
+@@ -573,7 +578,11 @@ static int hidp_session(void *arg)
+ 	if (session->hid) {
+ 		if (session->hid->claimed & HID_CLAIMED_INPUT)
+ 			hidinput_disconnect(session->hid);
++		if (session->hid->claimed & HID_CLAIMED_HIDRAW)
++			hidraw_disconnect(session->hid);
++
+ 		hid_destroy_device(session->hid);
++		session->hid = NULL;
+ 	}
+ 
+ 	/* Wakeup user-space polling for socket errors */
+@@ -601,25 +610,27 @@ static struct device *hidp_get_device(struct hidp_session *session)
+ {
+ 	bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
+ 	bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
++	struct device *device = NULL;
+ 	struct hci_dev *hdev;
+-	struct hci_conn *conn;
+ 
+ 	hdev = hci_get_route(dst, src);
+ 	if (!hdev)
+ 		return NULL;
+ 
+-	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
++	session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
++	if (session->conn)
++		device = &session->conn->dev;
+ 
+ 	hci_dev_put(hdev);
+ 
+-	return conn ? &conn->dev : NULL;
++	return device;
+ }
+ 
+ static int hidp_setup_input(struct hidp_session *session,
+ 				struct hidp_connadd_req *req)
+ {
+ 	struct input_dev *input;
+-	int i;
++	int err, i;
+ 
+ 	input = input_allocate_device();
+ 	if (!input)
+@@ -666,7 +677,13 @@ static int hidp_setup_input(struct hidp_session *session,
+ 
+ 	input->event = hidp_input_event;
+ 
+-	return input_register_device(input);
++	err = input_register_device(input);
++	if (err < 0) {
++		hci_conn_put_device(session->conn);
++		return err;
++	}
++
++	return 0;
+ }
+ 
+ static int hidp_open(struct hid_device *hid)
+@@ -748,13 +765,11 @@ static int hidp_setup_hid(struct hidp_session *session,
+ {
+ 	struct hid_device *hid;
+ 	bdaddr_t src, dst;
+-	int ret;
++	int err;
+ 
+ 	hid = hid_allocate_device();
+-	if (IS_ERR(hid)) {
+-		ret = PTR_ERR(session->hid);
+-		goto err;
+-	}
++	if (IS_ERR(hid))
++		return PTR_ERR(session->hid);
+ 
+ 	session->hid = hid;
+ 	session->req = req;
+@@ -776,16 +791,17 @@ static int hidp_setup_hid(struct hidp_session *session,
+ 	hid->dev.parent = hidp_get_device(session);
+ 	hid->ll_driver = &hidp_hid_driver;
+ 
+-	ret = hid_add_device(hid);
+-	if (ret)
+-		goto err_hid;
++	err = hid_add_device(hid);
++	if (err < 0)
++		goto failed;
+ 
+ 	return 0;
+-err_hid:
++
++failed:
+ 	hid_destroy_device(hid);
+ 	session->hid = NULL;
+-err:
+-	return ret;
++
++	return err;
+ }
+ 
+ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
+@@ -835,13 +851,13 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
+ 	if (req->rd_size > 0) {
+ 		err = hidp_setup_hid(session, req);
+ 		if (err && err != -ENODEV)
+-			goto err_skb;
++			goto purge;
+ 	}
+ 
+ 	if (!session->hid) {
+ 		err = hidp_setup_input(session, req);
+ 		if (err < 0)
+-			goto err_skb;
++			goto purge;
+ 	}
+ 
+ 	__hidp_link_session(session);
+@@ -869,13 +885,20 @@ unlink:
+ 
+ 	__hidp_unlink_session(session);
+ 
+-	if (session->input)
++	if (session->input) {
+ 		input_unregister_device(session->input);
+-	if (session->hid)
++		session->input = NULL;
++	}
++
++	if (session->hid) {
+ 		hid_destroy_device(session->hid);
+-err_skb:
++		session->hid = NULL;
++	}
++
++purge:
+ 	skb_queue_purge(&session->ctrl_transmit);
+ 	skb_queue_purge(&session->intr_transmit);
++
+ failed:
+ 	up_write(&hidp_session_sem);
+ 
+diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
+index e503c89..faf3d74 100644
+--- a/net/bluetooth/hidp/hidp.h
++++ b/net/bluetooth/hidp/hidp.h
+@@ -126,6 +126,8 @@ int hidp_get_conninfo(struct hidp_conninfo *ci);
+ struct hidp_session {
+ 	struct list_head list;
+ 
++	struct hci_conn *conn;
++
+ 	struct socket *ctrl_sock;
+ 	struct socket *intr_sock;
+ 
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 0936fc2..9e50fdb 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2155,11 +2155,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+ 
+ 	skb = rx.skb;
+ 
+-	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
++	if (rx.sdata && ieee80211_is_data(hdr->frame_control)) {
++		rx.flags |= IEEE80211_RX_RA_MATCH;
++		prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
++		if (prepares)
++			prev = rx.sdata;
++	} else list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ 		if (!netif_running(sdata->dev))
+ 			continue;
+ 
+-		if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
++		if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
++		    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ 			continue;
+ 
+ 		rx.flags |= IEEE80211_RX_RA_MATCH;
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index a360bce..5ccfd10 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -360,6 +360,7 @@ int sta_info_insert(struct sta_info *sta)
+ 					     u.ap);
+ 
+ 		drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
++		sdata = sta->sdata;
+ 	}
+ 
+ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+@@ -494,6 +495,7 @@ static void __sta_info_unlink(struct sta_info **sta)
+ 
+ 		drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+ 			       &(*sta)->sta);
++		sdata = (*sta)->sdata;
+ 	}
+ 
+ 	if (ieee80211_vif_is_mesh(&sdata->vif)) {
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 3a8922c..98576d4 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1736,7 +1736,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 	if (!is_multicast_ether_addr(hdr.addr1)) {
+ 		rcu_read_lock();
+ 		sta = sta_info_get(local, hdr.addr1);
+-		if (sta)
++		/* XXX: in the future, use sdata to look up the sta */
++		if (sta && sta->sdata == sdata)
+ 			sta_flags = get_sta_flags(sta);
+ 		rcu_read_unlock();
+ 	}
+diff --git a/scripts/Makefile.build b/scripts/Makefile.build
+index 5c4b7a4..98112d0 100644
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -269,7 +269,8 @@ targets += $(extra-y) $(MAKECMDGOALS) $(always)
+ # Linker scripts preprocessor (.lds.S -> .lds)
+ # ---------------------------------------------------------------------------
+ quiet_cmd_cpp_lds_S = LDS     $@
+-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
++      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
++	                     -D__ASSEMBLY__ -o $@ $<
+ 
+ $(obj)/%.lds: $(src)/%.lds.S FORCE
+ 	$(call if_changed_dep,cpp_lds_S)
+diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
+index f0ebc97..1dd66dd 100644
+--- a/sound/aoa/codecs/tas.c
++++ b/sound/aoa/codecs/tas.c
+@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
+ 	client = i2c_new_device(adapter, &info);
+ 	if (!client)
+ 		return -ENODEV;
++	/*
++	 * We know the driver is already loaded, so the device should be
++	 * already bound. If not it means binding failed, and then there
++	 * is no point in keeping the device instantiated.
++	 */
++	if (!client->driver) {
++		i2c_unregister_device(client);
++		return -ENODEV;
++	}
+ 
+ 	/*
+ 	 * Let i2c-core delete that device on driver removal.
+diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
+index 835fa19..bb6819a 100644
+--- a/sound/ppc/keywest.c
++++ b/sound/ppc/keywest.c
+@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
+ 	strlcpy(info.type, "keywest", I2C_NAME_SIZE);
+ 	info.addr = keywest_ctx->addr;
+ 	keywest_ctx->client = i2c_new_device(adapter, &info);
++	if (!keywest_ctx->client)
++		return -ENODEV;
++	/*
++	 * We know the driver is already loaded, so the device should be
++	 * already bound. If not it means binding failed, and then there
++	 * is no point in keeping the device instantiated.
++	 */
++	if (!keywest_ctx->client->driver) {
++		i2c_unregister_device(keywest_ctx->client);
++		keywest_ctx->client = NULL;
++		return -ENODEV;
++	}
+ 	
+ 	/*
+ 	 * Let i2c-core delete that device on driver removal.

Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base	Thu Oct 22 22:46:05 2009	(r14421)
+++ dists/trunk/linux-2.6/debian/patches/series/base	Fri Oct 23 01:13:40 2009	(r14422)
@@ -59,3 +59,4 @@
 + bugfix/all/hfsplus-limit-to-2tb.patch
 + bugfix/all/stable/2.6.31.4.patch
 + bugfix/all/cpuidle-return-with-irq-enabled.patch
++ bugfix/all/stable/2.6.31.5.patch



More information about the Kernel-svn-changes mailing list