Merge remote-tracking branch 'lts/linux-4.4.y' into linux-linaro-lsk-v4.4
authorAlex Shi <alex.shi@linaro.org>
Mon, 15 May 2017 09:35:45 +0000 (17:35 +0800)
committerAlex Shi <alex.shi@linaro.org>
Mon, 15 May 2017 09:35:45 +0000 (17:35 +0800)
92 files changed:
Makefile
arch/arm/kernel/Makefile
arch/arm/kernel/pj4-cp0.c
arch/arm/mach-omap2/omap-headsmp.S
arch/arm64/net/bpf_jit_comp.c
arch/mips/kernel/mips-r2-to-r6-emul.c
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/kprobes/common.h
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/kprobes/opt.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/vmx.c
arch/x86/platform/intel-mid/device_libs/platform_wdt.c
block/blk-integrity.c
block/partition-generic.c
drivers/block/drbd/drbd_bitmap.c
drivers/clk/Makefile
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/infiniband/hw/qib/qib_qp.c
drivers/leds/leds-ktd2692.c
drivers/md/dm-ioctl.c
drivers/mtd/chips/Kconfig
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/wireless/brcm80211/brcmfmac/core.c
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/phy/Kconfig
drivers/power/bq24190_charger.c
drivers/scsi/Kconfig
drivers/scsi/cxlflash/main.c
drivers/staging/emxx_udc/emxx_udc.c
drivers/staging/rdma/ehca/ehca_mrmw.c
drivers/staging/wlan-ng/p80211netdev.c
drivers/tty/serial/8250/8250_omap.c
drivers/tty/serial/8250/8250_pci.c
drivers/usb/chipidea/ci.h
drivers/usb/chipidea/core.c
drivers/usb/chipidea/otg.c
drivers/usb/host/ehci-exynos.c
drivers/usb/host/ohci-exynos.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/quatech2.c
drivers/usb/serial/ssu100.c
drivers/usb/serial/ti_usb_3410_5052.c
fs/9p/acl.c
fs/block_dev.c
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2proto.h
fs/cifs/smb2transport.c
fs/cifs/transport.c
fs/ext4/crypto.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/ioctl.c
fs/ext4/namei.c
fs/f2fs/super.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfsxdr.c
fs/timerfd.c
include/linux/f2fs_fs.h
include/linux/genhd.h
include/linux/mtd/map.h
include/linux/usb/chipidea.h
include/net/addrconf.h
include/net/ip6_route.h
lib/test_bpf.c
net/core/rtnetlink.c
net/ipv4/raw.c
net/ipv4/tcp_lp.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/raw.c
net/ipv6/route.c
net/netlink/af_netlink.c
sound/pci/hda/hda_intel.c
sound/ppc/awacs.c
sound/soc/intel/boards/bytcr_rt5640.c
tools/power/cpupower/utils/helpers/cpuid.c

index 1cd052823c03f2dcfec4f720a1cd6ae80fa7f6c5..e6c7990497e78f000e94cbd7ab2ffd56d50e150f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 66
+SUBLEVEL = 68
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
index 80856def246518e05015591f73d3bd0b4993bf8b..82bdac0f28048db6f3e6ffce2ed0dcc5758e0c4b 100644 (file)
@@ -73,7 +73,6 @@ obj-$(CONFIG_IWMMXT)          += iwmmxt.o
 obj-$(CONFIG_PERF_EVENTS)      += perf_regs.o perf_callchain.o
 obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event_xscale.o perf_event_v6.o \
                                   perf_event_v7.o
-CFLAGS_pj4-cp0.o               := -marm
 AFLAGS_iwmmxt.o                        := -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
 obj-$(CONFIG_VDSO)             += vdso.o
index 8153e36b24917e96c8fa69d18bd78e8b0c130c1a..7c9248b74d3f41548e5ce41d614dc8850d08aa94 100644 (file)
@@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
 
        __asm__ __volatile__ (
                "mcr    p15, 0, %1, c1, c0, 2\n\t"
+#ifdef CONFIG_THUMB2_KERNEL
+               "isb\n\t"
+#else
                "mrc    p15, 0, %0, c1, c0, 2\n\t"
                "mov    %0, %0\n\t"
                "sub    pc, pc, #4\n\t"
+#endif
                : "=r" (temp) : "r" (value));
 }
 
index 6d1dffca6c7b6d68f3bd6e29a16bf5334c54a5fb..748dde9fa4a5566b562f81d66ea5a3b40f4f0135 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 #include "omap44xx.h"
 
@@ -56,7 +57,7 @@ wait_2:       ldr     r2, =AUX_CORE_BOOT0_PA  @ read from AuxCoreBoot0
        cmp     r0, r4
        bne     wait_2
        ldr     r12, =API_HYP_ENTRY
-       adr     r0, hyp_boot
+       badr    r0, hyp_boot
        smc     #0
 hyp_boot:
        b       secondary_startup
index b162ad70effcfeacbc7a304d569b222717f495d7..6297140dd84f5e3f2bee4dba3c42818079258a8a 100644 (file)
@@ -728,14 +728,14 @@ static int build_body(struct jit_ctx *ctx)
                int ret;
 
                ret = build_insn(insn, ctx);
-
-               if (ctx->image == NULL)
-                       ctx->offset[i] = ctx->idx;
-
                if (ret > 0) {
                        i++;
+                       if (ctx->image == NULL)
+                               ctx->offset[i] = ctx->idx;
                        continue;
                }
+               if (ctx->image == NULL)
+                       ctx->offset[i] = ctx->idx;
                if (ret)
                        return ret;
        }
index af27334d6809b7a7d2e9918da1ed7a28575c53c7..e3384065f5e7c8f45d52fbf3f07ef0fc0f7200fd 100644 (file)
@@ -434,8 +434,8 @@ static int multu_func(struct pt_regs *regs, u32 ir)
        rs = regs->regs[MIPSInst_RS(ir)];
        res = (u64)rt * (u64)rs;
        rt = res;
-       regs->lo = (s64)rt;
-       regs->hi = (s64)(res >> 32);
+       regs->lo = (s64)(s32)rt;
+       regs->hi = (s64)(s32)(res >> 32);
 
        MIPS_R2_STATS(muls);
 
@@ -671,9 +671,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir)
        res += ((((s64)rt) << 32) | (u32)rs);
 
        rt = res;
-       regs->lo = (s64)rt;
+       regs->lo = (s64)(s32)rt;
        rs = res >> 32;
-       regs->hi = (s64)rs;
+       regs->hi = (s64)(s32)rs;
 
        MIPS_R2_STATS(dsps);
 
@@ -729,9 +729,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir)
        res = ((((s64)rt) << 32) | (u32)rs) - res;
 
        rt = res;
-       regs->lo = (s64)rt;
+       regs->lo = (s64)(s32)rt;
        rs = res >> 32;
-       regs->hi = (s64)rs;
+       regs->hi = (s64)(s32)rs;
 
        MIPS_R2_STATS(dsps);
 
index e45b88a5d7e0f7ed20f68516050a7e8a8c37fa1d..ae877c7b3905ecbcae05528c365964ab677084f6 100644 (file)
@@ -148,7 +148,7 @@ opal_tracepoint_entry:
 opal_tracepoint_return:
        std     r3,STK_REG(R31)(r1)
        mr      r4,r3
-       ld      r0,STK_REG(R23)(r1)
+       ld      r3,STK_REG(R23)(r1)
        bl      __trace_opal_exit
        ld      r3,STK_REG(R31)(r1)
        addi    r1,r1,STACKFRAMESIZE
index 8ca533b8c606a9c28a55fc0ff7927010f311efcc..1e5d2f07416b56529c0ddbf81629ad26c841f8c9 100644 (file)
@@ -1875,6 +1875,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
        .irq_ack                = irq_chip_ack_parent,
        .irq_eoi                = ioapic_ack_level,
        .irq_set_affinity       = ioapic_set_affinity,
+       .irq_retrigger          = irq_chip_retrigger_hierarchy,
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
 };
 
@@ -1886,6 +1887,7 @@ static struct irq_chip ioapic_ir_chip __read_mostly = {
        .irq_ack                = irq_chip_ack_parent,
        .irq_eoi                = ioapic_ir_ack_level,
        .irq_set_affinity       = ioapic_set_affinity,
+       .irq_retrigger          = irq_chip_retrigger_hierarchy,
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
 };
 
index c6ee63f927ab721dd542b016bcfb22d65a55f114..d688826e5736a18c9f9343ebe278ec2b04bff66d 100644 (file)
@@ -67,7 +67,7 @@
 #endif
 
 /* Ensure if the instruction can be boostable */
-extern int can_boost(kprobe_opcode_t *instruction);
+extern int can_boost(kprobe_opcode_t *instruction, void *addr);
 /* Recover instruction if given address is probed */
 extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
                                         unsigned long addr);
index 023c442c33bb4d3d1214f680cbb6370e323167ac..99d293ea2b496a8646847715afe3d15bee98768e 100644 (file)
@@ -163,12 +163,12 @@ NOKPROBE_SYMBOL(skip_prefixes);
  * Returns non-zero if opcode is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
-int can_boost(kprobe_opcode_t *opcodes)
+int can_boost(kprobe_opcode_t *opcodes, void *addr)
 {
        kprobe_opcode_t opcode;
        kprobe_opcode_t *orig_opcodes = opcodes;
 
-       if (search_exception_tables((unsigned long)opcodes))
+       if (search_exception_tables((unsigned long)addr))
                return 0;       /* Page fault may occur on this address. */
 
 retry:
@@ -413,7 +413,7 @@ static int arch_copy_kprobe(struct kprobe *p)
         * __copy_instruction can modify the displacement of the instruction,
         * but it doesn't affect boostable check.
         */
-       if (can_boost(p->ainsn.insn))
+       if (can_boost(p->ainsn.insn, p->addr))
                p->ainsn.boostable = 0;
        else
                p->ainsn.boostable = -1;
index 7b3b9d15c47a63953d6932026cc57db795e3a507..c9d488f3e4cd416ddaeeb0e61fff1cf0b34d1041 100644 (file)
@@ -177,7 +177,7 @@ static int copy_optimized_instructions(u8 *dest, u8 *src)
 
        while (len < RELATIVEJUMP_SIZE) {
                ret = __copy_instruction(dest + len, src + len);
-               if (!ret || !can_boost(dest + len))
+               if (!ret || !can_boost(dest + len, src + len))
                        return -EINVAL;
                len += ret;
        }
index 0497f719977dff8ca0094b536a6b7e40ac371ef2..c055e9a4e54727c294f4b20c9eda262d1f7578b1 100644 (file)
@@ -296,7 +296,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 
        /* were we called with bad_dma_address? */
        badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
-       if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
+       if (unlikely(dma_addr < badend)) {
                WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
                       "address 0x%Lx\n", dma_addr);
                return;
index 2e1fd586b895c734d6fdac2c6c7d878b65d6223d..642e9c93a097ebca3effa8c8374e5a1b10cb0900 100644 (file)
@@ -818,12 +818,6 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
        if (!best)
                best = check_cpuid_limit(vcpu, function, index);
 
-       /*
-        * Perfmon not yet supported for L2 guest.
-        */
-       if (is_guest_mode(vcpu) && function == 0xa)
-               best = NULL;
-
        if (best) {
                *eax = best->eax;
                *ebx = best->ebx;
index 0a472e9865c570174c66443131feea6f03b8a355..50ca8f409a7ce692e6a09afb09f85f3b774bbe95 100644 (file)
@@ -7754,8 +7754,6 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
        case EXIT_REASON_TASK_SWITCH:
                return true;
        case EXIT_REASON_CPUID:
-               if (kvm_register_read(vcpu, VCPU_REGS_RAX) == 0xa)
-                       return false;
                return true;
        case EXIT_REASON_HLT:
                return nested_cpu_has(vmcs12, CPU_BASED_HLT_EXITING);
@@ -7840,6 +7838,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
                return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES);
        case EXIT_REASON_PCOMMIT:
                return nested_cpu_has2(vmcs12, SECONDARY_EXEC_PCOMMIT);
+       case EXIT_REASON_PML_FULL:
+               /* We don't expose PML support to L1. */
+               return false;
        default:
                return true;
        }
@@ -9759,6 +9760,18 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 
        }
 
+       if (enable_pml) {
+               /*
+                * Conceptually we want to copy the PML address and index from
+                * vmcs01 here, and then back to vmcs01 on nested vmexit. But,
+                * since we always flush the log on each vmexit, this happens
+                * to be equivalent to simply resetting the fields in vmcs02.
+                */
+               ASSERT(vmx->pml_pg);
+               vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
+               vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
+       }
+
        if (nested_cpu_has_ept(vmcs12)) {
                kvm_mmu_unload(vcpu);
                nested_ept_init_mmu_context(vcpu);
index de734134bc8d2e1733fb831a32cdbfd8fcf80ed5..40c616495da79f09ac0ba4f4b5b57a815d4ca573 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/intel-mid.h>
 #include <asm/io_apic.h>
 
-#define TANGIER_EXT_TIMER0_MSI 15
+#define TANGIER_EXT_TIMER0_MSI 12
 
 static struct platform_device wdt_dev = {
        .name = "intel_mid_wdt",
index d69c5c79f98e71059827265531aba75a63458f74..319f2e4f4a8b39c09f487e641b65feea4ae149a3 100644 (file)
@@ -417,7 +417,7 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
        bi->tuple_size = template->tuple_size;
        bi->tag_size = template->tag_size;
 
-       blk_integrity_revalidate(disk);
+       disk->queue->backing_dev_info.capabilities |= BDI_CAP_STABLE_WRITES;
 }
 EXPORT_SYMBOL(blk_integrity_register);
 
@@ -430,26 +430,11 @@ EXPORT_SYMBOL(blk_integrity_register);
  */
 void blk_integrity_unregister(struct gendisk *disk)
 {
-       blk_integrity_revalidate(disk);
+       disk->queue->backing_dev_info.capabilities &= ~BDI_CAP_STABLE_WRITES;
        memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
 }
 EXPORT_SYMBOL(blk_integrity_unregister);
 
-void blk_integrity_revalidate(struct gendisk *disk)
-{
-       struct blk_integrity *bi = &disk->queue->integrity;
-
-       if (!(disk->flags & GENHD_FL_UP))
-               return;
-
-       if (bi->profile)
-               disk->queue->backing_dev_info.capabilities |=
-                       BDI_CAP_STABLE_WRITES;
-       else
-               disk->queue->backing_dev_info.capabilities &=
-                       ~BDI_CAP_STABLE_WRITES;
-}
-
 void blk_integrity_add(struct gendisk *disk)
 {
        if (kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
index a241e3900bc91d330002a39afe7febf3819c0650..3c062699f28b016620a76115f397599fe367946b 100644 (file)
@@ -435,7 +435,6 @@ rescan:
 
        if (disk->fops->revalidate_disk)
                disk->fops->revalidate_disk(disk);
-       blk_integrity_revalidate(disk);
        check_disk_size_change(disk, bdev);
        bdev->bd_invalidated = 0;
        if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
index 9462d27528507d693d8e4efe0e6464597ab1768b..8bdc34dbaedfc94eb4b9c469bef8d4c9c09a9254 100644 (file)
@@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device)
  * this masks out the remaining bits.
  * Returns the number of bits cleared.
  */
+#ifndef BITS_PER_PAGE
 #define BITS_PER_PAGE          (1UL << (PAGE_SHIFT + 3))
 #define BITS_PER_PAGE_MASK     (BITS_PER_PAGE - 1)
+#else
+# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3))
+#  error "ambiguous BITS_PER_PAGE"
+# endif
+#endif
 #define BITS_PER_LONG_MASK     (BITS_PER_LONG - 1)
 static int bm_clear_surplus(struct drbd_bitmap *b)
 {
index 820714c72d368e29fe211d1699c9a68202c98359..af9e9aff49e558c14d6f3b4346325a16b4f51c6f 100644 (file)
@@ -78,7 +78,9 @@ obj-$(CONFIG_ARCH_TEGRA)              += tegra/
 obj-$(CONFIG_ARCH_OMAP2PLUS)           += ti/
 obj-$(CONFIG_ARCH_U8500)               += ux500/
 obj-$(CONFIG_COMMON_CLK_VERSATILE)     += versatile/
+ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_X86)                      += x86/
+endif
 obj-$(CONFIG_ARCH_ZX)                  += zte/
 obj-$(CONFIG_ARCH_ZYNQ)                        += zynq/
 obj-$(CONFIG_H8300)            += h8300/
index 8fb7213277cc9029d101f2006e7bc50289ab51df..b753914957783dc1f2cb54b0b35cb41822938572 100644 (file)
@@ -66,8 +66,11 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
                if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
                        goto out_unlock;
 
+               ttm_bo_reference(bo);
                up_read(&vma->vm_mm->mmap_sem);
                (void) ttm_bo_wait(bo, false, true, false);
+               ttm_bo_unreserve(bo);
+               ttm_bo_unref(&bo);
                goto out_unlock;
        }
 
@@ -114,8 +117,10 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
                if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
                        if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
+                               ttm_bo_reference(bo);
                                up_read(&vma->vm_mm->mmap_sem);
                                (void) ttm_bo_wait_unreserved(bo);
+                               ttm_bo_unref(&bo);
                        }
 
                        return VM_FAULT_RETRY;
@@ -160,6 +165,13 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
        if (unlikely(ret != 0)) {
                retval = ret;
+
+               if (retval == VM_FAULT_RETRY &&
+                   !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
+                       /* The BO has already been unreserved. */
+                       return retval;
+               }
+
                goto out_unlock;
        }
 
index 3eff35c2d453f7b11f9475f5120cb4df26f94dda..2684605fe67f330fa94a796d6b0b48c9a39dae8c 100644 (file)
 
 #include "qib.h"
 
-#define BITS_PER_PAGE           (PAGE_SIZE*BITS_PER_BYTE)
-#define BITS_PER_PAGE_MASK      (BITS_PER_PAGE-1)
+#define RVT_BITS_PER_PAGE           (PAGE_SIZE*BITS_PER_BYTE)
+#define RVT_BITS_PER_PAGE_MASK      (RVT_BITS_PER_PAGE-1)
 
 static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
                              struct qpn_map *map, unsigned off)
 {
-       return (map - qpt->map) * BITS_PER_PAGE + off;
+       return (map - qpt->map) * RVT_BITS_PER_PAGE + off;
 }
 
 static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
@@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
                if (((off & qpt->mask) >> 1) >= n)
                        off = (off | qpt->mask) + 2;
        } else
-               off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
+               off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off);
        return off;
 }
 
@@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
                qpn = 2;
        if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues)
                qpn = (qpn | qpt->mask) + 2;
-       offset = qpn & BITS_PER_PAGE_MASK;
-       map = &qpt->map[qpn / BITS_PER_PAGE];
+       offset = qpn & RVT_BITS_PER_PAGE_MASK;
+       map = &qpt->map[qpn / RVT_BITS_PER_PAGE];
        max_scan = qpt->nmaps - !offset;
        for (i = 0;;) {
                if (unlikely(!map->page)) {
@@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
                         * We just need to be sure we don't loop
                         * forever.
                         */
-               } while (offset < BITS_PER_PAGE && qpn < QPN_MAX);
+               } while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX);
                /*
                 * In order to keep the number of pages allocated to a
                 * minimum, we scan the all existing pages before increasing
@@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn)
 {
        struct qpn_map *map;
 
-       map = qpt->map + qpn / BITS_PER_PAGE;
+       map = qpt->map + qpn / RVT_BITS_PER_PAGE;
        if (map->page)
-               clear_bit(qpn & BITS_PER_PAGE_MASK, map->page);
+               clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page);
 }
 
 static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn)
index feca07be85f590c09f4b12a69835e59e44ecff9b..1eb9fb33db38c083084d0f6f5542b78527cd3e5f 100644 (file)
@@ -296,15 +296,15 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
                return -ENXIO;
 
        led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);
-       if (IS_ERR(led->ctrl_gpio)) {
-               ret = PTR_ERR(led->ctrl_gpio);
+       ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);
+       if (ret) {
                dev_err(dev, "cannot get ctrl-gpios %d\n", ret);
                return ret;
        }
 
        led->aux_gpio = devm_gpiod_get(dev, "aux", GPIOD_ASIS);
-       if (IS_ERR(led->aux_gpio)) {
-               ret = PTR_ERR(led->aux_gpio);
+       ret = PTR_ERR_OR_ZERO(led->aux_gpio);
+       if (ret) {
                dev_err(dev, "cannot get aux-gpios %d\n", ret);
                return ret;
        }
index 80a43954325966a872cf8ebc95fb23c92c0b8819..e503279c34fcaf573bf21df93dbc2d539596b5bd 100644 (file)
@@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
        if (r)
                goto out;
 
-       param->data_size = sizeof(*param);
+       param->data_size = offsetof(struct dm_ioctl, data);
        r = fn(param, input_param_size);
 
        if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
index 54479c481a7a815dbedc5cbdc3bc734039620925..8a25adced79fa84d4ac0c2ba64f276d49ecf21cd 100644 (file)
@@ -111,6 +111,7 @@ config MTD_MAP_BANK_WIDTH_16
 
 config MTD_MAP_BANK_WIDTH_32
        bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY
+       select MTD_COMPLEX_MAPPINGS if HAS_IOMEM
        default n
        help
          If you wish to support CFI devices on a physical bus which is
index 07f5f239cb65baca35792dd5ba7a979d2b36b763..4744919440e004455b3ff81e7abdf2f32af5f965 100644 (file)
@@ -2473,7 +2473,8 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
                INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]);
 
        bp->ntp_fltr_count = 0;
-       bp->ntp_fltr_bmap = kzalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR),
+       bp->ntp_fltr_bmap = kcalloc(BITS_TO_LONGS(BNXT_NTP_FLTR_MAX_FLTR),
+                                   sizeof(long),
                                    GFP_KERNEL);
 
        if (!bp->ntp_fltr_bmap)
index 49056c33be74d05e19d2a60f6003b3c51fccbef0..21e5b9ed1ead4d28629bd647a662d730d92e1aed 100644 (file)
@@ -12031,7 +12031,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        int ret;
        u32 offset, len, b_offset, odd_len;
        u8 *buf;
-       __be32 start, end;
+       __be32 start = 0, end;
 
        if (tg3_flag(tp, NO_NVRAM) ||
            eeprom->magic != TG3_EEPROM_MAGIC)
index b5ab98ee14455aea9774814128faa8b0177a0071..82753e7c7e7ccc3495b79fbe454ced800e91d0fb 100644 (file)
@@ -211,7 +211,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
        int ret;
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_pub *drvr = ifp->drvr;
-       struct ethhdr *eh = (struct ethhdr *)(skb->data);
+       struct ethhdr *eh;
 
        brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
 
@@ -232,22 +232,13 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
                goto done;
        }
 
-       /* Make sure there's enough room for any header */
-       if (skb_headroom(skb) < drvr->hdrlen) {
-               struct sk_buff *skb2;
-
-               brcmf_dbg(INFO, "%s: insufficient headroom\n",
+       /* Make sure there's enough writable headroom*/
+       ret = skb_cow_head(skb, drvr->hdrlen);
+       if (ret < 0) {
+               brcmf_err("%s: skb_cow_head failed\n",
                          brcmf_ifname(drvr, ifp->bssidx));
-               drvr->bus_if->tx_realloc++;
-               skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
                dev_kfree_skb(skb);
-               skb = skb2;
-               if (skb == NULL) {
-                       brcmf_err("%s: skb_realloc_headroom failed\n",
-                                 brcmf_ifname(drvr, ifp->bssidx));
-                       ret = -ENOMEM;
-                       goto done;
-               }
+               goto done;
        }
 
        /* validate length for ether packet */
@@ -257,6 +248,8 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
                goto done;
        }
 
+       eh = (struct ethhdr *)(skb->data);
+
        if (eh->h_proto == htons(ETH_P_PAE))
                atomic_inc(&ifp->pend_8021x_cnt);
 
index aa498e0d2204b82b53ecd39a1da4aed9bf5ba9ba..49f3e17c28ea170b1bb283cff50002398f00bf59 100644 (file)
@@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
 {
        struct txpd *local_tx_pd;
        struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
-       unsigned int pad;
-       int headroom = (priv->adapter->iface_type ==
-                       MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
-
-       pad = ((void *)skb->data - sizeof(*local_tx_pd) -
-               headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
-       skb_push(skb, pad);
 
        skb_push(skb, sizeof(*local_tx_pd));
 
@@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
        local_tx_pd->bss_num = priv->bss_num;
        local_tx_pd->bss_type = priv->bss_type;
        /* Always zero as the data is followed by struct txpd */
-       local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) +
-                                                pad);
+       local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
        local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
        local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
-                                                sizeof(*local_tx_pd) -
-                                                pad);
+                                                sizeof(*local_tx_pd));
 
        if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
                local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
@@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                                       ra_list_flags);
                return -1;
        }
-       skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
+
+       /* skb_aggr->data already 64 byte align, just reserve bus interface
+        * header and txpd.
+        */
+       skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
        tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 
        memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
index 9824d8dd2b4447f11304557a44f3c7ea2d629d76..45d97b64ef84b5871dbecd47f423ad1ecd9a98e9 100644 (file)
@@ -115,7 +115,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
        if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
                p += sprintf(p, "multicast_count=\"%d\"\n",
                             netdev_mc_count(netdev));
-               p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
+               p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
+                            info.ssid.ssid);
                p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
                p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
                p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
index d6c4f0f60839c3c595d6fa0e8a35eafdfabf81ce..6cfa2969b123f0212c232f350dd949568e7767b6 100644 (file)
@@ -1098,8 +1098,6 @@ int mwifiex_set_encode(struct mwifiex_private *priv, struct key_params *kp,
                        encrypt_key.is_rx_seq_valid = true;
                }
        } else {
-               if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
-                       return 0;
                encrypt_key.key_disable = true;
                if (mac_addr)
                        memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
index 03cb3ea2d2c035b32254022b1506fcf52d770655..b5679fb6759187177bb7cfce1ce3aa9763d3ab10 100644 (file)
@@ -368,6 +368,7 @@ config PHY_QCOM_UFS
 config PHY_TUSB1210
        tristate "TI TUSB1210 ULPI PHY module"
        depends on USB_ULPI_BUS
+       depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
        select GENERIC_PHY
        help
          Support for TI TUSB1210 USB ULPI PHY.
index f5746b9f4e83900edd33fb049229b24aa48ba1b9..f05d2773fe00ccff87a55a177b1d27d71befabbf 100644 (file)
  * so the first read after a fault returns the latched value and subsequent
  * reads return the current value.  In order to return the fault status
  * to the user, have the interrupt handler save the reg's value and retrieve
- * it in the appropriate health/status routine.  Each routine has its own
- * flag indicating whether it should use the value stored by the last run
- * of the interrupt handler or do an actual reg read.  That way each routine
- * can report back whatever fault may have occured.
+ * it in the appropriate health/status routine.
  */
 struct bq24190_dev_info {
        struct i2c_client               *client;
@@ -159,10 +156,6 @@ struct bq24190_dev_info {
        unsigned int                    gpio_int;
        unsigned int                    irq;
        struct mutex                    f_reg_lock;
-       bool                            first_time;
-       bool                            charger_health_valid;
-       bool                            battery_health_valid;
-       bool                            battery_status_valid;
        u8                              f_reg;
        u8                              ss_reg;
        u8                              watchdog;
@@ -636,21 +629,11 @@ static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
                union power_supply_propval *val)
 {
        u8 v;
-       int health, ret;
+       int health;
 
        mutex_lock(&bdi->f_reg_lock);
-
-       if (bdi->charger_health_valid) {
-               v = bdi->f_reg;
-               bdi->charger_health_valid = false;
-               mutex_unlock(&bdi->f_reg_lock);
-       } else {
-               mutex_unlock(&bdi->f_reg_lock);
-
-               ret = bq24190_read(bdi, BQ24190_REG_F, &v);
-               if (ret < 0)
-                       return ret;
-       }
+       v = bdi->f_reg;
+       mutex_unlock(&bdi->f_reg_lock);
 
        if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
                /*
@@ -937,18 +920,8 @@ static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
        int status, ret;
 
        mutex_lock(&bdi->f_reg_lock);
-
-       if (bdi->battery_status_valid) {
-               chrg_fault = bdi->f_reg;
-               bdi->battery_status_valid = false;
-               mutex_unlock(&bdi->f_reg_lock);
-       } else {
-               mutex_unlock(&bdi->f_reg_lock);
-
-               ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
-               if (ret < 0)
-                       return ret;
-       }
+       chrg_fault = bdi->f_reg;
+       mutex_unlock(&bdi->f_reg_lock);
 
        chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
        chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
@@ -996,21 +969,11 @@ static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
                union power_supply_propval *val)
 {
        u8 v;
-       int health, ret;
+       int health;
 
        mutex_lock(&bdi->f_reg_lock);
-
-       if (bdi->battery_health_valid) {
-               v = bdi->f_reg;
-               bdi->battery_health_valid = false;
-               mutex_unlock(&bdi->f_reg_lock);
-       } else {
-               mutex_unlock(&bdi->f_reg_lock);
-
-               ret = bq24190_read(bdi, BQ24190_REG_F, &v);
-               if (ret < 0)
-                       return ret;
-       }
+       v = bdi->f_reg;
+       mutex_unlock(&bdi->f_reg_lock);
 
        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
@@ -1197,9 +1160,12 @@ static const struct power_supply_desc bq24190_battery_desc = {
 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
 {
        struct bq24190_dev_info *bdi = data;
-       bool alert_userspace = false;
+       const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
+       const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
+                               | BQ24190_REG_F_NTC_FAULT_MASK;
+       bool alert_charger = false, alert_battery = false;
        u8 ss_reg = 0, f_reg = 0;
-       int ret;
+       int i, ret;
 
        pm_runtime_get_sync(bdi->dev);
 
@@ -1209,6 +1175,32 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
                goto out;
        }
 
+       i = 0;
+       do {
+               ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
+               if (ret < 0) {
+                       dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
+                       goto out;
+               }
+       } while (f_reg && ++i < 2);
+
+       if (f_reg != bdi->f_reg) {
+               dev_info(bdi->dev,
+                       "Fault: boost %d, charge %d, battery %d, ntc %d\n",
+                       !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
+                       !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
+                       !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
+                       !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
+
+               mutex_lock(&bdi->f_reg_lock);
+               if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
+                       alert_battery = true;
+               if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
+                       alert_charger = true;
+               bdi->f_reg = f_reg;
+               mutex_unlock(&bdi->f_reg_lock);
+       }
+
        if (ss_reg != bdi->ss_reg) {
                /*
                 * The device is in host mode so when PG_STAT goes from 1->0
@@ -1225,47 +1217,17 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
                                        ret);
                }
 
+               if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
+                       alert_battery = true;
+               if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
+                       alert_charger = true;
                bdi->ss_reg = ss_reg;
-               alert_userspace = true;
-       }
-
-       mutex_lock(&bdi->f_reg_lock);
-
-       ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
-       if (ret < 0) {
-               mutex_unlock(&bdi->f_reg_lock);
-               dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
-               goto out;
        }
 
-       if (f_reg != bdi->f_reg) {
-               bdi->f_reg = f_reg;
-               bdi->charger_health_valid = true;
-               bdi->battery_health_valid = true;
-               bdi->battery_status_valid = true;
-
-               alert_userspace = true;
-       }
-
-       mutex_unlock(&bdi->f_reg_lock);
-
-       /*
-        * Sometimes bq24190 gives a steady trickle of interrupts even
-        * though the watchdog timer is turned off and neither the STATUS
-        * nor FAULT registers have changed.  Weed out these sprurious
-        * interrupts so userspace isn't alerted for no reason.
-        * In addition, the chip always generates an interrupt after
-        * register reset so we should ignore that one (the very first
-        * interrupt received).
-        */
-       if (alert_userspace) {
-               if (!bdi->first_time) {
-                       power_supply_changed(bdi->charger);
-                       power_supply_changed(bdi->battery);
-               } else {
-                       bdi->first_time = false;
-               }
-       }
+       if (alert_charger)
+               power_supply_changed(bdi->charger);
+       if (alert_battery)
+               power_supply_changed(bdi->battery);
 
 out:
        pm_runtime_put_sync(bdi->dev);
@@ -1300,6 +1262,10 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
                goto out;
 
        ret = bq24190_set_mode_host(bdi);
+       if (ret < 0)
+               goto out;
+
+       ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
 out:
        pm_runtime_put_sync(bdi->dev);
        return ret;
@@ -1375,10 +1341,8 @@ static int bq24190_probe(struct i2c_client *client,
        bdi->model = id->driver_data;
        strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
        mutex_init(&bdi->f_reg_lock);
-       bdi->first_time = true;
-       bdi->charger_health_valid = false;
-       bdi->battery_health_valid = false;
-       bdi->battery_status_valid = false;
+       bdi->f_reg = 0;
+       bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
 
        i2c_set_clientdata(client, bdi);
 
@@ -1392,22 +1356,13 @@ static int bq24190_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
-                       bq24190_irq_handler_thread,
-                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                       "bq24190-charger", bdi);
-       if (ret < 0) {
-               dev_err(dev, "Can't set up irq handler\n");
-               goto out1;
-       }
-
        pm_runtime_enable(dev);
        pm_runtime_resume(dev);
 
        ret = bq24190_hw_init(bdi);
        if (ret < 0) {
                dev_err(dev, "Hardware init failed\n");
-               goto out2;
+               goto out1;
        }
 
        charger_cfg.drv_data = bdi;
@@ -1418,7 +1373,7 @@ static int bq24190_probe(struct i2c_client *client,
        if (IS_ERR(bdi->charger)) {
                dev_err(dev, "Can't register charger\n");
                ret = PTR_ERR(bdi->charger);
-               goto out2;
+               goto out1;
        }
 
        battery_cfg.drv_data = bdi;
@@ -1427,24 +1382,34 @@ static int bq24190_probe(struct i2c_client *client,
        if (IS_ERR(bdi->battery)) {
                dev_err(dev, "Can't register battery\n");
                ret = PTR_ERR(bdi->battery);
-               goto out3;
+               goto out2;
        }
 
        ret = bq24190_sysfs_create_group(bdi);
        if (ret) {
                dev_err(dev, "Can't create sysfs entries\n");
+               goto out3;
+       }
+
+       ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
+                       bq24190_irq_handler_thread,
+                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                       "bq24190-charger", bdi);
+       if (ret < 0) {
+               dev_err(dev, "Can't set up irq handler\n");
                goto out4;
        }
 
        return 0;
 
 out4:
-       power_supply_unregister(bdi->battery);
+       bq24190_sysfs_remove_group(bdi);
 out3:
-       power_supply_unregister(bdi->charger);
+       power_supply_unregister(bdi->battery);
 out2:
-       pm_runtime_disable(dev);
+       power_supply_unregister(bdi->charger);
 out1:
+       pm_runtime_disable(dev);
        if (bdi->gpio_int)
                gpio_free(bdi->gpio_int);
 
@@ -1488,12 +1453,13 @@ static int bq24190_pm_resume(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
 
-       bdi->charger_health_valid = false;
-       bdi->battery_health_valid = false;
-       bdi->battery_status_valid = false;
+       bdi->f_reg = 0;
+       bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
 
        pm_runtime_get_sync(bdi->dev);
        bq24190_register_reset(bdi);
+       bq24190_set_mode_host(bdi);
+       bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
        pm_runtime_put_sync(bdi->dev);
 
        /* Things may have changed while suspended so alert upper layer */
index 64eed87d34a87840d5da60d267383589541e1d73..433c5e3d57338210626dc3ef52cec31fb02bf1b2 100644 (file)
@@ -1637,7 +1637,7 @@ config ATARI_SCSI_RESET_BOOT
 
 config MAC_SCSI
        tristate "Macintosh NCR5380 SCSI"
-       depends on MAC && SCSI=y
+       depends on MAC && SCSI
        select SCSI_SPI_ATTRS
        help
          This is the NCR 5380 SCSI controller included on most of the 68030
index 2882bcac918a05732f6a8c36d84bcfaf3b9ef049..0b096730c72a3bf98151fa282090ca3199678b1b 100644 (file)
@@ -996,6 +996,8 @@ static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
        do {
                msleep(delay_us / 1000);
                status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]);
+               if (status == U64_MAX)
+                       nretry /= 2;
        } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_ONLINE &&
                 nretry--);
 
@@ -1027,6 +1029,8 @@ static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry)
        do {
                msleep(delay_us / 1000);
                status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]);
+               if (status == U64_MAX)
+                       nretry /= 2;
        } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_OFFLINE &&
                 nretry--);
 
@@ -1137,7 +1141,7 @@ static const struct asyc_intr_info ainfo[] = {
        {SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR},
        {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST},
        {SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0},
-       {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST},
+       {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0},
        {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET},
        {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0},
        {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET},
@@ -1145,7 +1149,7 @@ static const struct asyc_intr_info ainfo[] = {
        {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR},
        {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST},
        {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0},
-       {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST},
+       {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0},
        {0x0, "", 0, 0}         /* terminator */
 };
 
@@ -1962,6 +1966,11 @@ retry:
  * cxlflash_eh_host_reset_handler() - reset the host adapter
  * @scp:       SCSI command from stack identifying host.
  *
+ * Following a reset, the state is evaluated again in case an EEH occurred
+ * during the reset. In such a scenario, the host reset will either yield
+ * until the EEH recovery is complete or return success or failure based
+ * upon the current device state.
+ *
  * Return:
  *     SUCCESS as defined in scsi/scsi.h
  *     FAILED as defined in scsi/scsi.h
@@ -1993,7 +2002,8 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
                } else
                        cfg->state = STATE_NORMAL;
                wake_up_all(&cfg->reset_waitq);
-               break;
+               ssleep(1);
+               /* fall through */
        case STATE_RESET:
                wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
                if (cfg->state == STATE_NORMAL)
@@ -2534,6 +2544,9 @@ static void drain_ioctls(struct cxlflash_cfg *cfg)
  * @pdev:      PCI device struct.
  * @state:     PCI channel state.
  *
+ * When an EEH occurs during an active reset, wait until the reset is
+ * complete and then take action based upon the device state.
+ *
  * Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
  */
 static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
@@ -2547,6 +2560,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
 
        switch (state) {
        case pci_channel_io_frozen:
+               wait_event(cfg->reset_waitq, cfg->state != STATE_RESET);
+               if (cfg->state == STATE_FAILTERM)
+                       return PCI_ERS_RESULT_DISCONNECT;
+
                cfg->state = STATE_RESET;
                scsi_block_requests(cfg->host);
                drain_ioctls(cfg);
index 4e6c16af40fc5f8fa2065dacb946ad2a78adf0e9..91ff8fb0cc3a85f3941d1d33178a64b631f73c36 100644 (file)
@@ -3181,7 +3181,7 @@ static const struct {
 };
 
 /*-------------------------------------------------------------------------*/
-static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
+static void nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
 {
        int     i;
 
@@ -3211,7 +3211,7 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
 
 /*-------------------------------------------------------------------------*/
 /* platform_driver */
-static int __init nbu2ss_drv_contest_init(
+static int nbu2ss_drv_contest_init(
        struct platform_device *pdev,
        struct nbu2ss_udc *udc)
 {
index f914b30999f8d1519ee28edeb134762cf4796b52..4d52ca42644a04130f21f4113d25e8601e750b28 100644 (file)
@@ -1921,7 +1921,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
                                  u64 *kpage)
 {
        int ret = 0;
-       u64 pgaddr, prev_pgaddr;
+       u64 pgaddr, prev_pgaddr = 0;
        u32 j = 0;
        int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE;
        int nr_kpages = kpages_per_hwpage;
@@ -2417,6 +2417,7 @@ static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca,
                ehca_err(&shca->ib_device, "kpage alloc failed");
                return -ENOMEM;
        }
+       hret = H_SUCCESS;
        for (top = 0; top < EHCA_MAP_ENTRIES; top++) {
                if (!ehca_bmap_valid(ehca_bmap->top[top]))
                        continue;
index a9c1e0bafa62badc12221ba92b90b7e75a178605..e35fbece3d2f2d71229b41405cb522ce4c795e12 100644 (file)
@@ -232,7 +232,7 @@ static int p80211_convert_to_ether(wlandevice_t *wlandev, struct sk_buff *skb)
        struct p80211_hdr_a3 *hdr;
 
        hdr = (struct p80211_hdr_a3 *) skb->data;
-       if (p80211_rx_typedrop(wlandev, hdr->fc))
+       if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->fc)))
                return CONV_TO_ETHER_SKIPPED;
 
        /* perform mcast filtering: allow my local address through but reject
index a2c0734c76e2eb47eab5d7b294b3071a99efcf0e..e8dd296fb25b4c9e23d6585f25b1e7ba50324f11 100644 (file)
@@ -1235,7 +1235,8 @@ static int omap8250_probe(struct platform_device *pdev)
        pm_runtime_put_autosuspend(&pdev->dev);
        return 0;
 err:
-       pm_runtime_put(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
+       pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        return ret;
 }
@@ -1244,6 +1245,7 @@ static int omap8250_remove(struct platform_device *pdev)
 {
        struct omap8250_priv *priv = platform_get_drvdata(pdev);
 
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        serial8250_unregister_port(priv->line);
@@ -1343,6 +1345,10 @@ static int omap8250_runtime_suspend(struct device *dev)
        struct omap8250_priv *priv = dev_get_drvdata(dev);
        struct uart_8250_port *up;
 
+       /* In case runtime-pm tries this before we are setup */
+       if (!priv)
+               return 0;
+
        up = serial8250_get_port(priv->line);
        /*
         * When using 'no_console_suspend', the console UART must not be
index 83ff1724ec791f2e18001a21520eb3ba908b2dbd..cf3da51a3536d00fb9b9812eb30b1faeb27ca5ec 100644 (file)
@@ -5850,17 +5850,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
 static void serial8250_io_resume(struct pci_dev *dev)
 {
        struct serial_private *priv = pci_get_drvdata(dev);
-       const struct pciserial_board *board;
+       struct serial_private *new;
 
        if (!priv)
                return;
 
-       board = priv->board;
-       kfree(priv);
-       priv = pciserial_init_ports(dev, board);
-
-       if (!IS_ERR(priv)) {
-               pci_set_drvdata(dev, priv);
+       new = pciserial_init_ports(dev, priv->board);
+       if (!IS_ERR(new)) {
+               pci_set_drvdata(dev, new);
+               kfree(priv);
        }
 }
 
index 41d7cf6d63ba32a240add0eaa7c01f63fa8b1f28..858c30814497918afe491e24113a6d7a64c1cc6e 100644 (file)
@@ -428,9 +428,6 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
 
 u8 hw_port_test_get(struct ci_hdrc *ci);
 
-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
-                               u32 value, unsigned int timeout_ms);
-
 void ci_platform_configure(struct ci_hdrc *ci);
 
 #endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
index ba4a2a1eb3fff95dcb60fd86f0d1fbf38c300f5c..939c6ad7106891689b3c7405f39bea7ae48fae9a 100644 (file)
@@ -518,38 +518,6 @@ int hw_device_reset(struct ci_hdrc *ci)
        return 0;
 }
 
-/**
- * hw_wait_reg: wait the register value
- *
- * Sometimes, it needs to wait register value before going on.
- * Eg, when switch to device mode, the vbus value should be lower
- * than OTGSC_BSV before connects to host.
- *
- * @ci: the controller
- * @reg: register index
- * @mask: mast bit
- * @value: the bit value to wait
- * @timeout_ms: timeout in millisecond
- *
- * This function returns an error code if timeout
- */
-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
-                               u32 value, unsigned int timeout_ms)
-{
-       unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
-
-       while (hw_read(ci, reg, mask) != value) {
-               if (time_after(jiffies, elapse)) {
-                       dev_err(ci->dev, "timeout waiting for %08x in %d\n",
-                                       mask, reg);
-                       return -ETIMEDOUT;
-               }
-               msleep(20);
-       }
-
-       return 0;
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
        struct ci_hdrc *ci = data;
index 03b6743461d15de129a2d7908e851db450111d3c..0cf149edddd84e33bb22456041f75c50883a41ac 100644 (file)
@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
                else
                        val &= ~OTGSC_BSVIS;
 
-               cable->changed = false;
-
                if (cable->state)
                        val |= OTGSC_BSV;
                else
                        val &= ~OTGSC_BSV;
+
+               if (cable->enabled)
+                       val |= OTGSC_BSVIE;
+               else
+                       val &= ~OTGSC_BSVIE;
        }
 
        cable = &ci->platdata->id_extcon;
@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
                else
                        val &= ~OTGSC_IDIS;
 
-               cable->changed = false;
-
                if (cable->state)
                        val |= OTGSC_ID;
                else
                        val &= ~OTGSC_ID;
+
+               if (cable->enabled)
+                       val |= OTGSC_IDIE;
+               else
+                       val &= ~OTGSC_IDIE;
        }
 
-       return val;
+       return val & mask;
 }
 
 /**
@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
  */
 void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
 {
+       struct ci_hdrc_cable *cable;
+
+       cable = &ci->platdata->vbus_extcon;
+       if (!IS_ERR(cable->edev)) {
+               if (data & mask & OTGSC_BSVIS)
+                       cable->changed = false;
+
+               /* Don't enable vbus interrupt if using external notifier */
+               if (data & mask & OTGSC_BSVIE) {
+                       cable->enabled = true;
+                       data &= ~OTGSC_BSVIE;
+               } else if (mask & OTGSC_BSVIE) {
+                       cable->enabled = false;
+               }
+       }
+
+       cable = &ci->platdata->id_extcon;
+       if (!IS_ERR(cable->edev)) {
+               if (data & mask & OTGSC_IDIS)
+                       cable->changed = false;
+
+               /* Don't enable id interrupt if using external notifier */
+               if (data & mask & OTGSC_IDIE) {
+                       cable->enabled = true;
+                       data &= ~OTGSC_IDIE;
+               } else if (mask & OTGSC_IDIE) {
+                       cable->enabled = false;
+               }
+       }
+
        hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
 }
 
@@ -104,7 +140,31 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
                usb_gadget_vbus_disconnect(&ci->gadget);
 }
 
-#define CI_VBUS_STABLE_TIMEOUT_MS 5000
+/**
+ * When we switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connecting to host.
+ *
+ * @ci: the controller
+ *
+ * This function returns an error code if timeout
+ */
+static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
+{
+       unsigned long elapse = jiffies + msecs_to_jiffies(5000);
+       u32 mask = OTGSC_BSV;
+
+       while (hw_read_otgsc(ci, mask)) {
+               if (time_after(jiffies, elapse)) {
+                       dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
+                                       mask);
+                       return -ETIMEDOUT;
+               }
+               msleep(20);
+       }
+
+       return 0;
+}
+
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
        enum ci_role role = ci_otg_role(ci);
@@ -116,9 +176,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
                ci_role_stop(ci);
 
                if (role == CI_ROLE_GADGET)
-                       /* wait vbus lower than OTGSC_BSV */
-                       hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-                                       CI_VBUS_STABLE_TIMEOUT_MS);
+                       /*
+                        * wait vbus lower than OTGSC_BSV before connecting
+                        * to host
+                        */
+                       hw_wait_vbus_lower_bsv(ci);
 
                ci_role_start(ci, role);
        }
index df538fd10aa4c0dd566b5df861fac36cbbca7532..46f5354c534d421f03d6a6221ae473a6c0969f23 100644 (file)
@@ -77,10 +77,12 @@ static int exynos_ehci_get_phy(struct device *dev,
                if (IS_ERR(phy)) {
                        ret = PTR_ERR(phy);
                        if (ret == -EPROBE_DEFER) {
+                               of_node_put(child);
                                return ret;
                        } else if (ret != -ENOSYS && ret != -ENODEV) {
                                dev_err(dev,
                                        "Error retrieving usb2 phy: %d\n", ret);
+                               of_node_put(child);
                                return ret;
                        }
                }
index 2cd105be7319f6e61ec2bd799f9eb1b8cdef5fa1..6865b919403f761efc3c732f28930b097ca4b05b 100644 (file)
@@ -66,10 +66,12 @@ static int exynos_ohci_get_phy(struct device *dev,
                if (IS_ERR(phy)) {
                        ret = PTR_ERR(phy);
                        if (ret == -EPROBE_DEFER) {
+                               of_node_put(child);
                                return ret;
                        } else if (ret != -ENOSYS && ret != -ENODEV) {
                                dev_err(dev,
                                        "Error retrieving usb2 phy: %d\n", ret);
+                               of_node_put(child);
                                return ret;
                        }
                }
index 7812052dc7001519f4f73e5e2afa34857ae21431..754fc3e41005195b605ac9da123cf18c8255f143 100644 (file)
@@ -373,23 +373,29 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
                dev_dbg(&port->dev,
                        "%s - usb_serial_generic_open failed: %d\n",
                        __func__, result);
-               goto err_out;
+               goto err_free;
        }
 
        /* remove any data still left: also clears error state */
        ark3116_read_reg(serial, UART_RX, buf);
 
        /* read modem status */
-       priv->msr = ark3116_read_reg(serial, UART_MSR, buf);
+       result = ark3116_read_reg(serial, UART_MSR, buf);
+       if (result < 0)
+               goto err_close;
+       priv->msr = *buf;
+
        /* read line status */
-       priv->lsr = ark3116_read_reg(serial, UART_LSR, buf);
+       result = ark3116_read_reg(serial, UART_LSR, buf);
+       if (result < 0)
+               goto err_close;
+       priv->lsr = *buf;
 
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
        if (result) {
                dev_err(&port->dev, "submit irq_in urb failed %d\n",
                        result);
-               ark3116_close(port);
-               goto err_out;
+               goto err_close;
        }
 
        /* activate interrupts */
@@ -402,8 +408,15 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
        if (tty)
                ark3116_set_termios(tty, port, NULL);
 
-err_out:
        kfree(buf);
+
+       return 0;
+
+err_close:
+       usb_serial_generic_close(port);
+err_free:
+       kfree(buf);
+
        return result;
 }
 
index e0b1fe2f60e17ced557e372bd835b35fe4e1a87a..be93b9ff2d989a7afbc58e4ea220909dc2c0bdb2 100644 (file)
@@ -1399,25 +1399,30 @@ static int digi_read_inb_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct digi_port *priv = usb_get_serial_port_data(port);
-       int opcode = ((unsigned char *)urb->transfer_buffer)[0];
-       int len = ((unsigned char *)urb->transfer_buffer)[1];
-       int port_status = ((unsigned char *)urb->transfer_buffer)[2];
-       unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
+       unsigned char *buf = urb->transfer_buffer;
+       int opcode;
+       int len;
+       int port_status;
+       unsigned char *data;
        int flag, throttled;
-       int status = urb->status;
-
-       /* do not process callbacks on closed ports */
-       /* but do continue the read chain */
-       if (urb->status == -ENOENT)
-               return 0;
 
        /* short/multiple packet check */
+       if (urb->actual_length < 2) {
+               dev_warn(&port->dev, "short packet received\n");
+               return -1;
+       }
+
+       opcode = buf[0];
+       len = buf[1];
+
        if (urb->actual_length != len + 2) {
-               dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, "
-                       "status=%d, port=%d, opcode=%d, len=%d, "
-                       "actual_length=%d, status=%d\n", __func__, status,
-                       priv->dp_port_num, opcode, len, urb->actual_length,
-                       port_status);
+               dev_err(&port->dev, "malformed packet received: port=%d, opcode=%d, len=%d, actual_length=%u\n",
+                       priv->dp_port_num, opcode, len, urb->actual_length);
+               return -1;
+       }
+
+       if (opcode == DIGI_CMD_RECEIVE_DATA && len < 1) {
+               dev_err(&port->dev, "malformed data packet received\n");
                return -1;
        }
 
@@ -1431,6 +1436,9 @@ static int digi_read_inb_callback(struct urb *urb)
 
        /* receive data */
        if (opcode == DIGI_CMD_RECEIVE_DATA) {
+               port_status = buf[2];
+               data = &buf[3];
+
                /* get flag from port_status */
                flag = 0;
 
index 19a98116c2ab08c9778c969f591c1152b7e8a71b..b3a21fcbbaf902c51e7b1c13dc54a8913b500589 100644 (file)
@@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port)
                             FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
                             0, priv->interface,
                             buf, 1, WDR_TIMEOUT);
-       if (rv < 0)
+       if (rv < 1) {
                dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
-       else
+               if (rv >= 0)
+                       rv = -EIO;
+       } else {
                priv->latency = buf[0];
+       }
 
        kfree(buf);
 
index b63a6c3899c59b47a7146bacab8c226474976107..749e1b674145e0bf4e5a81c17eecc7ae7d01213f 100644 (file)
@@ -492,20 +492,24 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
        int result;
        struct usb_serial *serial = ep->serial;
        struct edgeport_product_info *product_info = &ep->product_info;
-       struct edge_compatibility_descriptor *epic = &ep->epic_descriptor;
+       struct edge_compatibility_descriptor *epic;
        struct edge_compatibility_bits *bits;
        struct device *dev = &serial->dev->dev;
 
        ep->is_epic = 0;
+
+       epic = kmalloc(sizeof(*epic), GFP_KERNEL);
+       if (!epic)
+               return -ENOMEM;
+
        result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                                 USB_REQUEST_ION_GET_EPIC_DESC,
                                 0xC0, 0x00, 0x00,
-                                &ep->epic_descriptor,
-                                sizeof(struct edge_compatibility_descriptor),
+                                epic, sizeof(*epic),
                                 300);
-
-       if (result > 0) {
+       if (result == sizeof(*epic)) {
                ep->is_epic = 1;
+               memcpy(&ep->epic_descriptor, epic, sizeof(*epic));
                memset(product_info, 0, sizeof(struct edgeport_product_info));
 
                product_info->NumPorts = epic->NumPorts;
@@ -534,8 +538,16 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
                dev_dbg(dev, "  IOSPWriteLCR     : %s\n", bits->IOSPWriteLCR    ? "TRUE": "FALSE");
                dev_dbg(dev, "  IOSPSetBaudRate  : %s\n", bits->IOSPSetBaudRate ? "TRUE": "FALSE");
                dev_dbg(dev, "  TrueEdgeport     : %s\n", bits->TrueEdgeport    ? "TRUE": "FALSE");
+
+               result = 0;
+       } else if (result >= 0) {
+               dev_warn(&serial->interface->dev, "short epic descriptor received: %d\n",
+                        result);
+               result = -EIO;
        }
 
+       kfree(epic);
+
        return result;
 }
 
@@ -2097,8 +2109,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
  * rom_read
  *     reads a number of bytes from the Edgeport device starting at the given
  *     address.
- *     If successful returns the number of bytes read, otherwise it returns
- *     a negative error number of the problem.
+ *     Returns zero on success or a negative error number.
  ****************************************************************************/
 static int rom_read(struct usb_serial *serial, __u16 extAddr,
                                        __u16 addr, __u16 length, __u8 *data)
@@ -2123,12 +2134,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr,
                                        USB_REQUEST_ION_READ_ROM,
                                        0xC0, addr, extAddr, transfer_buffer,
                                        current_length, 300);
-               if (result < 0)
+               if (result < current_length) {
+                       if (result >= 0)
+                               result = -EIO;
                        break;
+               }
                memcpy(data, transfer_buffer, current_length);
                length -= current_length;
                addr += current_length;
                data += current_length;
+
+               result = 0;
        }
 
        kfree(transfer_buffer);
@@ -2585,9 +2601,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial)
                                EDGE_MANUF_DESC_LEN,
                                (__u8 *)(&edge_serial->manuf_descriptor));
 
-       if (response < 1)
-               dev_err(dev, "error in getting manufacturer descriptor\n");
-       else {
+       if (response < 0) {
+               dev_err(dev, "error in getting manufacturer descriptor: %d\n",
+                               response);
+       } else {
                char string[30];
                dev_dbg(dev, "**Manufacturer Descriptor\n");
                dev_dbg(dev, "  RomSize:        %dK\n",
@@ -2644,9 +2661,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial)
                                EDGE_BOOT_DESC_LEN,
                                (__u8 *)(&edge_serial->boot_descriptor));
 
-       if (response < 1)
-               dev_err(dev, "error in getting boot descriptor\n");
-       else {
+       if (response < 0) {
+               dev_err(dev, "error in getting boot descriptor: %d\n",
+                               response);
+       } else {
                dev_dbg(dev, "**Boot Descriptor:\n");
                dev_dbg(dev, "  BootCodeLength: %d\n",
                        le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
@@ -2789,7 +2807,7 @@ static int edge_startup(struct usb_serial *serial)
        dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
 
        /* Read the epic descriptor */
-       if (get_epic_descriptor(edge_serial) <= 0) {
+       if (get_epic_descriptor(edge_serial) < 0) {
                /* memcpy descriptor to Supports structures */
                memcpy(&edge_serial->epic_descriptor.Supports, descriptor,
                       sizeof(struct edge_compatibility_bits));
index 930be98d59b389ca88fd6f06e1a84c9643f0258b..6b0942428917079fe7aeb0f699dc3eb0dc36f1ce 100644 (file)
@@ -139,6 +139,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
+       unsigned int len = urb->actual_length;
        int retval;
        int status = urb->status;
        struct keyspan_pda_private *priv;
@@ -159,18 +160,26 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
                goto exit;
        }
 
+       if (len < 1) {
+               dev_warn(&port->dev, "short message received\n");
+               goto exit;
+       }
+
        /* see if the message is data or a status interrupt */
        switch (data[0]) {
        case 0:
                 /* rest of message is rx data */
-               if (urb->actual_length) {
-                       tty_insert_flip_string(&port->port, data + 1,
-                                               urb->actual_length - 1);
-                       tty_flip_buffer_push(&port->port);
-               }
+               if (len < 2)
+                       break;
+               tty_insert_flip_string(&port->port, data + 1, len - 1);
+               tty_flip_buffer_push(&port->port);
                break;
        case 1:
                /* status interrupt */
+               if (len < 3) {
+                       dev_warn(&port->dev, "short interrupt message received\n");
+                       break;
+               }
                dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]);
                switch (data[1]) {
                case 1: /* modemline change */
index 89726f702202f4d4906ed9b16933998b72975294..9bf82c262c5be71224956b3ac945cdd476910c64 100644 (file)
@@ -322,8 +322,12 @@ static int mct_u232_get_modem_stat(struct usb_serial_port *port,
                        MCT_U232_GET_REQUEST_TYPE,
                        0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
                        WDR_TIMEOUT);
-       if (rc < 0) {
+       if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
                dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
+
+               if (rc >= 0)
+                       rc = -EIO;
+
                *msr = 0;
        } else {
                *msr = buf[0];
index a3ed07c58754e3803cacf9bf705b3fc5998cc003..af0c87276299ad2f7d23d31cbe5f0c485d56a4fe 100644 (file)
@@ -188,22 +188,22 @@ static inline int qt2_setdevice(struct usb_device *dev, u8 *data)
 }
 
 
-static inline int qt2_getdevice(struct usb_device *dev, u8 *data)
-{
-       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                              QT_SET_GET_DEVICE, 0xc0, 0, 0,
-                              data, 3, QT2_USB_TIMEOUT);
-}
-
 static inline int qt2_getregister(struct usb_device *dev,
                                  u8 uart,
                                  u8 reg,
                                  u8 *data)
 {
-       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                              QT_SET_GET_REGISTER, 0xc0, reg,
-                              uart, data, sizeof(*data), QT2_USB_TIMEOUT);
+       int ret;
+
+       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                             QT_SET_GET_REGISTER, 0xc0, reg,
+                             uart, data, sizeof(*data), QT2_USB_TIMEOUT);
+       if (ret < sizeof(*data)) {
+               if (ret >= 0)
+                       ret = -EIO;
+       }
 
+       return ret;
 }
 
 static inline int qt2_setregister(struct usb_device *dev,
@@ -372,9 +372,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
                                 0xc0, 0,
                                 device_port, data, 2, QT2_USB_TIMEOUT);
 
-       if (status < 0) {
+       if (status < 2) {
                dev_err(&port->dev, "%s - open port failed %i\n", __func__,
                        status);
+               if (status >= 0)
+                       status = -EIO;
                kfree(data);
                return status;
        }
index 70a098de429fc39934ef8808d3e6c5011f063352..886e1294b120a4d0d387fef741f21b88a13706cd 100644 (file)
@@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data)
 
 static inline int ssu100_getdevice(struct usb_device *dev, u8 *data)
 {
-       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                              QT_SET_GET_DEVICE, 0xc0, 0, 0,
-                              data, 3, 300);
+       int ret;
+
+       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                             QT_SET_GET_DEVICE, 0xc0, 0, 0,
+                             data, 3, 300);
+       if (ret < 3) {
+               if (ret >= 0)
+                       ret = -EIO;
+       }
+
+       return ret;
 }
 
 static inline int ssu100_getregister(struct usb_device *dev,
@@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev,
                                     unsigned short reg,
                                     u8 *data)
 {
-       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-                              QT_SET_GET_REGISTER, 0xc0, reg,
-                              uart, data, sizeof(*data), 300);
+       int ret;
+
+       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                             QT_SET_GET_REGISTER, 0xc0, reg,
+                             uart, data, sizeof(*data), 300);
+       if (ret < sizeof(*data)) {
+               if (ret >= 0)
+                       ret = -EIO;
+       }
 
+       return ret;
 }
 
 
@@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
                                 QT_OPEN_CLOSE_CHANNEL,
                                 QT_TRANSFER_IN, 0x01,
                                 0, data, 2, 300);
-       if (result < 0) {
+       if (result < 2) {
                dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result);
+               if (result >= 0)
+                       result = -EIO;
                kfree(data);
                return result;
        }
index 535fcfafc0977a8c56010c2c8c52b0def075b070..fe7f5ace60640929e91d007a94ce963f12be172d 100644 (file)
@@ -1352,13 +1352,10 @@ static int ti_command_out_sync(struct ti_device *tdev, __u8 command,
                (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
                value, moduleid, data, size, 1000);
 
-       if (status == size)
-               status = 0;
-
-       if (status > 0)
-               status = -ECOMM;
+       if (status < 0)
+               return status;
 
-       return status;
+       return 0;
 }
 
 
@@ -1374,8 +1371,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
 
        if (status == size)
                status = 0;
-
-       if (status > 0)
+       else if (status >= 0)
                status = -ECOMM;
 
        return status;
index 929b618da43bb345cc69699ee96fd00beb358e73..c30c6ceac2c43363701ccbb3a7b8c0660fd69850 100644 (file)
@@ -283,6 +283,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
        case ACL_TYPE_ACCESS:
                if (acl) {
                        struct iattr iattr;
+                       struct posix_acl *old_acl = acl;
 
                        retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
                        if (retval)
@@ -293,6 +294,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
                                 * by the mode bits. So don't
                                 * update ACL.
                                 */
+                               posix_acl_release(old_acl);
                                value = NULL;
                                size = 0;
                        }
index 198aea66fe71c7d8cb24416be9332c41507173e7..e5733bb537c99ea792f3d85d9dfff0aa2607c30a 100644 (file)
@@ -1098,7 +1098,6 @@ int revalidate_disk(struct gendisk *disk)
 
        if (disk->fops->revalidate_disk)
                ret = disk->fops->revalidate_disk(disk);
-       blk_integrity_revalidate(disk);
        bdev = bdget_disk(disk, 0);
        if (!bdev)
                return ret;
index 94906aaa9b7c5ce3e3e6127427e9d9df04bc397f..e2f6a79e9b012d695a33c90b684b3eaafa1cb6b2 100644 (file)
@@ -227,6 +227,7 @@ struct smb_version_operations {
        /* verify the message */
        int (*check_message)(char *, unsigned int);
        bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
+       int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *);
        void (*downgrade_oplock)(struct TCP_Server_Info *,
                                        struct cifsInodeInfo *, bool);
        /* process transaction2 response */
@@ -1289,12 +1290,19 @@ struct mid_q_entry {
        void *callback_data;      /* general purpose pointer for callback */
        void *resp_buf;         /* pointer to received SMB header */
        int mid_state;  /* wish this were enum but can not pass to wait_event */
+       unsigned int mid_flags;
        __le16 command;         /* smb command code */
        bool large_buf:1;       /* if valid response, is pointer to large buf */
        bool multiRsp:1;        /* multiple trans2 responses for one request  */
        bool multiEnd:1;        /* both received */
 };
 
+struct close_cancelled_open {
+       struct cifs_fid         fid;
+       struct cifs_tcon        *tcon;
+       struct work_struct      work;
+};
+
 /*     Make code in transport.c a little cleaner by moving
        update of optional stats into function below */
 #ifdef CONFIG_CIFS_STATS2
@@ -1426,6 +1434,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
 #define   MID_RESPONSE_MALFORMED 0x10
 #define   MID_SHUTDOWN          0x20
 
+/* Flags */
+#define   MID_WAIT_CANCELLED    1 /* Cancelled while waiting for response */
+
 /* Types of response buffer returned from SendReceive2 */
 #define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
 #define   CIFS_SMALL_BUFFER     1
index b1104ed8f54c042177061166da7c3088307b1fb3..5e2f8b8ca08aac0441d8cbeae6b37eef4ba73fda 100644 (file)
@@ -1424,6 +1424,8 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 
        length = discard_remaining_data(server);
        dequeue_mid(mid, rdata->result);
+       mid->resp_buf = server->smallbuf;
+       server->smallbuf = NULL;
        return length;
 }
 
@@ -1538,6 +1540,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                return cifs_readv_discard(server, mid);
 
        dequeue_mid(mid, false);
+       mid->resp_buf = server->smallbuf;
+       server->smallbuf = NULL;
        return length;
 }
 
index 5d59f25521ce12a25bd02c062756412bf234f7ab..156bc18eac69941f4554d68d5ccef26a3628cba0 100644 (file)
@@ -924,10 +924,19 @@ cifs_demultiplex_thread(void *p)
 
                server->lstrp = jiffies;
                if (mid_entry != NULL) {
+                       if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) &&
+                            mid_entry->mid_state == MID_RESPONSE_RECEIVED &&
+                                       server->ops->handle_cancelled_mid)
+                               server->ops->handle_cancelled_mid(
+                                                       mid_entry->resp_buf,
+                                                       server);
+
                        if (!mid_entry->multiRsp || mid_entry->multiEnd)
                                mid_entry->callback(mid_entry);
-               } else if (!server->ops->is_oplock_break ||
-                          !server->ops->is_oplock_break(buf, server)) {
+               } else if (server->ops->is_oplock_break &&
+                          server->ops->is_oplock_break(buf, server)) {
+                       cifs_dbg(FYI, "Received oplock break\n");
+               } else {
                        cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
                                 atomic_read(&midCount));
                        cifs_dump_mem("Received Data is: ", buf,
index e5bc85e49be713d9148341a0339da234fc6d588e..76ccf20fbfb7bd40773b0cb85a517e28fcf10b94 100644 (file)
@@ -630,3 +630,47 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
        cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
        return false;
 }
+
+void
+smb2_cancelled_close_fid(struct work_struct *work)
+{
+       struct close_cancelled_open *cancelled = container_of(work,
+                                       struct close_cancelled_open, work);
+
+       cifs_dbg(VFS, "Close unmatched open\n");
+
+       SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
+                  cancelled->fid.volatile_fid);
+       cifs_put_tcon(cancelled->tcon);
+       kfree(cancelled);
+}
+
+int
+smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
+{
+       struct smb2_hdr *hdr = (struct smb2_hdr *)buffer;
+       struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
+       struct cifs_tcon *tcon;
+       struct close_cancelled_open *cancelled;
+
+       if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS)
+               return 0;
+
+       cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
+       if (!cancelled)
+               return -ENOMEM;
+
+       tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId);
+       if (!tcon) {
+               kfree(cancelled);
+               return -ENOENT;
+       }
+
+       cancelled->fid.persistent_fid = rsp->PersistentFileId;
+       cancelled->fid.volatile_fid = rsp->VolatileFileId;
+       cancelled->tcon = tcon;
+       INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
+       queue_work(cifsiod_wq, &cancelled->work);
+
+       return 0;
+}
index be34b4860675f046cf8a475393eb994fe52f9fda..087918c4612a870a3f459cf502a1e0ddf3d9df1b 100644 (file)
@@ -1511,6 +1511,7 @@ struct smb_version_operations smb20_operations = {
        .clear_stats = smb2_clear_stats,
        .print_stats = smb2_print_stats,
        .is_oplock_break = smb2_is_valid_oplock_break,
+       .handle_cancelled_mid = smb2_handle_cancelled_mid,
        .downgrade_oplock = smb2_downgrade_oplock,
        .need_neg = smb2_need_neg,
        .negotiate = smb2_negotiate,
@@ -1589,6 +1590,7 @@ struct smb_version_operations smb21_operations = {
        .clear_stats = smb2_clear_stats,
        .print_stats = smb2_print_stats,
        .is_oplock_break = smb2_is_valid_oplock_break,
+       .handle_cancelled_mid = smb2_handle_cancelled_mid,
        .downgrade_oplock = smb2_downgrade_oplock,
        .need_neg = smb2_need_neg,
        .negotiate = smb2_negotiate,
@@ -1670,6 +1672,7 @@ struct smb_version_operations smb30_operations = {
        .print_stats = smb2_print_stats,
        .dump_share_caps = smb2_dump_share_caps,
        .is_oplock_break = smb2_is_valid_oplock_break,
+       .handle_cancelled_mid = smb2_handle_cancelled_mid,
        .downgrade_oplock = smb2_downgrade_oplock,
        .need_neg = smb2_need_neg,
        .negotiate = smb2_negotiate,
@@ -1757,6 +1760,7 @@ struct smb_version_operations smb311_operations = {
        .print_stats = smb2_print_stats,
        .dump_share_caps = smb2_dump_share_caps,
        .is_oplock_break = smb2_is_valid_oplock_break,
+       .handle_cancelled_mid = smb2_handle_cancelled_mid,
        .downgrade_oplock = smb2_downgrade_oplock,
        .need_neg = smb2_need_neg,
        .negotiate = smb2_negotiate,
index 0a406ae78129a3fbd5676a426ca0562bd5eaea23..adc5234486c37b979ddeea1d834818a6f0ecef4d 100644 (file)
@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
                              struct smb_rqst *rqst);
 extern struct mid_q_entry *smb2_setup_async_request(
                        struct TCP_Server_Info *server, struct smb_rqst *rqst);
+extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
+                                          __u64 ses_id);
+extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
+                                               __u64 ses_id, __u32  tid);
 extern int smb2_calc_signature(struct smb_rqst *rqst,
                                struct TCP_Server_Info *server);
 extern int smb3_calc_signature(struct smb_rqst *rqst,
@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
 extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
                             const u64 persistent_fid, const u64 volatile_fid,
                             const __u8 oplock_level);
+extern int smb2_handle_cancelled_mid(char *buffer,
+                                       struct TCP_Server_Info *server);
+void smb2_cancelled_close_fid(struct work_struct *work);
 extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
                         u64 persistent_file_id, u64 volatile_file_id,
                         struct kstatfs *FSData);
index d4c5b6f109a7feaa6f2c99f21ca332ff41a2673f..69e3b322bbfe630a41b30ae09e309e654b7ee6a0 100644 (file)
@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
 }
 
 static struct cifs_ses *
-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
+smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
 {
        struct cifs_ses *ses;
 
-       spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
-               if (ses->Suid != smb2hdr->SessionId)
+               if (ses->Suid != ses_id)
                        continue;
-               spin_unlock(&cifs_tcp_ses_lock);
                return ses;
        }
+
+       return NULL;
+}
+
+struct cifs_ses *
+smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
+{
+       struct cifs_ses *ses;
+
+       spin_lock(&cifs_tcp_ses_lock);
+       ses = smb2_find_smb_ses_unlocked(server, ses_id);
        spin_unlock(&cifs_tcp_ses_lock);
 
+       return ses;
+}
+
+static struct cifs_tcon *
+smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
+{
+       struct cifs_tcon *tcon;
+
+       list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+               if (tcon->tid != tid)
+                       continue;
+               ++tcon->tc_count;
+               return tcon;
+       }
+
        return NULL;
 }
 
+/*
+ * Obtain tcon corresponding to the tid in the given
+ * cifs_ses
+ */
+
+struct cifs_tcon *
+smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
+{
+       struct cifs_ses *ses;
+       struct cifs_tcon *tcon;
+
+       spin_lock(&cifs_tcp_ses_lock);
+       ses = smb2_find_smb_ses_unlocked(server, ses_id);
+       if (!ses) {
+               spin_unlock(&cifs_tcp_ses_lock);
+               return NULL;
+       }
+       tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
+       spin_unlock(&cifs_tcp_ses_lock);
+
+       return tcon;
+}
 
 int
 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
        struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
        struct cifs_ses *ses;
 
-       ses = smb2_find_smb_ses(smb2_pdu, server);
+       ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
        if (!ses) {
                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
                return 0;
@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
        struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
        struct cifs_ses *ses;
 
-       ses = smb2_find_smb_ses(smb2_pdu, server);
+       ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
        if (!ses) {
                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
                return 0;
index 87abe8ed074c31962a969b178d55757e44bdc0d5..54af10204e83c6c3e6d53515c203b3ecf0f49f1e 100644 (file)
@@ -786,9 +786,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
 
        rc = wait_for_response(ses->server, midQ);
        if (rc != 0) {
+               cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
                send_cancel(ses->server, buf, midQ);
                spin_lock(&GlobalMid_Lock);
                if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
+                       midQ->mid_flags |= MID_WAIT_CANCELLED;
                        midQ->callback = DeleteMidQEntry;
                        spin_unlock(&GlobalMid_Lock);
                        cifs_small_buf_release(buf);
index 1a0835073663ff3f1dad1f376328de5e2b1332ce..9d6c2dcf1bd055fa37db1946f8366d8240703e4b 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/random.h>
 #include <linux/scatterlist.h>
 #include <linux/spinlock_types.h>
+#include <linux/namei.h>
 
 #include "ext4_extents.h"
 #include "xattr.h"
@@ -469,3 +470,61 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
                return size;
        return 0;
 }
+
+/*
+ * Validate dentries for encrypted directories to make sure we aren't
+ * potentially caching stale data after a key has been added or
+ * removed.
+ */
+static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
+{
+       struct dentry *dir;
+       struct ext4_crypt_info *ci;
+       int dir_has_key, cached_with_key;
+
+       if (flags & LOOKUP_RCU)
+               return -ECHILD;
+
+       dir = dget_parent(dentry);
+       if (!ext4_encrypted_inode(d_inode(dir))) {
+               dput(dir);
+               return 0;
+       }
+       ci = EXT4_I(d_inode(dir))->i_crypt_info;
+
+       /* this should eventually be an flag in d_flags */
+       cached_with_key = dentry->d_fsdata != NULL;
+       dir_has_key = (ci != NULL);
+       dput(dir);
+
+       /*
+        * If the dentry was cached without the key, and it is a
+        * negative dentry, it might be a valid name.  We can't check
+        * if the key has since been made available due to locking
+        * reasons, so we fail the validation so ext4_lookup() can do
+        * this check.
+        *
+        * We also fail the validation if the dentry was created with
+        * the key present, but we no longer have the key, or vice versa.
+        */
+       if ((!cached_with_key && d_is_negative(dentry)) ||
+           (!cached_with_key && dir_has_key) ||
+           (cached_with_key && !dir_has_key)) {
+#if 0                          /* Revalidation debug */
+               char buf[80];
+               char *cp = simple_dname(dentry, buf, sizeof(buf));
+
+               if (IS_ERR(cp))
+                       cp = (char *) "???";
+               pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata,
+                      cached_with_key, d_is_negative(dentry),
+                      dir_has_key);
+#endif
+               return 0;
+       }
+       return 1;
+}
+
+const struct dentry_operations ext4_encrypted_d_ops = {
+       .d_revalidate = ext4_d_revalidate,
+};
index 1d1bca74f84437172d96c26e648e6ed45e129725..6d17f31a31d7479cae271f6d043ec9cb475e348e 100644 (file)
@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
        int dir_has_error = 0;
        struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
 
+       if (ext4_encrypted_inode(inode)) {
+               err = ext4_get_encryption_info(inode);
+               if (err && err != -ENOKEY)
+                       return err;
+       }
+
        if (is_dx_dir(inode)) {
                err = ext4_dx_readdir(file, ctx);
                if (err != ERR_BAD_DX_DIR) {
index 362d59b24f1ddf685b8a6178a50952091da972f7..3de9bb357b4f171996731a349658bd00dbc3fc7d 100644 (file)
@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *inode,
                          struct page *plaintext_page);
 int ext4_decrypt(struct page *page);
 int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
+extern const struct dentry_operations ext4_encrypted_d_ops;
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
 int ext4_init_crypto(void);
index 789e2d6724a9deb90b080cd2e16c276357c72942..bcd7c478890387bb2d2360f7e3110dc827f5fe01 100644 (file)
@@ -622,6 +622,9 @@ resizefs_out:
                struct ext4_encryption_policy policy;
                int err = 0;
 
+               if (!ext4_has_feature_encrypt(sb))
+                       return -EOPNOTSUPP;
+
                if (copy_from_user(&policy,
                                   (struct ext4_encryption_policy __user *)arg,
                                   sizeof(policy))) {
index 573b4cbb0cb991e1c60dd12d88d7c3c05d9a0120..fafa903ab3c0f2a8b32816b44408225f173a08e7 100644 (file)
@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
        struct ext4_dir_entry_2 *de;
        struct buffer_head *bh;
 
+       if (ext4_encrypted_inode(dir)) {
+               int res = ext4_get_encryption_info(dir);
+
+               /*
+                * This should be a properly defined flag for
+                * dentry->d_flags when we uplift this to the VFS.
+                * d_fsdata is set to (void *) 1 if if the dentry is
+                * created while the directory was encrypted and we
+                * don't have access to the key.
+                */
+              dentry->d_fsdata = NULL;
+              if (ext4_encryption_info(dir))
+                      dentry->d_fsdata = (void *) 1;
+              d_set_d_op(dentry, &ext4_encrypted_d_ops);
+              if (res && res != -ENOKEY)
+                      return ERR_PTR(res);
+       }
+
        if (dentry->d_name.len > EXT4_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
index 16462e702f964694fb7ff57281985dd8f34de360..86e1cb8999577bb28100e1219a2a10d1004e898e 100644 (file)
@@ -1059,6 +1059,13 @@ static int sanity_check_raw_super(struct super_block *sb,
                return 1;
        }
 
+       if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
+               f2fs_msg(sb, KERN_INFO,
+                       "Invalid segment count (%u)",
+                       le32_to_cpu(raw_super->segment_count));
+               return 1;
+       }
+
        /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
        if (sanity_check_area_boundary(sb, raw_super))
                return 1;
index 00575d776d91f58576523d1fc30e558585a91ace..7162ab7bc093e923fc415745684bd1446d728442 100644 (file)
@@ -358,6 +358,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
 {
        unsigned int len, v, hdr, dlen;
        u32 max_blocksize = svc_max_payload(rqstp);
+       struct kvec *head = rqstp->rq_arg.head;
 
        p = decode_fh(p, &args->fh);
        if (!p)
@@ -367,6 +368,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
        args->count = ntohl(*p++);
        args->stable = ntohl(*p++);
        len = args->len = ntohl(*p++);
+       if ((void *)p > head->iov_base + head->iov_len)
+               return 0;
        /*
         * The count must equal the amount of data passed.
         */
@@ -377,9 +380,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
         * Check to make sure that we got the right number of
         * bytes.
         */
-       hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
-       dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
-               - hdr;
+       hdr = (void*)p - head->iov_base;
+       dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
        /*
         * Round the length of the data which was specified up to
         * the next multiple of XDR units and then compare that
@@ -396,7 +398,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
                len = args->len = max_blocksize;
        }
        rqstp->rq_vec[0].iov_base = (void*)p;
-       rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
+       rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
        v = 0;
        while (len > rqstp->rq_vec[v].iov_len) {
                len -= rqstp->rq_vec[v].iov_len;
@@ -471,6 +473,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
        /* first copy and check from the first page */
        old = (char*)p;
        vec = &rqstp->rq_arg.head[0];
+       if ((void *)old > vec->iov_base + vec->iov_len)
+               return 0;
        avail = vec->iov_len - (old - (char*)vec->iov_base);
        while (len && avail && *old) {
                *new++ = *old++;
index 79d964aa8079f354fcadf50ac2a1d3d216668d4a..bf913201a6ad1cc963a06b6f245419a6389d1367 100644 (file)
@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_writeargs *args)
 {
        unsigned int len, hdr, dlen;
+       struct kvec *head = rqstp->rq_arg.head;
        int v;
 
        p = decode_fh(p, &args->fh);
@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
         * Check to make sure that we got the right number of
         * bytes.
         */
-       hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
-       dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
-               - hdr;
+       hdr = (void*)p - head->iov_base;
+       if (hdr > head->iov_len)
+               return 0;
+       dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
 
        /*
         * Round the length of the data which was specified up to
@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
                return 0;
 
        rqstp->rq_vec[0].iov_base = (void*)p;
-       rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
+       rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
        v = 0;
        while (len > rqstp->rq_vec[v].iov_len) {
                len -= rqstp->rq_vec[v].iov_len;
index 053818dd6c18be8f228e1c40483e50d78aa78007..1327a02ec77845f792aaac2649eb65ab3f0dc439 100644 (file)
@@ -40,6 +40,7 @@ struct timerfd_ctx {
        short unsigned settime_flags;   /* to show in fdinfo */
        struct rcu_head rcu;
        struct list_head clist;
+       spinlock_t cancel_lock;
        bool might_cancel;
 };
 
@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void)
        rcu_read_unlock();
 }
 
-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
 {
        if (ctx->might_cancel) {
                ctx->might_cancel = false;
@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
        }
 }
 
+static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+{
+       spin_lock(&ctx->cancel_lock);
+       __timerfd_remove_cancel(ctx);
+       spin_unlock(&ctx->cancel_lock);
+}
+
 static bool timerfd_canceled(struct timerfd_ctx *ctx)
 {
        if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx)
 
 static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
 {
+       spin_lock(&ctx->cancel_lock);
        if ((ctx->clockid == CLOCK_REALTIME ||
             ctx->clockid == CLOCK_REALTIME_ALARM) &&
            (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
                        list_add_rcu(&ctx->clist, &cancel_list);
                        spin_unlock(&cancel_lock);
                }
-       } else if (ctx->might_cancel) {
-               timerfd_remove_cancel(ctx);
+       } else {
+               __timerfd_remove_cancel(ctx);
        }
+       spin_unlock(&ctx->cancel_lock);
 }
 
 static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
                return -ENOMEM;
 
        init_waitqueue_head(&ctx->wqh);
+       spin_lock_init(&ctx->cancel_lock);
        ctx->clockid = clockid;
 
        if (isalarm(ctx))
index 25c6324a0dd04a9be333fcd22e9b4ffdda9c0796..3d6e6ce44c5ce8ab684174f046514f3a00b56424 100644 (file)
@@ -283,6 +283,12 @@ struct f2fs_nat_block {
 #define SIT_VBLOCK_MAP_SIZE 64
 #define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry))
 
+/*
+ * F2FS uses 4 bytes to represent block address. As a result, supported size of
+ * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
+ */
+#define F2FS_MAX_SEGMENT       ((16 * 1024 * 1024) / 2)
+
 /*
  * Note that f2fs_sit_entry->vblocks has the following bit-field information.
  * [15:10] : allocation type such as CURSEG_XXXX_TYPE
index 847cc1d916348386379c510ee38433e42d4b93d2..5012fcdb4c9edd24072892c6e33aa1e8c51d171e 100644 (file)
@@ -742,11 +742,9 @@ static inline void part_nr_sects_write(struct hd_struct *part, sector_t size)
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
 extern void blk_integrity_add(struct gendisk *);
 extern void blk_integrity_del(struct gendisk *);
-extern void blk_integrity_revalidate(struct gendisk *);
 #else  /* CONFIG_BLK_DEV_INTEGRITY */
 static inline void blk_integrity_add(struct gendisk *disk) { }
 static inline void blk_integrity_del(struct gendisk *disk) { }
-static inline void blk_integrity_revalidate(struct gendisk *disk) { }
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
 
 #else /* CONFIG_BLOCK */
index 366cf77953b55bc737fcded0179df083138b3dbf..806d0ab845e0f5e5dbdc6a9df16037df5a5ccd3c 100644 (file)
 #endif
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
-# ifdef map_bankwidth
-#  undef map_bankwidth
-#  define map_bankwidth(map) ((map)->bankwidth)
-#  undef map_bankwidth_is_large
-#  define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
-#  undef map_words
-#  define map_words(map) map_calc_words(map)
-# else
-#  define map_bankwidth(map) 32
-#  define map_bankwidth_is_large(map) (1)
-#  define map_words(map) map_calc_words(map)
-# endif
+/* always use indirect access for 256-bit to preserve kernel stack */
+# undef map_bankwidth
+# define map_bankwidth(map) ((map)->bankwidth)
+# undef map_bankwidth_is_large
+# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
+# undef map_words
+# define map_words(map) map_calc_words(map)
 #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
 #undef MAX_MAP_BANKWIDTH
 #define MAX_MAP_BANKWIDTH 32
index 5dd75fa47dd823fbfd2c58ae19d65bb27ee120e1..f9be467d669531733b4889311029ac8d251a327e 100644 (file)
@@ -14,6 +14,7 @@ struct ci_hdrc;
  * struct ci_hdrc_cable - structure for external connector cable state tracking
  * @state: current state of the line
  * @changed: set to true when extcon event happen
+ * @enabled: set to true if we've enabled the vbus or id interrupt
  * @edev: device which generate events
  * @ci: driver state of the chipidea device
  * @nb: hold event notification callback
@@ -22,6 +23,7 @@ struct ci_hdrc;
 struct ci_hdrc_cable {
        bool                            state;
        bool                            changed;
+       bool                            enabled;
        struct extcon_dev               *edev;
        struct ci_hdrc                  *ci;
        struct notifier_block           nb;
index 78003dfb8539bd42f75f8c2d04cbb7dce872e1bf..18dd7a3caf2ffd4b296e67a9255ce91ddb82b631 100644 (file)
@@ -19,6 +19,8 @@
 #define ADDRCONF_TIMER_FUZZ            (HZ / 4)
 #define ADDRCONF_TIMER_FUZZ_MAX                (HZ)
 
+#define ADDRCONF_NOTIFY_PRIORITY       0
+
 #include <linux/in.h>
 #include <linux/in6.h>
 
index 295d291269e2c88ed4930041597a28f7c9a7a2f7..6275d651f76e7c4e126327b3d400cae003c2c4f2 100644 (file)
@@ -77,6 +77,7 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
 struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
                                   int flags);
 
+void ip6_route_init_special_entries(void);
 int ip6_route_init(void);
 void ip6_route_cleanup(void);
 
index 10cd1860e5b04aa339853ff893855941aba41600..7e26aea3e4040aa321be6eef93d2f3c098e036d2 100644 (file)
@@ -4315,6 +4315,51 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 1 } },
        },
+       {
+               /* Mainly testing JIT + imm64 here. */
+               "JMP_JGE_X: ldimm64 test 1",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_LD_IMM64(R1, 3),
+                       BPF_LD_IMM64(R2, 2),
+                       BPF_JMP_REG(BPF_JGE, R1, R2, 2),
+                       BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
+                       BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xeeeeeeeeU } },
+       },
+       {
+               "JMP_JGE_X: ldimm64 test 2",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_LD_IMM64(R1, 3),
+                       BPF_LD_IMM64(R2, 2),
+                       BPF_JMP_REG(BPF_JGE, R1, R2, 0),
+                       BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0xffffffffU } },
+       },
+       {
+               "JMP_JGE_X: ldimm64 test 3",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_LD_IMM64(R1, 3),
+                       BPF_LD_IMM64(R2, 2),
+                       BPF_JMP_REG(BPF_JGE, R1, R2, 4),
+                       BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
+                       BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        /* BPF_JMP | BPF_JNE | BPF_X */
        {
                "JMP_JNE_X: if (3 != 2) return 1",
index b94e165a4f7911a5591c39380bba5b7c6a4bda57..fe38ef58997c203ba0954f58f1574c7d6de7b35b 100644 (file)
@@ -1018,7 +1018,7 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
                return err;
        }
 
-       if (nla_put(skb, IFLA_PHYS_PORT_NAME, strlen(name), name))
+       if (nla_put_string(skb, IFLA_PHYS_PORT_NAME, name))
                return -EMSGSIZE;
 
        return 0;
index 7113bae4e6a0c02726e0e11c33415b6779b7d04b..8f2cd7d0972096baa344b5ec508a2a2d914b8ca9 100644 (file)
@@ -354,6 +354,9 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
                               rt->dst.dev->mtu);
                return -EMSGSIZE;
        }
+       if (length < sizeof(struct iphdr))
+               return -EINVAL;
+
        if (flags&MSG_PROBE)
                goto out;
 
index 1e70fa8fa793fdbca3ca782231f8b775ed96f205..3861dedd536503a37031fc8d251e43fe610ef81b 100644 (file)
@@ -264,13 +264,15 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct lp *lp = inet_csk_ca(sk);
+       u32 delta;
 
        if (rtt_us > 0)
                tcp_lp_rtt_sample(sk, rtt_us);
 
        /* calc inference */
-       if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
-               lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
+       delta = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+       if ((s32)delta > 0)
+               lp->inference = 3 * delta;
 
        /* test if within inference */
        if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
index 019db68bdb9f517d14d839ef4b042d6d5be93d6e..4c1c94fa8f087514bf8dcc92eea15a9e8ed5cf78 100644 (file)
@@ -547,6 +547,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
                        newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len;
                newtp->rx_opt.mss_clamp = req->mss;
                tcp_ecn_openreq_child(newtp, req);
+               newtp->fastopen_req = NULL;
                newtp->fastopen_rsk = NULL;
                newtp->syn_data_acked = 0;
                newtp->rack.mstamp.v64 = 0;
index de95714d021c35e93f8ed52b7c96779e6e40cf6e..3fdcdc730f719bc7ea779ad659887d6923c97400 100644 (file)
@@ -1221,7 +1221,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
  * eventually). The difference is that pulled data not copied, but
  * immediately discarded.
  */
-static void __pskb_trim_head(struct sk_buff *skb, int len)
+static int __pskb_trim_head(struct sk_buff *skb, int len)
 {
        struct skb_shared_info *shinfo;
        int i, k, eat;
@@ -1231,7 +1231,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
                __skb_pull(skb, eat);
                len -= eat;
                if (!len)
-                       return;
+                       return 0;
        }
        eat = len;
        k = 0;
@@ -1257,23 +1257,28 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
        skb_reset_tail_pointer(skb);
        skb->data_len -= len;
        skb->len = skb->data_len;
+       return len;
 }
 
 /* Remove acked data from a packet in the transmit queue. */
 int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
 {
+       u32 delta_truesize;
+
        if (skb_unclone(skb, GFP_ATOMIC))
                return -ENOMEM;
 
-       __pskb_trim_head(skb, len);
+       delta_truesize = __pskb_trim_head(skb, len);
 
        TCP_SKB_CB(skb)->seq += len;
        skb->ip_summed = CHECKSUM_PARTIAL;
 
-       skb->truesize        -= len;
-       sk->sk_wmem_queued   -= len;
-       sk_mem_uncharge(sk, len);
-       sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
+       if (delta_truesize) {
+               skb->truesize      -= delta_truesize;
+               sk->sk_wmem_queued -= delta_truesize;
+               sk_mem_uncharge(sk, delta_truesize);
+               sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
+       }
 
        /* Any change of skb->len requires recalculation of tso factor. */
        if (tcp_skb_pcount(skb) > 1)
index 253186a3556730b5b22df84fe1645123feee9672..7090fef372cca1c261652fd4bc1104f03e37831e 100644 (file)
@@ -3306,6 +3306,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
  */
 static struct notifier_block ipv6_dev_notf = {
        .notifier_call = addrconf_notify,
+       .priority = ADDRCONF_NOTIFY_PRIORITY,
 };
 
 static void addrconf_type_change(struct net_device *dev, unsigned long event)
@@ -5940,6 +5941,8 @@ int __init addrconf_init(void)
                goto errlo;
        }
 
+       ip6_route_init_special_entries();
+
        for (i = 0; i < IN6_ADDR_HSIZE; i++)
                INIT_HLIST_HEAD(&inet6_addr_lst[i]);
 
index a625f69a28ddd9c8c193f3a35fbef9e065aafae7..c93ede16795d91ffd8e23802e1aa77602269b432 100644 (file)
@@ -630,6 +630,8 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
                ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
                return -EMSGSIZE;
        }
+       if (length < sizeof(struct ipv6hdr))
+               return -EINVAL;
        if (flags&MSG_PROBE)
                goto out;
 
index 6c91d5c4a92cec77588758d209c4b4a39625578a..8f4177a1d4f53280f0ff8177d5d8f61f238bb00e 100644 (file)
@@ -3363,7 +3363,10 @@ static int ip6_route_dev_notify(struct notifier_block *this,
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        struct net *net = dev_net(dev);
 
-       if (event == NETDEV_REGISTER && (dev->flags & IFF_LOOPBACK)) {
+       if (!(dev->flags & IFF_LOOPBACK))
+               return NOTIFY_OK;
+
+       if (event == NETDEV_REGISTER) {
                net->ipv6.ip6_null_entry->dst.dev = dev;
                net->ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(dev);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -3371,6 +3374,12 @@ static int ip6_route_dev_notify(struct notifier_block *this,
                net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
                net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
                net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
+#endif
+        } else if (event == NETDEV_UNREGISTER) {
+               in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+               in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev);
+               in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev);
 #endif
        }
 
@@ -3678,9 +3687,24 @@ static struct pernet_operations ip6_route_net_late_ops = {
 
 static struct notifier_block ip6_route_dev_notifier = {
        .notifier_call = ip6_route_dev_notify,
-       .priority = 0,
+       .priority = ADDRCONF_NOTIFY_PRIORITY - 10,
 };
 
+void __init ip6_route_init_special_entries(void)
+{
+       /* Registering of the loopback is done before this portion of code,
+        * the loopback reference in rt6_info will not be taken, do it
+        * manually for init_net */
+       init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
+       init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+       init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
+       init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+       init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
+       init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+  #endif
+}
+
 int __init ip6_route_init(void)
 {
        int ret;
@@ -3707,17 +3731,6 @@ int __init ip6_route_init(void)
 
        ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
 
-       /* Registering of the loopback is done before this portion of code,
-        * the loopback reference in rt6_info will not be taken, do it
-        * manually for init_net */
-       init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
-       init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
-       init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
-       init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-       init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
-       init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
-  #endif
        ret = fib6_init();
        if (ret)
                goto out_register_subsys;
index 8e33019d8e7bacbf37c6bb649c5fc3f08f38f1ab..acfb16fdcd5538c46397459dbf9e1d17a5d77f4a 100644 (file)
@@ -2107,7 +2107,7 @@ static int netlink_dump(struct sock *sk)
        if (!skb) {
                alloc_size = alloc_min_size;
                skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
-                                       (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM));
+                                       GFP_KERNEL);
        }
        if (!skb)
                goto errout_skb;
index 8f3e5e9d8bdb8fe4d57efe53de5b2c6b0accca1e..e6de496bffbeb29c193989dd24f82bfa9bd1b7b5 100644 (file)
@@ -2166,7 +2166,20 @@ static void azx_remove(struct pci_dev *pci)
                /* cancel the pending probing work */
                chip = card->private_data;
                hda = container_of(chip, struct hda_intel, chip);
+               /* FIXME: below is an ugly workaround.
+                * Both device_release_driver() and driver_probe_device()
+                * take *both* the device's and its parent's lock before
+                * calling the remove() and probe() callbacks.  The codec
+                * probe takes the locks of both the codec itself and its
+                * parent, i.e. the PCI controller dev.  Meanwhile, when
+                * the PCI controller is unbound, it takes its lock, too
+                * ==> ouch, a deadlock!
+                * As a workaround, we unlock temporarily here the controller
+                * device during cancel_work_sync() call.
+                */
+               device_unlock(&pci->dev);
                cancel_work_sync(&hda->probe_work);
+               device_lock(&pci->dev);
 
                snd_card_free(card);
        }
index 09da7b52bc2e6deba601d876a9578cfbb485b768..1468e4b7bf934fac19e04bd6b0aef6b5536e0589 100644 (file)
@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
                if (err < 0)
                        return err;
        }
+       master_vol = NULL;
        if (pm7500)
                err = build_mixers(chip,
                                   ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
index 7a5c9a36c1db670081c70480e71e6d6b2a3ef538..daba8c56b43bcd0d9f6b63dc631db6704ba4131c 100644 (file)
@@ -139,7 +139,7 @@ static struct snd_soc_dai_link byt_dailink[] = {
                .codec_dai_name = "snd-soc-dummy-dai",
                .codec_name = "snd-soc-dummy",
                .platform_name = "sst-mfld-platform",
-               .ignore_suspend = 1,
+               .nonatomic = true,
                .dynamic = 1,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
@@ -166,6 +166,7 @@ static struct snd_soc_dai_link byt_dailink[] = {
                                                | SND_SOC_DAIFMT_CBS_CFS,
                .be_hw_params_fixup = byt_codec_fixup,
                .ignore_suspend = 1,
+               .nonatomic = true,
                .dpcm_playback = 1,
                .dpcm_capture = 1,
                .ops = &byt_be_ssp2_ops,
index 93b0aa74ca03bada7db24ae827b902ce09591bef..39c2c7d067bba55cae5cf19983128369af1bb81c 100644 (file)
@@ -156,6 +156,7 @@ out:
                                         */
                        case 0x2C:      /* Westmere EP - Gulftown */
                                cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
+                               break;
                        case 0x2A:      /* SNB */
                        case 0x2D:      /* SNB Xeon */
                        case 0x3A:      /* IVB */