diff options
Diffstat (limited to '3.2.53/1051_linux-3.2.52.patch')
-rw-r--r-- | 3.2.53/1051_linux-3.2.52.patch | 5221 |
1 files changed, 5221 insertions, 0 deletions
diff --git a/3.2.53/1051_linux-3.2.52.patch b/3.2.53/1051_linux-3.2.52.patch new file mode 100644 index 0000000..94b9359 --- /dev/null +++ b/3.2.53/1051_linux-3.2.52.patch @@ -0,0 +1,5221 @@ +diff --git a/Makefile b/Makefile +index 0f11936..1dd2c09 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 51 ++SUBLEVEL = 52 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c +index c898deb..189ed00 100644 +--- a/arch/arm/mach-versatile/pci.c ++++ b/arch/arm/mach-versatile/pci.c +@@ -43,9 +43,9 @@ + #define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0) + #define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4) + #define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8) +-#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10) +-#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) +-#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14) ++#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18) ++#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c) + #define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc) + + #define DEVICE_ID_OFFSET 0x00 +diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c +index fbdd12e..cc3f35d 100644 +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -98,6 +98,9 @@ void show_mem(unsigned int filter) + printk("Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank (i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c +index f114a3b..ce6e7a8 100644 +--- a/arch/ia64/mm/contig.c ++++ b/arch/ia64/mm/contig.c +@@ -46,6 +46,8 @@ void show_mem(unsigned int filter) + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); + printk(KERN_INFO "Node memory in pages:\n"); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + for_each_online_pgdat(pgdat) { + unsigned long present; + unsigned long flags; +diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c +index c641333..2230817 100644 +--- a/arch/ia64/mm/discontig.c ++++ b/arch/ia64/mm/discontig.c +@@ -623,6 +623,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + printk(KERN_INFO "Node memory in pages:\n"); + for_each_online_pgdat(pgdat) { + unsigned long present; +diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds +new file mode 100644 +index 0000000..40e02d9 +--- /dev/null ++++ b/arch/m68k/kernel/vmlinux-nommu.lds +@@ -0,0 +1,93 @@ ++/* ++ * vmlinux.lds.S -- master linker script for m68knommu arch ++ * ++ * (C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com> ++ * ++ * This linker script is equipped to build either ROM loaded or RAM ++ * run kernels. ++ */ ++ ++#if defined(CONFIG_RAMKERNEL) ++#define KTEXT_ADDR CONFIG_KERNELBASE ++#endif ++#if defined(CONFIG_ROMKERNEL) ++#define KTEXT_ADDR CONFIG_ROMSTART ++#define KDATA_ADDR CONFIG_KERNELBASE ++#define LOAD_OFFSET KDATA_ADDR + (ADDR(.text) + SIZEOF(.text)) ++#endif ++ ++#include <asm/page.h> ++#include <asm/thread_info.h> ++#include <asm-generic/vmlinux.lds.h> ++ ++OUTPUT_ARCH(m68k) ++ENTRY(_start) ++ ++jiffies = jiffies_64 + 4; ++ ++SECTIONS { ++ ++#ifdef CONFIG_ROMVEC ++ . = CONFIG_ROMVEC; ++ .romvec : { ++ __rom_start = .; ++ _romvec = .; ++ *(.romvec) ++ *(.data..initvect) ++ } ++#endif ++ ++ . = KTEXT_ADDR; ++ ++ _text = .; ++ _stext = .; ++ .text : { ++ HEAD_TEXT ++ TEXT_TEXT ++ SCHED_TEXT ++ LOCK_TEXT ++ *(.fixup) ++ . = ALIGN(16); ++ } ++ _etext = .; ++ ++#ifdef KDATA_ADDR ++ . = KDATA_ADDR; ++#endif ++ ++ _sdata = .; ++ RO_DATA_SECTION(PAGE_SIZE) ++ RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) ++ _edata = .; ++ ++ EXCEPTION_TABLE(16) ++ NOTES ++ ++ . = ALIGN(PAGE_SIZE); ++ __init_begin = .; ++ INIT_TEXT_SECTION(PAGE_SIZE) ++ INIT_DATA_SECTION(16) ++ PERCPU_SECTION(16) ++ .m68k_fixup : { ++ __start_fixup = .; ++ *(.m68k_fixup) ++ __stop_fixup = .; ++ } ++ .init.data : { ++ . = ALIGN(PAGE_SIZE); ++ __init_end = .; ++ } ++ ++ _sbss = .; ++ BSS_SECTION(0, 0, 0) ++ _ebss = .; ++ ++ _end = .; ++ ++ STABS_DEBUG ++ .comment 0 : { *(.comment) } ++ ++ /* Sections to be discarded */ ++ DISCARDS ++} ++ +diff --git a/arch/m68k/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S +index 030dabf..69ec796 100644 +--- a/arch/m68k/kernel/vmlinux.lds.S ++++ b/arch/m68k/kernel/vmlinux.lds.S +@@ -1,5 +1,14 @@ +-#ifdef CONFIG_MMU +-#include "vmlinux.lds_mm.S" ++#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) ++PHDRS ++{ ++ text PT_LOAD FILEHDR PHDRS FLAGS (7); ++ data PT_LOAD FLAGS (7); ++} ++#ifdef CONFIG_SUN3 ++#include "vmlinux-sun3.lds" + #else +-#include "vmlinux.lds_no.S" ++#include "vmlinux-std.lds" ++#endif ++#else ++#include "vmlinux-nommu.lds" + #endif +diff --git a/arch/m68k/kernel/vmlinux.lds_mm.S b/arch/m68k/kernel/vmlinux.lds_mm.S +deleted file mode 100644 +index 99ba315..0000000 +--- a/arch/m68k/kernel/vmlinux.lds_mm.S ++++ /dev/null +@@ -1,10 +0,0 @@ +-PHDRS +-{ +- text PT_LOAD FILEHDR PHDRS FLAGS (7); +- data PT_LOAD FLAGS (7); +-} +-#ifdef CONFIG_SUN3 +-#include "vmlinux-sun3.lds" +-#else +-#include "vmlinux-std.lds" +-#endif +diff --git a/arch/m68k/kernel/vmlinux.lds_no.S b/arch/m68k/kernel/vmlinux.lds_no.S +deleted file mode 100644 +index 4e23893..0000000 +--- a/arch/m68k/kernel/vmlinux.lds_no.S ++++ /dev/null +@@ -1,187 +0,0 @@ +-/* +- * vmlinux.lds.S -- master linker script for m68knommu arch +- * +- * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com> +- * +- * This linker script is equipped to build either ROM loaded or RAM +- * run kernels. +- */ +- +-#include <asm-generic/vmlinux.lds.h> +-#include <asm/page.h> +-#include <asm/thread_info.h> +- +-#if defined(CONFIG_RAMKERNEL) +-#define RAM_START CONFIG_KERNELBASE +-#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE) +-#define TEXT ram +-#define DATA ram +-#define INIT ram +-#define BSSS ram +-#endif +-#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) +-#define RAM_START CONFIG_RAMBASE +-#define RAM_LENGTH CONFIG_RAMSIZE +-#define ROMVEC_START CONFIG_ROMVEC +-#define ROMVEC_LENGTH CONFIG_ROMVECSIZE +-#define ROM_START CONFIG_ROMSTART +-#define ROM_LENGTH CONFIG_ROMSIZE +-#define TEXT rom +-#define DATA ram +-#define INIT ram +-#define BSSS ram +-#endif +- +-#ifndef DATA_ADDR +-#define DATA_ADDR +-#endif +- +- +-OUTPUT_ARCH(m68k) +-ENTRY(_start) +- +-MEMORY { +- ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH +-#ifdef ROM_START +- romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH +- rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH +-#endif +-} +- +-jiffies = jiffies_64 + 4; +- +-SECTIONS { +- +-#ifdef ROMVEC_START +- . = ROMVEC_START ; +- .romvec : { +- __rom_start = . ; +- _romvec = .; +- *(.data..initvect) +- } > romvec +-#endif +- +- .text : { +- _text = .; +- _stext = . ; +- HEAD_TEXT +- TEXT_TEXT +- SCHED_TEXT +- LOCK_TEXT +- *(.text..lock) +- +- . = ALIGN(16); /* Exception table */ +- __start___ex_table = .; +- *(__ex_table) +- __stop___ex_table = .; +- +- *(.rodata) *(.rodata.*) +- *(__vermagic) /* Kernel version magic */ +- *(.rodata1) +- *(.rodata.str1.1) +- +- /* Kernel symbol table: Normal symbols */ +- . = ALIGN(4); +- __start___ksymtab = .; +- *(SORT(___ksymtab+*)) +- __stop___ksymtab = .; +- +- /* Kernel symbol table: GPL-only symbols */ +- __start___ksymtab_gpl = .; +- *(SORT(___ksymtab_gpl+*)) +- __stop___ksymtab_gpl = .; +- +- /* Kernel symbol table: Normal unused symbols */ +- __start___ksymtab_unused = .; +- *(SORT(___ksymtab_unused+*)) +- __stop___ksymtab_unused = .; +- +- /* Kernel symbol table: GPL-only unused symbols */ +- __start___ksymtab_unused_gpl = .; +- *(SORT(___ksymtab_unused_gpl+*)) +- __stop___ksymtab_unused_gpl = .; +- +- /* Kernel symbol table: GPL-future symbols */ +- __start___ksymtab_gpl_future = .; +- *(SORT(___ksymtab_gpl_future+*)) +- __stop___ksymtab_gpl_future = .; +- +- /* Kernel symbol table: Normal symbols */ +- __start___kcrctab = .; +- *(SORT(___kcrctab+*)) +- __stop___kcrctab = .; +- +- /* Kernel symbol table: GPL-only symbols */ +- __start___kcrctab_gpl = .; +- *(SORT(___kcrctab_gpl+*)) +- __stop___kcrctab_gpl = .; +- +- /* Kernel symbol table: Normal unused symbols */ +- __start___kcrctab_unused = .; +- *(SORT(___kcrctab_unused+*)) +- __stop___kcrctab_unused = .; +- +- /* Kernel symbol table: GPL-only unused symbols */ +- __start___kcrctab_unused_gpl = .; +- *(SORT(___kcrctab_unused_gpl+*)) +- __stop___kcrctab_unused_gpl = .; +- +- /* Kernel symbol table: GPL-future symbols */ +- __start___kcrctab_gpl_future = .; +- *(SORT(___kcrctab_gpl_future+*)) +- __stop___kcrctab_gpl_future = .; +- +- /* Kernel symbol table: strings */ +- *(__ksymtab_strings) +- +- /* Built-in module parameters */ +- . = ALIGN(4) ; +- __start___param = .; +- *(__param) +- __stop___param = .; +- +- /* Built-in module versions */ +- . = ALIGN(4) ; +- __start___modver = .; +- *(__modver) +- __stop___modver = .; +- +- . = ALIGN(4) ; +- _etext = . ; +- } > TEXT +- +- .data DATA_ADDR : { +- . = ALIGN(4); +- _sdata = . ; +- DATA_DATA +- CACHELINE_ALIGNED_DATA(32) +- PAGE_ALIGNED_DATA(PAGE_SIZE) +- *(.data..shared_aligned) +- INIT_TASK_DATA(THREAD_SIZE) +- _edata = . ; +- } > DATA +- +- .init.text : { +- . = ALIGN(PAGE_SIZE); +- __init_begin = .; +- } > INIT +- INIT_TEXT_SECTION(PAGE_SIZE) > INIT +- INIT_DATA_SECTION(16) > INIT +- .init.data : { +- . = ALIGN(PAGE_SIZE); +- __init_end = .; +- } > INIT +- +- .bss : { +- . = ALIGN(4); +- _sbss = . ; +- *(.bss) +- *(COMMON) +- . = ALIGN(4) ; +- _ebss = . ; +- _end = . ; +- } > BSSS +- +- DISCARDS +-} +- +diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c +index 82f364e..0b62162 100644 +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -685,6 +685,8 @@ void show_mem(unsigned int filter) + + printk(KERN_INFO "Mem-info:\n"); + show_free_areas(filter); ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; + #ifndef CONFIG_DISCONTIGMEM + i = max_mapnr; + while (i-- > 0) { +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index 8184ee9..3fcbae0 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -764,6 +764,16 @@ int fix_alignment(struct pt_regs *regs) + nb = aligninfo[instr].len; + flags = aligninfo[instr].flags; + ++ /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ ++ if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { ++ nb = 8; ++ flags = LD+SW; ++ } else if (IS_XFORM(instruction) && ++ ((instruction >> 1) & 0x3ff) == 660) { ++ nb = 8; ++ flags = ST+SW; ++ } ++ + /* Byteswap little endian loads and stores */ + swiz = 0; + if (regs->msr & MSR_LE) { +diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c +index 0cfcf98..d0b205c 100644 +--- a/arch/powerpc/kernel/iommu.c ++++ b/arch/powerpc/kernel/iommu.c +@@ -495,7 +495,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) + /* number of bytes needed for the bitmap */ + sz = (tbl->it_size + 7) >> 3; + +- page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); ++ page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz)); + if (!page) + panic("iommu_init_table: Can't allocate %ld bytes\n", sz); + tbl->it_map = page_address(page); +diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c +index 826681d..26af24b 100644 +--- a/arch/powerpc/kernel/lparcfg.c ++++ b/arch/powerpc/kernel/lparcfg.c +@@ -375,6 +375,7 @@ static void parse_system_parameter_string(struct seq_file *m) + __pa(rtas_data_buf), + RTAS_DATA_BUF_SIZE); + memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); ++ local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; + spin_unlock(&rtas_data_buf_lock); + + if (call_status != 0) { +diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c +index 55be64d..ca683a1 100644 +--- a/arch/powerpc/kernel/sysfs.c ++++ b/arch/powerpc/kernel/sysfs.c +@@ -18,6 +18,7 @@ + #include <asm/machdep.h> + #include <asm/smp.h> + #include <asm/pmc.h> ++#include <asm/firmware.h> + + #include "cacheinfo.h" + +@@ -178,14 +179,24 @@ SYSFS_PMCSETUP(purr, SPRN_PURR); + SYSFS_PMCSETUP(spurr, SPRN_SPURR); + SYSFS_PMCSETUP(dscr, SPRN_DSCR); + ++/* ++ Lets only enable read for phyp resources and ++ enable write when needed with a separate function. ++ Lets be conservative and default to pseries. ++*/ + static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); + static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); + static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); +-static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); ++static SYSDEV_ATTR(purr, 0400, show_purr, store_purr); + + unsigned long dscr_default = 0; + EXPORT_SYMBOL(dscr_default); + ++static void add_write_permission_dev_attr(struct sysdev_attribute *attr) ++{ ++ attr->attr.mode |= 0200; ++} ++ + static ssize_t show_dscr_default(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) + { +@@ -394,8 +405,11 @@ static void __cpuinit register_cpu_online(unsigned int cpu) + if (cpu_has_feature(CPU_FTR_MMCRA)) + sysdev_create_file(s, &attr_mmcra); + +- if (cpu_has_feature(CPU_FTR_PURR)) ++ if (cpu_has_feature(CPU_FTR_PURR)) { ++ if (!firmware_has_feature(FW_FEATURE_LPAR)) ++ add_write_permission_dev_attr(&attr_purr); + sysdev_create_file(s, &attr_purr); ++ } + + if (cpu_has_feature(CPU_FTR_SPURR)) + sysdev_create_file(s, &attr_spurr); +diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S +index 18245af..3cdbc64 100644 +--- a/arch/powerpc/lib/checksum_64.S ++++ b/arch/powerpc/lib/checksum_64.S +@@ -229,19 +229,35 @@ _GLOBAL(csum_partial) + blr + + +- .macro source ++ .macro srcnr + 100: + .section __ex_table,"a" + .align 3 +- .llong 100b,.Lsrc_error ++ .llong 100b,.Lsrc_error_nr + .previous + .endm + +- .macro dest ++ .macro source ++150: ++ .section __ex_table,"a" ++ .align 3 ++ .llong 150b,.Lsrc_error ++ .previous ++ .endm ++ ++ .macro dstnr + 200: + .section __ex_table,"a" + .align 3 +- .llong 200b,.Ldest_error ++ .llong 200b,.Ldest_error_nr ++ .previous ++ .endm ++ ++ .macro dest ++250: ++ .section __ex_table,"a" ++ .align 3 ++ .llong 250b,.Ldest_error + .previous + .endm + +@@ -272,16 +288,16 @@ _GLOBAL(csum_partial_copy_generic) + rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */ + beq .Lcopy_aligned + +- li r7,4 +- sub r6,r7,r6 ++ li r9,4 ++ sub r6,r9,r6 + mtctr r6 + + 1: +-source; lhz r6,0(r3) /* align to doubleword */ ++srcnr; lhz r6,0(r3) /* align to doubleword */ + subi r5,r5,2 + addi r3,r3,2 + adde r0,r0,r6 +-dest; sth r6,0(r4) ++dstnr; sth r6,0(r4) + addi r4,r4,2 + bdnz 1b + +@@ -395,10 +411,10 @@ dest; std r16,56(r4) + + mtctr r6 + 3: +-source; ld r6,0(r3) ++srcnr; ld r6,0(r3) + addi r3,r3,8 + adde r0,r0,r6 +-dest; std r6,0(r4) ++dstnr; std r6,0(r4) + addi r4,r4,8 + bdnz 3b + +@@ -408,10 +424,10 @@ dest; std r6,0(r4) + srdi. r6,r5,2 + beq .Lcopy_tail_halfword + +-source; lwz r6,0(r3) ++srcnr; lwz r6,0(r3) + addi r3,r3,4 + adde r0,r0,r6 +-dest; stw r6,0(r4) ++dstnr; stw r6,0(r4) + addi r4,r4,4 + subi r5,r5,4 + +@@ -419,10 +435,10 @@ dest; stw r6,0(r4) + srdi. r6,r5,1 + beq .Lcopy_tail_byte + +-source; lhz r6,0(r3) ++srcnr; lhz r6,0(r3) + addi r3,r3,2 + adde r0,r0,r6 +-dest; sth r6,0(r4) ++dstnr; sth r6,0(r4) + addi r4,r4,2 + subi r5,r5,2 + +@@ -430,10 +446,10 @@ dest; sth r6,0(r4) + andi. r6,r5,1 + beq .Lcopy_finish + +-source; lbz r6,0(r3) ++srcnr; lbz r6,0(r3) + sldi r9,r6,8 /* Pad the byte out to 16 bits */ + adde r0,r0,r9 +-dest; stb r6,0(r4) ++dstnr; stb r6,0(r4) + + .Lcopy_finish: + addze r0,r0 /* add in final carry */ +@@ -443,6 +459,11 @@ dest; stb r6,0(r4) + blr + + .Lsrc_error: ++ ld r14,STK_REG(r14)(r1) ++ ld r15,STK_REG(r15)(r1) ++ ld r16,STK_REG(r16)(r1) ++ addi r1,r1,STACKFRAMESIZE ++.Lsrc_error_nr: + cmpdi 0,r7,0 + beqlr + li r6,-EFAULT +@@ -450,6 +471,11 @@ dest; stb r6,0(r4) + blr + + .Ldest_error: ++ ld r14,STK_REG(r14)(r1) ++ ld r15,STK_REG(r15)(r1) ++ ld r16,STK_REG(r16)(r1) ++ addi r1,r1,STACKFRAMESIZE ++.Ldest_error_nr: + cmpdi 0,r8,0 + beqlr + li r6,-EFAULT +diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S +index f445e98..cfabc3d 100644 +--- a/arch/sparc/kernel/entry.S ++++ b/arch/sparc/kernel/entry.S +@@ -1177,7 +1177,7 @@ sys_sigreturn: + nop + + call syscall_trace +- nop ++ mov 1, %o1 + + 1: + /* We don't want to muck with user registers like a +diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S +index 79f3103..7c00735 100644 +--- a/arch/sparc/kernel/ktlb.S ++++ b/arch/sparc/kernel/ktlb.S +@@ -25,11 +25,10 @@ kvmap_itlb: + */ + kvmap_itlb_4v: + +-kvmap_itlb_nonlinear: + /* Catch kernel NULL pointer calls. */ + sethi %hi(PAGE_SIZE), %g5 + cmp %g4, %g5 +- bleu,pn %xcc, kvmap_dtlb_longpath ++ blu,pn %xcc, kvmap_itlb_longpath + nop + + KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load) +diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S +index 7f5f65d..817187d 100644 +--- a/arch/sparc/kernel/syscalls.S ++++ b/arch/sparc/kernel/syscalls.S +@@ -147,7 +147,7 @@ linux_syscall_trace32: + srl %i4, 0, %o4 + srl %i1, 0, %o1 + srl %i2, 0, %o2 +- ba,pt %xcc, 2f ++ ba,pt %xcc, 5f + srl %i3, 0, %o3 + + linux_syscall_trace: +@@ -177,13 +177,13 @@ linux_sparc_syscall32: + srl %i1, 0, %o1 ! IEU0 Group + ldx [%g6 + TI_FLAGS], %l0 ! Load + +- srl %i5, 0, %o5 ! IEU1 ++ srl %i3, 0, %o3 ! IEU0 + srl %i2, 0, %o2 ! IEU0 Group + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + bne,pn %icc, linux_syscall_trace32 ! CTI + mov %i0, %l5 ! IEU1 +- call %l7 ! CTI Group brk forced +- srl %i3, 0, %o3 ! IEU0 ++5: call %l7 ! CTI Group brk forced ++ srl %i5, 0, %o5 ! IEU1 + ba,a,pt %xcc, 3f + + /* Linux native system calls enter here... */ +diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S +index da1b781..8fa84a3 100644 +--- a/arch/sparc/kernel/trampoline_64.S ++++ b/arch/sparc/kernel/trampoline_64.S +@@ -131,7 +131,6 @@ startup_continue: + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + mov 15, %l7 + BRANCH_IF_ANY_CHEETAH(g1,g5,2f) +@@ -224,7 +223,6 @@ niagara_lock_tlb: + clr %l5 + sethi %hi(num_kernel_image_mappings), %l6 + lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 +- add %l6, 1, %l6 + + 1: + mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 +diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c +index 1b30bb3..fbb8005 100644 +--- a/arch/sparc/lib/ksyms.c ++++ b/arch/sparc/lib/ksyms.c +@@ -131,15 +131,6 @@ EXPORT_SYMBOL(___copy_from_user); + EXPORT_SYMBOL(___copy_in_user); + EXPORT_SYMBOL(__clear_user); + +-/* RW semaphores */ +-EXPORT_SYMBOL(__down_read); +-EXPORT_SYMBOL(__down_read_trylock); +-EXPORT_SYMBOL(__down_write); +-EXPORT_SYMBOL(__down_write_trylock); +-EXPORT_SYMBOL(__up_read); +-EXPORT_SYMBOL(__up_write); +-EXPORT_SYMBOL(__downgrade_write); +- + /* Atomic counter implementation. */ + EXPORT_SYMBOL(atomic_add); + EXPORT_SYMBOL(atomic_add_ret); +diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c +index 3b379cd..d1af4ed 100644 +--- a/arch/unicore32/mm/init.c ++++ b/arch/unicore32/mm/init.c +@@ -65,6 +65,9 @@ void show_mem(unsigned int filter) + printk(KERN_DEFAULT "Mem-info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_bank(i, mi) { + struct membank *bank = &mi->bank[i]; + unsigned int pfn1, pfn2; +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 47f4e5f..a4e1b4b 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -468,6 +468,22 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), + }, + }, ++ { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, ++ { /* Some C6100 machines were shipped with vendor being 'Dell'. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell PowerEdge C6100", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), ++ }, ++ }, + { } + }; + +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index f9537e3..a18d20d 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -703,10 +703,13 @@ void __init efi_enter_virtual_mode(void) + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; +- if (!(md->attribute & EFI_MEMORY_RUNTIME) && +- md->type != EFI_BOOT_SERVICES_CODE && +- md->type != EFI_BOOT_SERVICES_DATA) +- continue; ++ if (!(md->attribute & EFI_MEMORY_RUNTIME)) { ++#ifdef CONFIG_X86_64 ++ if (md->type != EFI_BOOT_SERVICES_CODE && ++ md->type != EFI_BOOT_SERVICES_DATA) ++#endif ++ continue; ++ } + + size = md->num_pages << EFI_PAGE_SHIFT; + end = md->phys_addr + size; +diff --git a/crypto/api.c b/crypto/api.c +index 033a714..cea3cf6 100644 +--- a/crypto/api.c ++++ b/crypto/api.c +@@ -34,6 +34,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem); + BLOCKING_NOTIFIER_HEAD(crypto_chain); + EXPORT_SYMBOL_GPL(crypto_chain); + ++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); ++ + static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg) + { + atomic_inc(&alg->cra_refcnt); +@@ -150,8 +152,11 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type, + } + up_write(&crypto_alg_sem); + +- if (alg != &larval->alg) ++ if (alg != &larval->alg) { + kfree(larval); ++ if (crypto_is_larval(alg)) ++ alg = crypto_larval_wait(alg); ++ } + + return alg; + } +diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c +index f40acef..a6977e1 100644 +--- a/drivers/acpi/acpi_ipmi.c ++++ b/drivers/acpi/acpi_ipmi.c +@@ -39,6 +39,7 @@ + #include <linux/ipmi.h> + #include <linux/device.h> + #include <linux/pnp.h> ++#include <linux/spinlock.h> + + MODULE_AUTHOR("Zhao Yakui"); + MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); +@@ -57,7 +58,7 @@ struct acpi_ipmi_device { + struct list_head head; + /* the IPMI request message list */ + struct list_head tx_msg_list; +- struct mutex tx_msg_lock; ++ spinlock_t tx_msg_lock; + acpi_handle handle; + struct pnp_dev *pnp_dev; + ipmi_user_t user_interface; +@@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, + struct kernel_ipmi_msg *msg; + struct acpi_ipmi_buffer *buffer; + struct acpi_ipmi_device *device; ++ unsigned long flags; + + msg = &tx_msg->tx_message; + /* +@@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, + + /* Get the msgid */ + device = tx_msg->device; +- mutex_lock(&device->tx_msg_lock); ++ spin_lock_irqsave(&device->tx_msg_lock, flags); + device->curr_msgid++; + tx_msg->tx_msgid = device->curr_msgid; +- mutex_unlock(&device->tx_msg_lock); ++ spin_unlock_irqrestore(&device->tx_msg_lock, flags); + } + + static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, +@@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + int msg_found = 0; + struct acpi_ipmi_msg *tx_msg; + struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; ++ unsigned long flags; + + if (msg->user != ipmi_device->user_interface) { + dev_warn(&pnp_dev->dev, "Unexpected response is returned. " +@@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + ipmi_free_recv_msg(msg); + return; + } +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { + if (msg->msgid == tx_msg->tx_msgid) { + msg_found = 1; +@@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) + } + } + +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + if (!msg_found) { + dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " + "returned.\n", msg->msgid); +@@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + struct acpi_ipmi_device *ipmi_device = handler_context; + int err, rem_time; + acpi_status status; ++ unsigned long flags; + /* + * IPMI opregion message. + * IPMI message is firstly written to the BMC and system software +@@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + return AE_NO_MEMORY; + + acpi_format_ipmi_msg(tx_msg, address, value); +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + err = ipmi_request_settime(ipmi_device->user_interface, + &tx_msg->addr, + tx_msg->tx_msgid, +@@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + status = AE_OK; + + end_label: +- mutex_lock(&ipmi_device->tx_msg_lock); ++ spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); + list_del(&tx_msg->head); +- mutex_unlock(&ipmi_device->tx_msg_lock); ++ spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); + kfree(tx_msg); + return status; + } +@@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) + + INIT_LIST_HEAD(&ipmi_device->head); + +- mutex_init(&ipmi_device->tx_msg_lock); ++ spin_lock_init(&ipmi_device->tx_msg_lock); + INIT_LIST_HEAD(&ipmi_device->tx_msg_list); + ipmi_install_space_handler(ipmi_device); + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 51de186..8176b82 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -964,6 +964,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { + ec_enlarge_storm_threshold, "CLEVO hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), + DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, ++ { ++ ec_validate_ecdt, "ASUS hardware", { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, + {}, + }; + +diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c +index d3446f6..d7ad865 100644 +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -1186,6 +1186,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + int err; + u32 cp; + ++ memset(&arg64, 0, sizeof(arg64)); + err = 0; + err |= + copy_from_user(&arg64.LUN_info, &arg32->LUN_info, +diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c +index 9125bbe..504bc16 100644 +--- a/drivers/block/cpqarray.c ++++ b/drivers/block/cpqarray.c +@@ -1195,6 +1195,7 @@ out_passthru: + ida_pci_info_struct pciinfo; + + if (!arg) return -EINVAL; ++ memset(&pciinfo, 0, sizeof(pciinfo)); + pciinfo.bus = host->pci_dev->bus->number; + pciinfo.dev_fn = host->pci_dev->devfn; + pciinfo.board_id = host->board_id; +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index bde72f7..3539f9b 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -84,6 +84,7 @@ static struct usb_device_id ath3k_table[] = { + { USB_DEVICE(0x04CA, 0x3008) }, + { USB_DEVICE(0x13d3, 0x3362) }, + { USB_DEVICE(0x0CF3, 0xE004) }, ++ { USB_DEVICE(0x0CF3, 0xE005) }, + { USB_DEVICE(0x0930, 0x0219) }, + { USB_DEVICE(0x0489, 0xe057) }, + { USB_DEVICE(0x13d3, 0x3393) }, +@@ -125,6 +126,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { + { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 1bd3924..f18b5a2 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -108,6 +108,7 @@ static struct usb_device_id btusb_table[] = { + + /* Broadcom BCM20702A0 */ + { USB_DEVICE(0x0b05, 0x17b5) }, ++ { USB_DEVICE(0x0b05, 0x17cb) }, + { USB_DEVICE(0x04ca, 0x2003) }, + { USB_DEVICE(0x0489, 0xe042) }, + { USB_DEVICE(0x413c, 0x8197) }, +@@ -154,6 +155,7 @@ static struct usb_device_id blacklist_table[] = { + { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 7211f67..72f460e 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -125,6 +125,9 @@ static struct edid_quirk { + + /* ViewSonic VA2026w */ + { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, ++ ++ /* Medion MD 30217 PG */ ++ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, + }; + + /*** DDC fetch and block validation ***/ +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index a07ccab..72163e8 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -621,7 +621,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, + DRM_DEBUG_KMS("aux_ch native nack\n"); + return -EREMOTEIO; + case AUX_NATIVE_REPLY_DEFER: +- udelay(100); ++ /* ++ * For now, just give more slack to branch devices. We ++ * could check the DPCD for I2C bit rate capabilities, ++ * and if available, adjust the interval. We could also ++ * be more careful with DP-to-Legacy adapters where a ++ * long legacy cable may force very low I2C bit rates. ++ */ ++ if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & ++ DP_DWN_STRM_PORT_PRESENT) ++ usleep_range(500, 600); ++ else ++ usleep_range(300, 400); + continue; + default: + DRM_ERROR("aux_ch invalid native reply 0x%02x\n", +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index cffb007..356a252 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -161,7 +161,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) + + max = intel_panel_get_max_backlight(dev); + intel_panel_set_backlight(dev, bclp * max / 255); +- asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; ++ asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; + + return 0; + } +diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c +index f0dc04b..3171294 100644 +--- a/drivers/gpu/drm/radeon/atombios_encoders.c ++++ b/drivers/gpu/drm/radeon/atombios_encoders.c +@@ -1385,8 +1385,12 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) + atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +- /* some early dce3.2 boards have a bug in their transmitter control table */ +- if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) ++ /* some dce3.x boards have a bug in their transmitter control table. ++ * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE ++ * does the same thing and more. ++ */ ++ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && ++ (rdev->family != CHIP_RS880)) + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + } + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index f5962a0..a68057a 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -501,7 +501,8 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, + struct drm_display_mode *mode, + struct drm_display_mode *other_mode) + { +- u32 tmp; ++ u32 tmp, buffer_alloc, i; ++ u32 pipe_offset = radeon_crtc->crtc_id * 0x20; + /* + * Line Buffer Setup + * There are 3 line buffers, each one shared by 2 display controllers. +@@ -524,18 +525,34 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, + * non-linked crtcs for maximum line buffer allocation. + */ + if (radeon_crtc->base.enabled && mode) { +- if (other_mode) ++ if (other_mode) { + tmp = 0; /* 1/2 */ +- else ++ buffer_alloc = 1; ++ } else { + tmp = 2; /* whole */ +- } else ++ buffer_alloc = 2; ++ } ++ } else { + tmp = 0; ++ buffer_alloc = 0; ++ } + + /* second controller of the pair uses second half of the lb */ + if (radeon_crtc->crtc_id % 2) + tmp += 4; + WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); + ++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { ++ WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, ++ DMIF_BUFFERS_ALLOCATED(buffer_alloc)); ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & ++ DMIF_BUFFERS_ALLOCATED_COMPLETED) ++ break; ++ udelay(1); ++ } ++ } ++ + if (radeon_crtc->base.enabled && mode) { + switch (tmp) { + case 0: +diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h +index fe44a95..47f3bd2 100644 +--- a/drivers/gpu/drm/radeon/evergreend.h ++++ b/drivers/gpu/drm/radeon/evergreend.h +@@ -459,6 +459,10 @@ + # define LATENCY_LOW_WATERMARK(x) ((x) << 0) + # define LATENCY_HIGH_WATERMARK(x) ((x) << 16) + ++#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 ++# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) ++# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) ++ + #define IH_RB_CNTL 0x3e00 + # define IH_RB_ENABLE (1 << 0) + # define IH_IB_SIZE(x) ((x) << 1) /* log2 */ +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 383b38e..cda89c6b 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -709,13 +709,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) + (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) + (ctx->bios + data_offset + + le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); ++ u8 *num_dst_objs = (u8 *) ++ ((u8 *)router_src_dst_table + 1 + ++ (router_src_dst_table->ucNumberOfSrc * 2)); ++ u16 *dst_objs = (u16 *)(num_dst_objs + 1); + int enum_id; + + router.router_id = router_obj_id; +- for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; +- enum_id++) { ++ for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) { + if (le16_to_cpu(path->usConnObjectId) == +- le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) ++ le16_to_cpu(dst_objs[enum_id])) + break; + } + +@@ -1616,7 +1619,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct + kfree(edid); + } + } +- record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); ++ record += fake_edid_record->ucFakeEDIDLength ? ++ fake_edid_record->ucFakeEDIDLength + 2 : ++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD); + break; + case LCD_PANEL_RESOLUTION_RECORD_TYPE: + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index 6fd53b6..b101843 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1387,6 +1387,24 @@ struct drm_connector_funcs radeon_dp_connector_funcs = { + .force = radeon_dvi_force, + }; + ++static const struct drm_connector_funcs radeon_edp_connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = radeon_dp_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = radeon_lvds_set_property, ++ .destroy = radeon_dp_connector_destroy, ++ .force = radeon_dvi_force, ++}; ++ ++static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = radeon_dp_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = radeon_lvds_set_property, ++ .destroy = radeon_dp_connector_destroy, ++ .force = radeon_dvi_force, ++}; ++ + void + radeon_add_atom_connector(struct drm_device *dev, + uint32_t connector_id, +@@ -1478,8 +1496,6 @@ radeon_add_atom_connector(struct drm_device *dev, + goto failed; + radeon_dig_connector->igp_lane_info = igp_lane_info; + radeon_connector->con_priv = radeon_dig_connector; +- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); +- drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); + if (i2c_bus->valid) { + /* add DP i2c bus */ + if (connector_type == DRM_MODE_CONNECTOR_eDP) +@@ -1496,6 +1512,10 @@ radeon_add_atom_connector(struct drm_device *dev, + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DVIA: + default: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_dp_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + connector->interlace_allowed = true; + connector->doublescan_allowed = true; + radeon_connector->dac_load_detect = true; +@@ -1508,6 +1528,10 @@ radeon_add_atom_connector(struct drm_device *dev, + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + case DRM_MODE_CONNECTOR_DisplayPort: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_dp_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_OFF); +@@ -1532,6 +1556,10 @@ radeon_add_atom_connector(struct drm_device *dev, + break; + case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: ++ drm_connector_init(dev, &radeon_connector->base, ++ &radeon_lvds_bridge_connector_funcs, connector_type); ++ drm_connector_helper_add(&radeon_connector->base, ++ &radeon_dp_connector_helper_funcs); + drm_connector_attach_property(&radeon_connector->base, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_FULLSCREEN); +@@ -1695,7 +1723,7 @@ radeon_add_atom_connector(struct drm_device *dev, + goto failed; + radeon_dig_connector->igp_lane_info = igp_lane_info; + radeon_connector->con_priv = radeon_dig_connector; +- drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); ++ drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type); + drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); + if (i2c_bus->valid) { + /* add DP i2c bus */ +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index cd94abb..8cde84b 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -818,10 +818,16 @@ int radeon_device_init(struct radeon_device *rdev, + return r; + } + if (radeon_testing) { +- radeon_test_moves(rdev); ++ if (rdev->accel_working) ++ radeon_test_moves(rdev); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping move tests\n"); + } + if (radeon_benchmarking) { +- radeon_benchmark(rdev, radeon_benchmarking); ++ if (rdev->accel_working) ++ radeon_benchmark(rdev, radeon_benchmarking); ++ else ++ DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); + } + return 0; + } +diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c +index 4dd9512..c087434 100644 +--- a/drivers/gpu/drm/radeon/rs400.c ++++ b/drivers/gpu/drm/radeon/rs400.c +@@ -174,10 +174,13 @@ int rs400_gart_enable(struct radeon_device *rdev) + /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, + * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ + if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { +- WREG32_MC(RS480_MC_MISC_CNTL, +- (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } else { +- WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); ++ tmp = RREG32_MC(RS480_MC_MISC_CNTL); ++ tmp |= RS480_GART_INDEX_REG_EN; ++ WREG32_MC(RS480_MC_MISC_CNTL, tmp); + } + /* Enable gart */ + WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 611aafc..9ac4389 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -59,6 +59,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, + struct hid_report_enum *report_enum = device->report_enum + type; + struct hid_report *report; + ++ if (id >= HID_MAX_IDS) ++ return NULL; + if (report_enum->report_id_hash[id]) + return report_enum->report_id_hash[id]; + +@@ -216,9 +218,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign + { + struct hid_report *report; + struct hid_field *field; +- int usages; ++ unsigned usages; + unsigned offset; +- int i; ++ unsigned i; + + report = hid_register_report(parser->device, report_type, parser->global.report_id); + if (!report) { +@@ -237,7 +239,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign + if (!parser->local.usage_index) /* Ignore padding fields */ + return 0; + +- usages = max_t(int, parser->local.usage_index, parser->global.report_count); ++ usages = max_t(unsigned, parser->local.usage_index, ++ parser->global.report_count); + + field = hid_register_field(report, usages, parser->global.report_count); + if (!field) +@@ -248,7 +251,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign + field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); + + for (i = 0; i < usages; i++) { +- int j = i; ++ unsigned j = i; + /* Duplicate the last usage we parsed if we have excess values */ + if (i >= parser->local.usage_index) + j = parser->local.usage_index - 1; +@@ -380,8 +383,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) + + case HID_GLOBAL_ITEM_TAG_REPORT_ID: + parser->global.report_id = item_udata(item); +- if (parser->global.report_id == 0) { +- dbg_hid("report_id 0 is invalid\n"); ++ if (parser->global.report_id == 0 || ++ parser->global.report_id >= HID_MAX_IDS) { ++ dbg_hid("report_id %u is invalid\n", ++ parser->global.report_id); + return -1; + } + return 0; +@@ -552,7 +557,7 @@ static void hid_device_release(struct device *dev) + for (i = 0; i < HID_REPORT_TYPES; i++) { + struct hid_report_enum *report_enum = device->report_enum + i; + +- for (j = 0; j < 256; j++) { ++ for (j = 0; j < HID_MAX_IDS; j++) { + struct hid_report *report = report_enum->report_id_hash[j]; + if (report) + hid_free_report(report); +@@ -710,6 +715,64 @@ err: + } + EXPORT_SYMBOL_GPL(hid_parse_report); + ++static const char * const hid_report_names[] = { ++ "HID_INPUT_REPORT", ++ "HID_OUTPUT_REPORT", ++ "HID_FEATURE_REPORT", ++}; ++/** ++ * hid_validate_values - validate existing device report's value indexes ++ * ++ * @device: hid device ++ * @type: which report type to examine ++ * @id: which report ID to examine (0 for first) ++ * @field_index: which report field to examine ++ * @report_counts: expected number of values ++ * ++ * Validate the number of values in a given field of a given report, after ++ * parsing. ++ */ ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts) ++{ ++ struct hid_report *report; ++ ++ if (type > HID_FEATURE_REPORT) { ++ hid_err(hid, "invalid HID report type %u\n", type); ++ return NULL; ++ } ++ ++ if (id >= HID_MAX_IDS) { ++ hid_err(hid, "invalid HID report id %u\n", id); ++ return NULL; ++ } ++ ++ /* ++ * Explicitly not using hid_get_report() here since it depends on ++ * ->numbered being checked, which may not always be the case when ++ * drivers go to access report values. ++ */ ++ report = hid->report_enum[type].report_id_hash[id]; ++ if (!report) { ++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->maxfield <= field_index) { ++ hid_err(hid, "not enough fields in %s %u\n", ++ hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->field[field_index]->report_count < report_counts) { ++ hid_err(hid, "not enough values in %s %u field %u\n", ++ hid_report_names[type], id, field_index); ++ return NULL; ++ } ++ return report; ++} ++EXPORT_SYMBOL_GPL(hid_validate_values); ++ + /* + * Convert a signed n-bit integer to signed 32-bit integer. Common + * cases are done through the compiler, the screwed things has to be +@@ -990,7 +1053,12 @@ EXPORT_SYMBOL_GPL(hid_output_report); + + int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) + { +- unsigned size = field->report_size; ++ unsigned size; ++ ++ if (!field) ++ return -1; ++ ++ size = field->report_size; + + hid_dump_input(field->report->device, field->usage + offset, value); + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 08075f2..ca2b3e6 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -581,6 +581,7 @@ + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 + #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 ++#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500 + + #define USB_VENDOR_ID_ONTRAK 0x0a07 + #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index f333139..95c79a3 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -284,6 +284,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + if (field->flags & HID_MAIN_ITEM_CONSTANT) + goto ignore; + ++ /* Ignore if report count is out of bounds. */ ++ if (field->report_count < 1) ++ goto ignore; ++ + /* only LED usages are supported in output fields */ + if (field->report_type == HID_OUTPUT_REPORT && + (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { +@@ -887,10 +891,15 @@ static void report_features(struct hid_device *hid) + + rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; + list_for_each_entry(rep, &rep_enum->report_list, list) +- for (i = 0; i < rep->maxfield; i++) ++ for (i = 0; i < rep->maxfield; i++) { ++ /* Ignore if report count is out of bounds. */ ++ if (rep->field[i]->report_count < 1) ++ continue; ++ + for (j = 0; j < rep->field[i]->maxusage; j++) + drv->feature_mapping(hid, rep->field[i], + rep->field[i]->usage + j); ++ } + } + + /* +diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c +index 3c31bc6..128f011 100644 +--- a/drivers/hid/hid-lg2ff.c ++++ b/drivers/hid/hid-lg2ff.c +@@ -66,26 +66,13 @@ int lg2ff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); ++ /* Check that the report looks ok */ ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); ++ if (!report) + return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 1) { +- hid_err(hid, "output report is empty\n"); +- return -ENODEV; +- } +- if (report->field[0]->report_count < 7) { +- hid_err(hid, "not enough values in the field\n"); +- return -ENODEV; +- } + + lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); + if (!lg2ff) +diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c +index f98644c..91f981f 100644 +--- a/drivers/hid/hid-lg3ff.c ++++ b/drivers/hid/hid-lg3ff.c +@@ -68,10 +68,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, + int x, y; + + /* +- * Maxusage should always be 63 (maximum fields) +- * likely a better way to ensure this data is clean ++ * Available values in the field should always be 63, but we only use up to ++ * 35. Instead, clear the entire area, however big it is. + */ +- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage); ++ memset(report->field[0]->value, 0, ++ sizeof(__s32) * report->field[0]->report_count); + + switch (effect->type) { + case FF_CONSTANT: +@@ -131,32 +132,14 @@ static const signed short ff3_joystick_ac[] = { + int lg3ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff3_joystick_ac; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); +- return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) ++ return -ENODEV; + + /* Assume single fixed device G940 */ + for (i = 0; ff_bits[i] >= 0; i++) +diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c +index 103f30d..5c6bf4b 100644 +--- a/drivers/hid/hid-lg4ff.c ++++ b/drivers/hid/hid-lg4ff.c +@@ -339,33 +339,15 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at + int lg4ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + struct lg4ff_device_entry *entry; + struct usb_device_descriptor *udesc; + int error, i, j; + __u16 bcdDevice, rev_maj, rev_min; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) + return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } + + /* Check what wheel has been connected */ + for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { +diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c +index 27bc54f..1d978daa 100644 +--- a/drivers/hid/hid-lgff.c ++++ b/drivers/hid/hid-lgff.c +@@ -130,27 +130,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) + int lgff_init(struct hid_device* hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff_joystick; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) ++ return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + if (dev->id.vendor == devices[i].idVendor && +diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c +index 8821ecc..828a0dd 100644 +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -791,6 +791,12 @@ static int logi_dj_probe(struct hid_device *hdev, + goto hid_parse_fail; + } + ++ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT, ++ 0, DJREPORT_SHORT_LENGTH - 1)) { ++ retval = -ENODEV; ++ goto hid_parse_fail; ++ } ++ + /* Starts the usb device and connects to upper interfaces hiddev and + * hidraw */ + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c +index 9fae2eb..48cba85 100644 +--- a/drivers/hid/hid-ntrig.c ++++ b/drivers/hid/hid-ntrig.c +@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) + struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. + report_id_hash[0x0d]; + +- if (!report) ++ if (!report || report->maxfield < 1 || ++ report->field[0]->report_count < 1) + return -EINVAL; + + usbhid_submit_report(hdev, report, USB_DIR_IN); +diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c +index 01e7d2c..1daeaca 100644 +--- a/drivers/hid/hid-picolcd.c ++++ b/drivers/hid/hid-picolcd.c +@@ -1424,7 +1424,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, + buf += 10; + cnt -= 10; + } +- if (!report) ++ if (!report || report->maxfield != 1) + return -EINVAL; + + while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) +diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c +index 070f93a..12786cd 100644 +--- a/drivers/hid/hid-pl.c ++++ b/drivers/hid/hid-pl.c +@@ -129,8 +129,14 @@ static int plff_init(struct hid_device *hid) + strong = &report->field[0]->value[2]; + weak = &report->field[0]->value[3]; + debug("detected single-field device"); +- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && +- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { ++ } else if (report->field[0]->maxusage == 1 && ++ report->field[0]->usage[0].hid == ++ (HID_UP_LED | 0x43) && ++ report->maxfield >= 4 && ++ report->field[0]->report_count >= 1 && ++ report->field[1]->report_count >= 1 && ++ report->field[2]->report_count >= 1 && ++ report->field[3]->report_count >= 1) { + report->field[0]->value[0] = 0x00; + report->field[1]->value[0] = 0x00; + strong = &report->field[2]->value[0]; +diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c +index 6020137..2b03c9b 100644 +--- a/drivers/hid/hid-speedlink.c ++++ b/drivers/hid/hid-speedlink.c +@@ -3,7 +3,7 @@ + * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from + * the HID descriptor. + * +- * Copyright (c) 2011 Stefan Kriwanek <mail@stefankriwanek.de> ++ * Copyright (c) 2011, 2013 Stefan Kriwanek <dev@stefankriwanek.de> + */ + + /* +@@ -48,8 +48,13 @@ static int speedlink_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) + { + /* No other conditions due to usage_table. */ +- /* Fix "jumpy" cursor (invalid events sent by device). */ +- if (value == 256) ++ ++ /* This fixes the "jumpy" cursor occuring due to invalid events sent ++ * by the device. Some devices only send them with value==+256, others ++ * don't. However, catching abs(value)>=256 is restrictive enough not ++ * to interfere with devices that were bug-free (has been tested). ++ */ ++ if (abs(value) >= 256) + return 1; + /* Drop useless distance 0 events (on button clicks etc.) as well */ + if (value == 0) +diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c +index f6ba81d..f348f7f 100644 +--- a/drivers/hid/hid-zpff.c ++++ b/drivers/hid/hid-zpff.c +@@ -70,21 +70,13 @@ static int zpff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- int error; ++ int i, error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); +- return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 4) { +- hid_err(hid, "not enough fields in report\n"); +- return -ENODEV; ++ for (i = 0; i < 4; i++) { ++ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); ++ if (!report) ++ return -ENODEV; + } + + zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); +diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c +index 17d15bb..9e50f61 100644 +--- a/drivers/hid/hidraw.c ++++ b/drivers/hid/hidraw.c +@@ -42,7 +42,6 @@ static struct cdev hidraw_cdev; + static struct class *hidraw_class; + static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; + static DEFINE_MUTEX(minors_lock); +-static void drop_ref(struct hidraw *hid, int exists_bit); + + static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) + { +@@ -296,14 +295,37 @@ out: + + } + ++static void drop_ref(struct hidraw *hidraw, int exists_bit) ++{ ++ if (exists_bit) { ++ hid_hw_close(hidraw->hid); ++ hidraw->exist = 0; ++ if (hidraw->open) ++ wake_up_interruptible(&hidraw->wait); ++ } else { ++ --hidraw->open; ++ } ++ ++ if (!hidraw->open && !hidraw->exist) { ++ device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); ++ hidraw_table[hidraw->minor] = NULL; ++ kfree(hidraw); ++ } ++} ++ + static int hidraw_release(struct inode * inode, struct file * file) + { + unsigned int minor = iminor(inode); + struct hidraw_list *list = file->private_data; + +- drop_ref(hidraw_table[minor], 0); ++ mutex_lock(&minors_lock); ++ + list_del(&list->node); + kfree(list); ++ ++ drop_ref(hidraw_table[minor], 0); ++ ++ mutex_unlock(&minors_lock); + return 0; + } + +@@ -506,7 +528,12 @@ EXPORT_SYMBOL_GPL(hidraw_connect); + void hidraw_disconnect(struct hid_device *hid) + { + struct hidraw *hidraw = hid->hidraw; ++ ++ mutex_lock(&minors_lock); ++ + drop_ref(hidraw, 1); ++ ++ mutex_unlock(&minors_lock); + } + EXPORT_SYMBOL_GPL(hidraw_disconnect); + +@@ -555,23 +582,3 @@ void hidraw_exit(void) + unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); + + } +- +-static void drop_ref(struct hidraw *hidraw, int exists_bit) +-{ +- mutex_lock(&minors_lock); +- if (exists_bit) { +- hid_hw_close(hidraw->hid); +- hidraw->exist = 0; +- if (hidraw->open) +- wake_up_interruptible(&hidraw->wait); +- } else { +- --hidraw->open; +- } +- +- if (!hidraw->open && !hidraw->exist) { +- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); +- hidraw_table[hidraw->minor] = NULL; +- kfree(hidraw); +- } +- mutex_unlock(&minors_lock); +-} +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index 96a1e0f..f98fbad 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -99,6 +99,8 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, ++ { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, ++ + { 0, 0 } + }; + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index d99aa84..30cac58 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -344,8 +344,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) + while (begin != end) { + int middle = begin + (end - begin) / 2; + entry = applesmc_get_entry_by_index(middle); +- if (IS_ERR(entry)) ++ if (IS_ERR(entry)) { ++ *lo = 0; + return PTR_ERR(entry); ++ } + if (strcmp(entry->key, key) < 0) + begin = middle + 1; + else +@@ -364,8 +366,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) + while (begin != end) { + int middle = begin + (end - begin) / 2; + entry = applesmc_get_entry_by_index(middle); +- if (IS_ERR(entry)) ++ if (IS_ERR(entry)) { ++ *hi = smcreg.key_count; + return PTR_ERR(entry); ++ } + if (strcmp(key, entry->key) < 0) + end = middle; + else +@@ -485,16 +489,25 @@ static int applesmc_init_smcreg_try(void) + { + struct applesmc_registers *s = &smcreg; + bool left_light_sensor, right_light_sensor; ++ unsigned int count; + u8 tmp[1]; + int ret; + + if (s->init_complete) + return 0; + +- ret = read_register_count(&s->key_count); ++ ret = read_register_count(&count); + if (ret) + return ret; + ++ if (s->cache && s->key_count != count) { ++ pr_warn("key count changed from %d to %d\n", ++ s->key_count, count); ++ kfree(s->cache); ++ s->cache = NULL; ++ } ++ s->key_count = count; ++ + if (!s->cache) + s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); + if (!s->cache) +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index f44a067..b4a4aaf 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -861,56 +861,54 @@ static int dma_pte_clear_range(struct dmar_domain *domain, + return order; + } + ++static void dma_pte_free_level(struct dmar_domain *domain, int level, ++ struct dma_pte *pte, unsigned long pfn, ++ unsigned long start_pfn, unsigned long last_pfn) ++{ ++ pfn = max(start_pfn, pfn); ++ pte = &pte[pfn_level_offset(pfn, level)]; ++ ++ do { ++ unsigned long level_pfn; ++ struct dma_pte *level_pte; ++ ++ if (!dma_pte_present(pte) || dma_pte_superpage(pte)) ++ goto next; ++ ++ level_pfn = pfn & level_mask(level - 1); ++ level_pte = phys_to_virt(dma_pte_addr(pte)); ++ ++ if (level > 2) ++ dma_pte_free_level(domain, level - 1, level_pte, ++ level_pfn, start_pfn, last_pfn); ++ ++ /* If range covers entire pagetable, free it */ ++ if (!(start_pfn > level_pfn || ++ last_pfn < level_pfn + level_size(level))) { ++ dma_clear_pte(pte); ++ domain_flush_cache(domain, pte, sizeof(*pte)); ++ free_pgtable_page(level_pte); ++ } ++next: ++ pfn += level_size(level); ++ } while (!first_pte_in_page(++pte) && pfn <= last_pfn); ++} ++ + /* free page table pages. last level pte should already be cleared */ + static void dma_pte_free_pagetable(struct dmar_domain *domain, + unsigned long start_pfn, + unsigned long last_pfn) + { + int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; +- struct dma_pte *first_pte, *pte; +- int total = agaw_to_level(domain->agaw); +- int level; +- unsigned long tmp; +- int large_page = 2; + + BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); + BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + BUG_ON(start_pfn > last_pfn); + + /* We don't need lock here; nobody else touches the iova range */ +- level = 2; +- while (level <= total) { +- tmp = align_to_level(start_pfn, level); +- +- /* If we can't even clear one PTE at this level, we're done */ +- if (tmp + level_size(level) - 1 > last_pfn) +- return; +- +- do { +- large_page = level; +- first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); +- if (large_page > level) +- level = large_page + 1; +- if (!pte) { +- tmp = align_to_level(tmp + 1, level + 1); +- continue; +- } +- do { +- if (dma_pte_present(pte)) { +- free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); +- dma_clear_pte(pte); +- } +- pte++; +- tmp += level_size(level); +- } while (!first_pte_in_page(pte) && +- tmp + level_size(level) - 1 <= last_pfn); ++ dma_pte_free_level(domain, agaw_to_level(domain->agaw), ++ domain->pgd, 0, start_pfn, last_pfn); + +- domain_flush_cache(domain, first_pte, +- (void *)pte - (void *)first_pte); +- +- } while (tmp && tmp + level_size(level) - 1 <= last_pfn); +- level++; +- } + /* free pgd */ + if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { + free_pgtable_page(domain->pgd); +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index b4aaa7b..5c30316 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -721,17 +721,16 @@ static int calc_max_buckets(void) + */ + static int init_hash_tables(struct dm_snapshot *s) + { +- sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; ++ sector_t hash_size, cow_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->bdev); +- origin_dev_size = get_dev_size(s->origin->bdev); + max_buckets = calc_max_buckets(); + +- hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; ++ hash_size = cow_dev_size >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + + if (hash_size < 64) +diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c +index 441dacf..060353e 100644 +--- a/drivers/media/video/hdpvr/hdpvr-core.c ++++ b/drivers/media/video/hdpvr/hdpvr-core.c +@@ -297,6 +297,11 @@ static int hdpvr_probe(struct usb_interface *interface, + + dev->workqueue = 0; + ++ /* init video transfer queues first of all */ ++ /* to prevent oops in hdpvr_delete() on error paths */ ++ INIT_LIST_HEAD(&dev->free_buff_list); ++ INIT_LIST_HEAD(&dev->rec_buff_list); ++ + /* register v4l2_device early so it can be used for printks */ + if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { + err("v4l2_device_register failed"); +@@ -319,10 +324,6 @@ static int hdpvr_probe(struct usb_interface *interface, + if (!dev->workqueue) + goto error; + +- /* init video transfer queues */ +- INIT_LIST_HEAD(&dev->free_buff_list); +- INIT_LIST_HEAD(&dev->rec_buff_list); +- + dev->options = hdpvr_default_options; + + if (default_video_input < HDPVR_VIDEO_INPUTS) +@@ -373,12 +374,6 @@ static int hdpvr_probe(struct usb_interface *interface, + } + mutex_unlock(&dev->io_mutex); + +- if (hdpvr_register_videodev(dev, &interface->dev, +- video_nr[atomic_inc_return(&dev_nr)])) { +- v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); +- goto error; +- } +- + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + retval = hdpvr_register_i2c_adapter(dev); + if (retval < 0) { +@@ -399,6 +394,13 @@ static int hdpvr_probe(struct usb_interface *interface, + } + #endif + ++ retval = hdpvr_register_videodev(dev, &interface->dev, ++ video_nr[atomic_inc_return(&dev_nr)]); ++ if (retval < 0) { ++ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); ++ goto reg_fail; ++ } ++ + /* let the user know what node this device is now attached to */ + v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", + video_device_node_name(dev->video_dev)); +diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c +index 86f259c..be9e74d 100644 +--- a/drivers/mmc/host/tmio_mmc_dma.c ++++ b/drivers/mmc/host/tmio_mmc_dma.c +@@ -92,6 +92,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host) + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_rx = NULL; +@@ -104,7 +105,6 @@ pio: + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, +@@ -173,6 +173,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host) + pio: + if (!desc) { + /* DMA failed, fall back to PIO */ ++ tmio_mmc_enable_dma(host, false); + if (ret >= 0) + ret = -EIO; + host->chan_tx = NULL; +@@ -185,7 +186,6 @@ pio: + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); +- tmio_mmc_enable_dma(host, false); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__, +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index b436b84..1bf36ac 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1911,6 +1911,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr addr; ++ int old_flags = bond_dev->flags; + u32 old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2041,12 +2042,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) + * already taken care of above when we detached the slave + */ + if (!USES_PRIMARY(bond->params.mode)) { +- /* unset promiscuity level from slave */ +- if (bond_dev->flags & IFF_PROMISC) ++ /* unset promiscuity level from slave ++ * NOTE: The NETDEV_CHANGEADDR call above may change the value ++ * of the IFF_PROMISC flag in the bond_dev, but we need the ++ * value of that flag before that change, as that was the value ++ * when this slave was attached, so we cache at the start of the ++ * function and use it here. Same goes for ALLMULTI below ++ */ ++ if (old_flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ +- if (bond_dev->flags & IFF_ALLMULTI) ++ if (old_flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + + /* flush master's mc_list from slave */ +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index e59d006..bb828c2 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -60,7 +60,7 @@ + #define FLEXCAN_MCR_BCC BIT(16) + #define FLEXCAN_MCR_LPRIO_EN BIT(13) + #define FLEXCAN_MCR_AEN BIT(12) +-#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf) ++#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) + #define FLEXCAN_MCR_IDAM_A (0 << 8) + #define FLEXCAN_MCR_IDAM_B (1 << 8) + #define FLEXCAN_MCR_IDAM_C (2 << 8) +@@ -666,7 +666,6 @@ static int flexcan_chip_start(struct net_device *dev) + { + struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->base; +- unsigned int i; + int err; + u32 reg_mcr, reg_ctrl; + +@@ -700,9 +699,11 @@ static int flexcan_chip_start(struct net_device *dev) + * + */ + reg_mcr = flexcan_read(®s->mcr); ++ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | + FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | +- FLEXCAN_MCR_IDAM_C; ++ FLEXCAN_MCR_IDAM_C | ++ FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); + dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); + flexcan_write(reg_mcr, ®s->mcr); + +@@ -732,16 +733,9 @@ static int flexcan_chip_start(struct net_device *dev) + dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); + flexcan_write(reg_ctrl, ®s->ctrl); + +- for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { +- flexcan_write(0, ®s->cantxfg[i].can_ctrl); +- flexcan_write(0, ®s->cantxfg[i].can_id); +- flexcan_write(0, ®s->cantxfg[i].data[0]); +- flexcan_write(0, ®s->cantxfg[i].data[1]); +- +- /* put MB into rx queue */ +- flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), +- ®s->cantxfg[i].can_ctrl); +- } ++ /* Abort any pending TX, mark Mailbox as INACTIVE */ ++ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), ++ ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); + + /* acceptance mask/acceptance code (accept everything) */ + flexcan_write(0x0, ®s->rxgmask); +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index d0722a7..fb9e7d3 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -397,7 +397,13 @@ static void gfar_init_mac(struct net_device *ndev) + if (ndev->features & NETIF_F_IP_CSUM) + tctrl |= TCTRL_INIT_CSUM; + +- tctrl |= TCTRL_TXSCHED_PRIO; ++ if (priv->prio_sched_en) ++ tctrl |= TCTRL_TXSCHED_PRIO; ++ else { ++ tctrl |= TCTRL_TXSCHED_WRRS; ++ gfar_write(®s->tr03wt, DEFAULT_WRRS_WEIGHT); ++ gfar_write(®s->tr47wt, DEFAULT_WRRS_WEIGHT); ++ } + + gfar_write(®s->tctrl, tctrl); + +@@ -1157,6 +1163,9 @@ static int gfar_probe(struct platform_device *ofdev) + priv->rx_filer_enable = 1; + /* Enable most messages by default */ + priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; ++ /* use pritority h/w tx queue scheduling for single queue devices */ ++ if (priv->num_tx_queues == 1) ++ priv->prio_sched_en = 1; + + /* Carrier starts down, phylib will bring it up */ + netif_carrier_off(dev); +diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h +index 9aa4377..abeb79a 100644 +--- a/drivers/net/ethernet/freescale/gianfar.h ++++ b/drivers/net/ethernet/freescale/gianfar.h +@@ -304,8 +304,16 @@ extern const char gfar_driver_version[]; + #define TCTRL_TFCPAUSE 0x00000008 + #define TCTRL_TXSCHED_MASK 0x00000006 + #define TCTRL_TXSCHED_INIT 0x00000000 ++/* priority scheduling */ + #define TCTRL_TXSCHED_PRIO 0x00000002 ++/* weighted round-robin scheduling (WRRS) */ + #define TCTRL_TXSCHED_WRRS 0x00000004 ++/* default WRRS weight and policy setting, ++ * tailored to the tr03wt and tr47wt registers: ++ * equal weight for all Tx Qs, measured in 64byte units ++ */ ++#define DEFAULT_WRRS_WEIGHT 0x18181818 ++ + #define TCTRL_INIT_CSUM (TCTRL_TUCSEN | TCTRL_IPCSEN) + + #define IEVENT_INIT_CLEAR 0xffffffff +@@ -1101,7 +1109,8 @@ struct gfar_private { + extended_hash:1, + bd_stash_en:1, + rx_filer_enable:1, +- wol_en:1; /* Wake-on-LAN enabled */ ++ wol_en:1, /* Wake-on-LAN enabled */ ++ prio_sched_en:1; /* Enable priorty based Tx scheduling in Hw */ + unsigned short padding; + + /* PHY stuff */ +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index 8f47907..4236b82 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -478,7 +478,7 @@ rx_status_loop: + + while (1) { + u32 status, len; +- dma_addr_t mapping; ++ dma_addr_t mapping, new_mapping; + struct sk_buff *skb, *new_skb; + struct cp_desc *desc; + const unsigned buflen = cp->rx_buf_sz; +@@ -520,6 +520,14 @@ rx_status_loop: + goto rx_next; + } + ++ new_mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen, ++ PCI_DMA_FROMDEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, new_mapping)) { ++ dev->stats.rx_dropped++; ++ kfree_skb(new_skb); ++ goto rx_next; ++ } ++ + dma_unmap_single(&cp->pdev->dev, mapping, + buflen, PCI_DMA_FROMDEVICE); + +@@ -531,12 +539,11 @@ rx_status_loop: + + skb_put(skb, len); + +- mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen, +- PCI_DMA_FROMDEVICE); + cp->rx_skb[rx_tail] = new_skb; + + cp_rx_skb(cp, skb, desc); + rx++; ++ mapping = new_mapping; + + rx_next: + cp->rx_ring[rx_tail].opts2 = 0; +@@ -704,6 +711,22 @@ static inline u32 cp_tx_vlan_tag(struct sk_buff *skb) + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; + } + ++static void unwind_tx_frag_mapping(struct cp_private *cp, struct sk_buff *skb, ++ int first, int entry_last) ++{ ++ int frag, index; ++ struct cp_desc *txd; ++ skb_frag_t *this_frag; ++ for (frag = 0; frag+first < entry_last; frag++) { ++ index = first+frag; ++ cp->tx_skb[index] = NULL; ++ txd = &cp->tx_ring[index]; ++ this_frag = &skb_shinfo(skb)->frags[frag]; ++ dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr), ++ skb_frag_size(this_frag), PCI_DMA_TODEVICE); ++ } ++} ++ + static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + struct net_device *dev) + { +@@ -737,6 +760,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + + len = skb->len; + mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) ++ goto out_dma_error; ++ + txd->opts2 = opts2; + txd->addr = cpu_to_le64(mapping); + wmb(); +@@ -774,6 +800,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + first_len = skb_headlen(skb); + first_mapping = dma_map_single(&cp->pdev->dev, skb->data, + first_len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, first_mapping)) ++ goto out_dma_error; ++ + cp->tx_skb[entry] = skb; + entry = NEXT_TX(entry); + +@@ -787,6 +816,11 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + mapping = dma_map_single(&cp->pdev->dev, + skb_frag_address(this_frag), + len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) { ++ unwind_tx_frag_mapping(cp, skb, first_entry, entry); ++ goto out_dma_error; ++ } ++ + eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; + + ctrl = eor | len | DescOwn; +@@ -845,11 +879,16 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1)) + netif_stop_queue(dev); + ++out_unlock: + spin_unlock_irqrestore(&cp->lock, intr_flags); + + cpw8(TxPoll, NormalTxPoll); + + return NETDEV_TX_OK; ++out_dma_error: ++ kfree_skb(skb); ++ cp->dev->stats.tx_dropped++; ++ goto out_unlock; + } + + /* Set or clear the multicast filter for this adaptor. +@@ -1023,6 +1062,10 @@ static int cp_refill_rx(struct cp_private *cp) + + mapping = dma_map_single(&cp->pdev->dev, skb->data, + cp->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ if (dma_mapping_error(&cp->pdev->dev, mapping)) { ++ kfree_skb(skb); ++ goto err_out; ++ } + cp->rx_skb[i] = skb; + + cp->rx_ring[i].opts2 = 0; +diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c +index 9ce8665..c231b3f 100644 +--- a/drivers/net/ethernet/sfc/rx.c ++++ b/drivers/net/ethernet/sfc/rx.c +@@ -312,8 +312,9 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, + + index = rx_queue->added_count & rx_queue->ptr_mask; + new_buf = efx_rx_buffer(rx_queue, index); +- new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); + new_buf->u.page = rx_buf->u.page; ++ new_buf->page_offset = rx_buf->page_offset ^ (PAGE_SIZE >> 1); ++ new_buf->dma_addr = state->dma_addr + new_buf->page_offset; + new_buf->len = rx_buf->len; + new_buf->is_page = true; + ++rx_queue->added_count; +diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c +index f34dd99..f37e0ae 100644 +--- a/drivers/net/ethernet/via/via-rhine.c ++++ b/drivers/net/ethernet/via/via-rhine.c +@@ -32,7 +32,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #define DRV_NAME "via-rhine" +-#define DRV_VERSION "1.5.0" ++#define DRV_VERSION "1.5.1" + #define DRV_RELDATE "2010-10-09" + + +@@ -1518,7 +1518,12 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, + cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + + if (unlikely(vlan_tx_tag_present(skb))) { +- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); ++ u16 vid_pcp = vlan_tx_tag_get(skb); ++ ++ /* drop CFI/DEI bit, register needs VID and PCP */ ++ vid_pcp = (vid_pcp & VLAN_VID_MASK) | ++ ((vid_pcp & VLAN_PRIO_MASK) >> 1); ++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + } +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 2681b53..e26945d 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -308,6 +308,12 @@ static int temac_dma_bd_init(struct net_device *ndev) + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + ++ /* Init descriptor indexes */ ++ lp->tx_bd_ci = 0; ++ lp->tx_bd_next = 0; ++ lp->tx_bd_tail = 0; ++ lp->rx_bd_ci = 0; ++ + return 0; + + out: +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index 96b9e3c..b0f9015 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -641,6 +641,28 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, + return 0; + } + ++static unsigned long iov_pages(const struct iovec *iv, int offset, ++ unsigned long nr_segs) ++{ ++ unsigned long seg, base; ++ int pages = 0, len, size; ++ ++ while (nr_segs && (offset >= iv->iov_len)) { ++ offset -= iv->iov_len; ++ ++iv; ++ --nr_segs; ++ } ++ ++ for (seg = 0; seg < nr_segs; seg++) { ++ base = (unsigned long)iv[seg].iov_base + offset; ++ len = iv[seg].iov_len - offset; ++ size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; ++ pages += size; ++ offset = 0; ++ } ++ ++ return pages; ++} + + /* Get packet from user space buffer */ + static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, +@@ -687,31 +709,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + if (unlikely(count > UIO_MAXIOV)) + goto err; + +- if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) +- zerocopy = true; +- +- if (zerocopy) { +- /* Userspace may produce vectors with count greater than +- * MAX_SKB_FRAGS, so we need to linearize parts of the skb +- * to let the rest of data to be fit in the frags. +- */ +- if (count > MAX_SKB_FRAGS) { +- copylen = iov_length(iv, count - MAX_SKB_FRAGS); +- if (copylen < vnet_hdr_len) +- copylen = 0; +- else +- copylen -= vnet_hdr_len; +- } +- /* There are 256 bytes to be copied in skb, so there is enough +- * room for skb expand head in case it is used. +- * The rest buffer is mapped from userspace. +- */ +- if (copylen < vnet_hdr.hdr_len) +- copylen = vnet_hdr.hdr_len; +- if (!copylen) +- copylen = GOODCOPY_LEN; ++ if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { ++ copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; + linear = copylen; +- } else { ++ if (iov_pages(iv, vnet_hdr_len + copylen, count) ++ <= MAX_SKB_FRAGS) ++ zerocopy = true; ++ } ++ ++ if (!zerocopy) { + copylen = len; + linear = vnet_hdr.hdr_len; + } +@@ -723,9 +729,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + + if (zerocopy) + err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); +- else ++ else { + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, + len); ++ if (!err && m && m->msg_control) { ++ struct ubuf_info *uarg = m->msg_control; ++ uarg->callback(uarg); ++ } ++ } ++ + if (err) + goto err_kfree; + +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c +index ad6a9d9..2b349d3 100644 +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index f4c5de6..ee1aab0 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -614,8 +614,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, + int offset = 0; + + if (!(tun->flags & TUN_NO_PI)) { +- if ((len -= sizeof(pi)) > count) ++ if (len < sizeof(pi)) + return -EINVAL; ++ len -= sizeof(pi); + + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + return -EFAULT; +@@ -623,8 +624,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, + } + + if (tun->flags & TUN_VNET_HDR) { +- if ((len -= tun->vnet_hdr_sz) > count) ++ if (len < tun->vnet_hdr_sz) + return -EINVAL; ++ len -= tun->vnet_hdr_sz; + + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + return -EFAULT; +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 2ba40cf..43aa06b 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -615,6 +615,11 @@ static const struct usb_device_id products [] = { + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long)&wwan_info, + }, { ++ /* Telit modules */ ++ USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = (kernel_ulong_t) &wwan_info, ++}, { + USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c +index fbc0e4d..136ecf3 100644 +--- a/drivers/net/usb/dm9601.c ++++ b/drivers/net/usb/dm9601.c +@@ -384,7 +384,7 @@ static void dm9601_set_multicast(struct net_device *net) + rx_ctl |= 0x02; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > DM_MAX_MCAST) { +- rx_ctl |= 0x04; ++ rx_ctl |= 0x08; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +index 73be7ff..f146824 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1016,6 +1016,10 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, + * is_on == 0 means MRC CCK is OFF (more noise imm) + */ + bool is_on = param ? 1 : 0; ++ ++ if (ah->caps.rx_chainmask == 1) ++ break; ++ + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_ENABLE, is_on); + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, +diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h +index 1c269f5..7c70cf2 100644 +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -77,10 +77,6 @@ struct ath_config { + sizeof(struct ath_buf_state)); \ + } while (0) + +-#define ATH_RXBUF_RESET(_bf) do { \ +- (_bf)->bf_stale = false; \ +- } while (0) +- + /** + * enum buffer_type - Buffer type flags + * +@@ -308,6 +304,7 @@ struct ath_rx { + struct ath_buf *rx_bufptr; + struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; + ++ struct ath_buf *buf_hold; + struct sk_buff *frag; + }; + +diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c +index d171a72..8326c14 100644 +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -78,8 +78,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) + struct ath_desc *ds; + struct sk_buff *skb; + +- ATH_RXBUF_RESET(bf); +- + ds = bf->bf_desc; + ds->ds_link = 0; /* link to null */ + ds->ds_data = bf->bf_buf_addr; +@@ -106,6 +104,14 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) + sc->rx.rxlink = &ds->ds_link; + } + ++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf) ++{ ++ if (sc->rx.buf_hold) ++ ath_rx_buf_link(sc, sc->rx.buf_hold); ++ ++ sc->rx.buf_hold = bf; ++} ++ + static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) + { + /* XXX block beacon interrupts */ +@@ -153,7 +159,6 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc, + + skb = bf->bf_mpdu; + +- ATH_RXBUF_RESET(bf); + memset(skb->data, 0, ah->caps.rx_status_len); + dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + ah->caps.rx_status_len, DMA_TO_DEVICE); +@@ -492,6 +497,7 @@ int ath_startrecv(struct ath_softc *sc) + if (list_empty(&sc->rx.rxbuf)) + goto start_recv; + ++ sc->rx.buf_hold = NULL; + sc->rx.rxlink = NULL; + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { + ath_rx_buf_link(sc, bf); +@@ -742,6 +748,9 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, + } + + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ++ if (bf == sc->rx.buf_hold) ++ return NULL; ++ + ds = bf->bf_desc; + + /* +@@ -1974,7 +1983,7 @@ requeue: + if (edma) { + ath_rx_edma_buf_link(sc, qtype); + } else { +- ath_rx_buf_link(sc, bf); ++ ath_rx_buf_relink(sc, bf); + ath9k_hw_rxena(ah); + } + } while (1); +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 18da100..126ed31 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2423,6 +2423,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) + for (acno = 0, ac = &an->ac[acno]; + acno < WME_NUM_AC; acno++, ac++) { + ac->sched = false; ++ ac->clear_ps_filter = true; + ac->txq = sc->tx.txq_map[acno]; + INIT_LIST_HEAD(&ac->tid_q); + } +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index 564218c..0784493 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = { + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ + {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ ++ {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ + {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ + {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ + {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 67cbe5a..8fb8c9e 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2067,6 +2067,13 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) + int i; + + /* ++ * First check if temperature compensation is supported. ++ */ ++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC)) ++ return 0; ++ ++ /* + * Read TSSI boundaries for temperature compensation from + * the EEPROM. + * +diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h +index deb87e9..82baaa2 100644 +--- a/drivers/net/wireless/rtlwifi/wifi.h ++++ b/drivers/net/wireless/rtlwifi/wifi.h +@@ -1630,7 +1630,7 @@ struct rtl_priv { + that it points to the data allocated + beyond this structure like: + rtl_pci_priv or rtl_usb_priv */ +- u8 priv[0]; ++ u8 priv[0] __aligned(sizeof(void *)); + }; + + #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 9b6588e..37639a6 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -1189,6 +1189,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) + ap = dt_alloc(sizeof(*ap) + len + 1, 4); + if (!ap) + continue; ++ memset(ap, 0, sizeof(*ap) + len + 1); + ap->alias = start; + of_alias_add(ap, np, id, start, len); + } +diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c +index 394ed9e..4aa30d8 100644 +--- a/drivers/scsi/esp_scsi.c ++++ b/drivers/scsi/esp_scsi.c +@@ -530,7 +530,7 @@ static int esp_need_to_nego_sync(struct esp_target_data *tp) + static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (!ent->tag[0]) { ++ if (!ent->orig_tag[0]) { + /* Non-tagged, slot already taken? */ + if (lp->non_tagged_cmd) + return -EBUSY; +@@ -564,9 +564,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + return -EBUSY; + } + +- BUG_ON(lp->tagged_cmds[ent->tag[1]]); ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]); + +- lp->tagged_cmds[ent->tag[1]] = ent; ++ lp->tagged_cmds[ent->orig_tag[1]] = ent; + lp->num_tagged++; + + return 0; +@@ -575,9 +575,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, + static void esp_free_lun_tag(struct esp_cmd_entry *ent, + struct esp_lun_data *lp) + { +- if (ent->tag[0]) { +- BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent); +- lp->tagged_cmds[ent->tag[1]] = NULL; ++ if (ent->orig_tag[0]) { ++ BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent); ++ lp->tagged_cmds[ent->orig_tag[1]] = NULL; + lp->num_tagged--; + } else { + BUG_ON(lp->non_tagged_cmd != ent); +@@ -667,6 +667,8 @@ static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp) + ent->tag[0] = 0; + ent->tag[1] = 0; + } ++ ent->orig_tag[0] = ent->tag[0]; ++ ent->orig_tag[1] = ent->tag[1]; + + if (esp_alloc_lun_tag(ent, lp) < 0) + continue; +diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h +index 28e22ac..cd68805 100644 +--- a/drivers/scsi/esp_scsi.h ++++ b/drivers/scsi/esp_scsi.h +@@ -271,6 +271,7 @@ struct esp_cmd_entry { + #define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */ + + u8 tag[2]; ++ u8 orig_tag[2]; + + u8 status; + u8 message; +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index 96029e6..c874458 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -2105,7 +2105,7 @@ iscsi_if_rx(struct sk_buff *skb) + break; + err = iscsi_if_send_reply(group, nlh->nlmsg_seq, + nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); +- } while (err < 0 && err != -ECONNREFUSED); ++ } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH); + skb_pull(skb, rlen); + } + mutex_unlock(&rx_queue_mutex); +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 17603da..f6d2b62 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2136,14 +2136,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) + } + } + +- if (modepage == 0x3F) { +- sd_printk(KERN_ERR, sdkp, "No Caching mode page " +- "present\n"); +- goto defaults; +- } else if ((buffer[offset] & 0x3f) != modepage) { +- sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); +- goto defaults; +- } ++ sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); ++ goto defaults; ++ + Page_found: + if (modepage == 8) { + sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); +diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c +index 95ebc26..e3adb38 100644 +--- a/drivers/staging/comedi/drivers/dt282x.c ++++ b/drivers/staging/comedi/drivers/dt282x.c +@@ -407,8 +407,9 @@ struct dt282x_private { + } \ + udelay(5); \ + } \ +- if (_i) \ ++ if (_i) { \ + b \ ++ } \ + } while (0) + + static int dt282x_attach(struct comedi_device *dev, +diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c +index 403fc09..8b564ad 100644 +--- a/drivers/staging/comedi/drivers/ni_65xx.c ++++ b/drivers/staging/comedi/drivers/ni_65xx.c +@@ -411,29 +411,25 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) + { +- unsigned base_bitfield_channel; +- const unsigned max_ports_per_bitfield = 5; ++ int base_bitfield_channel; + unsigned read_bits = 0; +- unsigned j; ++ int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1); ++ int port_offset; ++ + if (insn->n != 2) + return -EINVAL; + base_bitfield_channel = CR_CHAN(insn->chanspec); +- for (j = 0; j < max_ports_per_bitfield; ++j) { +- const unsigned port_offset = +- ni_65xx_port_by_channel(base_bitfield_channel) + j; +- const unsigned port = +- sprivate(s)->base_port + port_offset; +- unsigned base_port_channel; ++ for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel); ++ port_offset <= last_port_offset; port_offset++) { ++ unsigned port = sprivate(s)->base_port + port_offset; ++ int base_port_channel = port_offset * ni_65xx_channels_per_port; + unsigned port_mask, port_data, port_read_bits; +- int bitshift; +- if (port >= ni_65xx_total_num_ports(board(dev))) ++ int bitshift = base_port_channel - base_bitfield_channel; ++ ++ if (bitshift >= 32) + break; +- base_port_channel = port_offset * ni_65xx_channels_per_port; + port_mask = data[0]; + port_data = data[1]; +- bitshift = base_port_channel - base_bitfield_channel; +- if (bitshift >= 32 || bitshift <= -32) +- break; + if (bitshift > 0) { + port_mask >>= bitshift; + port_data >>= bitshift; +diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c +index 754d54e..f680766 100644 +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -1221,6 +1221,8 @@ device_release_WPADEV(pDevice); + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + ++ pDevice->flags &= ~DEVICE_FLAGS_OPENED; ++ + device_free_tx_bufs(pDevice); + device_free_rx_bufs(pDevice); + device_free_int_bufs(pDevice); +@@ -1232,7 +1234,6 @@ device_release_WPADEV(pDevice); + usb_free_urb(pDevice->pInterruptURB); + + BSSvClearNodeDBTable(pDevice, 0); +- pDevice->flags &=(~DEVICE_FLAGS_OPENED); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n"); + +diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c +index 926d483..d197b3e 100644 +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -709,9 +709,7 @@ static void zram_slot_free_notify(struct block_device *bdev, + struct zram *zram; + + zram = bdev->bd_disk->private_data; +- down_write(&zram->lock); + zram_free_page(zram, index); +- up_write(&zram->lock); + zram_stat64_inc(zram, &zram->stats.notify_free); + } + +diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h +index 87f2fec..e5cd246 100644 +--- a/drivers/staging/zram/zram_drv.h ++++ b/drivers/staging/zram/zram_drv.h +@@ -107,9 +107,8 @@ struct zram { + void *compress_buffer; + struct table *table; + spinlock_t stat64_lock; /* protect 64-bit stats */ +- struct rw_semaphore lock; /* protect compression buffers, table, +- * 32bit stat counters against concurrent +- * notifications, reads and writes */ ++ struct rw_semaphore lock; /* protect compression buffers and table ++ * against concurrent read and writes */ + struct request_queue *queue; + struct gendisk *disk; + int init_done; +diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c +index c0b4872..f5440a7 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -552,11 +552,12 @@ static int dma_push_rx(struct eg20t_port *priv, int size) + dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", + size - room); + if (!room) +- return room; ++ goto out; + + tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size); + + port->icount.rx += room; ++out: + tty_kref_put(tty); + + return room; +@@ -970,6 +971,8 @@ static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) + if (tty == NULL) { + for (i = 0; error_msg[i] != NULL; i++) + dev_err(&priv->pdev->dev, error_msg[i]); ++ } else { ++ tty_kref_put(tty); + } + } + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index fe8c04b..06dfb4f 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -187,6 +187,7 @@ skip_error: + static void wdm_int_callback(struct urb *urb) + { + int rv = 0; ++ int responding; + int status = urb->status; + struct wdm_device *desc; + struct usb_ctrlrequest *req; +@@ -260,8 +261,8 @@ static void wdm_int_callback(struct urb *urb) + desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + spin_lock(&desc->iuspin); + clear_bit(WDM_READ, &desc->flags); +- set_bit(WDM_RESPONDING, &desc->flags); +- if (!test_bit(WDM_DISCONNECTING, &desc->flags) ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); ++ if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { + rv = usb_submit_urb(desc->response, GFP_ATOMIC); + dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", +@@ -658,16 +659,20 @@ static void wdm_rxwork(struct work_struct *work) + { + struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); + unsigned long flags; +- int rv; ++ int rv = 0; ++ int responding; + + spin_lock_irqsave(&desc->iuspin, flags); + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + spin_unlock_irqrestore(&desc->iuspin, flags); + } else { ++ responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); + spin_unlock_irqrestore(&desc->iuspin, flags); +- rv = usb_submit_urb(desc->response, GFP_KERNEL); ++ if (!responding) ++ rv = usb_submit_urb(desc->response, GFP_KERNEL); + if (rv < 0 && rv != -EPERM) { + spin_lock_irqsave(&desc->iuspin, flags); ++ clear_bit(WDM_RESPONDING, &desc->flags); + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) + schedule_work(&desc->rxwork); + spin_unlock_irqrestore(&desc->iuspin, flags); +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index f4bdd0c..78609d3 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -424,7 +424,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, + + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + if (config->desc.bDescriptorType != USB_DT_CONFIG || +- config->desc.bLength < USB_DT_CONFIG_SIZE) { ++ config->desc.bLength < USB_DT_CONFIG_SIZE || ++ config->desc.bLength > size) { + dev_err(ddev, "invalid descriptor for config index %d: " + "type = 0x%X, length = %d\n", cfgidx, + config->desc.bDescriptorType, config->desc.bLength); +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 22f770a..49257b3 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -646,6 +646,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, + if ((index & ~USB_DIR_IN) == 0) + return 0; + ret = findintfep(ps->dev, index); ++ if (ret < 0) { ++ /* ++ * Some not fully compliant Win apps seem to get ++ * index wrong and have the endpoint number here ++ * rather than the endpoint address (with the ++ * correct direction). Win does let this through, ++ * so we'll not reject it here but leave it to ++ * the device to not break KVM. But we warn. ++ */ ++ ret = findintfep(ps->dev, index ^ 0x80); ++ if (ret >= 0) ++ dev_info(&ps->dev->dev, ++ "%s: process %i (%s) requesting ep %02x but needs %02x\n", ++ __func__, task_pid_nr(current), ++ current->comm, index, index ^ 0x80); ++ } + if (ret >= 0) + ret = checkintf(ps, ret); + break; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 2768a7e..a5ea85f 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3749,7 +3749,8 @@ static void hub_events(void) + hub->hdev->children[i - 1]; + + dev_dbg(hub_dev, "warm reset port %d\n", i); +- if (!udev) { ++ if (!udev || !(portstatus & ++ USB_PORT_STAT_CONNECTION)) { + status = hub_port_reset(hub, i, + NULL, HUB_BH_RESET_TIME, + true); +@@ -3759,8 +3760,8 @@ static void hub_events(void) + usb_lock_device(udev); + status = usb_reset_device(udev); + usb_unlock_device(udev); ++ connect_change = 0; + } +- connect_change = 0; + } + + if (connect_change) +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index f77c000..9edc582 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -45,6 +45,8 @@ + /* FIXME define these in <linux/pci_ids.h> */ + #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd ++#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 ++#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e + + #define DWC3_PCI_DEVS_POSSIBLE 32 + +@@ -191,6 +193,8 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { } /* Terminating Entry */ + }; + MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); +diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c +index 55978fc..0874473 100644 +--- a/drivers/usb/host/ehci-mxc.c ++++ b/drivers/usb/host/ehci-mxc.c +@@ -296,7 +296,7 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev) + if (pdata && pdata->exit) + pdata->exit(pdev); + +- if (pdata->otg) ++ if (pdata && pdata->otg) + otg_shutdown(pdata->otg); + + usb_remove_hcd(hcd); +diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c +index b71e22e..29c0421 100644 +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -543,7 +543,7 @@ static struct pci_driver ehci_pci_driver = { + .remove = usb_hcd_pci_remove, + .shutdown = usb_hcd_pci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c +index bc01b06..839cb64 100644 +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -413,7 +413,7 @@ static struct pci_driver ohci_pci_driver = { + .remove = usb_hcd_pci_remove, + .shutdown = usb_hcd_pci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c +index c300bd2f7..0f228c4 100644 +--- a/drivers/usb/host/uhci-pci.c ++++ b/drivers/usb/host/uhci-pci.c +@@ -293,7 +293,7 @@ static struct pci_driver uhci_pci_driver = { + .remove = usb_hcd_pci_remove, + .shutdown = uhci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 79d2720..61b0668 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -330,7 +330,7 @@ static struct pci_driver xhci_pci_driver = { + /* suspend and resume implemented later */ + + .shutdown = usb_hcd_pci_shutdown, +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 633476e..2b4f42b 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -879,8 +879,12 @@ remove_finished_td: + /* Otherwise ring the doorbell(s) to restart queued transfers */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + } +- ep->stopped_td = NULL; +- ep->stopped_trb = NULL; ++ ++ /* Clear stopped_td and stopped_trb if endpoint is not halted */ ++ if (!(ep->ep_state & EP_HALTED)) { ++ ep->stopped_td = NULL; ++ ep->stopped_trb = NULL; ++ } + + /* + * Drop the lock and complete the URBs in the cancelled TD list. +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 6e1c92a..629aa74 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3484,10 +3484,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev; ++ struct device *dev = hcd->self.controller; + unsigned long flags; + u32 state; + int i, ret; + ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * We called pm_runtime_get_noresume when the device was attached. ++ * Decrement the counter here to allow controller to runtime suspend ++ * if no devices remain. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_put_noidle(dev); ++#endif ++ + ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); + /* If the host is halted due to driver unload, we still need to free the + * device. +@@ -3559,6 +3570,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci) + int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ struct device *dev = hcd->self.controller; + unsigned long flags; + int timeleft; + int ret; +@@ -3611,6 +3623,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + goto disable_slot; + } + udev->slot_id = xhci->slot_id; ++ ++#ifndef CONFIG_USB_DEFAULT_PERSIST ++ /* ++ * If resetting upon resume, we can't put the controller into runtime ++ * suspend if there is a device attached. ++ */ ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ pm_runtime_get_noresume(dev); ++#endif ++ + /* Is this a LS or FS device under a HS hub? */ + /* Hub or peripherial? */ + return 1; +diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c +index 9270d5c..8e02ff2 100644 +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + kfree(urbtrack); + return -ENOMEM; + } +- urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); ++ urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack); +@@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; +- urbtrack->setup->wValue = get_reg_value(reg, dummy); +- urbtrack->setup->wIndex = get_reg_index(reg); ++ urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); ++ urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); + urbtrack->setup->wLength = 0; + usb_fill_control_urb(urbtrack->urb, usbdev, + usb_sndctrlpipe(usbdev, 0), +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index c2103f4..536c4ad 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb); + + #define HUAWEI_VENDOR_ID 0x12D1 + #define HUAWEI_PRODUCT_E173 0x140C ++#define HUAWEI_PRODUCT_E1750 0x1406 + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_K4605 0x14C6 +@@ -581,6 +582,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), +diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c +index bf1c094..b657de6 100644 +--- a/drivers/xen/grant-table.c ++++ b/drivers/xen/grant-table.c +@@ -355,9 +355,18 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback, + void (*fn)(void *), void *arg, u16 count) + { + unsigned long flags; ++ struct gnttab_free_callback *cb; ++ + spin_lock_irqsave(&gnttab_list_lock, flags); +- if (callback->next) +- goto out; ++ ++ /* Check if the callback is already on the list */ ++ cb = gnttab_free_callback_list; ++ while (cb) { ++ if (cb == callback) ++ goto out; ++ cb = cb->next; ++ } ++ + callback->fn = fn; + callback->arg = arg; + callback->count = count; +diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c +index f3a257d..fb001cd 100644 +--- a/fs/debugfs/inode.c ++++ b/fs/debugfs/inode.c +@@ -380,8 +380,7 @@ EXPORT_SYMBOL_GPL(debugfs_remove); + */ + void debugfs_remove_recursive(struct dentry *dentry) + { +- struct dentry *child; +- struct dentry *parent; ++ struct dentry *child, *next, *parent; + + if (!dentry) + return; +@@ -391,61 +390,37 @@ void debugfs_remove_recursive(struct dentry *dentry) + return; + + parent = dentry; ++ down: + mutex_lock(&parent->d_inode->i_mutex); ++ list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) { ++ if (!debugfs_positive(child)) ++ continue; + +- while (1) { +- /* +- * When all dentries under "parent" has been removed, +- * walk up the tree until we reach our starting point. +- */ +- if (list_empty(&parent->d_subdirs)) { +- mutex_unlock(&parent->d_inode->i_mutex); +- if (parent == dentry) +- break; +- parent = parent->d_parent; +- mutex_lock(&parent->d_inode->i_mutex); +- } +- child = list_entry(parent->d_subdirs.next, struct dentry, +- d_u.d_child); +- next_sibling: +- +- /* +- * If "child" isn't empty, walk down the tree and +- * remove all its descendants first. +- */ ++ /* perhaps simple_empty(child) makes more sense */ + if (!list_empty(&child->d_subdirs)) { + mutex_unlock(&parent->d_inode->i_mutex); + parent = child; +- mutex_lock(&parent->d_inode->i_mutex); +- continue; +- } +- __debugfs_remove(child, parent); +- if (parent->d_subdirs.next == &child->d_u.d_child) { +- /* +- * Try the next sibling. +- */ +- if (child->d_u.d_child.next != &parent->d_subdirs) { +- child = list_entry(child->d_u.d_child.next, +- struct dentry, +- d_u.d_child); +- goto next_sibling; +- } +- +- /* +- * Avoid infinite loop if we fail to remove +- * one dentry. +- */ +- mutex_unlock(&parent->d_inode->i_mutex); +- break; ++ goto down; + } +- simple_release_fs(&debugfs_mount, &debugfs_mount_count); ++ up: ++ if (!__debugfs_remove(child, parent)) ++ simple_release_fs(&debugfs_mount, &debugfs_mount_count); + } + +- parent = dentry->d_parent; ++ mutex_unlock(&parent->d_inode->i_mutex); ++ child = parent; ++ parent = parent->d_parent; + mutex_lock(&parent->d_inode->i_mutex); +- __debugfs_remove(dentry, parent); ++ ++ if (child != dentry) { ++ next = list_entry(child->d_u.d_child.next, struct dentry, ++ d_u.d_child); ++ goto up; ++ } ++ ++ if (!__debugfs_remove(child, parent)) ++ simple_release_fs(&debugfs_mount, &debugfs_mount_count); + mutex_unlock(&parent->d_inode->i_mutex); +- simple_release_fs(&debugfs_mount, &debugfs_mount_count); + } + EXPORT_SYMBOL_GPL(debugfs_remove_recursive); + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 3ca3b7f..2e0e34f 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2054,7 +2054,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) + int err = 0; + + /* ext4_handle_valid() assumes a valid handle_t pointer */ +- if (handle && !ext4_handle_valid(handle)) ++ if (handle && !ext4_handle_valid(handle) && ++ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) + return 0; + + mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index 5ef7afb..06e2f73 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1063,6 +1063,8 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file, + return -EIO; + if (reclen > nbytes) + break; ++ if (memchr(dirent->name, '/', dirent->namelen) != NULL) ++ return -EIO; + + over = filldir(dstbuf, dirent->name, dirent->namelen, + file->f_pos, dirent->ino, dirent->type); +@@ -1282,6 +1284,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + { + struct inode *inode = entry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + struct fuse_req *req; + struct fuse_setattr_in inarg; + struct fuse_attr_out outarg; +@@ -1312,8 +1315,10 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + if (IS_ERR(req)) + return PTR_ERR(req); + +- if (is_truncate) ++ if (is_truncate) { + fuse_set_nowrite(inode); ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ } + + memset(&inarg, 0, sizeof(inarg)); + memset(&outarg, 0, sizeof(outarg)); +@@ -1375,12 +1380,14 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + invalidate_inode_pages2(inode->i_mapping); + } + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return 0; + + error: + if (is_truncate) + fuse_release_nowrite(inode); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + return err; + } + +@@ -1439,6 +1446,8 @@ static int fuse_setxattr(struct dentry *entry, const char *name, + fc->no_setxattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +@@ -1568,6 +1577,8 @@ static int fuse_removexattr(struct dentry *entry, const char *name) + fc->no_removexattr = 1; + err = -EOPNOTSUPP; + } ++ if (!err) ++ fuse_invalidate_attr(inode); + return err; + } + +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 5242006..510d4aa 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -519,7 +519,8 @@ static void fuse_read_update_size(struct inode *inode, loff_t size, + struct fuse_inode *fi = get_fuse_inode(inode); + + spin_lock(&fc->lock); +- if (attr_ver == fi->attr_version && size < inode->i_size) { ++ if (attr_ver == fi->attr_version && size < inode->i_size && ++ !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + fi->attr_version = ++fc->attr_version; + i_size_write(inode, size); + } +@@ -881,12 +882,16 @@ static ssize_t fuse_perform_write(struct file *file, + { + struct inode *inode = mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); ++ struct fuse_inode *fi = get_fuse_inode(inode); + int err = 0; + ssize_t res = 0; + + if (is_bad_inode(inode)) + return -EIO; + ++ if (inode->i_size < pos + iov_iter_count(ii)) ++ set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); ++ + do { + struct fuse_req *req; + ssize_t count; +@@ -921,6 +926,7 @@ static ssize_t fuse_perform_write(struct file *file, + if (res > 0) + fuse_write_update_size(inode, pos); + ++ clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); + fuse_invalidate_attr(inode); + + return res > 0 ? res : err; +@@ -1251,7 +1257,6 @@ static int fuse_writepage_locked(struct page *page) + + inc_bdi_stat(mapping->backing_dev_info, BDI_WRITEBACK); + inc_zone_page_state(tmp_page, NR_WRITEBACK_TEMP); +- end_page_writeback(page); + + spin_lock(&fc->lock); + list_add(&req->writepages_entry, &fi->writepages); +@@ -1259,6 +1264,8 @@ static int fuse_writepage_locked(struct page *page) + fuse_flush_writepages(inode); + spin_unlock(&fc->lock); + ++ end_page_writeback(page); ++ + return 0; + + err_free: +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index 89c4a58..52ffd24 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -103,6 +103,15 @@ struct fuse_inode { + + /** List of writepage requestst (pending or sent) */ + struct list_head writepages; ++ ++ /** Miscellaneous bits describing inode state */ ++ unsigned long state; ++}; ++ ++/** FUSE inode state bits */ ++enum { ++ /** An operation changing file size is in progress */ ++ FUSE_I_SIZE_UNSTABLE, + }; + + struct fuse_conn; +diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c +index 1f82d95..912c250 100644 +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -92,6 +92,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) + fi->attr_version = 0; + fi->writectr = 0; + fi->orig_ino = 0; ++ fi->state = 0; + INIT_LIST_HEAD(&fi->write_files); + INIT_LIST_HEAD(&fi->queued_writes); + INIT_LIST_HEAD(&fi->writepages); +@@ -200,7 +201,8 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, + loff_t oldsize; + + spin_lock(&fc->lock); +- if (attr_version != 0 && fi->attr_version > attr_version) { ++ if ((attr_version != 0 && fi->attr_version > attr_version) || ++ test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { + spin_unlock(&fc->lock); + return; + } +diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c +index f950059..a5f25a7 100644 +--- a/fs/isofs/inode.c ++++ b/fs/isofs/inode.c +@@ -120,8 +120,8 @@ static void destroy_inodecache(void) + + static int isofs_remount(struct super_block *sb, int *flags, char *data) + { +- /* we probably want a lot more here */ +- *flags |= MS_RDONLY; ++ if (!(*flags & MS_RDONLY)) ++ return -EROFS; + return 0; + } + +@@ -770,15 +770,6 @@ root_found: + */ + s->s_maxbytes = 0x80000000000LL; + +- /* +- * The CDROM is read-only, has no nodes (devices) on it, and since +- * all of the files appear to be owned by root, we really do not want +- * to allow suid. (suid or devices will not show up unless we have +- * Rock Ridge extensions) +- */ +- +- s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */; +- + /* Set this for reference. Its not currently used except on write + which we don't have .. */ + +@@ -1535,6 +1526,9 @@ struct inode *isofs_iget(struct super_block *sb, + static struct dentry *isofs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { ++ /* We don't support read-write mounts */ ++ if (!(flags & MS_RDONLY)) ++ return ERR_PTR(-EACCES); + return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + } + +diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c +index 65221a0..16eacec 100644 +--- a/fs/nilfs2/page.c ++++ b/fs/nilfs2/page.c +@@ -94,6 +94,7 @@ void nilfs_forget_buffer(struct buffer_head *bh) + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); + clear_buffer_nilfs_redirected(bh); ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + if (nilfs_page_buffers_clean(page)) + __nilfs_clear_page_dirty(page); +@@ -390,6 +391,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping) + bh = head = page_buffers(page); + do { + lock_buffer(bh); ++ clear_buffer_async_write(bh); + clear_buffer_dirty(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_checked(bh); +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 6f24e67..233d3ed 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -662,7 +662,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + + bh = head = page_buffers(page); + do { +- if (!buffer_dirty(bh)) ++ if (!buffer_dirty(bh) || buffer_async_write(bh)) + continue; + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, listp); +@@ -696,7 +696,8 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode, + for (i = 0; i < pagevec_count(&pvec); i++) { + bh = head = page_buffers(pvec.pages[i]); + do { +- if (buffer_dirty(bh)) { ++ if (buffer_dirty(bh) && ++ !buffer_async_write(bh)) { + get_bh(bh); + list_add_tail(&bh->b_assoc_buffers, + listp); +@@ -1576,6 +1577,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) { + lock_page(bd_page); +@@ -1589,6 +1591,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ set_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + lock_page(bd_page); +@@ -1674,6 +1677,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) + list_for_each_entry(segbuf, logs, sb_list) { + list_for_each_entry(bh, &segbuf->sb_segsum_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1683,6 +1687,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) + + list_for_each_entry(bh, &segbuf->sb_payload_buffers, + b_assoc_buffers) { ++ clear_buffer_async_write(bh); + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + end_page_writeback(bd_page); +@@ -1752,6 +1757,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + if (bh->b_page != bd_page) { + if (bd_page) + end_page_writeback(bd_page); +@@ -1773,6 +1779,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) + b_assoc_buffers) { + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); ++ clear_buffer_async_write(bh); + clear_buffer_delay(bh); + clear_buffer_nilfs_volatile(bh); + clear_buffer_nilfs_redirected(bh); +diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c +index a506360..0c2f912 100644 +--- a/fs/notify/fanotify/fanotify.c ++++ b/fs/notify/fanotify/fanotify.c +@@ -18,6 +18,12 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) + old->tgid == new->tgid) { + switch (old->data_type) { + case (FSNOTIFY_EVENT_PATH): ++#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS ++ /* dont merge two permission events */ ++ if ((old->mask & FAN_ALL_PERM_EVENTS) && ++ (new->mask & FAN_ALL_PERM_EVENTS)) ++ return false; ++#endif + if ((old->path.mnt == new->path.mnt) && + (old->path.dentry == new->path.dentry)) + return true; +diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c +index 7eb1c0c..cf22847 100644 +--- a/fs/ocfs2/extent_map.c ++++ b/fs/ocfs2/extent_map.c +@@ -782,7 +782,6 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + cpos = map_start >> osb->s_clustersize_bits; + mapping_end = ocfs2_clusters_for_bytes(inode->i_sb, + map_start + map_len); +- mapping_end -= cpos; + is_last = 0; + while (cpos < mapping_end && !is_last) { + u32 fe_flags; +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 331e2ef..19fe719 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -416,10 +416,12 @@ struct hid_report { + struct hid_device *device; /* associated device */ + }; + ++#define HID_MAX_IDS 256 ++ + struct hid_report_enum { + unsigned numbered; + struct list_head report_list; +- struct hid_report *report_id_hash[256]; ++ struct hid_report *report_id_hash[HID_MAX_IDS]; + }; + + #define HID_REPORT_TYPES 3 +@@ -716,6 +718,10 @@ void hid_output_report(struct hid_report *report, __u8 *data); + struct hid_device *hid_allocate_device(void); + struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); + int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); ++struct hid_report *hid_validate_values(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int field_index, ++ unsigned int report_counts); + int hid_check_keys_pressed(struct hid_device *hid); + int hid_connect(struct hid_device *hid, unsigned int connect_mask); + void hid_disconnect(struct hid_device *hid); +diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h +index ba45e6b..f5a21d0 100644 +--- a/include/linux/icmpv6.h ++++ b/include/linux/icmpv6.h +@@ -123,6 +123,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb) + #define ICMPV6_NOT_NEIGHBOUR 2 + #define ICMPV6_ADDR_UNREACH 3 + #define ICMPV6_PORT_UNREACH 4 ++#define ICMPV6_POLICY_FAIL 5 ++#define ICMPV6_REJECT_ROUTE 6 + + /* + * Codes for Time Exceeded +diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h +index 0c99776..84b1447 100644 +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -255,6 +255,7 @@ struct inet6_skb_parm { + #define IP6SKB_XFRM_TRANSFORMED 1 + #define IP6SKB_FORWARDED 2 + #define IP6SKB_REROUTED 4 ++#define IP6SKB_FRAGMENTED 16 + }; + + #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) +diff --git a/include/linux/mm.h b/include/linux/mm.h +index d0493f6..305fd75 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -865,7 +865,8 @@ extern void pagefault_out_of_memory(void); + * Flags passed to show_mem() and show_free_areas() to suppress output in + * various contexts. + */ +-#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ ++#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ ++#define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */ + + extern void show_free_areas(unsigned int flags); + extern bool skip_free_areas_node(unsigned int flags, int nid); +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 3cfcfea..eeb6a29 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -927,7 +927,7 @@ struct perf_cpu_context { + int exclusive; + struct list_head rotation_list; + int jiffies_interval; +- struct pmu *active_pmu; ++ struct pmu *unique_pmu; + struct perf_cgroup *cgrp; + }; + +diff --git a/include/linux/rculist.h b/include/linux/rculist.h +index 6f95e24..3863352 100644 +--- a/include/linux/rculist.h ++++ b/include/linux/rculist.h +@@ -254,8 +254,9 @@ static inline void list_splice_init_rcu(struct list_head *list, + */ + #define list_first_or_null_rcu(ptr, type, member) \ + ({struct list_head *__ptr = (ptr); \ +- struct list_head __rcu *__next = list_next_rcu(__ptr); \ +- likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ ++ struct list_head *__next = ACCESS_ONCE(__ptr->next); \ ++ likely(__ptr != __next) ? \ ++ list_entry_rcu(__next, type, member) : NULL; \ + }) + + /** +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index 03354d5..0daa46b 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -395,7 +395,7 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev, + extern void usb_hcd_pci_remove(struct pci_dev *dev); + extern void usb_hcd_pci_shutdown(struct pci_dev *dev); + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + extern const struct dev_pm_ops usb_hcd_pci_pm_ops; + #endif + #endif /* CONFIG_PCI */ +diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h +index e9ff3fc..34b06da 100644 +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -41,6 +41,10 @@ struct inet_peer { + u32 pmtu_orig; + u32 pmtu_learned; + struct inetpeer_addr_base redirect_learned; ++ union { ++ struct list_head gc_list; ++ struct rcu_head gc_rcu; ++ }; + /* + * Once inet_peer is queued for deletion (refcnt == -1), following fields + * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp +@@ -96,6 +100,8 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, + extern void inet_putpeer(struct inet_peer *p); + extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); + ++extern void inetpeer_invalidate_tree(int family); ++ + /* + * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, + * tcp_ts_stamp if no refcount is taken on inet_peer +diff --git a/include/net/ip.h b/include/net/ip.h +index eca0ef7..06aed72 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -266,9 +266,11 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) + + extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); + +-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) ++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in +@@ -280,9 +282,11 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str + __ip_select_ident(iph, dst, 0); + } + +-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) ++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; +diff --git a/include/net/ipip.h b/include/net/ipip.h +index a32654d..4dccfe3 100644 +--- a/include/net/ipip.h ++++ b/include/net/ipip.h +@@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry { + int pkt_len = skb->len - skb_transport_offset(skb); \ + \ + skb->ip_summed = CHECKSUM_NONE; \ +- ip_select_ident(iph, &rt->dst, NULL); \ ++ ip_select_ident(skb, &rt->dst, NULL); \ + \ + err = ip_local_out(skb); \ + if (likely(net_xmit_eval(err) == 0)) { \ +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index d2a01fe..2a1ffb7 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -3504,6 +3504,7 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft, + const char *buffer) + { + struct cgroup_event *event = NULL; ++ struct cgroup *cgrp_cfile; + unsigned int efd, cfd; + struct file *efile = NULL; + struct file *cfile = NULL; +@@ -3559,6 +3560,16 @@ static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft, + goto fail; + } + ++ /* ++ * The file to be monitored must be in the same cgroup as ++ * cgroup.event_control is. ++ */ ++ cgrp_cfile = __d_cgrp(cfile->f_dentry->d_parent); ++ if (cgrp_cfile != cgrp) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ + if (!event->cft->register_event || !event->cft->unregister_event) { + ret = -EINVAL; + goto fail; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 5bbe443..83d5621 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -242,9 +242,9 @@ perf_cgroup_match(struct perf_event *event) + return !event->cgrp || event->cgrp == cpuctx->cgrp; + } + +-static inline void perf_get_cgroup(struct perf_event *event) ++static inline bool perf_tryget_cgroup(struct perf_event *event) + { +- css_get(&event->cgrp->css); ++ return css_tryget(&event->cgrp->css); + } + + static inline void perf_put_cgroup(struct perf_event *event) +@@ -360,6 +360,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode) + + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); ++ if (cpuctx->unique_pmu != pmu) ++ continue; /* ensure we process each cpuctx once */ + + /* + * perf_cgroup_events says at least one +@@ -383,9 +385,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode) + + if (mode & PERF_CGROUP_SWIN) { + WARN_ON_ONCE(cpuctx->cgrp); +- /* set cgrp before ctxsw in to +- * allow event_filter_match() to not +- * have to pass task around ++ /* ++ * set cgrp before ctxsw in to allow ++ * event_filter_match() to not have to pass ++ * task around + */ + cpuctx->cgrp = perf_cgroup_from_task(task); + cpu_ctx_sched_in(cpuctx, EVENT_ALL, task); +@@ -473,7 +476,11 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, + event->cgrp = cgrp; + + /* must be done before we fput() the file */ +- perf_get_cgroup(event); ++ if (!perf_tryget_cgroup(event)) { ++ event->cgrp = NULL; ++ ret = -ENOENT; ++ goto out; ++ } + + /* + * all events in a group must monitor +@@ -4377,7 +4384,7 @@ static void perf_event_task_event(struct perf_task_event *task_event) + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_task_ctx(&cpuctx->ctx, task_event); + +@@ -4523,7 +4530,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_comm_ctx(&cpuctx->ctx, comm_event); + +@@ -4719,7 +4726,7 @@ got_name: + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); +- if (cpuctx->active_pmu != pmu) ++ if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, + vma->vm_flags & VM_EXEC); +@@ -5741,8 +5748,8 @@ static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu) + + cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); + +- if (cpuctx->active_pmu == old_pmu) +- cpuctx->active_pmu = pmu; ++ if (cpuctx->unique_pmu == old_pmu) ++ cpuctx->unique_pmu = pmu; + } + } + +@@ -5877,7 +5884,7 @@ skip_type: + cpuctx->ctx.pmu = pmu; + cpuctx->jiffies_interval = 1; + INIT_LIST_HEAD(&cpuctx->rotation_list); +- cpuctx->active_pmu = pmu; ++ cpuctx->unique_pmu = pmu; + } + + got_cpu_context: +diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c +index 59474c5..c261da7 100644 +--- a/kernel/sched_fair.c ++++ b/kernel/sched_fair.c +@@ -4890,11 +4890,15 @@ static void task_fork_fair(struct task_struct *p) + + update_rq_clock(rq); + +- if (unlikely(task_cpu(p) != this_cpu)) { +- rcu_read_lock(); +- __set_task_cpu(p, this_cpu); +- rcu_read_unlock(); +- } ++ /* ++ * Not only the cpu but also the task_group of the parent might have ++ * been changed after parent->se.parent,cfs_rq were copied to ++ * child->se.parent,cfs_rq. So call __set_task_cpu() to make those ++ * of child point to valid ones. ++ */ ++ rcu_read_lock(); ++ __set_task_cpu(p, this_cpu); ++ rcu_read_unlock(); + + update_curr(cfs_rq); + +diff --git a/lib/show_mem.c b/lib/show_mem.c +index 4407f8c..b7c7231 100644 +--- a/lib/show_mem.c ++++ b/lib/show_mem.c +@@ -18,6 +18,9 @@ void show_mem(unsigned int filter) + printk("Mem-Info:\n"); + show_free_areas(filter); + ++ if (filter & SHOW_MEM_FILTER_PAGE_COUNT) ++ return; ++ + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index d80ac4b..ed0ed8a 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1882,6 +1882,8 @@ static void collapse_huge_page(struct mm_struct *mm, + goto out; + + vma = find_vma(mm, address); ++ if (!vma) ++ goto out; + hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; + hend = vma->vm_end & HPAGE_PMD_MASK; + if (address < hstart || address + HPAGE_PMD_SIZE > hend) +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index d027a24..204de6a 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4385,7 +4385,13 @@ static int compare_thresholds(const void *a, const void *b) + const struct mem_cgroup_threshold *_a = a; + const struct mem_cgroup_threshold *_b = b; + +- return _a->threshold - _b->threshold; ++ if (_a->threshold > _b->threshold) ++ return 1; ++ ++ if (_a->threshold < _b->threshold) ++ return -1; ++ ++ return 0; + } + + static int mem_cgroup_oom_notify_cb(struct mem_cgroup *memcg) +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index b5afea2..d8762b2 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1760,6 +1760,13 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) + return; + + /* ++ * Walking all memory to count page types is very expensive and should ++ * be inhibited in non-blockable contexts. ++ */ ++ if (!(gfp_mask & __GFP_WAIT)) ++ filter |= SHOW_MEM_FILTER_PAGE_COUNT; ++ ++ /* + * This documents exceptions given to allocations in certain + * contexts that are allowed to allocate outside current's set + * of allowed nodes. +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index b81500c..a06deca 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1155,7 +1155,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, + mld2q = (struct mld2_query *)icmp6_hdr(skb); + if (!mld2q->mld2q_nsrcs) + group = &mld2q->mld2q_mca; +- max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1; ++ ++ max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL); + } + + if (!group) +diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c +index dd147d7..8ac946f 100644 +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -189,7 +189,7 @@ static void br_record_config_information(struct net_bridge_port *p, + p->designated_age = jiffies + bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies +- + (p->br->max_age - bpdu->message_age)); ++ + (bpdu->max_age - bpdu->message_age)); + } + + /* called under bridge lock */ +diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c +index 5cf5222..84efbe4 100644 +--- a/net/caif/cfctrl.c ++++ b/net/caif/cfctrl.c +@@ -288,9 +288,10 @@ int cfctrl_linkup_request(struct cflayer *layer, + + count = cfctrl_cancel_req(&cfctrl->serv.layer, + user_layer); +- if (count != 1) ++ if (count != 1) { + pr_err("Could not remove request (%d)", count); + return -ENODEV; ++ } + } + return 0; + } +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index f4f3f58..a70f426 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -1719,6 +1719,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, + dout("osdc_start_request failed map, " + " will retry %lld\n", req->r_tid); + rc = 0; ++ } else { ++ __unregister_request(osdc, req); + } + goto out_unlock; + } +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index db4bb7a..9649cea 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -923,15 +923,14 @@ EXPORT_SYMBOL_GPL(__netpoll_cleanup); + + void netpoll_cleanup(struct netpoll *np) + { +- if (!np->dev) +- return; +- + rtnl_lock(); ++ if (!np->dev) ++ goto out; + __netpoll_cleanup(np); +- rtnl_unlock(); +- + dev_put(np->dev); + np->dev = NULL; ++out: ++ rtnl_unlock(); + } + EXPORT_SYMBOL(netpoll_cleanup); + +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index 77a65f0..f0bdd36 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -19,6 +19,9 @@ + #include <net/sock.h> + #include <net/net_ratelimit.h> + ++static int zero = 0; ++static int ushort_max = USHRT_MAX; ++ + #ifdef CONFIG_RPS + static int rps_sock_flow_sysctl(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +@@ -192,7 +195,9 @@ static struct ctl_table netns_core_table[] = { + .data = &init_net.core.sysctl_somaxconn, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .extra1 = &zero, ++ .extra2 = &ushort_max, ++ .proc_handler = proc_dointvec_minmax + }, + { } + }; +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index cd2d639..c7c6724 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -72,7 +72,6 @@ + #include <linux/init.h> + #include <linux/list.h> + #include <linux/slab.h> +-#include <linux/prefetch.h> + #include <linux/export.h> + #include <net/net_namespace.h> + #include <net/ip.h> +@@ -1773,10 +1772,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c) + if (!c) + continue; + +- if (IS_LEAF(c)) { +- prefetch(rcu_dereference_rtnl(p->child[idx])); ++ if (IS_LEAF(c)) + return (struct leaf *) c; +- } + + /* Rescan start scanning in new node */ + p = (struct tnode *) c; +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index c8989a7..75b0860 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -342,7 +342,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) + pip->saddr = fl4.saddr; + pip->protocol = IPPROTO_IGMP; + pip->tot_len = 0; /* filled in later */ +- ip_select_ident(pip, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&pip[1])[0] = IPOPT_RA; + ((u8*)&pip[1])[1] = 4; + ((u8*)&pip[1])[2] = 0; +@@ -683,7 +683,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->protocol = IPPROTO_IGMP; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&iph[1])[0] = IPOPT_RA; + ((u8*)&iph[1])[1] = 4; + ((u8*)&iph[1])[2] = 0; +@@ -705,7 +705,7 @@ static void igmp_gq_timer_expire(unsigned long data) + + in_dev->mr_gq_running = 0; + igmpv3_send_report(in_dev, NULL); +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_timer_expire(unsigned long data) +@@ -717,7 +717,7 @@ static void igmp_ifc_timer_expire(unsigned long data) + in_dev->mr_ifc_count--; + igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); + } +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_event(struct in_device *in_dev) +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index 86f13c67..58c4e696 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -17,6 +17,7 @@ + #include <linux/kernel.h> + #include <linux/mm.h> + #include <linux/net.h> ++#include <linux/workqueue.h> + #include <net/ip.h> + #include <net/inetpeer.h> + #include <net/secure_seq.h> +@@ -31,8 +32,8 @@ + * At the moment of writing this notes identifier of IP packets is generated + * to be unpredictable using this code only for packets subjected + * (actually or potentially) to defragmentation. I.e. DF packets less than +- * PMTU in size uses a constant ID and do not use this code (see +- * ip_select_ident() in include/net/ip.h). ++ * PMTU in size when local fragmentation is disabled use a constant ID and do ++ * not use this code (see ip_select_ident() in include/net/ip.h). + * + * Route cache entries hold references to our nodes. + * New cache entries get references via lookup by destination IP address in +@@ -66,6 +67,11 @@ + + static struct kmem_cache *peer_cachep __read_mostly; + ++static LIST_HEAD(gc_list); ++static const int gc_delay = 60 * HZ; ++static struct delayed_work gc_work; ++static DEFINE_SPINLOCK(gc_lock); ++ + #define node_height(x) x->avl_height + + #define peer_avl_empty ((struct inet_peer *)&peer_fake_node) +@@ -102,6 +108,50 @@ int inet_peer_threshold __read_mostly = 65536 + 128; /* start to throw entries m + int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */ + int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min */ + ++static void inetpeer_gc_worker(struct work_struct *work) ++{ ++ struct inet_peer *p, *n; ++ LIST_HEAD(list); ++ ++ spin_lock_bh(&gc_lock); ++ list_replace_init(&gc_list, &list); ++ spin_unlock_bh(&gc_lock); ++ ++ if (list_empty(&list)) ++ return; ++ ++ list_for_each_entry_safe(p, n, &list, gc_list) { ++ ++ if(need_resched()) ++ cond_resched(); ++ ++ if (p->avl_left != peer_avl_empty) { ++ list_add_tail(&p->avl_left->gc_list, &list); ++ p->avl_left = peer_avl_empty; ++ } ++ ++ if (p->avl_right != peer_avl_empty) { ++ list_add_tail(&p->avl_right->gc_list, &list); ++ p->avl_right = peer_avl_empty; ++ } ++ ++ n = list_entry(p->gc_list.next, struct inet_peer, gc_list); ++ ++ if (!atomic_read(&p->refcnt)) { ++ list_del(&p->gc_list); ++ kmem_cache_free(peer_cachep, p); ++ } ++ } ++ ++ if (list_empty(&list)) ++ return; ++ ++ spin_lock_bh(&gc_lock); ++ list_splice(&list, &gc_list); ++ spin_unlock_bh(&gc_lock); ++ ++ schedule_delayed_work(&gc_work, gc_delay); ++} + + /* Called from ip_output.c:ip_init */ + void __init inet_initpeers(void) +@@ -126,6 +176,7 @@ void __init inet_initpeers(void) + 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, + NULL); + ++ INIT_DELAYED_WORK_DEFERRABLE(&gc_work, inetpeer_gc_worker); + } + + static int addr_compare(const struct inetpeer_addr *a, +@@ -448,7 +499,7 @@ relookup: + p->pmtu_expires = 0; + p->pmtu_orig = 0; + memset(&p->redirect_learned, 0, sizeof(p->redirect_learned)); +- ++ INIT_LIST_HEAD(&p->gc_list); + + /* Link the node. */ + link_to_pool(p, base); +@@ -508,3 +559,38 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout) + return rc; + } + EXPORT_SYMBOL(inet_peer_xrlim_allow); ++ ++static void inetpeer_inval_rcu(struct rcu_head *head) ++{ ++ struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu); ++ ++ spin_lock_bh(&gc_lock); ++ list_add_tail(&p->gc_list, &gc_list); ++ spin_unlock_bh(&gc_lock); ++ ++ schedule_delayed_work(&gc_work, gc_delay); ++} ++ ++void inetpeer_invalidate_tree(int family) ++{ ++ struct inet_peer *old, *new, *prev; ++ struct inet_peer_base *base = family_to_base(family); ++ ++ write_seqlock_bh(&base->lock); ++ ++ old = base->root; ++ if (old == peer_avl_empty_rcu) ++ goto out; ++ ++ new = peer_avl_empty_rcu; ++ ++ prev = cmpxchg(&base->root, old, new); ++ if (prev == old) { ++ base->total = 0; ++ call_rcu(&prev->gc_rcu, inetpeer_inval_rcu); ++ } ++ ++out: ++ write_sequnlock_bh(&base->lock); ++} ++EXPORT_SYMBOL(inetpeer_invalidate_tree); +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 0bc95f3..daf408e 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -162,7 +162,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, + iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); + iph->saddr = saddr; + iph->protocol = sk->sk_protocol; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt && opt->opt.optlen) { + iph->ihl += opt->opt.optlen>>2; +@@ -390,7 +390,7 @@ packet_routed: + ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); + } + +- ip_select_ident_more(iph, &rt->dst, sk, ++ ip_select_ident_more(skb, &rt->dst, sk, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + skb->priority = sk->sk_priority; +@@ -1334,7 +1334,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, + iph->ihl = 5; + iph->tos = inet->tos; + iph->frag_off = df; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + iph->saddr = fl4->saddr; +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 0064394..b5e64e4 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1576,7 +1576,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) + iph->protocol = IPPROTO_IPIP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + ip_send_check(iph); + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index e1d4f30..2815014 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -380,7 +380,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, + iph->check = 0; + iph->tot_len = htons(length); + if (!iph->id) +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 94cdbc5..c45a155a3 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -939,6 +939,7 @@ static void rt_cache_invalidate(struct net *net) + get_random_bytes(&shuffle, sizeof(shuffle)); + atomic_add(shuffle + 1U, &net->ipv4.rt_genid); + redirect_genid++; ++ inetpeer_invalidate_tree(AF_INET); + } + + /* +diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c +index f376b05..b78eac2 100644 +--- a/net/ipv4/tcp_cubic.c ++++ b/net/ipv4/tcp_cubic.c +@@ -204,8 +204,8 @@ static u32 cubic_root(u64 a) + */ + static inline void bictcp_update(struct bictcp *ca, u32 cwnd) + { +- u64 offs; +- u32 delta, t, bic_target, max_cnt; ++ u32 delta, bic_target, max_cnt; ++ u64 offs, t; + + ca->ack_cnt++; /* count the number of ACKs */ + +@@ -248,9 +248,11 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) + * if the cwnd < 1 million packets !!! + */ + ++ t = (s32)(tcp_time_stamp - ca->epoch_start); ++ t += msecs_to_jiffies(ca->delay_min >> 3); + /* change the unit from HZ to bictcp_HZ */ +- t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3) +- - ca->epoch_start) << BICTCP_HZ) / HZ; ++ t <<= BICTCP_HZ; ++ do_div(t, HZ); + + if (t < ca->bic_K) /* t - K */ + offs = ca->bic_K - t; +@@ -412,7 +414,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) + return; + + /* Discard delay samples right after fast recovery */ +- if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ) ++ if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ) + return; + + delay = (rtt_us << 3) / USEC_PER_MSEC; +diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c +index ed4bf11..938553e 100644 +--- a/net/ipv4/xfrm4_mode_tunnel.c ++++ b/net/ipv4/xfrm4_mode_tunnel.c +@@ -54,7 +54,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) + + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); +- ip_select_ident(top_iph, dst->child, NULL); ++ ip_select_ident(skb, dst->child, NULL); + + top_iph->ttl = ip4_dst_hoplimit(dst->child); + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 314bda2..5d41293 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -913,12 +913,10 @@ retry: + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + +- ift = !max_addresses || +- ipv6_count_addresses(idev) < max_addresses ? +- ipv6_add_addr(idev, &addr, tmp_plen, +- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, +- addr_flags) : NULL; +- if (!ift || IS_ERR(ift)) { ++ ift = ipv6_add_addr(idev, &addr, tmp_plen, ++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, ++ addr_flags); ++ if (IS_ERR(ift)) { + in6_ifa_put(ifp); + in6_dev_put(idev); + printk(KERN_INFO +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 90868fb..d505453 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -911,6 +911,14 @@ static const struct icmp6_err { + .err = ECONNREFUSED, + .fatal = 1, + }, ++ { /* POLICY_FAIL */ ++ .err = EACCES, ++ .fatal = 1, ++ }, ++ { /* REJECT_ROUTE */ ++ .err = EACCES, ++ .fatal = 1, ++ }, + }; + + int icmpv6_err_convert(u8 type, u8 code, int *err) +@@ -922,7 +930,7 @@ int icmpv6_err_convert(u8 type, u8 code, int *err) + switch (type) { + case ICMPV6_DEST_UNREACH: + fatal = 1; +- if (code <= ICMPV6_PORT_UNREACH) { ++ if (code < ARRAY_SIZE(tab_unreach)) { + *err = tab_unreach[code].err; + fatal = tab_unreach[code].fatal; + } +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 93718f3..443724f 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -862,14 +862,22 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root, + + if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) { + #ifdef CONFIG_IPV6_SUBTREES +- if (fn->subtree) +- fn = fib6_lookup_1(fn->subtree, args + 1); ++ if (fn->subtree) { ++ struct fib6_node *sfn; ++ sfn = fib6_lookup_1(fn->subtree, ++ args + 1); ++ if (!sfn) ++ goto backtrack; ++ fn = sfn; ++ } + #endif +- if (!fn || fn->fn_flags & RTN_RTINFO) ++ if (fn->fn_flags & RTN_RTINFO) + return fn; + } + } +- ++#ifdef CONFIG_IPV6_SUBTREES ++backtrack: ++#endif + if (fn->fn_flags & RTN_ROOT) + break; + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index db60043..91d0711 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1125,6 +1125,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { ++ struct frag_hdr fhdr; ++ + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); +@@ -1145,12 +1147,6 @@ static inline int ip6_ufo_append_data(struct sock *sk, + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = 0; +- } +- +- err = skb_append_datato_frags(sk,skb, getfrag, from, +- (length - transhdrlen)); +- if (!err) { +- struct frag_hdr fhdr; + + /* Specify the length of each IPv6 datagram fragment. + * It has to be a multiple of 8. +@@ -1161,15 +1157,10 @@ static inline int ip6_ufo_append_data(struct sock *sk, + ipv6_select_ident(&fhdr, rt); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); +- +- return 0; + } +- /* There is not enough support do UPD LSO, +- * so follow normal path +- */ +- kfree_skb(skb); + +- return err; ++ return skb_append_datato_frags(sk, skb, getfrag, from, ++ (length - transhdrlen)); + } + + static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +@@ -1342,27 +1333,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + * --yoshfuji + */ + +- cork->length += length; +- if (length > mtu) { +- int proto = sk->sk_protocol; +- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ +- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); +- return -EMSGSIZE; +- } +- +- if (proto == IPPROTO_UDP && +- (rt->dst.dev->features & NETIF_F_UFO)) { ++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || ++ sk->sk_protocol == IPPROTO_RAW)) { ++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); ++ return -EMSGSIZE; ++ } + +- err = ip6_ufo_append_data(sk, getfrag, from, length, +- hh_len, fragheaderlen, +- transhdrlen, mtu, flags, rt); +- if (err) +- goto error; +- return 0; +- } ++ skb = skb_peek_tail(&sk->sk_write_queue); ++ cork->length += length; ++ if (((length > mtu) || ++ (skb && skb_is_gso(skb))) && ++ (sk->sk_protocol == IPPROTO_UDP) && ++ (rt->dst.dev->features & NETIF_F_UFO)) { ++ err = ip6_ufo_append_data(sk, getfrag, from, length, ++ hh_len, fragheaderlen, ++ transhdrlen, mtu, flags, rt); ++ if (err) ++ goto error; ++ return 0; + } + +- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) ++ if (!skb) + goto alloc_new_skb; + + while (length > 0) { +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index c7ec4bb..d20a9be 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2159,7 +2159,7 @@ static void mld_gq_timer_expire(unsigned long data) + + idev->mc_gq_running = 0; + mld_send_report(idev, NULL); +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_timer_expire(unsigned long data) +@@ -2172,7 +2172,7 @@ static void mld_ifc_timer_expire(unsigned long data) + if (idev->mc_ifc_count) + mld_ifc_start_timer(idev, idev->mc_maxdelay); + } +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_event(struct inet6_dev *idev) +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 9ffc37f..bc55358 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -447,7 +447,6 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + struct sk_buff *skb; + struct icmp6hdr *hdr; + int len; +- int err; + u8 *opt; + + if (!dev->addr_len) +@@ -457,14 +456,12 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + if (llinfo) + len += ndisc_opt_addr_space(dev); + +- skb = sock_alloc_send_skb(sk, +- (MAX_HEADER + sizeof(struct ipv6hdr) + +- len + LL_ALLOCATED_SPACE(dev)), +- 1, &err); ++ skb = alloc_skb((MAX_HEADER + sizeof(struct ipv6hdr) + ++ len + LL_ALLOCATED_SPACE(dev)), GFP_ATOMIC); + if (!skb) { + ND_PRINTK0(KERN_ERR +- "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n", +- __func__, err); ++ "ICMPv6 ND: %s() failed to allocate an skb.\n", ++ __func__); + return NULL; + } + +@@ -492,6 +489,11 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, + csum_partial(hdr, + len, 0)); + ++ /* Manually assign socket ownership as we avoid calling ++ * sock_alloc_send_pskb() to bypass wmem buffer limits ++ */ ++ skb_set_owner_w(skb, sk); ++ + return skb; + } + +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index 411fe2c..eba5deb 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -517,6 +517,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, + head->tstamp = fq->q.stamp; + ipv6_hdr(head)->payload_len = htons(payload_len); + IP6CB(head)->nhoff = nhoff; ++ IP6CB(head)->flags |= IP6SKB_FRAGMENTED; + + /* Yes, and fold redundant checksum back. 8) */ + if (head->ip_summed == CHECKSUM_COMPLETE) +@@ -552,6 +553,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb) + const struct ipv6hdr *hdr = ipv6_hdr(skb); + struct net *net = dev_net(skb_dst(skb)->dev); + ++ if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED) ++ goto fail_hdr; ++ + IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS); + + /* Jumbo payload inhibits frag. header */ +@@ -572,6 +576,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) + ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS); + + IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); ++ IP6CB(skb)->flags |= IP6SKB_FRAGMENTED; + return 1; + } + +diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c +index aa2d720..38c0813 100644 +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -853,7 +853,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, + iph->daddr = cp->daddr.ip; + iph->saddr = saddr; + iph->ttl = old_iph->ttl; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + /* Another hack: avoid icmp_send in ip_fragment */ + skb->local_df = 1; +diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c +index f08b9166..caa5aff 100644 +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -86,7 +86,7 @@ struct htb_class { + unsigned int children; + struct htb_class *parent; /* parent class */ + +- int prio; /* these two are used only by leaves... */ ++ u32 prio; /* these two are used only by leaves... */ + int quantum; /* but stored for parent-to-leaf return */ + + union { +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index 8104278..0b6a391 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -205,45 +205,24 @@ out: + in6_dev_put(idev); + } + +-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ + static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) + { + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); +- struct flowi6 fl6; +- +- memset(&fl6, 0, sizeof(fl6)); +- +- fl6.flowi6_proto = sk->sk_protocol; +- +- /* Fill in the dest address from the route entry passed with the skb +- * and the source address from the transport. +- */ +- ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr); +- ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr); +- +- fl6.flowlabel = np->flow_label; +- IP6_ECN_flow_xmit(sk, fl6.flowlabel); +- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) +- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; +- else +- fl6.flowi6_oif = sk->sk_bound_dev_if; +- +- if (np->opt && np->opt->srcrt) { +- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; +- ipv6_addr_copy(&fl6.daddr, rt0->addr); +- } ++ struct flowi6 *fl6 = &transport->fl.u.ip6; + + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", + __func__, skb, skb->len, +- &fl6.saddr, &fl6.daddr); ++ &fl6->saddr, &fl6->daddr); + +- SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ IP6_ECN_flow_xmit(sk, fl6->flowlabel); + + if (!(transport->param_flags & SPP_PMTUD_ENABLE)) + skb->local_df = 1; + +- return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); ++ SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ ++ return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -256,10 +235,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + struct dst_entry *dst = NULL; + struct flowi6 *fl6 = &fl->u.ip6; + struct sctp_bind_addr *bp; ++ struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; + union sctp_addr *baddr = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; ++ struct in6_addr *final_p, final; + __u8 matchlen = 0; + __u8 bmatchlen; + sctp_scope_t scope; +@@ -282,7 +263,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); + } + +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + if (!asoc || saddr) + goto out; + +@@ -333,10 +315,12 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + } + } + rcu_read_unlock(); ++ + if (baddr) { + ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); + fl6->fl6_sport = baddr->v6.sin6_port; +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + } + + out: +diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c +index 9032d50..76388b0 100644 +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -1604,9 +1604,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, + asoc->outqueue.outstanding_bytes; + sackh.num_gap_ack_blocks = 0; + sackh.num_dup_tsns = 0; +- chunk->subh.sack_hdr = &sackh; + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, +- SCTP_CHUNK(chunk)); ++ SCTP_SACKH(&sackh)); + break; + + case SCTP_CMD_DISCARD_PACKET: +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index ba0108f..c53d01e 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -814,6 +814,9 @@ static int sctp_send_asconf_del_ip(struct sock *sk, + goto skip_mkasconf; + } + ++ if (laddr == NULL) ++ return -EINVAL; ++ + /* We do not need RCU protection throughout this loop + * because this is done under a socket lock from the + * setsockopt call. +diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c +index e728d4c..a224a38 100644 +--- a/net/tipc/eth_media.c ++++ b/net/tipc/eth_media.c +@@ -53,6 +53,7 @@ struct eth_bearer { + struct tipc_bearer *bearer; + struct net_device *dev; + struct packet_type tipc_packet_type; ++ struct work_struct setup; + }; + + static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; +@@ -121,6 +122,17 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, + } + + /** ++ * setup_bearer - setup association between Ethernet bearer and interface ++ */ ++static void setup_bearer(struct work_struct *work) ++{ ++ struct eth_bearer *eb_ptr = ++ container_of(work, struct eth_bearer, setup); ++ ++ dev_add_pack(&eb_ptr->tipc_packet_type); ++} ++ ++/** + * enable_bearer - attach TIPC bearer to an Ethernet interface + */ + +@@ -164,7 +176,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) + eb_ptr->tipc_packet_type.func = recv_msg; + eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; + INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); +- dev_add_pack(&eb_ptr->tipc_packet_type); ++ INIT_WORK(&eb_ptr->setup, setup_bearer); ++ schedule_work(&eb_ptr->setup); + + /* Associate TIPC bearer with Ethernet bearer */ + +diff --git a/scripts/kernel-doc b/scripts/kernel-doc +index d793001..ba3d9df 100755 +--- a/scripts/kernel-doc ++++ b/scripts/kernel-doc +@@ -2044,6 +2044,9 @@ sub process_file($) { + + $section_counter = 0; + while (<IN>) { ++ while (s/\\\s*$//) { ++ $_ .= <IN>; ++ } + if ($state == 0) { + if (/$doc_start/o) { + $state = 1; # next line is always the function name +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index a166a85..7ebe4b7 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2621,6 +2621,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = { + SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ + SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ ++ SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */ + SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ + {} +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 55d9b30..05f097a 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -512,6 +512,17 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels) + } + } + ++ if (!ca) { ++ /* if there was no match, select the regular ALSA channel ++ * allocation with the matching number of channels */ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ if (channels == channel_allocations[i].channels) { ++ ca = channel_allocations[i].ca_index; ++ break; ++ } ++ } ++ } ++ + snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf)); + snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", + ca, channels, buf); +diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c +index 5ca122e..290f4d3 100644 +--- a/sound/soc/codecs/88pm860x-codec.c ++++ b/sound/soc/codecs/88pm860x-codec.c +@@ -351,6 +351,9 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, + val = ucontrol->value.integer.value[0]; + val2 = ucontrol->value.integer.value[1]; + ++ if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table)) ++ return -EINVAL; ++ + err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m); + if (err < 0) + return err; +diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c +index 26d7b08..a52c15b 100644 +--- a/sound/soc/codecs/max98095.c ++++ b/sound/soc/codecs/max98095.c +@@ -1861,7 +1861,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_eq_channel(kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_eq_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; +@@ -2014,7 +2014,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, + struct max98095_pdata *pdata = max98095->pdata; + int channel = max98095_get_bq_channel(codec, kcontrol->id.name); + struct max98095_cdata *cdata; +- int sel = ucontrol->value.integer.value[0]; ++ unsigned int sel = ucontrol->value.integer.value[0]; + struct max98095_biquad_cfg *coef_set; + int fs, best, best_val, i; + int regmask, regsave; +diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c +index 2df253c..ef96ca6 100644 +--- a/sound/soc/codecs/wm8960.c ++++ b/sound/soc/codecs/wm8960.c +@@ -805,9 +805,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + if (pll_div.k) { + reg |= 0x20; + +- snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); +- snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); +- snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); ++ snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); ++ snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); ++ snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); + } + snd_soc_write(codec, WM8960_PLL1, reg); + +diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c +index 42dffa0..f7a7b9d 100644 +--- a/tools/perf/util/map.c ++++ b/tools/perf/util/map.c +@@ -16,6 +16,7 @@ const char *map_type__name[MAP__NR_TYPES] = { + static inline int is_anon_memory(const char *filename) + { + return !strcmp(filename, "//anon") || ++ !strcmp(filename, "/dev/zero (deleted)") || + !strcmp(filename, "/anon_hugepage (deleted)"); + } + |