* [gentoo-commits] linux-patches r1624 - genpatches-2.6/trunk/2.6.31
@ 2009-10-23 13:46 Mike Pagano (mpagano)
0 siblings, 0 replies; only message in thread
From: Mike Pagano (mpagano) @ 2009-10-23 13:46 UTC (permalink / raw
To: gentoo-commits
Author: mpagano
Date: 2009-10-23 13:46:13 +0000 (Fri, 23 Oct 2009)
New Revision: 1624
Added:
genpatches-2.6/trunk/2.6.31/1004_linux-2.6.31.5.patch
genpatches-2.6/trunk/2.6.31/2900_makefile-changes.patch
Modified:
genpatches-2.6/trunk/2.6.31/0000_README
Log:
Linux patch 2.6.31.5. Changes for makefile included in 2.6.31.5
Modified: genpatches-2.6/trunk/2.6.31/0000_README
===================================================================
--- genpatches-2.6/trunk/2.6.31/0000_README 2009-10-14 01:10:41 UTC (rev 1623)
+++ genpatches-2.6/trunk/2.6.31/0000_README 2009-10-23 13:46:13 UTC (rev 1624)
@@ -63,6 +63,10 @@
From: http://www.kernel.org
Desc: Linux 2.6.31.4
+Patch: 1004_linux-2.6.31.5.patch
+From: http://www.kernel.org
+Desc: Linux 2.6.31.5
+
Patch: 2700_kworld-plustv-dual-dvb.patch
From: http://bugs.gentoo.org/show_bug.cgi?id=288818
Desc: Add new USB ID for KWorld PlusTV Dual DVB-T Stick
@@ -78,3 +82,8 @@
Patch: 4400_alpha-sysctl-uac.patch
From: Tavis Ormandy <taviso@gentoo.org> and http://bugs.gentoo.org/show_bug.cgi?id=217323
Desc: Enable control of the unaligned access control policy from sysctl
+
+Patch: 2900_makefile-changes.patch
+From: http://www.kernel.org
+Desc: Minor patch to makefile from Linux 2.6.31.5
+
Added: genpatches-2.6/trunk/2.6.31/1004_linux-2.6.31.5.patch
===================================================================
--- genpatches-2.6/trunk/2.6.31/1004_linux-2.6.31.5.patch (rev 0)
+++ genpatches-2.6/trunk/2.6.31/1004_linux-2.6.31.5.patch 2009-10-23 13:46:13 UTC (rev 1624)
@@ -0,0 +1,2583 @@
+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@iki.fi>
++M: Riku Voipio <riku.voipio@iki.fi>
+ L: lm-sensors@lm-sensors.org
+ S: Maintained
+ F: drivers/hwmon/f75375s.c
+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.
Added: genpatches-2.6/trunk/2.6.31/2900_makefile-changes.patch
===================================================================
--- genpatches-2.6/trunk/2.6.31/2900_makefile-changes.patch (rev 0)
+++ genpatches-2.6/trunk/2.6.31/2900_makefile-changes.patch 2009-10-23 13:46:13 UTC (rev 1624)
@@ -0,0 +1,16 @@
+diff --git a/Makefile b/Makefile
+index 314a3aa..8190a1c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -980,11 +980,6 @@ prepare0: archprepare FORCE
+ # All the preparing..
+ prepare: prepare0
+
+-# Leave this as default for preprocessing vmlinux.lds.S, which is now
+-# done in arch/$(ARCH)/kernel/Makefile
+-
+-export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
+-
+ # The asm symlink changes when $(ARCH) changes.
+ # Detect this and ask user to run make mrproper
+ # If asm is a stale symlink (point to dir that does not exist) remove it
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-10-23 13:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-23 13:46 [gentoo-commits] linux-patches r1624 - genpatches-2.6/trunk/2.6.31 Mike Pagano (mpagano)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox