From da534ba7f1db249b09aba292e8f353209058be66 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 23 Oct 2009 01:13:40 +0000 Subject: [PATCH] Add stable release 2.6.31.5 svn path=/dists/trunk/linux-2.6/; revision=14422 --- debian/changelog | 1 + .../patches/bugfix/all/stable/2.6.31.5.patch | 2585 +++++++++++++++++ debian/patches/series/base | 1 + 3 files changed, 2587 insertions(+) create mode 100644 debian/patches/bugfix/all/stable/2.6.31.5.patch diff --git a/debian/changelog b/debian/changelog index 292e52cb2..096dff260 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ linux-2.6 (2.6.31-1~experimental.3) UNRELEASED; urgency=low [ 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. diff --git a/debian/patches/bugfix/all/stable/2.6.31.5.patch b/debian/patches/bugfix/all/stable/2.6.31.5.patch new file mode 100644 index 000000000..40d5bc3d0 --- /dev/null +++ b/debian/patches/bugfix/all/stable/2.6.31.5.patch @@ -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 ++M: Riku Voipio + L: lm-sensors@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 + #include ++#include + + #include + #include +@@ -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. diff --git a/debian/patches/series/base b/debian/patches/series/base index 13846eb6d..1ded6acda 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -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