diff options
124 files changed, 868 insertions, 567 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5678de36d9b3..8a0cbf3cf2c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4476,6 +4476,13 @@ L: linux-serial@vger.kernel.org | |||
| 4476 | S: Maintained | 4476 | S: Maintained |
| 4477 | F: drivers/tty/serial/ioc3_serial.c | 4477 | F: drivers/tty/serial/ioc3_serial.c |
| 4478 | 4478 | ||
| 4479 | IOMMU DRIVERS | ||
| 4480 | M: Joerg Roedel <joro@8bytes.org> | ||
| 4481 | L: iommu@lists.linux-foundation.org | ||
| 4482 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | ||
| 4483 | S: Maintained | ||
| 4484 | F: drivers/iommu/ | ||
| 4485 | |||
| 4479 | IP MASQUERADING | 4486 | IP MASQUERADING |
| 4480 | M: Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar> | 4487 | M: Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar> |
| 4481 | S: Maintained | 4488 | S: Maintained |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 3 | 1 | VERSION = 3 |
| 2 | PATCHLEVEL = 12 | 2 | PATCHLEVEL = 12 |
| 3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
| 4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc4 |
| 5 | NAME = One Giant Leap for Frogkind | 5 | NAME = One Giant Leap for Frogkind |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 1a6bfe954d49..835c559786bd 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug | |||
| @@ -6,13 +6,6 @@ config FRAME_POINTER | |||
| 6 | bool | 6 | bool |
| 7 | default y | 7 | default y |
| 8 | 8 | ||
| 9 | config DEBUG_STACK_USAGE | ||
| 10 | bool "Enable stack utilization instrumentation" | ||
| 11 | depends on DEBUG_KERNEL | ||
| 12 | help | ||
| 13 | Enables the display of the minimum amount of free stack which each | ||
| 14 | task has ever had available in the sysrq-T output. | ||
| 15 | |||
| 16 | config EARLY_PRINTK | 9 | config EARLY_PRINTK |
| 17 | bool "Early printk support" | 10 | bool "Early printk support" |
| 18 | default y | 11 | default y |
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 5b3e83217b03..31c81e9b792e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
| @@ -42,7 +42,7 @@ CONFIG_IP_PNP_BOOTP=y | |||
| 42 | # CONFIG_WIRELESS is not set | 42 | # CONFIG_WIRELESS is not set |
| 43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 44 | CONFIG_DEVTMPFS=y | 44 | CONFIG_DEVTMPFS=y |
| 45 | # CONFIG_BLK_DEV is not set | 45 | CONFIG_BLK_DEV=y |
| 46 | CONFIG_SCSI=y | 46 | CONFIG_SCSI=y |
| 47 | # CONFIG_SCSI_PROC_FS is not set | 47 | # CONFIG_SCSI_PROC_FS is not set |
| 48 | CONFIG_BLK_DEV_SD=y | 48 | CONFIG_BLK_DEV_SD=y |
| @@ -72,6 +72,7 @@ CONFIG_LOGO=y | |||
| 72 | # CONFIG_IOMMU_SUPPORT is not set | 72 | # CONFIG_IOMMU_SUPPORT is not set |
| 73 | CONFIG_EXT2_FS=y | 73 | CONFIG_EXT2_FS=y |
| 74 | CONFIG_EXT3_FS=y | 74 | CONFIG_EXT3_FS=y |
| 75 | CONFIG_EXT4_FS=y | ||
| 75 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 76 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 76 | # CONFIG_EXT3_FS_XATTR is not set | 77 | # CONFIG_EXT3_FS_XATTR is not set |
| 77 | CONFIG_FUSE_FS=y | 78 | CONFIG_FUSE_FS=y |
| @@ -90,3 +91,5 @@ CONFIG_DEBUG_KERNEL=y | |||
| 90 | CONFIG_DEBUG_INFO=y | 91 | CONFIG_DEBUG_INFO=y |
| 91 | # CONFIG_FTRACE is not set | 92 | # CONFIG_FTRACE is not set |
| 92 | CONFIG_ATOMIC64_SELFTEST=y | 93 | CONFIG_ATOMIC64_SELFTEST=y |
| 94 | CONFIG_VIRTIO_MMIO=y | ||
| 95 | CONFIG_VIRTIO_BLK=y | ||
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index edb3d5c73a32..7ecc2b23882e 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h | |||
| @@ -166,9 +166,10 @@ do { \ | |||
| 166 | 166 | ||
| 167 | #define get_user(x, ptr) \ | 167 | #define get_user(x, ptr) \ |
| 168 | ({ \ | 168 | ({ \ |
| 169 | __typeof__(*(ptr)) __user *__p = (ptr); \ | ||
| 169 | might_fault(); \ | 170 | might_fault(); \ |
| 170 | access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ? \ | 171 | access_ok(VERIFY_READ, __p, sizeof(*__p)) ? \ |
| 171 | __get_user((x), (ptr)) : \ | 172 | __get_user((x), __p) : \ |
| 172 | ((x) = 0, -EFAULT); \ | 173 | ((x) = 0, -EFAULT); \ |
| 173 | }) | 174 | }) |
| 174 | 175 | ||
| @@ -227,9 +228,10 @@ do { \ | |||
| 227 | 228 | ||
| 228 | #define put_user(x, ptr) \ | 229 | #define put_user(x, ptr) \ |
| 229 | ({ \ | 230 | ({ \ |
| 231 | __typeof__(*(ptr)) __user *__p = (ptr); \ | ||
| 230 | might_fault(); \ | 232 | might_fault(); \ |
| 231 | access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ? \ | 233 | access_ok(VERIFY_WRITE, __p, sizeof(*__p)) ? \ |
| 232 | __put_user((x), (ptr)) : \ | 234 | __put_user((x), __p) : \ |
| 233 | -EFAULT; \ | 235 | -EFAULT; \ |
| 234 | }) | 236 | }) |
| 235 | 237 | ||
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 1f2e4d5a5c0f..bb785d23dbde 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c | |||
| @@ -80,8 +80,10 @@ void fpsimd_thread_switch(struct task_struct *next) | |||
| 80 | 80 | ||
| 81 | void fpsimd_flush_thread(void) | 81 | void fpsimd_flush_thread(void) |
| 82 | { | 82 | { |
| 83 | preempt_disable(); | ||
| 83 | memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); | 84 | memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); |
| 84 | fpsimd_load_state(¤t->thread.fpsimd_state); | 85 | fpsimd_load_state(¤t->thread.fpsimd_state); |
| 86 | preempt_enable(); | ||
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | #ifdef CONFIG_KERNEL_MODE_NEON | 89 | #ifdef CONFIG_KERNEL_MODE_NEON |
diff --git a/arch/arm64/mm/tlb.S b/arch/arm64/mm/tlb.S index 8ae80a18e8ec..19da91e0cd27 100644 --- a/arch/arm64/mm/tlb.S +++ b/arch/arm64/mm/tlb.S | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | */ | 35 | */ |
| 36 | ENTRY(__cpu_flush_user_tlb_range) | 36 | ENTRY(__cpu_flush_user_tlb_range) |
| 37 | vma_vm_mm x3, x2 // get vma->vm_mm | 37 | vma_vm_mm x3, x2 // get vma->vm_mm |
| 38 | mmid x3, x3 // get vm_mm->context.id | 38 | mmid w3, x3 // get vm_mm->context.id |
| 39 | dsb sy | 39 | dsb sy |
| 40 | lsr x0, x0, #12 // align address | 40 | lsr x0, x0, #12 // align address |
| 41 | lsr x1, x1, #12 | 41 | lsr x1, x1, #12 |
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 4a9baa9f6330..9969dbab19e3 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c | |||
| @@ -276,7 +276,7 @@ static struct platform_device mtx1_pci_host = { | |||
| 276 | .resource = alchemy_pci_host_res, | 276 | .resource = alchemy_pci_host_res, |
| 277 | }; | 277 | }; |
| 278 | 278 | ||
| 279 | static struct __initdata platform_device * mtx1_devs[] = { | 279 | static struct platform_device *mtx1_devs[] __initdata = { |
| 280 | &mtx1_pci_host, | 280 | &mtx1_pci_host, |
| 281 | &mtx1_gpio_leds, | 281 | &mtx1_gpio_leds, |
| 282 | &mtx1_wdt, | 282 | &mtx1_wdt, |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 627883bc6d5f..bc6f96fcb529 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
| @@ -609,6 +609,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
| 609 | r4k_blast_scache(); | 609 | r4k_blast_scache(); |
| 610 | else | 610 | else |
| 611 | blast_scache_range(addr, addr + size); | 611 | blast_scache_range(addr, addr + size); |
| 612 | preempt_enable(); | ||
| 612 | __sync(); | 613 | __sync(); |
| 613 | return; | 614 | return; |
| 614 | } | 615 | } |
| @@ -650,6 +651,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
| 650 | */ | 651 | */ |
| 651 | blast_inv_scache_range(addr, addr + size); | 652 | blast_inv_scache_range(addr, addr + size); |
| 652 | } | 653 | } |
| 654 | preempt_enable(); | ||
| 653 | __sync(); | 655 | __sync(); |
| 654 | return; | 656 | return; |
| 655 | } | 657 | } |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 57d286a78f86..c7cb8c232d2f 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -495,14 +495,15 @@ void __do_irq(struct pt_regs *regs) | |||
| 495 | void do_IRQ(struct pt_regs *regs) | 495 | void do_IRQ(struct pt_regs *regs) |
| 496 | { | 496 | { |
| 497 | struct pt_regs *old_regs = set_irq_regs(regs); | 497 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 498 | struct thread_info *curtp, *irqtp; | 498 | struct thread_info *curtp, *irqtp, *sirqtp; |
| 499 | 499 | ||
| 500 | /* Switch to the irq stack to handle this */ | 500 | /* Switch to the irq stack to handle this */ |
| 501 | curtp = current_thread_info(); | 501 | curtp = current_thread_info(); |
| 502 | irqtp = hardirq_ctx[raw_smp_processor_id()]; | 502 | irqtp = hardirq_ctx[raw_smp_processor_id()]; |
| 503 | sirqtp = softirq_ctx[raw_smp_processor_id()]; | ||
| 503 | 504 | ||
| 504 | /* Already there ? */ | 505 | /* Already there ? */ |
| 505 | if (unlikely(curtp == irqtp)) { | 506 | if (unlikely(curtp == irqtp || curtp == sirqtp)) { |
| 506 | __do_irq(regs); | 507 | __do_irq(regs); |
| 507 | set_irq_regs(old_regs); | 508 | set_irq_regs(old_regs); |
| 508 | return; | 509 | return; |
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index c84f33d51f7b..7dd21720e5b0 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c | |||
| @@ -40,28 +40,26 @@ static inline void *load_real_addr(void *addr) | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| 43 | * Copy up to one page to vmalloc or real memory | 43 | * Copy real to virtual or real memory |
| 44 | */ | 44 | */ |
| 45 | static ssize_t copy_page_real(void *buf, void *src, size_t csize) | 45 | static int copy_from_realmem(void *dest, void *src, size_t count) |
| 46 | { | 46 | { |
| 47 | size_t size; | 47 | unsigned long size; |
| 48 | int rc; | ||
| 48 | 49 | ||
| 49 | if (is_vmalloc_addr(buf)) { | 50 | if (!count) |
| 50 | BUG_ON(csize >= PAGE_SIZE); | 51 | return 0; |
| 51 | /* If buf is not page aligned, copy first part */ | 52 | if (!is_vmalloc_or_module_addr(dest)) |
| 52 | size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize); | 53 | return memcpy_real(dest, src, count); |
| 53 | if (size) { | 54 | do { |
| 54 | if (memcpy_real(load_real_addr(buf), src, size)) | 55 | size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK)); |
| 55 | return -EFAULT; | 56 | if (memcpy_real(load_real_addr(dest), src, size)) |
| 56 | buf += size; | 57 | return -EFAULT; |
| 57 | src += size; | 58 | count -= size; |
| 58 | } | 59 | dest += size; |
| 59 | /* Copy second part */ | 60 | src += size; |
| 60 | size = csize - size; | 61 | } while (count); |
| 61 | return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0; | 62 | return 0; |
| 62 | } else { | ||
| 63 | return memcpy_real(buf, src, csize); | ||
| 64 | } | ||
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | /* | 65 | /* |
| @@ -114,7 +112,7 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, | |||
| 114 | rc = copy_to_user_real((void __force __user *) buf, | 112 | rc = copy_to_user_real((void __force __user *) buf, |
| 115 | (void *) src, csize); | 113 | (void *) src, csize); |
| 116 | else | 114 | else |
| 117 | rc = copy_page_real(buf, (void *) src, csize); | 115 | rc = copy_from_realmem(buf, (void *) src, csize); |
| 118 | return (rc == 0) ? rc : csize; | 116 | return (rc == 0) ? rc : csize; |
| 119 | } | 117 | } |
| 120 | 118 | ||
| @@ -210,7 +208,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count) | |||
| 210 | if (OLDMEM_BASE) { | 208 | if (OLDMEM_BASE) { |
| 211 | if ((unsigned long) src < OLDMEM_SIZE) { | 209 | if ((unsigned long) src < OLDMEM_SIZE) { |
| 212 | copied = min(count, OLDMEM_SIZE - (unsigned long) src); | 210 | copied = min(count, OLDMEM_SIZE - (unsigned long) src); |
| 213 | rc = memcpy_real(dest, src + OLDMEM_BASE, copied); | 211 | rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied); |
| 214 | if (rc) | 212 | if (rc) |
| 215 | return rc; | 213 | return rc; |
| 216 | } | 214 | } |
| @@ -223,7 +221,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count) | |||
| 223 | return rc; | 221 | return rc; |
| 224 | } | 222 | } |
| 225 | } | 223 | } |
| 226 | return memcpy_real(dest + copied, src + copied, count - copied); | 224 | return copy_from_realmem(dest + copied, src + copied, count - copied); |
| 227 | } | 225 | } |
| 228 | 226 | ||
| 229 | /* | 227 | /* |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index cc30d1fb000c..0dc2b6d0a1ec 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -266,6 +266,7 @@ sysc_sigpending: | |||
| 266 | tm __TI_flags+3(%r12),_TIF_SYSCALL | 266 | tm __TI_flags+3(%r12),_TIF_SYSCALL |
| 267 | jno sysc_return | 267 | jno sysc_return |
| 268 | lm %r2,%r7,__PT_R2(%r11) # load svc arguments | 268 | lm %r2,%r7,__PT_R2(%r11) # load svc arguments |
| 269 | l %r10,__TI_sysc_table(%r12) # 31 bit system call table | ||
| 269 | xr %r8,%r8 # svc 0 returns -ENOSYS | 270 | xr %r8,%r8 # svc 0 returns -ENOSYS |
| 270 | clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2) | 271 | clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2) |
| 271 | jnl sysc_nr_ok # invalid svc number -> do svc 0 | 272 | jnl sysc_nr_ok # invalid svc number -> do svc 0 |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 2b2188b97c6a..e5b43c97a834 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -297,6 +297,7 @@ sysc_sigpending: | |||
| 297 | tm __TI_flags+7(%r12),_TIF_SYSCALL | 297 | tm __TI_flags+7(%r12),_TIF_SYSCALL |
| 298 | jno sysc_return | 298 | jno sysc_return |
| 299 | lmg %r2,%r7,__PT_R2(%r11) # load svc arguments | 299 | lmg %r2,%r7,__PT_R2(%r11) # load svc arguments |
| 300 | lg %r10,__TI_sysc_table(%r12) # address of system call table | ||
| 300 | lghi %r8,0 # svc 0 returns -ENOSYS | 301 | lghi %r8,0 # svc 0 returns -ENOSYS |
| 301 | llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number | 302 | llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number |
| 302 | cghi %r1,NR_syscalls | 303 | cghi %r1,NR_syscalls |
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 0ce9fb245034..d86e64eddb42 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
| @@ -67,6 +67,11 @@ static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn) | |||
| 67 | case 0xac: /* stnsm */ | 67 | case 0xac: /* stnsm */ |
| 68 | case 0xad: /* stosm */ | 68 | case 0xad: /* stosm */ |
| 69 | return -EINVAL; | 69 | return -EINVAL; |
| 70 | case 0xc6: | ||
| 71 | switch (insn[0] & 0x0f) { | ||
| 72 | case 0x00: /* exrl */ | ||
| 73 | return -EINVAL; | ||
| 74 | } | ||
| 70 | } | 75 | } |
| 71 | switch (insn[0]) { | 76 | switch (insn[0]) { |
| 72 | case 0x0101: /* pr */ | 77 | case 0x0101: /* pr */ |
| @@ -180,7 +185,6 @@ static int __kprobes is_insn_relative_long(kprobe_opcode_t *insn) | |||
| 180 | break; | 185 | break; |
| 181 | case 0xc6: | 186 | case 0xc6: |
| 182 | switch (insn[0] & 0x0f) { | 187 | switch (insn[0] & 0x0f) { |
| 183 | case 0x00: /* exrl */ | ||
| 184 | case 0x02: /* pfdrl */ | 188 | case 0x02: /* pfdrl */ |
| 185 | case 0x04: /* cghrl */ | 189 | case 0x04: /* cghrl */ |
| 186 | case 0x05: /* chrl */ | 190 | case 0x05: /* chrl */ |
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index d385eaadece7..709798460763 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h | |||
| @@ -166,7 +166,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int o, int n) | |||
| 166 | * | 166 | * |
| 167 | * Atomically sets @v to @i and returns old @v | 167 | * Atomically sets @v to @i and returns old @v |
| 168 | */ | 168 | */ |
| 169 | static inline u64 atomic64_xchg(atomic64_t *v, u64 n) | 169 | static inline long long atomic64_xchg(atomic64_t *v, long long n) |
| 170 | { | 170 | { |
| 171 | return xchg64(&v->counter, n); | 171 | return xchg64(&v->counter, n); |
| 172 | } | 172 | } |
| @@ -180,7 +180,8 @@ static inline u64 atomic64_xchg(atomic64_t *v, u64 n) | |||
| 180 | * Atomically checks if @v holds @o and replaces it with @n if so. | 180 | * Atomically checks if @v holds @o and replaces it with @n if so. |
| 181 | * Returns the old value at @v. | 181 | * Returns the old value at @v. |
| 182 | */ | 182 | */ |
| 183 | static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) | 183 | static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, |
| 184 | long long n) | ||
| 184 | { | 185 | { |
| 185 | return cmpxchg64(&v->counter, o, n); | 186 | return cmpxchg64(&v->counter, o, n); |
| 186 | } | 187 | } |
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index 0d0395b1b152..1ad4a1f7d42b 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h | |||
| @@ -80,7 +80,7 @@ static inline void atomic_set(atomic_t *v, int n) | |||
| 80 | /* A 64bit atomic type */ | 80 | /* A 64bit atomic type */ |
| 81 | 81 | ||
| 82 | typedef struct { | 82 | typedef struct { |
| 83 | u64 __aligned(8) counter; | 83 | long long counter; |
| 84 | } atomic64_t; | 84 | } atomic64_t; |
| 85 | 85 | ||
| 86 | #define ATOMIC64_INIT(val) { (val) } | 86 | #define ATOMIC64_INIT(val) { (val) } |
| @@ -91,14 +91,14 @@ typedef struct { | |||
| 91 | * | 91 | * |
| 92 | * Atomically reads the value of @v. | 92 | * Atomically reads the value of @v. |
| 93 | */ | 93 | */ |
| 94 | static inline u64 atomic64_read(const atomic64_t *v) | 94 | static inline long long atomic64_read(const atomic64_t *v) |
| 95 | { | 95 | { |
| 96 | /* | 96 | /* |
| 97 | * Requires an atomic op to read both 32-bit parts consistently. | 97 | * Requires an atomic op to read both 32-bit parts consistently. |
| 98 | * Casting away const is safe since the atomic support routines | 98 | * Casting away const is safe since the atomic support routines |
| 99 | * do not write to memory if the value has not been modified. | 99 | * do not write to memory if the value has not been modified. |
| 100 | */ | 100 | */ |
| 101 | return _atomic64_xchg_add((u64 *)&v->counter, 0); | 101 | return _atomic64_xchg_add((long long *)&v->counter, 0); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | /** | 104 | /** |
| @@ -108,7 +108,7 @@ static inline u64 atomic64_read(const atomic64_t *v) | |||
| 108 | * | 108 | * |
| 109 | * Atomically adds @i to @v. | 109 | * Atomically adds @i to @v. |
| 110 | */ | 110 | */ |
| 111 | static inline void atomic64_add(u64 i, atomic64_t *v) | 111 | static inline void atomic64_add(long long i, atomic64_t *v) |
| 112 | { | 112 | { |
| 113 | _atomic64_xchg_add(&v->counter, i); | 113 | _atomic64_xchg_add(&v->counter, i); |
| 114 | } | 114 | } |
| @@ -120,7 +120,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v) | |||
| 120 | * | 120 | * |
| 121 | * Atomically adds @i to @v and returns @i + @v | 121 | * Atomically adds @i to @v and returns @i + @v |
| 122 | */ | 122 | */ |
| 123 | static inline u64 atomic64_add_return(u64 i, atomic64_t *v) | 123 | static inline long long atomic64_add_return(long long i, atomic64_t *v) |
| 124 | { | 124 | { |
| 125 | smp_mb(); /* barrier for proper semantics */ | 125 | smp_mb(); /* barrier for proper semantics */ |
| 126 | return _atomic64_xchg_add(&v->counter, i) + i; | 126 | return _atomic64_xchg_add(&v->counter, i) + i; |
| @@ -135,7 +135,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) | |||
| 135 | * Atomically adds @a to @v, so long as @v was not already @u. | 135 | * Atomically adds @a to @v, so long as @v was not already @u. |
| 136 | * Returns non-zero if @v was not @u, and zero otherwise. | 136 | * Returns non-zero if @v was not @u, and zero otherwise. |
| 137 | */ | 137 | */ |
| 138 | static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) | 138 | static inline long long atomic64_add_unless(atomic64_t *v, long long a, |
| 139 | long long u) | ||
| 139 | { | 140 | { |
| 140 | smp_mb(); /* barrier for proper semantics */ | 141 | smp_mb(); /* barrier for proper semantics */ |
| 141 | return _atomic64_xchg_add_unless(&v->counter, a, u) != u; | 142 | return _atomic64_xchg_add_unless(&v->counter, a, u) != u; |
| @@ -151,7 +152,7 @@ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) | |||
| 151 | * atomic64_set() can't be just a raw store, since it would be lost if it | 152 | * atomic64_set() can't be just a raw store, since it would be lost if it |
| 152 | * fell between the load and store of one of the other atomic ops. | 153 | * fell between the load and store of one of the other atomic ops. |
| 153 | */ | 154 | */ |
| 154 | static inline void atomic64_set(atomic64_t *v, u64 n) | 155 | static inline void atomic64_set(atomic64_t *v, long long n) |
| 155 | { | 156 | { |
| 156 | _atomic64_xchg(&v->counter, n); | 157 | _atomic64_xchg(&v->counter, n); |
| 157 | } | 158 | } |
| @@ -236,11 +237,13 @@ extern struct __get_user __atomic_xchg_add_unless(volatile int *p, | |||
| 236 | extern struct __get_user __atomic_or(volatile int *p, int *lock, int n); | 237 | extern struct __get_user __atomic_or(volatile int *p, int *lock, int n); |
| 237 | extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n); | 238 | extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n); |
| 238 | extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n); | 239 | extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n); |
| 239 | extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n); | 240 | extern long long __atomic64_cmpxchg(volatile long long *p, int *lock, |
| 240 | extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n); | 241 | long long o, long long n); |
| 241 | extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n); | 242 | extern long long __atomic64_xchg(volatile long long *p, int *lock, long long n); |
| 242 | extern u64 __atomic64_xchg_add_unless(volatile u64 *p, | 243 | extern long long __atomic64_xchg_add(volatile long long *p, int *lock, |
| 243 | int *lock, u64 o, u64 n); | 244 | long long n); |
| 245 | extern long long __atomic64_xchg_add_unless(volatile long long *p, | ||
| 246 | int *lock, long long o, long long n); | ||
| 244 | 247 | ||
| 245 | /* Return failure from the atomic wrappers. */ | 248 | /* Return failure from the atomic wrappers. */ |
| 246 | struct __get_user __atomic_bad_address(int __user *addr); | 249 | struct __get_user __atomic_bad_address(int __user *addr); |
diff --git a/arch/tile/include/asm/cmpxchg.h b/arch/tile/include/asm/cmpxchg.h index 4001d5eab4bb..0ccda3c425be 100644 --- a/arch/tile/include/asm/cmpxchg.h +++ b/arch/tile/include/asm/cmpxchg.h | |||
| @@ -35,10 +35,10 @@ int _atomic_xchg(int *ptr, int n); | |||
| 35 | int _atomic_xchg_add(int *v, int i); | 35 | int _atomic_xchg_add(int *v, int i); |
| 36 | int _atomic_xchg_add_unless(int *v, int a, int u); | 36 | int _atomic_xchg_add_unless(int *v, int a, int u); |
| 37 | int _atomic_cmpxchg(int *ptr, int o, int n); | 37 | int _atomic_cmpxchg(int *ptr, int o, int n); |
| 38 | u64 _atomic64_xchg(u64 *v, u64 n); | 38 | long long _atomic64_xchg(long long *v, long long n); |
| 39 | u64 _atomic64_xchg_add(u64 *v, u64 i); | 39 | long long _atomic64_xchg_add(long long *v, long long i); |
| 40 | u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u); | 40 | long long _atomic64_xchg_add_unless(long long *v, long long a, long long u); |
| 41 | u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | 41 | long long _atomic64_cmpxchg(long long *v, long long o, long long n); |
| 42 | 42 | ||
| 43 | #define xchg(ptr, n) \ | 43 | #define xchg(ptr, n) \ |
| 44 | ({ \ | 44 | ({ \ |
| @@ -53,7 +53,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | |||
| 53 | if (sizeof(*(ptr)) != 4) \ | 53 | if (sizeof(*(ptr)) != 4) \ |
| 54 | __cmpxchg_called_with_bad_pointer(); \ | 54 | __cmpxchg_called_with_bad_pointer(); \ |
| 55 | smp_mb(); \ | 55 | smp_mb(); \ |
| 56 | (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, (int)n); \ | 56 | (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, \ |
| 57 | (int)n); \ | ||
| 57 | }) | 58 | }) |
| 58 | 59 | ||
| 59 | #define xchg64(ptr, n) \ | 60 | #define xchg64(ptr, n) \ |
| @@ -61,7 +62,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | |||
| 61 | if (sizeof(*(ptr)) != 8) \ | 62 | if (sizeof(*(ptr)) != 8) \ |
| 62 | __xchg_called_with_bad_pointer(); \ | 63 | __xchg_called_with_bad_pointer(); \ |
| 63 | smp_mb(); \ | 64 | smp_mb(); \ |
| 64 | (typeof(*(ptr)))_atomic64_xchg((u64 *)(ptr), (u64)(n)); \ | 65 | (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr), \ |
| 66 | (long long)(n)); \ | ||
| 65 | }) | 67 | }) |
| 66 | 68 | ||
| 67 | #define cmpxchg64(ptr, o, n) \ | 69 | #define cmpxchg64(ptr, o, n) \ |
| @@ -69,7 +71,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | |||
| 69 | if (sizeof(*(ptr)) != 8) \ | 71 | if (sizeof(*(ptr)) != 8) \ |
| 70 | __cmpxchg_called_with_bad_pointer(); \ | 72 | __cmpxchg_called_with_bad_pointer(); \ |
| 71 | smp_mb(); \ | 73 | smp_mb(); \ |
| 72 | (typeof(*(ptr)))_atomic64_cmpxchg((u64 *)ptr, (u64)o, (u64)n); \ | 74 | (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr, \ |
| 75 | (long long)o, (long long)n); \ | ||
| 73 | }) | 76 | }) |
| 74 | 77 | ||
| 75 | #else | 78 | #else |
| @@ -81,10 +84,11 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | |||
| 81 | switch (sizeof(*(ptr))) { \ | 84 | switch (sizeof(*(ptr))) { \ |
| 82 | case 4: \ | 85 | case 4: \ |
| 83 | __x = (typeof(__x))(unsigned long) \ | 86 | __x = (typeof(__x))(unsigned long) \ |
| 84 | __insn_exch4((ptr), (u32)(unsigned long)(n)); \ | 87 | __insn_exch4((ptr), \ |
| 88 | (u32)(unsigned long)(n)); \ | ||
| 85 | break; \ | 89 | break; \ |
| 86 | case 8: \ | 90 | case 8: \ |
| 87 | __x = (typeof(__x)) \ | 91 | __x = (typeof(__x)) \ |
| 88 | __insn_exch((ptr), (unsigned long)(n)); \ | 92 | __insn_exch((ptr), (unsigned long)(n)); \ |
| 89 | break; \ | 93 | break; \ |
| 90 | default: \ | 94 | default: \ |
| @@ -103,10 +107,12 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); | |||
| 103 | switch (sizeof(*(ptr))) { \ | 107 | switch (sizeof(*(ptr))) { \ |
| 104 | case 4: \ | 108 | case 4: \ |
| 105 | __x = (typeof(__x))(unsigned long) \ | 109 | __x = (typeof(__x))(unsigned long) \ |
| 106 | __insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \ | 110 | __insn_cmpexch4((ptr), \ |
| 111 | (u32)(unsigned long)(n)); \ | ||
| 107 | break; \ | 112 | break; \ |
| 108 | case 8: \ | 113 | case 8: \ |
| 109 | __x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \ | 114 | __x = (typeof(__x))__insn_cmpexch((ptr), \ |
| 115 | (long long)(n)); \ | ||
| 110 | break; \ | 116 | break; \ |
| 111 | default: \ | 117 | default: \ |
| 112 | __cmpxchg_called_with_bad_pointer(); \ | 118 | __cmpxchg_called_with_bad_pointer(); \ |
diff --git a/arch/tile/include/asm/percpu.h b/arch/tile/include/asm/percpu.h index 63294f5a8efb..4f7ae39fa202 100644 --- a/arch/tile/include/asm/percpu.h +++ b/arch/tile/include/asm/percpu.h | |||
| @@ -15,9 +15,37 @@ | |||
| 15 | #ifndef _ASM_TILE_PERCPU_H | 15 | #ifndef _ASM_TILE_PERCPU_H |
| 16 | #define _ASM_TILE_PERCPU_H | 16 | #define _ASM_TILE_PERCPU_H |
| 17 | 17 | ||
| 18 | register unsigned long __my_cpu_offset __asm__("tp"); | 18 | register unsigned long my_cpu_offset_reg asm("tp"); |
| 19 | #define __my_cpu_offset __my_cpu_offset | 19 | |
| 20 | #define set_my_cpu_offset(tp) (__my_cpu_offset = (tp)) | 20 | #ifdef CONFIG_PREEMPT |
| 21 | /* | ||
| 22 | * For full preemption, we can't just use the register variable | ||
| 23 | * directly, since we need barrier() to hazard against it, causing the | ||
| 24 | * compiler to reload anything computed from a previous "tp" value. | ||
| 25 | * But we also don't want to use volatile asm, since we'd like the | ||
| 26 | * compiler to be able to cache the value across multiple percpu reads. | ||
| 27 | * So we use a fake stack read as a hazard against barrier(). | ||
| 28 | * The 'U' constraint is like 'm' but disallows postincrement. | ||
| 29 | */ | ||
| 30 | static inline unsigned long __my_cpu_offset(void) | ||
| 31 | { | ||
| 32 | unsigned long tp; | ||
| 33 | register unsigned long *sp asm("sp"); | ||
| 34 | asm("move %0, tp" : "=r" (tp) : "U" (*sp)); | ||
| 35 | return tp; | ||
| 36 | } | ||
| 37 | #define __my_cpu_offset __my_cpu_offset() | ||
| 38 | #else | ||
| 39 | /* | ||
| 40 | * We don't need to hazard against barrier() since "tp" doesn't ever | ||
| 41 | * change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only | ||
| 42 | * changes at function call points, at which we are already re-reading | ||
| 43 | * the value of "tp" due to "my_cpu_offset_reg" being a global variable. | ||
| 44 | */ | ||
| 45 | #define __my_cpu_offset my_cpu_offset_reg | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp)) | ||
| 21 | 49 | ||
| 22 | #include <asm-generic/percpu.h> | 50 | #include <asm-generic/percpu.h> |
| 23 | 51 | ||
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index df27a1fd94a3..531f4c365351 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
| @@ -66,7 +66,7 @@ static struct hardwall_type hardwall_types[] = { | |||
| 66 | 0, | 66 | 0, |
| 67 | "udn", | 67 | "udn", |
| 68 | LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list), | 68 | LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list), |
| 69 | __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock), | 69 | __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_UDN].lock), |
| 70 | NULL | 70 | NULL |
| 71 | }, | 71 | }, |
| 72 | #ifndef __tilepro__ | 72 | #ifndef __tilepro__ |
| @@ -77,7 +77,7 @@ static struct hardwall_type hardwall_types[] = { | |||
| 77 | 1, /* disabled pending hypervisor support */ | 77 | 1, /* disabled pending hypervisor support */ |
| 78 | "idn", | 78 | "idn", |
| 79 | LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list), | 79 | LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list), |
| 80 | __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock), | 80 | __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IDN].lock), |
| 81 | NULL | 81 | NULL |
| 82 | }, | 82 | }, |
| 83 | { /* access to user-space IPI */ | 83 | { /* access to user-space IPI */ |
| @@ -87,7 +87,7 @@ static struct hardwall_type hardwall_types[] = { | |||
| 87 | 0, | 87 | 0, |
| 88 | "ipi", | 88 | "ipi", |
| 89 | LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list), | 89 | LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list), |
| 90 | __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock), | 90 | __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IPI].lock), |
| 91 | NULL | 91 | NULL |
| 92 | }, | 92 | }, |
| 93 | #endif | 93 | #endif |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 088d5c141e68..2cbe6d5dd6b0 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
| @@ -815,6 +815,9 @@ STD_ENTRY(interrupt_return) | |||
| 815 | } | 815 | } |
| 816 | bzt r28, 1f | 816 | bzt r28, 1f |
| 817 | bnz r29, 1f | 817 | bnz r29, 1f |
| 818 | /* Disable interrupts explicitly for preemption. */ | ||
| 819 | IRQ_DISABLE(r20,r21) | ||
| 820 | TRACE_IRQS_OFF | ||
| 818 | jal preempt_schedule_irq | 821 | jal preempt_schedule_irq |
| 819 | FEEDBACK_REENTER(interrupt_return) | 822 | FEEDBACK_REENTER(interrupt_return) |
| 820 | 1: | 823 | 1: |
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index ec755d3f3734..b8fc497f2437 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S | |||
| @@ -841,6 +841,9 @@ STD_ENTRY(interrupt_return) | |||
| 841 | } | 841 | } |
| 842 | beqzt r28, 1f | 842 | beqzt r28, 1f |
| 843 | bnez r29, 1f | 843 | bnez r29, 1f |
| 844 | /* Disable interrupts explicitly for preemption. */ | ||
| 845 | IRQ_DISABLE(r20,r21) | ||
| 846 | TRACE_IRQS_OFF | ||
| 844 | jal preempt_schedule_irq | 847 | jal preempt_schedule_irq |
| 845 | FEEDBACK_REENTER(interrupt_return) | 848 | FEEDBACK_REENTER(interrupt_return) |
| 846 | 1: | 849 | 1: |
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index 362284af3afd..c93977a62116 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mmzone.h> | 23 | #include <linux/mmzone.h> |
| 24 | #include <linux/dcache.h> | 24 | #include <linux/dcache.h> |
| 25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 26 | #include <linux/string.h> | ||
| 26 | #include <asm/backtrace.h> | 27 | #include <asm/backtrace.h> |
| 27 | #include <asm/page.h> | 28 | #include <asm/page.h> |
| 28 | #include <asm/ucontext.h> | 29 | #include <asm/ucontext.h> |
| @@ -332,21 +333,18 @@ static void describe_addr(struct KBacktraceIterator *kbt, | |||
| 332 | } | 333 | } |
| 333 | 334 | ||
| 334 | if (vma->vm_file) { | 335 | if (vma->vm_file) { |
| 335 | char *s; | ||
| 336 | p = d_path(&vma->vm_file->f_path, buf, bufsize); | 336 | p = d_path(&vma->vm_file->f_path, buf, bufsize); |
| 337 | if (IS_ERR(p)) | 337 | if (IS_ERR(p)) |
| 338 | p = "?"; | 338 | p = "?"; |
| 339 | s = strrchr(p, '/'); | 339 | name = kbasename(p); |
| 340 | if (s) | ||
| 341 | p = s+1; | ||
| 342 | } else { | 340 | } else { |
| 343 | p = "anon"; | 341 | name = "anon"; |
| 344 | } | 342 | } |
| 345 | 343 | ||
| 346 | /* Generate a string description of the vma info. */ | 344 | /* Generate a string description of the vma info. */ |
| 347 | namelen = strlen(p); | 345 | namelen = strlen(name); |
| 348 | remaining = (bufsize - 1) - namelen; | 346 | remaining = (bufsize - 1) - namelen; |
| 349 | memmove(buf, p, namelen); | 347 | memmove(buf, name, namelen); |
| 350 | snprintf(buf + namelen, remaining, "[%lx+%lx] ", | 348 | snprintf(buf + namelen, remaining, "[%lx+%lx] ", |
| 351 | vma->vm_start, vma->vm_end - vma->vm_start); | 349 | vma->vm_start, vma->vm_end - vma->vm_start); |
| 352 | } | 350 | } |
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c index 759efa337be8..c89b211fd9e7 100644 --- a/arch/tile/lib/atomic_32.c +++ b/arch/tile/lib/atomic_32.c | |||
| @@ -107,19 +107,19 @@ unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask) | |||
| 107 | EXPORT_SYMBOL(_atomic_xor); | 107 | EXPORT_SYMBOL(_atomic_xor); |
| 108 | 108 | ||
| 109 | 109 | ||
| 110 | u64 _atomic64_xchg(u64 *v, u64 n) | 110 | long long _atomic64_xchg(long long *v, long long n) |
| 111 | { | 111 | { |
| 112 | return __atomic64_xchg(v, __atomic_setup(v), n); | 112 | return __atomic64_xchg(v, __atomic_setup(v), n); |
| 113 | } | 113 | } |
| 114 | EXPORT_SYMBOL(_atomic64_xchg); | 114 | EXPORT_SYMBOL(_atomic64_xchg); |
| 115 | 115 | ||
| 116 | u64 _atomic64_xchg_add(u64 *v, u64 i) | 116 | long long _atomic64_xchg_add(long long *v, long long i) |
| 117 | { | 117 | { |
| 118 | return __atomic64_xchg_add(v, __atomic_setup(v), i); | 118 | return __atomic64_xchg_add(v, __atomic_setup(v), i); |
| 119 | } | 119 | } |
| 120 | EXPORT_SYMBOL(_atomic64_xchg_add); | 120 | EXPORT_SYMBOL(_atomic64_xchg_add); |
| 121 | 121 | ||
| 122 | u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u) | 122 | long long _atomic64_xchg_add_unless(long long *v, long long a, long long u) |
| 123 | { | 123 | { |
| 124 | /* | 124 | /* |
| 125 | * Note: argument order is switched here since it is easier | 125 | * Note: argument order is switched here since it is easier |
| @@ -130,7 +130,7 @@ u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u) | |||
| 130 | } | 130 | } |
| 131 | EXPORT_SYMBOL(_atomic64_xchg_add_unless); | 131 | EXPORT_SYMBOL(_atomic64_xchg_add_unless); |
| 132 | 132 | ||
| 133 | u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n) | 133 | long long _atomic64_cmpxchg(long long *v, long long o, long long n) |
| 134 | { | 134 | { |
| 135 | return __atomic64_cmpxchg(v, __atomic_setup(v), o, n); | 135 | return __atomic64_cmpxchg(v, __atomic_setup(v), o, n); |
| 136 | } | 136 | } |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 897783b3302a..9d8449158cf9 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1888,10 +1888,7 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) | |||
| 1888 | userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; | 1888 | userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; |
| 1889 | userpg->pmc_width = x86_pmu.cntval_bits; | 1889 | userpg->pmc_width = x86_pmu.cntval_bits; |
| 1890 | 1890 | ||
| 1891 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) | 1891 | if (!sched_clock_stable) |
| 1892 | return; | ||
| 1893 | |||
| 1894 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | ||
| 1895 | return; | 1892 | return; |
| 1896 | 1893 | ||
| 1897 | userpg->cap_user_time = 1; | 1894 | userpg->cap_user_time = 1; |
| @@ -1899,10 +1896,8 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) | |||
| 1899 | userpg->time_shift = CYC2NS_SCALE_FACTOR; | 1896 | userpg->time_shift = CYC2NS_SCALE_FACTOR; |
| 1900 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; | 1897 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; |
| 1901 | 1898 | ||
| 1902 | if (sched_clock_stable && !check_tsc_disabled()) { | 1899 | userpg->cap_user_time_zero = 1; |
| 1903 | userpg->cap_user_time_zero = 1; | 1900 | userpg->time_zero = this_cpu_read(cyc2ns_offset); |
| 1904 | userpg->time_zero = this_cpu_read(cyc2ns_offset); | ||
| 1905 | } | ||
| 1906 | } | 1901 | } |
| 1907 | 1902 | ||
| 1908 | /* | 1903 | /* |
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c index 22513e96b012..86179d409893 100644 --- a/arch/x86/kernel/sysfb_simplefb.c +++ b/arch/x86/kernel/sysfb_simplefb.c | |||
| @@ -72,14 +72,14 @@ __init int create_simplefb(const struct screen_info *si, | |||
| 72 | * the part that is occupied by the framebuffer */ | 72 | * the part that is occupied by the framebuffer */ |
| 73 | len = mode->height * mode->stride; | 73 | len = mode->height * mode->stride; |
| 74 | len = PAGE_ALIGN(len); | 74 | len = PAGE_ALIGN(len); |
| 75 | if (len > si->lfb_size << 16) { | 75 | if (len > (u64)si->lfb_size << 16) { |
| 76 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); | 76 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); |
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | /* setup IORESOURCE_MEM as framebuffer memory */ | 80 | /* setup IORESOURCE_MEM as framebuffer memory */ |
| 81 | memset(&res, 0, sizeof(res)); | 81 | memset(&res, 0, sizeof(res)); |
| 82 | res.flags = IORESOURCE_MEM; | 82 | res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| 83 | res.name = simplefb_resname; | 83 | res.name = simplefb_resname; |
| 84 | res.start = si->lfb_base; | 84 | res.start = si->lfb_base; |
| 85 | res.end = si->lfb_base + len - 1; | 85 | res.end = si->lfb_base + len - 1; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 5596c7bdd327..082e88129712 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
| @@ -700,7 +700,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, | |||
| 700 | if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) | 700 | if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) |
| 701 | return -ENODEV; | 701 | return -ENODEV; |
| 702 | 702 | ||
| 703 | if (start > end || !addr) | 703 | if (start > end) |
| 704 | return -EINVAL; | 704 | return -EINVAL; |
| 705 | 705 | ||
| 706 | mutex_lock(&pci_mmcfg_lock); | 706 | mutex_lock(&pci_mmcfg_lock); |
| @@ -716,6 +716,11 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, | |||
| 716 | return -EEXIST; | 716 | return -EEXIST; |
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | if (!addr) { | ||
| 720 | mutex_unlock(&pci_mmcfg_lock); | ||
| 721 | return -EINVAL; | ||
| 722 | } | ||
| 723 | |||
| 719 | rc = -EBUSY; | 724 | rc = -EBUSY; |
| 720 | cfg = pci_mmconfig_alloc(seg, start, end, addr); | 725 | cfg = pci_mmconfig_alloc(seg, start, end, addr); |
| 721 | if (cfg == NULL) { | 726 | if (cfg == NULL) { |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 611ce9061dc5..407ad13cac2f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -968,7 +968,7 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | |||
| 968 | } | 968 | } |
| 969 | return 0; | 969 | return 0; |
| 970 | } | 970 | } |
| 971 | EXPORT_SYMBOL_GPL(acpi_bus_get_device); | 971 | EXPORT_SYMBOL(acpi_bus_get_device); |
| 972 | 972 | ||
| 973 | int acpi_device_add(struct acpi_device *device, | 973 | int acpi_device_add(struct acpi_device *device, |
| 974 | void (*release)(struct device *)) | 974 | void (*release)(struct device *)) |
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 78c49d8e0f4a..c522a95c0e16 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
| @@ -229,7 +229,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
| 229 | if (of_property_read_u32(np, "clock-latency", &transition_latency)) | 229 | if (of_property_read_u32(np, "clock-latency", &transition_latency)) |
| 230 | transition_latency = CPUFREQ_ETERNAL; | 230 | transition_latency = CPUFREQ_ETERNAL; |
| 231 | 231 | ||
| 232 | if (cpu_reg) { | 232 | if (!IS_ERR(cpu_reg)) { |
| 233 | struct opp *opp; | 233 | struct opp *opp; |
| 234 | unsigned long min_uV, max_uV; | 234 | unsigned long min_uV, max_uV; |
| 235 | int i; | 235 | int i; |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9733f29ed148..32b3479a2405 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -394,7 +394,10 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | |||
| 394 | trace_cpu_frequency(pstate * 100000, cpu->cpu); | 394 | trace_cpu_frequency(pstate * 100000, cpu->cpu); |
| 395 | 395 | ||
| 396 | cpu->pstate.current_pstate = pstate; | 396 | cpu->pstate.current_pstate = pstate; |
| 397 | wrmsrl(MSR_IA32_PERF_CTL, pstate << 8); | 397 | if (limits.no_turbo) |
| 398 | wrmsrl(MSR_IA32_PERF_CTL, BIT(32) | (pstate << 8)); | ||
| 399 | else | ||
| 400 | wrmsrl(MSR_IA32_PERF_CTL, pstate << 8); | ||
| 398 | 401 | ||
| 399 | } | 402 | } |
| 400 | 403 | ||
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 19e364fa5955..3f418166ce02 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
| @@ -113,7 +113,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, | |||
| 113 | unsigned int target_freq, unsigned int relation) | 113 | unsigned int target_freq, unsigned int relation) |
| 114 | { | 114 | { |
| 115 | struct cpufreq_freqs freqs; | 115 | struct cpufreq_freqs freqs; |
| 116 | unsigned long newfreq; | 116 | long newfreq; |
| 117 | struct clk *srcclk; | 117 | struct clk *srcclk; |
| 118 | int index, ret, mult = 1; | 118 | int index, ret, mult = 1; |
| 119 | 119 | ||
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 526ec77c7ba0..f238cfd33847 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
| @@ -198,6 +198,7 @@ config TI_EDMA | |||
| 198 | depends on ARCH_DAVINCI || ARCH_OMAP | 198 | depends on ARCH_DAVINCI || ARCH_OMAP |
| 199 | select DMA_ENGINE | 199 | select DMA_ENGINE |
| 200 | select DMA_VIRTUAL_CHANNELS | 200 | select DMA_VIRTUAL_CHANNELS |
| 201 | select TI_PRIV_EDMA | ||
| 201 | default n | 202 | default n |
| 202 | help | 203 | help |
| 203 | Enable support for the TI EDMA controller. This DMA | 204 | Enable support for the TI EDMA controller. This DMA |
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index ff50ff4c6a57..098a8da450f0 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c | |||
| @@ -749,6 +749,6 @@ static void __exit edma_exit(void) | |||
| 749 | } | 749 | } |
| 750 | module_exit(edma_exit); | 750 | module_exit(edma_exit); |
| 751 | 751 | ||
| 752 | MODULE_AUTHOR("Matt Porter <mporter@ti.com>"); | 752 | MODULE_AUTHOR("Matt Porter <matt.porter@linaro.org>"); |
| 753 | MODULE_DESCRIPTION("TI EDMA DMA engine driver"); | 753 | MODULE_DESCRIPTION("TI EDMA DMA engine driver"); |
| 754 | MODULE_LICENSE("GPL v2"); | 754 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 78f8ca5fccee..55852c026791 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
| @@ -437,17 +437,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) | |||
| 437 | struct imxdma_engine *imxdma = imxdmac->imxdma; | 437 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
| 438 | int chno = imxdmac->channel; | 438 | int chno = imxdmac->channel; |
| 439 | struct imxdma_desc *desc; | 439 | struct imxdma_desc *desc; |
| 440 | unsigned long flags; | ||
| 440 | 441 | ||
| 441 | spin_lock(&imxdma->lock); | 442 | spin_lock_irqsave(&imxdma->lock, flags); |
| 442 | if (list_empty(&imxdmac->ld_active)) { | 443 | if (list_empty(&imxdmac->ld_active)) { |
| 443 | spin_unlock(&imxdma->lock); | 444 | spin_unlock_irqrestore(&imxdma->lock, flags); |
| 444 | goto out; | 445 | goto out; |
| 445 | } | 446 | } |
| 446 | 447 | ||
| 447 | desc = list_first_entry(&imxdmac->ld_active, | 448 | desc = list_first_entry(&imxdmac->ld_active, |
| 448 | struct imxdma_desc, | 449 | struct imxdma_desc, |
| 449 | node); | 450 | node); |
| 450 | spin_unlock(&imxdma->lock); | 451 | spin_unlock_irqrestore(&imxdma->lock, flags); |
| 451 | 452 | ||
| 452 | if (desc->sg) { | 453 | if (desc->sg) { |
| 453 | u32 tmp; | 454 | u32 tmp; |
| @@ -519,7 +520,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) | |||
| 519 | { | 520 | { |
| 520 | struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); | 521 | struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); |
| 521 | struct imxdma_engine *imxdma = imxdmac->imxdma; | 522 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
| 522 | unsigned long flags; | ||
| 523 | int slot = -1; | 523 | int slot = -1; |
| 524 | int i; | 524 | int i; |
| 525 | 525 | ||
| @@ -527,7 +527,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) | |||
| 527 | switch (d->type) { | 527 | switch (d->type) { |
| 528 | case IMXDMA_DESC_INTERLEAVED: | 528 | case IMXDMA_DESC_INTERLEAVED: |
| 529 | /* Try to get a free 2D slot */ | 529 | /* Try to get a free 2D slot */ |
| 530 | spin_lock_irqsave(&imxdma->lock, flags); | ||
| 531 | for (i = 0; i < IMX_DMA_2D_SLOTS; i++) { | 530 | for (i = 0; i < IMX_DMA_2D_SLOTS; i++) { |
| 532 | if ((imxdma->slots_2d[i].count > 0) && | 531 | if ((imxdma->slots_2d[i].count > 0) && |
| 533 | ((imxdma->slots_2d[i].xsr != d->x) || | 532 | ((imxdma->slots_2d[i].xsr != d->x) || |
| @@ -537,10 +536,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) | |||
| 537 | slot = i; | 536 | slot = i; |
| 538 | break; | 537 | break; |
| 539 | } | 538 | } |
| 540 | if (slot < 0) { | 539 | if (slot < 0) |
| 541 | spin_unlock_irqrestore(&imxdma->lock, flags); | ||
| 542 | return -EBUSY; | 540 | return -EBUSY; |
| 543 | } | ||
| 544 | 541 | ||
| 545 | imxdma->slots_2d[slot].xsr = d->x; | 542 | imxdma->slots_2d[slot].xsr = d->x; |
| 546 | imxdma->slots_2d[slot].ysr = d->y; | 543 | imxdma->slots_2d[slot].ysr = d->y; |
| @@ -549,7 +546,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) | |||
| 549 | 546 | ||
| 550 | imxdmac->slot_2d = slot; | 547 | imxdmac->slot_2d = slot; |
| 551 | imxdmac->enabled_2d = true; | 548 | imxdmac->enabled_2d = true; |
| 552 | spin_unlock_irqrestore(&imxdma->lock, flags); | ||
| 553 | 549 | ||
| 554 | if (slot == IMX_DMA_2D_SLOT_A) { | 550 | if (slot == IMX_DMA_2D_SLOT_A) { |
| 555 | d->config_mem &= ~CCR_MSEL_B; | 551 | d->config_mem &= ~CCR_MSEL_B; |
| @@ -625,18 +621,17 @@ static void imxdma_tasklet(unsigned long data) | |||
| 625 | struct imxdma_channel *imxdmac = (void *)data; | 621 | struct imxdma_channel *imxdmac = (void *)data; |
| 626 | struct imxdma_engine *imxdma = imxdmac->imxdma; | 622 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
| 627 | struct imxdma_desc *desc; | 623 | struct imxdma_desc *desc; |
| 624 | unsigned long flags; | ||
| 628 | 625 | ||
| 629 | spin_lock(&imxdma->lock); | 626 | spin_lock_irqsave(&imxdma->lock, flags); |
| 630 | 627 | ||
| 631 | if (list_empty(&imxdmac->ld_active)) { | 628 | if (list_empty(&imxdmac->ld_active)) { |
| 632 | /* Someone might have called terminate all */ | 629 | /* Someone might have called terminate all */ |
| 633 | goto out; | 630 | spin_unlock_irqrestore(&imxdma->lock, flags); |
| 631 | return; | ||
| 634 | } | 632 | } |
| 635 | desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node); | 633 | desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node); |
| 636 | 634 | ||
| 637 | if (desc->desc.callback) | ||
| 638 | desc->desc.callback(desc->desc.callback_param); | ||
| 639 | |||
| 640 | /* If we are dealing with a cyclic descriptor, keep it on ld_active | 635 | /* If we are dealing with a cyclic descriptor, keep it on ld_active |
| 641 | * and dont mark the descriptor as complete. | 636 | * and dont mark the descriptor as complete. |
| 642 | * Only in non-cyclic cases it would be marked as complete | 637 | * Only in non-cyclic cases it would be marked as complete |
| @@ -663,7 +658,11 @@ static void imxdma_tasklet(unsigned long data) | |||
| 663 | __func__, imxdmac->channel); | 658 | __func__, imxdmac->channel); |
| 664 | } | 659 | } |
| 665 | out: | 660 | out: |
| 666 | spin_unlock(&imxdma->lock); | 661 | spin_unlock_irqrestore(&imxdma->lock, flags); |
| 662 | |||
| 663 | if (desc->desc.callback) | ||
| 664 | desc->desc.callback(desc->desc.callback_param); | ||
| 665 | |||
| 667 | } | 666 | } |
| 668 | 667 | ||
| 669 | static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 668 | static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
| @@ -883,7 +882,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( | |||
| 883 | kfree(imxdmac->sg_list); | 882 | kfree(imxdmac->sg_list); |
| 884 | 883 | ||
| 885 | imxdmac->sg_list = kcalloc(periods + 1, | 884 | imxdmac->sg_list = kcalloc(periods + 1, |
| 886 | sizeof(struct scatterlist), GFP_KERNEL); | 885 | sizeof(struct scatterlist), GFP_ATOMIC); |
| 887 | if (!imxdmac->sg_list) | 886 | if (!imxdmac->sg_list) |
| 888 | return NULL; | 887 | return NULL; |
| 889 | 888 | ||
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0ff43552d472..89675f862308 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -63,6 +63,7 @@ struct gpio_bank { | |||
| 63 | struct gpio_chip chip; | 63 | struct gpio_chip chip; |
| 64 | struct clk *dbck; | 64 | struct clk *dbck; |
| 65 | u32 mod_usage; | 65 | u32 mod_usage; |
| 66 | u32 irq_usage; | ||
| 66 | u32 dbck_enable_mask; | 67 | u32 dbck_enable_mask; |
| 67 | bool dbck_enabled; | 68 | bool dbck_enabled; |
| 68 | struct device *dev; | 69 | struct device *dev; |
| @@ -86,6 +87,9 @@ struct gpio_bank { | |||
| 86 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) | 87 | #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) |
| 87 | #define GPIO_MOD_CTRL_BIT BIT(0) | 88 | #define GPIO_MOD_CTRL_BIT BIT(0) |
| 88 | 89 | ||
| 90 | #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) | ||
| 91 | #define LINE_USED(line, offset) (line & (1 << offset)) | ||
| 92 | |||
| 89 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) | 93 | static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) |
| 90 | { | 94 | { |
| 91 | return bank->chip.base + gpio_irq; | 95 | return bank->chip.base + gpio_irq; |
| @@ -420,15 +424,69 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
| 420 | return 0; | 424 | return 0; |
| 421 | } | 425 | } |
| 422 | 426 | ||
| 427 | static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset) | ||
| 428 | { | ||
| 429 | if (bank->regs->pinctrl) { | ||
| 430 | void __iomem *reg = bank->base + bank->regs->pinctrl; | ||
| 431 | |||
| 432 | /* Claim the pin for MPU */ | ||
| 433 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | ||
| 434 | } | ||
| 435 | |||
| 436 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
| 437 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
| 438 | u32 ctrl; | ||
| 439 | |||
| 440 | ctrl = __raw_readl(reg); | ||
| 441 | /* Module is enabled, clocks are not gated */ | ||
| 442 | ctrl &= ~GPIO_MOD_CTRL_BIT; | ||
| 443 | __raw_writel(ctrl, reg); | ||
| 444 | bank->context.ctrl = ctrl; | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset) | ||
| 449 | { | ||
| 450 | void __iomem *base = bank->base; | ||
| 451 | |||
| 452 | if (bank->regs->wkup_en && | ||
| 453 | !LINE_USED(bank->mod_usage, offset) && | ||
| 454 | !LINE_USED(bank->irq_usage, offset)) { | ||
| 455 | /* Disable wake-up during idle for dynamic tick */ | ||
| 456 | _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); | ||
| 457 | bank->context.wake_en = | ||
| 458 | __raw_readl(bank->base + bank->regs->wkup_en); | ||
| 459 | } | ||
| 460 | |||
| 461 | if (bank->regs->ctrl && !BANK_USED(bank)) { | ||
| 462 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
| 463 | u32 ctrl; | ||
| 464 | |||
| 465 | ctrl = __raw_readl(reg); | ||
| 466 | /* Module is disabled, clocks are gated */ | ||
| 467 | ctrl |= GPIO_MOD_CTRL_BIT; | ||
| 468 | __raw_writel(ctrl, reg); | ||
| 469 | bank->context.ctrl = ctrl; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
| 474 | { | ||
| 475 | void __iomem *reg = bank->base + bank->regs->direction; | ||
| 476 | |||
| 477 | return __raw_readl(reg) & mask; | ||
| 478 | } | ||
| 479 | |||
| 423 | static int gpio_irq_type(struct irq_data *d, unsigned type) | 480 | static int gpio_irq_type(struct irq_data *d, unsigned type) |
| 424 | { | 481 | { |
| 425 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 482 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
| 426 | unsigned gpio = 0; | 483 | unsigned gpio = 0; |
| 427 | int retval; | 484 | int retval; |
| 428 | unsigned long flags; | 485 | unsigned long flags; |
| 486 | unsigned offset; | ||
| 429 | 487 | ||
| 430 | if (WARN_ON(!bank->mod_usage)) | 488 | if (!BANK_USED(bank)) |
| 431 | return -EINVAL; | 489 | pm_runtime_get_sync(bank->dev); |
| 432 | 490 | ||
| 433 | #ifdef CONFIG_ARCH_OMAP1 | 491 | #ifdef CONFIG_ARCH_OMAP1 |
| 434 | if (d->irq > IH_MPUIO_BASE) | 492 | if (d->irq > IH_MPUIO_BASE) |
| @@ -446,7 +504,17 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) | |||
| 446 | return -EINVAL; | 504 | return -EINVAL; |
| 447 | 505 | ||
| 448 | spin_lock_irqsave(&bank->lock, flags); | 506 | spin_lock_irqsave(&bank->lock, flags); |
| 449 | retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); | 507 | offset = GPIO_INDEX(bank, gpio); |
| 508 | retval = _set_gpio_triggering(bank, offset, type); | ||
| 509 | if (!LINE_USED(bank->mod_usage, offset)) { | ||
| 510 | _enable_gpio_module(bank, offset); | ||
| 511 | _set_gpio_direction(bank, offset, 1); | ||
| 512 | } else if (!gpio_is_input(bank, 1 << offset)) { | ||
| 513 | spin_unlock_irqrestore(&bank->lock, flags); | ||
| 514 | return -EINVAL; | ||
| 515 | } | ||
| 516 | |||
| 517 | bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); | ||
| 450 | spin_unlock_irqrestore(&bank->lock, flags); | 518 | spin_unlock_irqrestore(&bank->lock, flags); |
| 451 | 519 | ||
| 452 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 520 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
| @@ -603,35 +671,19 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
| 603 | * If this is the first gpio_request for the bank, | 671 | * If this is the first gpio_request for the bank, |
| 604 | * enable the bank module. | 672 | * enable the bank module. |
| 605 | */ | 673 | */ |
| 606 | if (!bank->mod_usage) | 674 | if (!BANK_USED(bank)) |
| 607 | pm_runtime_get_sync(bank->dev); | 675 | pm_runtime_get_sync(bank->dev); |
| 608 | 676 | ||
| 609 | spin_lock_irqsave(&bank->lock, flags); | 677 | spin_lock_irqsave(&bank->lock, flags); |
| 610 | /* Set trigger to none. You need to enable the desired trigger with | 678 | /* Set trigger to none. You need to enable the desired trigger with |
| 611 | * request_irq() or set_irq_type(). | 679 | * request_irq() or set_irq_type(). Only do this if the IRQ line has |
| 680 | * not already been requested. | ||
| 612 | */ | 681 | */ |
| 613 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); | 682 | if (!LINE_USED(bank->irq_usage, offset)) { |
| 614 | 683 | _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); | |
| 615 | if (bank->regs->pinctrl) { | 684 | _enable_gpio_module(bank, offset); |
| 616 | void __iomem *reg = bank->base + bank->regs->pinctrl; | ||
| 617 | |||
| 618 | /* Claim the pin for MPU */ | ||
| 619 | __raw_writel(__raw_readl(reg) | (1 << offset), reg); | ||
| 620 | } | ||
| 621 | |||
| 622 | if (bank->regs->ctrl && !bank->mod_usage) { | ||
| 623 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
| 624 | u32 ctrl; | ||
| 625 | |||
| 626 | ctrl = __raw_readl(reg); | ||
| 627 | /* Module is enabled, clocks are not gated */ | ||
| 628 | ctrl &= ~GPIO_MOD_CTRL_BIT; | ||
| 629 | __raw_writel(ctrl, reg); | ||
| 630 | bank->context.ctrl = ctrl; | ||
| 631 | } | 685 | } |
| 632 | |||
| 633 | bank->mod_usage |= 1 << offset; | 686 | bank->mod_usage |= 1 << offset; |
| 634 | |||
| 635 | spin_unlock_irqrestore(&bank->lock, flags); | 687 | spin_unlock_irqrestore(&bank->lock, flags); |
| 636 | 688 | ||
| 637 | return 0; | 689 | return 0; |
| @@ -640,31 +692,11 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
| 640 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | 692 | static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) |
| 641 | { | 693 | { |
| 642 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); | 694 | struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); |
| 643 | void __iomem *base = bank->base; | ||
| 644 | unsigned long flags; | 695 | unsigned long flags; |
| 645 | 696 | ||
| 646 | spin_lock_irqsave(&bank->lock, flags); | 697 | spin_lock_irqsave(&bank->lock, flags); |
| 647 | |||
| 648 | if (bank->regs->wkup_en) { | ||
| 649 | /* Disable wake-up during idle for dynamic tick */ | ||
| 650 | _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); | ||
| 651 | bank->context.wake_en = | ||
| 652 | __raw_readl(bank->base + bank->regs->wkup_en); | ||
| 653 | } | ||
| 654 | |||
| 655 | bank->mod_usage &= ~(1 << offset); | 698 | bank->mod_usage &= ~(1 << offset); |
| 656 | 699 | _disable_gpio_module(bank, offset); | |
| 657 | if (bank->regs->ctrl && !bank->mod_usage) { | ||
| 658 | void __iomem *reg = bank->base + bank->regs->ctrl; | ||
| 659 | u32 ctrl; | ||
| 660 | |||
| 661 | ctrl = __raw_readl(reg); | ||
| 662 | /* Module is disabled, clocks are gated */ | ||
| 663 | ctrl |= GPIO_MOD_CTRL_BIT; | ||
| 664 | __raw_writel(ctrl, reg); | ||
| 665 | bank->context.ctrl = ctrl; | ||
| 666 | } | ||
| 667 | |||
| 668 | _reset_gpio(bank, bank->chip.base + offset); | 700 | _reset_gpio(bank, bank->chip.base + offset); |
| 669 | spin_unlock_irqrestore(&bank->lock, flags); | 701 | spin_unlock_irqrestore(&bank->lock, flags); |
| 670 | 702 | ||
| @@ -672,7 +704,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
| 672 | * If this is the last gpio to be freed in the bank, | 704 | * If this is the last gpio to be freed in the bank, |
| 673 | * disable the bank module. | 705 | * disable the bank module. |
| 674 | */ | 706 | */ |
| 675 | if (!bank->mod_usage) | 707 | if (!BANK_USED(bank)) |
| 676 | pm_runtime_put(bank->dev); | 708 | pm_runtime_put(bank->dev); |
| 677 | } | 709 | } |
| 678 | 710 | ||
| @@ -762,10 +794,20 @@ static void gpio_irq_shutdown(struct irq_data *d) | |||
| 762 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 794 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
| 763 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); | 795 | unsigned int gpio = irq_to_gpio(bank, d->hwirq); |
| 764 | unsigned long flags; | 796 | unsigned long flags; |
| 797 | unsigned offset = GPIO_INDEX(bank, gpio); | ||
| 765 | 798 | ||
| 766 | spin_lock_irqsave(&bank->lock, flags); | 799 | spin_lock_irqsave(&bank->lock, flags); |
| 800 | bank->irq_usage &= ~(1 << offset); | ||
| 801 | _disable_gpio_module(bank, offset); | ||
| 767 | _reset_gpio(bank, gpio); | 802 | _reset_gpio(bank, gpio); |
| 768 | spin_unlock_irqrestore(&bank->lock, flags); | 803 | spin_unlock_irqrestore(&bank->lock, flags); |
| 804 | |||
| 805 | /* | ||
| 806 | * If this is the last IRQ to be freed in the bank, | ||
| 807 | * disable the bank module. | ||
| 808 | */ | ||
| 809 | if (!BANK_USED(bank)) | ||
| 810 | pm_runtime_put(bank->dev); | ||
| 769 | } | 811 | } |
| 770 | 812 | ||
| 771 | static void gpio_ack_irq(struct irq_data *d) | 813 | static void gpio_ack_irq(struct irq_data *d) |
| @@ -897,13 +939,6 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
| 897 | return 0; | 939 | return 0; |
| 898 | } | 940 | } |
| 899 | 941 | ||
| 900 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
| 901 | { | ||
| 902 | void __iomem *reg = bank->base + bank->regs->direction; | ||
| 903 | |||
| 904 | return __raw_readl(reg) & mask; | ||
| 905 | } | ||
| 906 | |||
| 907 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 942 | static int gpio_get(struct gpio_chip *chip, unsigned offset) |
| 908 | { | 943 | { |
| 909 | struct gpio_bank *bank; | 944 | struct gpio_bank *bank; |
| @@ -922,13 +957,22 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | |||
| 922 | { | 957 | { |
| 923 | struct gpio_bank *bank; | 958 | struct gpio_bank *bank; |
| 924 | unsigned long flags; | 959 | unsigned long flags; |
| 960 | int retval = 0; | ||
| 925 | 961 | ||
| 926 | bank = container_of(chip, struct gpio_bank, chip); | 962 | bank = container_of(chip, struct gpio_bank, chip); |
| 927 | spin_lock_irqsave(&bank->lock, flags); | 963 | spin_lock_irqsave(&bank->lock, flags); |
| 964 | |||
| 965 | if (LINE_USED(bank->irq_usage, offset)) { | ||
| 966 | retval = -EINVAL; | ||
| 967 | goto exit; | ||
| 968 | } | ||
| 969 | |||
| 928 | bank->set_dataout(bank, offset, value); | 970 | bank->set_dataout(bank, offset, value); |
| 929 | _set_gpio_direction(bank, offset, 0); | 971 | _set_gpio_direction(bank, offset, 0); |
| 972 | |||
| 973 | exit: | ||
| 930 | spin_unlock_irqrestore(&bank->lock, flags); | 974 | spin_unlock_irqrestore(&bank->lock, flags); |
| 931 | return 0; | 975 | return retval; |
| 932 | } | 976 | } |
| 933 | 977 | ||
| 934 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, | 978 | static int gpio_debounce(struct gpio_chip *chip, unsigned offset, |
| @@ -1400,7 +1444,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) | |||
| 1400 | struct gpio_bank *bank; | 1444 | struct gpio_bank *bank; |
| 1401 | 1445 | ||
| 1402 | list_for_each_entry(bank, &omap_gpio_list, node) { | 1446 | list_for_each_entry(bank, &omap_gpio_list, node) { |
| 1403 | if (!bank->mod_usage || !bank->loses_context) | 1447 | if (!BANK_USED(bank) || !bank->loses_context) |
| 1404 | continue; | 1448 | continue; |
| 1405 | 1449 | ||
| 1406 | bank->power_mode = pwr_mode; | 1450 | bank->power_mode = pwr_mode; |
| @@ -1414,7 +1458,7 @@ void omap2_gpio_resume_after_idle(void) | |||
| 1414 | struct gpio_bank *bank; | 1458 | struct gpio_bank *bank; |
| 1415 | 1459 | ||
| 1416 | list_for_each_entry(bank, &omap_gpio_list, node) { | 1460 | list_for_each_entry(bank, &omap_gpio_list, node) { |
| 1417 | if (!bank->mod_usage || !bank->loses_context) | 1461 | if (!BANK_USED(bank) || !bank->loses_context) |
| 1418 | continue; | 1462 | continue; |
| 1419 | 1463 | ||
| 1420 | pm_runtime_get_sync(bank->dev); | 1464 | pm_runtime_get_sync(bank->dev); |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 71b70e3a7a71..c91d547191dd 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -241,6 +241,7 @@ config HID_HOLTEK | |||
| 241 | - Sharkoon Drakonia / Perixx MX-2000 gaming mice | 241 | - Sharkoon Drakonia / Perixx MX-2000 gaming mice |
| 242 | - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / | 242 | - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / |
| 243 | Zalman ZM-GM1 | 243 | Zalman ZM-GM1 |
| 244 | - SHARKOON DarkGlider Gaming mouse | ||
| 244 | 245 | ||
| 245 | config HOLTEK_FF | 246 | config HOLTEK_FF |
| 246 | bool "Holtek On Line Grip force feedback support" | 247 | bool "Holtek On Line Grip force feedback support" |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8470b1a10fe..5a8c01112a23 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1715,6 +1715,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1715 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, | 1715 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, |
| 1716 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, | 1716 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, |
| 1717 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, | 1717 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, |
| 1718 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, | ||
| 1718 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, | 1719 | { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, |
| 1719 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, | 1720 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, |
| 1720 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | 1721 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index 7e6db3cf46f9..e696566cde46 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000 | 27 | * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000 |
| 28 | * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 | 28 | * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 |
| 29 | * and Zalman ZM-GM1 | 29 | * and Zalman ZM-GM1 |
| 30 | * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse | ||
| 30 | */ | 31 | */ |
| 31 | 32 | ||
| 32 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 33 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| @@ -46,6 +47,7 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 46 | } | 47 | } |
| 47 | break; | 48 | break; |
| 48 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A: | 49 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A: |
| 50 | case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081: | ||
| 49 | if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f | 51 | if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f |
| 50 | && rdesc[111] == 0xff && rdesc[112] == 0x7f) { | 52 | && rdesc[111] == 0xff && rdesc[112] == 0x7f) { |
| 51 | hid_info(hdev, "Fixing up report descriptor\n"); | 53 | hid_info(hdev, "Fixing up report descriptor\n"); |
| @@ -63,6 +65,8 @@ static const struct hid_device_id holtek_mouse_devices[] = { | |||
| 63 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, | 65 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, |
| 64 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | 66 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, |
| 65 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, | 67 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, |
| 68 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, | ||
| 69 | USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, | ||
| 66 | { } | 70 | { } |
| 67 | }; | 71 | }; |
| 68 | MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); | 72 | MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e60e8d530697..9cbc7ab07dfa 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -450,6 +450,7 @@ | |||
| 450 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 | 450 | #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 |
| 451 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067 | 451 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067 |
| 452 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a | 452 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a |
| 453 | #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 | ||
| 453 | 454 | ||
| 454 | #define USB_VENDOR_ID_IMATION 0x0718 | 455 | #define USB_VENDOR_ID_IMATION 0x0718 |
| 455 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 456 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 602c188e9d86..6101816a7ddd 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c | |||
| @@ -382,7 +382,7 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp, | |||
| 382 | } | 382 | } |
| 383 | #define PROFILE_ATTR(number) \ | 383 | #define PROFILE_ATTR(number) \ |
| 384 | static struct bin_attribute bin_attr_profile##number = { \ | 384 | static struct bin_attribute bin_attr_profile##number = { \ |
| 385 | .attr = { .name = "profile##number", .mode = 0660 }, \ | 385 | .attr = { .name = "profile" #number, .mode = 0660 }, \ |
| 386 | .size = sizeof(struct kone_profile), \ | 386 | .size = sizeof(struct kone_profile), \ |
| 387 | .read = kone_sysfs_read_profilex, \ | 387 | .read = kone_sysfs_read_profilex, \ |
| 388 | .write = kone_sysfs_write_profilex, \ | 388 | .write = kone_sysfs_write_profilex, \ |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 5ddf605b6b89..5e99fcdc71b9 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
| @@ -229,13 +229,13 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | |||
| 229 | 229 | ||
| 230 | #define PROFILE_ATTR(number) \ | 230 | #define PROFILE_ATTR(number) \ |
| 231 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | 231 | static struct bin_attribute bin_attr_profile##number##_settings = { \ |
| 232 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | 232 | .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \ |
| 233 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \ | 233 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \ |
| 234 | .read = koneplus_sysfs_read_profilex_settings, \ | 234 | .read = koneplus_sysfs_read_profilex_settings, \ |
| 235 | .private = &profile_numbers[number-1], \ | 235 | .private = &profile_numbers[number-1], \ |
| 236 | }; \ | 236 | }; \ |
| 237 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | 237 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ |
| 238 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | 238 | .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \ |
| 239 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \ | 239 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \ |
| 240 | .read = koneplus_sysfs_read_profilex_buttons, \ | 240 | .read = koneplus_sysfs_read_profilex_buttons, \ |
| 241 | .private = &profile_numbers[number-1], \ | 241 | .private = &profile_numbers[number-1], \ |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 515bc03136c0..0c8e1ef0b67d 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
| @@ -257,13 +257,13 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, | |||
| 257 | 257 | ||
| 258 | #define PROFILE_ATTR(number) \ | 258 | #define PROFILE_ATTR(number) \ |
| 259 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | 259 | static struct bin_attribute bin_attr_profile##number##_settings = { \ |
| 260 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | 260 | .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \ |
| 261 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \ | 261 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \ |
| 262 | .read = kovaplus_sysfs_read_profilex_settings, \ | 262 | .read = kovaplus_sysfs_read_profilex_settings, \ |
| 263 | .private = &profile_numbers[number-1], \ | 263 | .private = &profile_numbers[number-1], \ |
| 264 | }; \ | 264 | }; \ |
| 265 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | 265 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ |
| 266 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | 266 | .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \ |
| 267 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \ | 267 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \ |
| 268 | .read = kovaplus_sysfs_read_profilex_buttons, \ | 268 | .read = kovaplus_sysfs_read_profilex_buttons, \ |
| 269 | .private = &profile_numbers[number-1], \ | 269 | .private = &profile_numbers[number-1], \ |
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 5a6dbbeee790..1a07e07d99a0 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
| @@ -225,13 +225,13 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, | |||
| 225 | 225 | ||
| 226 | #define PROFILE_ATTR(number) \ | 226 | #define PROFILE_ATTR(number) \ |
| 227 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | 227 | static struct bin_attribute bin_attr_profile##number##_settings = { \ |
| 228 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | 228 | .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \ |
| 229 | .size = PYRA_SIZE_PROFILE_SETTINGS, \ | 229 | .size = PYRA_SIZE_PROFILE_SETTINGS, \ |
| 230 | .read = pyra_sysfs_read_profilex_settings, \ | 230 | .read = pyra_sysfs_read_profilex_settings, \ |
| 231 | .private = &profile_numbers[number-1], \ | 231 | .private = &profile_numbers[number-1], \ |
| 232 | }; \ | 232 | }; \ |
| 233 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | 233 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ |
| 234 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | 234 | .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \ |
| 235 | .size = PYRA_SIZE_PROFILE_BUTTONS, \ | 235 | .size = PYRA_SIZE_PROFILE_BUTTONS, \ |
| 236 | .read = pyra_sysfs_read_profilex_buttons, \ | 236 | .read = pyra_sysfs_read_profilex_buttons, \ |
| 237 | .private = &profile_numbers[number-1], \ | 237 | .private = &profile_numbers[number-1], \ |
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 2e7d644dba18..71adf9e60b13 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
| @@ -119,12 +119,22 @@ static const struct wiimod_ops wiimod_keys = { | |||
| 119 | * the rumble motor, this flag shouldn't be set. | 119 | * the rumble motor, this flag shouldn't be set. |
| 120 | */ | 120 | */ |
| 121 | 121 | ||
| 122 | /* used by wiimod_rumble and wiipro_rumble */ | ||
| 123 | static void wiimod_rumble_worker(struct work_struct *work) | ||
| 124 | { | ||
| 125 | struct wiimote_data *wdata = container_of(work, struct wiimote_data, | ||
| 126 | rumble_worker); | ||
| 127 | |||
| 128 | spin_lock_irq(&wdata->state.lock); | ||
| 129 | wiiproto_req_rumble(wdata, wdata->state.cache_rumble); | ||
| 130 | spin_unlock_irq(&wdata->state.lock); | ||
| 131 | } | ||
| 132 | |||
| 122 | static int wiimod_rumble_play(struct input_dev *dev, void *data, | 133 | static int wiimod_rumble_play(struct input_dev *dev, void *data, |
| 123 | struct ff_effect *eff) | 134 | struct ff_effect *eff) |
| 124 | { | 135 | { |
| 125 | struct wiimote_data *wdata = input_get_drvdata(dev); | 136 | struct wiimote_data *wdata = input_get_drvdata(dev); |
| 126 | __u8 value; | 137 | __u8 value; |
| 127 | unsigned long flags; | ||
| 128 | 138 | ||
| 129 | /* | 139 | /* |
| 130 | * The wiimote supports only a single rumble motor so if any magnitude | 140 | * The wiimote supports only a single rumble motor so if any magnitude |
| @@ -137,9 +147,10 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data, | |||
| 137 | else | 147 | else |
| 138 | value = 0; | 148 | value = 0; |
| 139 | 149 | ||
| 140 | spin_lock_irqsave(&wdata->state.lock, flags); | 150 | /* Locking state.lock here might deadlock with input_event() calls. |
| 141 | wiiproto_req_rumble(wdata, value); | 151 | * schedule_work acts as barrier. Merging multiple changes is fine. */ |
| 142 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 152 | wdata->state.cache_rumble = value; |
| 153 | schedule_work(&wdata->rumble_worker); | ||
| 143 | 154 | ||
| 144 | return 0; | 155 | return 0; |
| 145 | } | 156 | } |
| @@ -147,6 +158,8 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data, | |||
| 147 | static int wiimod_rumble_probe(const struct wiimod_ops *ops, | 158 | static int wiimod_rumble_probe(const struct wiimod_ops *ops, |
| 148 | struct wiimote_data *wdata) | 159 | struct wiimote_data *wdata) |
| 149 | { | 160 | { |
| 161 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); | ||
| 162 | |||
| 150 | set_bit(FF_RUMBLE, wdata->input->ffbit); | 163 | set_bit(FF_RUMBLE, wdata->input->ffbit); |
| 151 | if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play)) | 164 | if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play)) |
| 152 | return -ENOMEM; | 165 | return -ENOMEM; |
| @@ -159,6 +172,8 @@ static void wiimod_rumble_remove(const struct wiimod_ops *ops, | |||
| 159 | { | 172 | { |
| 160 | unsigned long flags; | 173 | unsigned long flags; |
| 161 | 174 | ||
| 175 | cancel_work_sync(&wdata->rumble_worker); | ||
| 176 | |||
| 162 | spin_lock_irqsave(&wdata->state.lock, flags); | 177 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 163 | wiiproto_req_rumble(wdata, 0); | 178 | wiiproto_req_rumble(wdata, 0); |
| 164 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 179 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| @@ -1731,7 +1746,6 @@ static int wiimod_pro_play(struct input_dev *dev, void *data, | |||
| 1731 | { | 1746 | { |
| 1732 | struct wiimote_data *wdata = input_get_drvdata(dev); | 1747 | struct wiimote_data *wdata = input_get_drvdata(dev); |
| 1733 | __u8 value; | 1748 | __u8 value; |
| 1734 | unsigned long flags; | ||
| 1735 | 1749 | ||
| 1736 | /* | 1750 | /* |
| 1737 | * The wiimote supports only a single rumble motor so if any magnitude | 1751 | * The wiimote supports only a single rumble motor so if any magnitude |
| @@ -1744,9 +1758,10 @@ static int wiimod_pro_play(struct input_dev *dev, void *data, | |||
| 1744 | else | 1758 | else |
| 1745 | value = 0; | 1759 | value = 0; |
| 1746 | 1760 | ||
| 1747 | spin_lock_irqsave(&wdata->state.lock, flags); | 1761 | /* Locking state.lock here might deadlock with input_event() calls. |
| 1748 | wiiproto_req_rumble(wdata, value); | 1762 | * schedule_work acts as barrier. Merging multiple changes is fine. */ |
| 1749 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 1763 | wdata->state.cache_rumble = value; |
| 1764 | schedule_work(&wdata->rumble_worker); | ||
| 1750 | 1765 | ||
| 1751 | return 0; | 1766 | return 0; |
| 1752 | } | 1767 | } |
| @@ -1756,6 +1771,8 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops, | |||
| 1756 | { | 1771 | { |
| 1757 | int ret, i; | 1772 | int ret, i; |
| 1758 | 1773 | ||
| 1774 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); | ||
| 1775 | |||
| 1759 | wdata->extension.input = input_allocate_device(); | 1776 | wdata->extension.input = input_allocate_device(); |
| 1760 | if (!wdata->extension.input) | 1777 | if (!wdata->extension.input) |
| 1761 | return -ENOMEM; | 1778 | return -ENOMEM; |
| @@ -1817,12 +1834,13 @@ static void wiimod_pro_remove(const struct wiimod_ops *ops, | |||
| 1817 | if (!wdata->extension.input) | 1834 | if (!wdata->extension.input) |
| 1818 | return; | 1835 | return; |
| 1819 | 1836 | ||
| 1837 | input_unregister_device(wdata->extension.input); | ||
| 1838 | wdata->extension.input = NULL; | ||
| 1839 | cancel_work_sync(&wdata->rumble_worker); | ||
| 1840 | |||
| 1820 | spin_lock_irqsave(&wdata->state.lock, flags); | 1841 | spin_lock_irqsave(&wdata->state.lock, flags); |
| 1821 | wiiproto_req_rumble(wdata, 0); | 1842 | wiiproto_req_rumble(wdata, 0); |
| 1822 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 1843 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
| 1823 | |||
| 1824 | input_unregister_device(wdata->extension.input); | ||
| 1825 | wdata->extension.input = NULL; | ||
| 1826 | } | 1844 | } |
| 1827 | 1845 | ||
| 1828 | static const struct wiimod_ops wiimod_pro = { | 1846 | static const struct wiimod_ops wiimod_pro = { |
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index f1474f372c0b..75db0c400037 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
| @@ -133,13 +133,15 @@ struct wiimote_state { | |||
| 133 | __u8 *cmd_read_buf; | 133 | __u8 *cmd_read_buf; |
| 134 | __u8 cmd_read_size; | 134 | __u8 cmd_read_size; |
| 135 | 135 | ||
| 136 | /* calibration data */ | 136 | /* calibration/cache data */ |
| 137 | __u16 calib_bboard[4][3]; | 137 | __u16 calib_bboard[4][3]; |
| 138 | __u8 cache_rumble; | ||
| 138 | }; | 139 | }; |
| 139 | 140 | ||
| 140 | struct wiimote_data { | 141 | struct wiimote_data { |
| 141 | struct hid_device *hdev; | 142 | struct hid_device *hdev; |
| 142 | struct input_dev *input; | 143 | struct input_dev *input; |
| 144 | struct work_struct rumble_worker; | ||
| 143 | struct led_classdev *leds[4]; | 145 | struct led_classdev *leds[4]; |
| 144 | struct input_dev *accel; | 146 | struct input_dev *accel; |
| 145 | struct input_dev *ir; | 147 | struct input_dev *ir; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 8918dd12bb69..6a6dd5cd7833 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -308,18 +308,25 @@ static int hidraw_fasync(int fd, struct file *file, int on) | |||
| 308 | static void drop_ref(struct hidraw *hidraw, int exists_bit) | 308 | static void drop_ref(struct hidraw *hidraw, int exists_bit) |
| 309 | { | 309 | { |
| 310 | if (exists_bit) { | 310 | if (exists_bit) { |
| 311 | hid_hw_close(hidraw->hid); | ||
| 312 | hidraw->exist = 0; | 311 | hidraw->exist = 0; |
| 313 | if (hidraw->open) | 312 | if (hidraw->open) { |
| 313 | hid_hw_close(hidraw->hid); | ||
| 314 | wake_up_interruptible(&hidraw->wait); | 314 | wake_up_interruptible(&hidraw->wait); |
| 315 | } | ||
| 315 | } else { | 316 | } else { |
| 316 | --hidraw->open; | 317 | --hidraw->open; |
| 317 | } | 318 | } |
| 318 | 319 | if (!hidraw->open) { | |
| 319 | if (!hidraw->open && !hidraw->exist) { | 320 | if (!hidraw->exist) { |
| 320 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | 321 | device_destroy(hidraw_class, |
| 321 | hidraw_table[hidraw->minor] = NULL; | 322 | MKDEV(hidraw_major, hidraw->minor)); |
| 322 | kfree(hidraw); | 323 | hidraw_table[hidraw->minor] = NULL; |
| 324 | kfree(hidraw); | ||
| 325 | } else { | ||
| 326 | /* close device for last reader */ | ||
| 327 | hid_hw_power(hidraw->hid, PM_HINT_NORMAL); | ||
| 328 | hid_hw_close(hidraw->hid); | ||
| 329 | } | ||
| 323 | } | 330 | } |
| 324 | } | 331 | } |
| 325 | 332 | ||
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 5bf2fb785844..93b00d76374c 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
| @@ -615,7 +615,7 @@ static const struct file_operations uhid_fops = { | |||
| 615 | 615 | ||
| 616 | static struct miscdevice uhid_misc = { | 616 | static struct miscdevice uhid_misc = { |
| 617 | .fops = &uhid_fops, | 617 | .fops = &uhid_fops, |
| 618 | .minor = MISC_DYNAMIC_MINOR, | 618 | .minor = UHID_MINOR, |
| 619 | .name = UHID_NAME, | 619 | .name = UHID_NAME, |
| 620 | }; | 620 | }; |
| 621 | 621 | ||
| @@ -634,4 +634,5 @@ module_exit(uhid_exit); | |||
| 634 | MODULE_LICENSE("GPL"); | 634 | MODULE_LICENSE("GPL"); |
| 635 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); | 635 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); |
| 636 | MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); | 636 | MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); |
| 637 | MODULE_ALIAS_MISCDEV(UHID_MINOR); | ||
| 637 | MODULE_ALIAS("devname:" UHID_NAME); | 638 | MODULE_ALIAS("devname:" UHID_NAME); |
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index d0a79a4bce1c..ba6f6a91dfff 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c | |||
| @@ -185,10 +185,8 @@ static int ad8366_remove(struct spi_device *spi) | |||
| 185 | 185 | ||
| 186 | iio_device_unregister(indio_dev); | 186 | iio_device_unregister(indio_dev); |
| 187 | 187 | ||
| 188 | if (!IS_ERR(reg)) { | 188 | if (!IS_ERR(reg)) |
| 189 | regulator_disable(reg); | 189 | regulator_disable(reg); |
| 190 | regulator_put(reg); | ||
| 191 | } | ||
| 192 | 190 | ||
| 193 | return 0; | 191 | return 0; |
| 194 | } | 192 | } |
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 8e84cd522e49..f95c6979efd8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
| @@ -852,7 +852,6 @@ static void iio_dev_release(struct device *device) | |||
| 852 | iio_device_unregister_trigger_consumer(indio_dev); | 852 | iio_device_unregister_trigger_consumer(indio_dev); |
| 853 | iio_device_unregister_eventset(indio_dev); | 853 | iio_device_unregister_eventset(indio_dev); |
| 854 | iio_device_unregister_sysfs(indio_dev); | 854 | iio_device_unregister_sysfs(indio_dev); |
| 855 | iio_device_unregister_debugfs(indio_dev); | ||
| 856 | 855 | ||
| 857 | ida_simple_remove(&iio_ida, indio_dev->id); | 856 | ida_simple_remove(&iio_ida, indio_dev->id); |
| 858 | kfree(indio_dev); | 857 | kfree(indio_dev); |
| @@ -1087,6 +1086,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) | |||
| 1087 | 1086 | ||
| 1088 | if (indio_dev->chrdev.dev) | 1087 | if (indio_dev->chrdev.dev) |
| 1089 | cdev_del(&indio_dev->chrdev); | 1088 | cdev_del(&indio_dev->chrdev); |
| 1089 | iio_device_unregister_debugfs(indio_dev); | ||
| 1090 | 1090 | ||
| 1091 | iio_disable_all_buffers(indio_dev); | 1091 | iio_disable_all_buffers(indio_dev); |
| 1092 | 1092 | ||
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index e8d2849cc81d..cab3bc7494a2 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c | |||
| @@ -29,9 +29,9 @@ | |||
| 29 | #define ST_MAGN_NUMBER_DATA_CHANNELS 3 | 29 | #define ST_MAGN_NUMBER_DATA_CHANNELS 3 |
| 30 | 30 | ||
| 31 | /* DEFAULT VALUE FOR SENSORS */ | 31 | /* DEFAULT VALUE FOR SENSORS */ |
| 32 | #define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04 | 32 | #define ST_MAGN_DEFAULT_OUT_X_H_ADDR 0X03 |
| 33 | #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08 | 33 | #define ST_MAGN_DEFAULT_OUT_Y_H_ADDR 0X07 |
| 34 | #define ST_MAGN_DEFAULT_OUT_Z_L_ADDR 0X06 | 34 | #define ST_MAGN_DEFAULT_OUT_Z_H_ADDR 0X05 |
| 35 | 35 | ||
| 36 | /* FULLSCALE */ | 36 | /* FULLSCALE */ |
| 37 | #define ST_MAGN_FS_AVL_1300MG 1300 | 37 | #define ST_MAGN_FS_AVL_1300MG 1300 |
| @@ -117,16 +117,16 @@ | |||
| 117 | static const struct iio_chan_spec st_magn_16bit_channels[] = { | 117 | static const struct iio_chan_spec st_magn_16bit_channels[] = { |
| 118 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, | 118 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, |
| 119 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | 119 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), |
| 120 | ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16, | 120 | ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16, |
| 121 | ST_MAGN_DEFAULT_OUT_X_L_ADDR), | 121 | ST_MAGN_DEFAULT_OUT_X_H_ADDR), |
| 122 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, | 122 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, |
| 123 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | 123 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), |
| 124 | ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16, | 124 | ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16, |
| 125 | ST_MAGN_DEFAULT_OUT_Y_L_ADDR), | 125 | ST_MAGN_DEFAULT_OUT_Y_H_ADDR), |
| 126 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, | 126 | ST_SENSORS_LSM_CHANNELS(IIO_MAGN, |
| 127 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | 127 | BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), |
| 128 | ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16, | 128 | ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16, |
| 129 | ST_MAGN_DEFAULT_OUT_Z_L_ADDR), | 129 | ST_MAGN_DEFAULT_OUT_Z_H_ADDR), |
| 130 | IIO_CHAN_SOFT_TIMESTAMP(3) | 130 | IIO_CHAN_SOFT_TIMESTAMP(3) |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 653ac6bfc57a..6c923c7039a1 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
| @@ -1588,7 +1588,7 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, | |||
| 1588 | int resp_data_len; | 1588 | int resp_data_len; |
| 1589 | int resp_len; | 1589 | int resp_len; |
| 1590 | 1590 | ||
| 1591 | resp_data_len = (rsp_code == SRP_TSK_MGMT_SUCCESS) ? 0 : 4; | 1591 | resp_data_len = 4; |
| 1592 | resp_len = sizeof(*srp_rsp) + resp_data_len; | 1592 | resp_len = sizeof(*srp_rsp) + resp_data_len; |
| 1593 | 1593 | ||
| 1594 | srp_rsp = ioctx->ioctx.buf; | 1594 | srp_rsp = ioctx->ioctx.buf; |
| @@ -1600,11 +1600,9 @@ static int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, | |||
| 1600 | + atomic_xchg(&ch->req_lim_delta, 0)); | 1600 | + atomic_xchg(&ch->req_lim_delta, 0)); |
| 1601 | srp_rsp->tag = tag; | 1601 | srp_rsp->tag = tag; |
| 1602 | 1602 | ||
| 1603 | if (rsp_code != SRP_TSK_MGMT_SUCCESS) { | 1603 | srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; |
| 1604 | srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; | 1604 | srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); |
| 1605 | srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); | 1605 | srp_rsp->data[3] = rsp_code; |
| 1606 | srp_rsp->data[3] = rsp_code; | ||
| 1607 | } | ||
| 1608 | 1606 | ||
| 1609 | return resp_len; | 1607 | return resp_len; |
| 1610 | } | 1608 | } |
| @@ -2358,6 +2356,8 @@ static void srpt_release_channel_work(struct work_struct *w) | |||
| 2358 | transport_deregister_session(se_sess); | 2356 | transport_deregister_session(se_sess); |
| 2359 | ch->sess = NULL; | 2357 | ch->sess = NULL; |
| 2360 | 2358 | ||
| 2359 | ib_destroy_cm_id(ch->cm_id); | ||
| 2360 | |||
| 2361 | srpt_destroy_ch_ib(ch); | 2361 | srpt_destroy_ch_ib(ch); |
| 2362 | 2362 | ||
| 2363 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, | 2363 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, |
| @@ -2368,8 +2368,6 @@ static void srpt_release_channel_work(struct work_struct *w) | |||
| 2368 | list_del(&ch->list); | 2368 | list_del(&ch->list); |
| 2369 | spin_unlock_irq(&sdev->spinlock); | 2369 | spin_unlock_irq(&sdev->spinlock); |
| 2370 | 2370 | ||
| 2371 | ib_destroy_cm_id(ch->cm_id); | ||
| 2372 | |||
| 2373 | if (ch->release_done) | 2371 | if (ch->release_done) |
| 2374 | complete(ch->release_done); | 2372 | complete(ch->release_done); |
| 2375 | 2373 | ||
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index f417e89e1e7e..181c9ba929cd 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
| @@ -377,6 +377,7 @@ struct arm_smmu_cfg { | |||
| 377 | u32 cbar; | 377 | u32 cbar; |
| 378 | pgd_t *pgd; | 378 | pgd_t *pgd; |
| 379 | }; | 379 | }; |
| 380 | #define INVALID_IRPTNDX 0xff | ||
| 380 | 381 | ||
| 381 | #define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) | 382 | #define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) |
| 382 | #define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) | 383 | #define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) |
| @@ -840,7 +841,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
| 840 | if (IS_ERR_VALUE(ret)) { | 841 | if (IS_ERR_VALUE(ret)) { |
| 841 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", | 842 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", |
| 842 | root_cfg->irptndx, irq); | 843 | root_cfg->irptndx, irq); |
| 843 | root_cfg->irptndx = -1; | 844 | root_cfg->irptndx = INVALID_IRPTNDX; |
| 844 | goto out_free_context; | 845 | goto out_free_context; |
| 845 | } | 846 | } |
| 846 | 847 | ||
| @@ -869,7 +870,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | |||
| 869 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); | 870 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); |
| 870 | arm_smmu_tlb_inv_context(root_cfg); | 871 | arm_smmu_tlb_inv_context(root_cfg); |
| 871 | 872 | ||
| 872 | if (root_cfg->irptndx != -1) { | 873 | if (root_cfg->irptndx != INVALID_IRPTNDX) { |
| 873 | irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx]; | 874 | irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx]; |
| 874 | free_irq(irq, domain); | 875 | free_irq(irq, domain); |
| 875 | } | 876 | } |
| @@ -1857,8 +1858,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1857 | goto out_put_parent; | 1858 | goto out_put_parent; |
| 1858 | } | 1859 | } |
| 1859 | 1860 | ||
| 1860 | arm_smmu_device_reset(smmu); | ||
| 1861 | |||
| 1862 | for (i = 0; i < smmu->num_global_irqs; ++i) { | 1861 | for (i = 0; i < smmu->num_global_irqs; ++i) { |
| 1863 | err = request_irq(smmu->irqs[i], | 1862 | err = request_irq(smmu->irqs[i], |
| 1864 | arm_smmu_global_fault, | 1863 | arm_smmu_global_fault, |
| @@ -1876,6 +1875,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1876 | spin_lock(&arm_smmu_devices_lock); | 1875 | spin_lock(&arm_smmu_devices_lock); |
| 1877 | list_add(&smmu->list, &arm_smmu_devices); | 1876 | list_add(&smmu->list, &arm_smmu_devices); |
| 1878 | spin_unlock(&arm_smmu_devices_lock); | 1877 | spin_unlock(&arm_smmu_devices_lock); |
| 1878 | |||
| 1879 | arm_smmu_device_reset(smmu); | ||
| 1879 | return 0; | 1880 | return 0; |
| 1880 | 1881 | ||
| 1881 | out_free_irqs: | 1882 | out_free_irqs: |
| @@ -1966,10 +1967,10 @@ static int __init arm_smmu_init(void) | |||
| 1966 | return ret; | 1967 | return ret; |
| 1967 | 1968 | ||
| 1968 | /* Oh, for a proper bus abstraction */ | 1969 | /* Oh, for a proper bus abstraction */ |
| 1969 | if (!iommu_present(&platform_bus_type)); | 1970 | if (!iommu_present(&platform_bus_type)) |
| 1970 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); | 1971 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); |
| 1971 | 1972 | ||
| 1972 | if (!iommu_present(&amba_bustype)); | 1973 | if (!iommu_present(&amba_bustype)) |
| 1973 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); | 1974 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); |
| 1974 | 1975 | ||
| 1975 | return 0; | 1976 | return 0; |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 26b14f9fcac6..6bc9618af094 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
| @@ -168,12 +168,25 @@ static inline int write_disable(struct m25p *flash) | |||
| 168 | */ | 168 | */ |
| 169 | static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) | 169 | static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) |
| 170 | { | 170 | { |
| 171 | int status; | ||
| 172 | bool need_wren = false; | ||
| 173 | |||
| 171 | switch (JEDEC_MFR(jedec_id)) { | 174 | switch (JEDEC_MFR(jedec_id)) { |
| 172 | case CFI_MFR_MACRONIX: | ||
| 173 | case CFI_MFR_ST: /* Micron, actually */ | 175 | case CFI_MFR_ST: /* Micron, actually */ |
| 176 | /* Some Micron need WREN command; all will accept it */ | ||
| 177 | need_wren = true; | ||
| 178 | case CFI_MFR_MACRONIX: | ||
| 174 | case 0xEF /* winbond */: | 179 | case 0xEF /* winbond */: |
| 180 | if (need_wren) | ||
| 181 | write_enable(flash); | ||
| 182 | |||
| 175 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; | 183 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; |
| 176 | return spi_write(flash->spi, flash->command, 1); | 184 | status = spi_write(flash->spi, flash->command, 1); |
| 185 | |||
| 186 | if (need_wren) | ||
| 187 | write_disable(flash); | ||
| 188 | |||
| 189 | return status; | ||
| 177 | default: | 190 | default: |
| 178 | /* Spansion style */ | 191 | /* Spansion style */ |
| 179 | flash->command[0] = OPCODE_BRWR; | 192 | flash->command[0] = OPCODE_BRWR; |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7ed4841327f2..d340b2f198c6 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -2869,10 +2869,8 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd, | |||
| 2869 | 2869 | ||
| 2870 | len = le16_to_cpu(p->ext_param_page_length) * 16; | 2870 | len = le16_to_cpu(p->ext_param_page_length) * 16; |
| 2871 | ep = kmalloc(len, GFP_KERNEL); | 2871 | ep = kmalloc(len, GFP_KERNEL); |
| 2872 | if (!ep) { | 2872 | if (!ep) |
| 2873 | ret = -ENOMEM; | 2873 | return -ENOMEM; |
| 2874 | goto ext_out; | ||
| 2875 | } | ||
| 2876 | 2874 | ||
| 2877 | /* Send our own NAND_CMD_PARAM. */ | 2875 | /* Send our own NAND_CMD_PARAM. */ |
| 2878 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); | 2876 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); |
| @@ -2920,7 +2918,7 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd, | |||
| 2920 | } | 2918 | } |
| 2921 | 2919 | ||
| 2922 | pr_info("ONFI extended param page detected.\n"); | 2920 | pr_info("ONFI extended param page detected.\n"); |
| 2923 | return 0; | 2921 | ret = 0; |
| 2924 | 2922 | ||
| 2925 | ext_out: | 2923 | ext_out: |
| 2926 | kfree(ep); | 2924 | kfree(ep); |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 8cd34bf644b3..77df9cb00688 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
| @@ -145,9 +145,11 @@ bool __init sclp_has_linemode(void) | |||
| 145 | 145 | ||
| 146 | if (sccb->header.response_code != 0x20) | 146 | if (sccb->header.response_code != 0x20) |
| 147 | return 0; | 147 | return 0; |
| 148 | if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)) | 148 | if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK))) |
| 149 | return 1; | 149 | return 0; |
| 150 | return 0; | 150 | if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))) |
| 151 | return 0; | ||
| 152 | return 1; | ||
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | bool __init sclp_has_vt220(void) | 155 | bool __init sclp_has_vt220(void) |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index a0f47c83fd62..3f4ca4e09a4c 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
| @@ -810,7 +810,7 @@ static void tty3270_resize_work(struct work_struct *work) | |||
| 810 | struct winsize ws; | 810 | struct winsize ws; |
| 811 | 811 | ||
| 812 | screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols); | 812 | screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols); |
| 813 | if (!screen) | 813 | if (IS_ERR(screen)) |
| 814 | return; | 814 | return; |
| 815 | /* Switch to new output size */ | 815 | /* Switch to new output size */ |
| 816 | spin_lock_bh(&tp->view.lock); | 816 | spin_lock_bh(&tp->view.lock); |
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index fd7cc566095a..d4ac60b4a56e 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
| @@ -1583,7 +1583,7 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
| 1583 | /* Initialize the hardware */ | 1583 | /* Initialize the hardware */ |
| 1584 | ret = clk_prepare_enable(clk); | 1584 | ret = clk_prepare_enable(clk); |
| 1585 | if (ret) | 1585 | if (ret) |
| 1586 | goto out_unmap_regs; | 1586 | goto out_free_irq; |
| 1587 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1587 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1588 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1588 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1589 | if (as->caps.has_wdrbt) { | 1589 | if (as->caps.has_wdrbt) { |
| @@ -1614,6 +1614,7 @@ out_free_dma: | |||
| 1614 | spi_writel(as, CR, SPI_BIT(SWRST)); | 1614 | spi_writel(as, CR, SPI_BIT(SWRST)); |
| 1615 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | 1615 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ |
| 1616 | clk_disable_unprepare(clk); | 1616 | clk_disable_unprepare(clk); |
| 1617 | out_free_irq: | ||
| 1617 | free_irq(irq, master); | 1618 | free_irq(irq, master); |
| 1618 | out_unmap_regs: | 1619 | out_unmap_regs: |
| 1619 | iounmap(as->regs); | 1620 | iounmap(as->regs); |
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 5655acf55bfe..6416798828e7 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c | |||
| @@ -226,7 +226,6 @@ static int spi_clps711x_probe(struct platform_device *pdev) | |||
| 226 | dev_name(&pdev->dev), hw); | 226 | dev_name(&pdev->dev), hw); |
| 227 | if (ret) { | 227 | if (ret) { |
| 228 | dev_err(&pdev->dev, "Can't request IRQ\n"); | 228 | dev_err(&pdev->dev, "Can't request IRQ\n"); |
| 229 | clk_put(hw->spi_clk); | ||
| 230 | goto clk_out; | 229 | goto clk_out; |
| 231 | } | 230 | } |
| 232 | 231 | ||
| @@ -247,7 +246,6 @@ err_out: | |||
| 247 | gpio_free(hw->chipselect[i]); | 246 | gpio_free(hw->chipselect[i]); |
| 248 | 247 | ||
| 249 | spi_master_put(master); | 248 | spi_master_put(master); |
| 250 | kfree(master); | ||
| 251 | 249 | ||
| 252 | return ret; | 250 | return ret; |
| 253 | } | 251 | } |
| @@ -263,7 +261,6 @@ static int spi_clps711x_remove(struct platform_device *pdev) | |||
| 263 | gpio_free(hw->chipselect[i]); | 261 | gpio_free(hw->chipselect[i]); |
| 264 | 262 | ||
| 265 | spi_unregister_master(master); | 263 | spi_unregister_master(master); |
| 266 | kfree(master); | ||
| 267 | 264 | ||
| 268 | return 0; | 265 | return 0; |
| 269 | } | 266 | } |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 6cd07d13ecab..4e44575bd87a 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
| @@ -476,15 +476,9 @@ static int dspi_probe(struct platform_device *pdev) | |||
| 476 | master->bus_num = bus_num; | 476 | master->bus_num = bus_num; |
| 477 | 477 | ||
| 478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 479 | if (!res) { | ||
| 480 | dev_err(&pdev->dev, "can't get platform resource\n"); | ||
| 481 | ret = -EINVAL; | ||
| 482 | goto out_master_put; | ||
| 483 | } | ||
| 484 | |||
| 485 | dspi->base = devm_ioremap_resource(&pdev->dev, res); | 479 | dspi->base = devm_ioremap_resource(&pdev->dev, res); |
| 486 | if (!dspi->base) { | 480 | if (IS_ERR(dspi->base)) { |
| 487 | ret = -EINVAL; | 481 | ret = PTR_ERR(dspi->base); |
| 488 | goto out_master_put; | 482 | goto out_master_put; |
| 489 | } | 483 | } |
| 490 | 484 | ||
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index dbc5e999a1f5..6adf4e35816d 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c | |||
| @@ -522,8 +522,10 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, | |||
| 522 | psc_num = master->bus_num; | 522 | psc_num = master->bus_num; |
| 523 | snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); | 523 | snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); |
| 524 | clk = devm_clk_get(dev, clk_name); | 524 | clk = devm_clk_get(dev, clk_name); |
| 525 | if (IS_ERR(clk)) | 525 | if (IS_ERR(clk)) { |
| 526 | ret = PTR_ERR(clk); | ||
| 526 | goto free_irq; | 527 | goto free_irq; |
| 528 | } | ||
| 527 | ret = clk_prepare_enable(clk); | 529 | ret = clk_prepare_enable(clk); |
| 528 | if (ret) | 530 | if (ret) |
| 529 | goto free_irq; | 531 | goto free_irq; |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 2eb06ee0b326..c1a50674c1e3 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
| @@ -546,8 +546,17 @@ static irqreturn_t ssp_int(int irq, void *dev_id) | |||
| 546 | if (pm_runtime_suspended(&drv_data->pdev->dev)) | 546 | if (pm_runtime_suspended(&drv_data->pdev->dev)) |
| 547 | return IRQ_NONE; | 547 | return IRQ_NONE; |
| 548 | 548 | ||
| 549 | sccr1_reg = read_SSCR1(reg); | 549 | /* |
| 550 | * If the device is not yet in RPM suspended state and we get an | ||
| 551 | * interrupt that is meant for another device, check if status bits | ||
| 552 | * are all set to one. That means that the device is already | ||
| 553 | * powered off. | ||
| 554 | */ | ||
| 550 | status = read_SSSR(reg); | 555 | status = read_SSSR(reg); |
| 556 | if (status == ~0) | ||
| 557 | return IRQ_NONE; | ||
| 558 | |||
| 559 | sccr1_reg = read_SSCR1(reg); | ||
| 551 | 560 | ||
| 552 | /* Ignore possible writes if we don't need to write */ | 561 | /* Ignore possible writes if we don't need to write */ |
| 553 | if (!(sccr1_reg & SSCR1_TIE)) | 562 | if (!(sccr1_reg & SSCR1_TIE)) |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 512b8893893b..a80376dc3a10 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
| @@ -1428,6 +1428,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) | |||
| 1428 | S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, | 1428 | S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, |
| 1429 | sdd->regs + S3C64XX_SPI_INT_EN); | 1429 | sdd->regs + S3C64XX_SPI_INT_EN); |
| 1430 | 1430 | ||
| 1431 | pm_runtime_enable(&pdev->dev); | ||
| 1432 | |||
| 1431 | if (spi_register_master(master)) { | 1433 | if (spi_register_master(master)) { |
| 1432 | dev_err(&pdev->dev, "cannot register SPI master\n"); | 1434 | dev_err(&pdev->dev, "cannot register SPI master\n"); |
| 1433 | ret = -EBUSY; | 1435 | ret = -EBUSY; |
| @@ -1440,8 +1442,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) | |||
| 1440 | mem_res, | 1442 | mem_res, |
| 1441 | sdd->rx_dma.dmach, sdd->tx_dma.dmach); | 1443 | sdd->rx_dma.dmach, sdd->tx_dma.dmach); |
| 1442 | 1444 | ||
| 1443 | pm_runtime_enable(&pdev->dev); | ||
| 1444 | |||
| 1445 | return 0; | 1445 | return 0; |
| 1446 | 1446 | ||
| 1447 | err3: | 1447 | err3: |
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 0b68cb592fa4..e488a90a98b8 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c | |||
| @@ -296,6 +296,8 @@ static int hspi_probe(struct platform_device *pdev) | |||
| 296 | goto error1; | 296 | goto error1; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | pm_runtime_enable(&pdev->dev); | ||
| 300 | |||
| 299 | master->num_chipselect = 1; | 301 | master->num_chipselect = 1; |
| 300 | master->bus_num = pdev->id; | 302 | master->bus_num = pdev->id; |
| 301 | master->setup = hspi_setup; | 303 | master->setup = hspi_setup; |
| @@ -309,8 +311,6 @@ static int hspi_probe(struct platform_device *pdev) | |||
| 309 | goto error1; | 311 | goto error1; |
| 310 | } | 312 | } |
| 311 | 313 | ||
| 312 | pm_runtime_enable(&pdev->dev); | ||
| 313 | |||
| 314 | return 0; | 314 | return 0; |
| 315 | 315 | ||
| 316 | error1: | 316 | error1: |
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 3ba4c5712dff..853f62b2b1a9 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c | |||
| @@ -369,28 +369,23 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, | |||
| 369 | { | 369 | { |
| 370 | const struct ni_65xx_board *board = comedi_board(dev); | 370 | const struct ni_65xx_board *board = comedi_board(dev); |
| 371 | struct ni_65xx_private *devpriv = dev->private; | 371 | struct ni_65xx_private *devpriv = dev->private; |
| 372 | unsigned base_bitfield_channel; | 372 | int base_bitfield_channel; |
| 373 | const unsigned max_ports_per_bitfield = 5; | ||
| 374 | unsigned read_bits = 0; | 373 | unsigned read_bits = 0; |
| 375 | unsigned j; | 374 | int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1); |
| 375 | int port_offset; | ||
| 376 | 376 | ||
| 377 | base_bitfield_channel = CR_CHAN(insn->chanspec); | 377 | base_bitfield_channel = CR_CHAN(insn->chanspec); |
| 378 | for (j = 0; j < max_ports_per_bitfield; ++j) { | 378 | for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel); |
| 379 | const unsigned port_offset = | 379 | port_offset <= last_port_offset; port_offset++) { |
| 380 | ni_65xx_port_by_channel(base_bitfield_channel) + j; | 380 | unsigned port = sprivate(s)->base_port + port_offset; |
| 381 | const unsigned port = | 381 | int base_port_channel = port_offset * ni_65xx_channels_per_port; |
| 382 | sprivate(s)->base_port + port_offset; | ||
| 383 | unsigned base_port_channel; | ||
| 384 | unsigned port_mask, port_data, port_read_bits; | 382 | unsigned port_mask, port_data, port_read_bits; |
| 385 | int bitshift; | 383 | int bitshift = base_port_channel - base_bitfield_channel; |
| 386 | if (port >= ni_65xx_total_num_ports(board)) | 384 | |
| 385 | if (bitshift >= 32) | ||
| 387 | break; | 386 | break; |
| 388 | base_port_channel = port_offset * ni_65xx_channels_per_port; | ||
| 389 | port_mask = data[0]; | 387 | port_mask = data[0]; |
| 390 | port_data = data[1]; | 388 | port_data = data[1]; |
| 391 | bitshift = base_port_channel - base_bitfield_channel; | ||
| 392 | if (bitshift >= 32 || bitshift <= -32) | ||
| 393 | break; | ||
| 394 | if (bitshift > 0) { | 389 | if (bitshift > 0) { |
| 395 | port_mask >>= bitshift; | 390 | port_mask >>= bitshift; |
| 396 | port_data >>= bitshift; | 391 | port_data >>= bitshift; |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 35b61f7d6c63..38e44b9abf0f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -753,7 +753,8 @@ static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) | |||
| 753 | 753 | ||
| 754 | static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | 754 | static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) |
| 755 | { | 755 | { |
| 756 | struct iscsi_cmd *cmd; | 756 | LIST_HEAD(ack_list); |
| 757 | struct iscsi_cmd *cmd, *cmd_p; | ||
| 757 | 758 | ||
| 758 | conn->exp_statsn = exp_statsn; | 759 | conn->exp_statsn = exp_statsn; |
| 759 | 760 | ||
| @@ -761,19 +762,23 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
| 761 | return; | 762 | return; |
| 762 | 763 | ||
| 763 | spin_lock_bh(&conn->cmd_lock); | 764 | spin_lock_bh(&conn->cmd_lock); |
| 764 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { | 765 | list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) { |
| 765 | spin_lock(&cmd->istate_lock); | 766 | spin_lock(&cmd->istate_lock); |
| 766 | if ((cmd->i_state == ISTATE_SENT_STATUS) && | 767 | if ((cmd->i_state == ISTATE_SENT_STATUS) && |
| 767 | iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { | 768 | iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { |
| 768 | cmd->i_state = ISTATE_REMOVE; | 769 | cmd->i_state = ISTATE_REMOVE; |
| 769 | spin_unlock(&cmd->istate_lock); | 770 | spin_unlock(&cmd->istate_lock); |
| 770 | iscsit_add_cmd_to_immediate_queue(cmd, conn, | 771 | list_move_tail(&cmd->i_conn_node, &ack_list); |
| 771 | cmd->i_state); | ||
| 772 | continue; | 772 | continue; |
| 773 | } | 773 | } |
| 774 | spin_unlock(&cmd->istate_lock); | 774 | spin_unlock(&cmd->istate_lock); |
| 775 | } | 775 | } |
| 776 | spin_unlock_bh(&conn->cmd_lock); | 776 | spin_unlock_bh(&conn->cmd_lock); |
| 777 | |||
| 778 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { | ||
| 779 | list_del(&cmd->i_conn_node); | ||
| 780 | iscsit_free_cmd(cmd, false); | ||
| 781 | } | ||
| 777 | } | 782 | } |
| 778 | 783 | ||
| 779 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) | 784 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 14d1aed5af1d..ef6d836a4d09 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
| @@ -1192,7 +1192,7 @@ get_target: | |||
| 1192 | */ | 1192 | */ |
| 1193 | alloc_tags: | 1193 | alloc_tags: |
| 1194 | tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth); | 1194 | tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth); |
| 1195 | tag_num += ISCSIT_EXTRA_TAGS; | 1195 | tag_num += (tag_num / 2) + ISCSIT_EXTRA_TAGS; |
| 1196 | tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size; | 1196 | tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size; |
| 1197 | 1197 | ||
| 1198 | ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size); | 1198 | ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size); |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index f2de28e178fd..b0cac0c342e1 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
| @@ -736,7 +736,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) | |||
| 736 | * Fallthrough | 736 | * Fallthrough |
| 737 | */ | 737 | */ |
| 738 | case ISCSI_OP_SCSI_TMFUNC: | 738 | case ISCSI_OP_SCSI_TMFUNC: |
| 739 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); | 739 | rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); |
| 740 | if (!rc && shutdown && se_cmd && se_cmd->se_sess) { | 740 | if (!rc && shutdown && se_cmd && se_cmd->se_sess) { |
| 741 | __iscsit_free_cmd(cmd, true, shutdown); | 741 | __iscsit_free_cmd(cmd, true, shutdown); |
| 742 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | 742 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); |
| @@ -752,7 +752,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) | |||
| 752 | se_cmd = &cmd->se_cmd; | 752 | se_cmd = &cmd->se_cmd; |
| 753 | __iscsit_free_cmd(cmd, true, shutdown); | 753 | __iscsit_free_cmd(cmd, true, shutdown); |
| 754 | 754 | ||
| 755 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); | 755 | rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); |
| 756 | if (!rc && shutdown && se_cmd->se_sess) { | 756 | if (!rc && shutdown && se_cmd->se_sess) { |
| 757 | __iscsit_free_cmd(cmd, true, shutdown); | 757 | __iscsit_free_cmd(cmd, true, shutdown); |
| 758 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | 758 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 6c17295e8d7c..4714c6f8da4b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
| @@ -349,7 +349,16 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd) | |||
| 349 | { | 349 | { |
| 350 | struct se_device *dev = cmd->se_dev; | 350 | struct se_device *dev = cmd->se_dev; |
| 351 | 351 | ||
| 352 | cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; | 352 | /* |
| 353 | * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through | ||
| 354 | * within target_complete_ok_work() if the command was successfully | ||
| 355 | * sent to the backend driver. | ||
| 356 | */ | ||
| 357 | spin_lock_irq(&cmd->t_state_lock); | ||
| 358 | if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) | ||
| 359 | cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; | ||
| 360 | spin_unlock_irq(&cmd->t_state_lock); | ||
| 361 | |||
| 353 | /* | 362 | /* |
| 354 | * Unlock ->caw_sem originally obtained during sbc_compare_and_write() | 363 | * Unlock ->caw_sem originally obtained during sbc_compare_and_write() |
| 355 | * before the original READ I/O submission. | 364 | * before the original READ I/O submission. |
| @@ -363,7 +372,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) | |||
| 363 | { | 372 | { |
| 364 | struct se_device *dev = cmd->se_dev; | 373 | struct se_device *dev = cmd->se_dev; |
| 365 | struct scatterlist *write_sg = NULL, *sg; | 374 | struct scatterlist *write_sg = NULL, *sg; |
| 366 | unsigned char *buf, *addr; | 375 | unsigned char *buf = NULL, *addr; |
| 367 | struct sg_mapping_iter m; | 376 | struct sg_mapping_iter m; |
| 368 | unsigned int offset = 0, len; | 377 | unsigned int offset = 0, len; |
| 369 | unsigned int nlbas = cmd->t_task_nolb; | 378 | unsigned int nlbas = cmd->t_task_nolb; |
| @@ -378,6 +387,15 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) | |||
| 378 | */ | 387 | */ |
| 379 | if (!cmd->t_data_sg || !cmd->t_bidi_data_sg) | 388 | if (!cmd->t_data_sg || !cmd->t_bidi_data_sg) |
| 380 | return TCM_NO_SENSE; | 389 | return TCM_NO_SENSE; |
| 390 | /* | ||
| 391 | * Immediately exit + release dev->caw_sem if command has already | ||
| 392 | * been failed with a non-zero SCSI status. | ||
| 393 | */ | ||
| 394 | if (cmd->scsi_status) { | ||
| 395 | pr_err("compare_and_write_callback: non zero scsi_status:" | ||
| 396 | " 0x%02x\n", cmd->scsi_status); | ||
| 397 | goto out; | ||
| 398 | } | ||
| 381 | 399 | ||
| 382 | buf = kzalloc(cmd->data_length, GFP_KERNEL); | 400 | buf = kzalloc(cmd->data_length, GFP_KERNEL); |
| 383 | if (!buf) { | 401 | if (!buf) { |
| @@ -508,6 +526,12 @@ sbc_compare_and_write(struct se_cmd *cmd) | |||
| 508 | cmd->transport_complete_callback = NULL; | 526 | cmd->transport_complete_callback = NULL; |
| 509 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 527 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 510 | } | 528 | } |
| 529 | /* | ||
| 530 | * Reset cmd->data_length to individual block_size in order to not | ||
| 531 | * confuse backend drivers that depend on this value matching the | ||
| 532 | * size of the I/O being submitted. | ||
| 533 | */ | ||
| 534 | cmd->data_length = cmd->t_task_nolb * dev->dev_attrib.block_size; | ||
| 511 | 535 | ||
| 512 | ret = cmd->execute_rw(cmd, cmd->t_bidi_data_sg, cmd->t_bidi_data_nents, | 536 | ret = cmd->execute_rw(cmd, cmd->t_bidi_data_sg, cmd->t_bidi_data_nents, |
| 513 | DMA_FROM_DEVICE); | 537 | DMA_FROM_DEVICE); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 84747cc1aac0..81e945eefbbd 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -236,17 +236,24 @@ int transport_alloc_session_tags(struct se_session *se_sess, | |||
| 236 | { | 236 | { |
| 237 | int rc; | 237 | int rc; |
| 238 | 238 | ||
| 239 | se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, GFP_KERNEL); | 239 | se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, |
| 240 | GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); | ||
| 240 | if (!se_sess->sess_cmd_map) { | 241 | if (!se_sess->sess_cmd_map) { |
| 241 | pr_err("Unable to allocate se_sess->sess_cmd_map\n"); | 242 | se_sess->sess_cmd_map = vzalloc(tag_num * tag_size); |
| 242 | return -ENOMEM; | 243 | if (!se_sess->sess_cmd_map) { |
| 244 | pr_err("Unable to allocate se_sess->sess_cmd_map\n"); | ||
| 245 | return -ENOMEM; | ||
| 246 | } | ||
| 243 | } | 247 | } |
| 244 | 248 | ||
| 245 | rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num); | 249 | rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num); |
| 246 | if (rc < 0) { | 250 | if (rc < 0) { |
| 247 | pr_err("Unable to init se_sess->sess_tag_pool," | 251 | pr_err("Unable to init se_sess->sess_tag_pool," |
| 248 | " tag_num: %u\n", tag_num); | 252 | " tag_num: %u\n", tag_num); |
| 249 | kfree(se_sess->sess_cmd_map); | 253 | if (is_vmalloc_addr(se_sess->sess_cmd_map)) |
| 254 | vfree(se_sess->sess_cmd_map); | ||
| 255 | else | ||
| 256 | kfree(se_sess->sess_cmd_map); | ||
| 250 | se_sess->sess_cmd_map = NULL; | 257 | se_sess->sess_cmd_map = NULL; |
| 251 | return -ENOMEM; | 258 | return -ENOMEM; |
| 252 | } | 259 | } |
| @@ -412,7 +419,10 @@ void transport_free_session(struct se_session *se_sess) | |||
| 412 | { | 419 | { |
| 413 | if (se_sess->sess_cmd_map) { | 420 | if (se_sess->sess_cmd_map) { |
| 414 | percpu_ida_destroy(&se_sess->sess_tag_pool); | 421 | percpu_ida_destroy(&se_sess->sess_tag_pool); |
| 415 | kfree(se_sess->sess_cmd_map); | 422 | if (is_vmalloc_addr(se_sess->sess_cmd_map)) |
| 423 | vfree(se_sess->sess_cmd_map); | ||
| 424 | else | ||
| 425 | kfree(se_sess->sess_cmd_map); | ||
| 416 | } | 426 | } |
| 417 | kmem_cache_free(se_sess_cache, se_sess); | 427 | kmem_cache_free(se_sess_cache, se_sess); |
| 418 | } | 428 | } |
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 4d22e7d2adca..3da4fd10b9f8 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c | |||
| @@ -298,8 +298,8 @@ static int target_xcopy_parse_segdesc_02(struct se_cmd *se_cmd, struct xcopy_op | |||
| 298 | (unsigned long long)xop->dst_lba); | 298 | (unsigned long long)xop->dst_lba); |
| 299 | 299 | ||
| 300 | if (dc != 0) { | 300 | if (dc != 0) { |
| 301 | xop->dbl = (desc[29] << 16) & 0xff; | 301 | xop->dbl = (desc[29] & 0xff) << 16; |
| 302 | xop->dbl |= (desc[30] << 8) & 0xff; | 302 | xop->dbl |= (desc[30] & 0xff) << 8; |
| 303 | xop->dbl |= desc[31] & 0xff; | 303 | xop->dbl |= desc[31] & 0xff; |
| 304 | 304 | ||
| 305 | pr_debug("XCOPY seg desc 0x02: DC=1 w/ dbl: %u\n", xop->dbl); | 305 | pr_debug("XCOPY seg desc 0x02: DC=1 w/ dbl: %u\n", xop->dbl); |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index e61c36cbb866..c193af6a628f 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
| @@ -636,6 +636,7 @@ struct console xenboot_console = { | |||
| 636 | .name = "xenboot", | 636 | .name = "xenboot", |
| 637 | .write = xenboot_write_console, | 637 | .write = xenboot_write_console, |
| 638 | .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, | 638 | .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, |
| 639 | .index = -1, | ||
| 639 | }; | 640 | }; |
| 640 | #endif /* CONFIG_EARLY_PRINTK */ | 641 | #endif /* CONFIG_EARLY_PRINTK */ |
| 641 | 642 | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 01bf5eb4f238..7a744b69c3d1 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
| @@ -2183,28 +2183,34 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
| 2183 | 2183 | ||
| 2184 | if (!input_available_p(tty, 0)) { | 2184 | if (!input_available_p(tty, 0)) { |
| 2185 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { | 2185 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
| 2186 | retval = -EIO; | 2186 | up_read(&tty->termios_rwsem); |
| 2187 | break; | 2187 | tty_flush_to_ldisc(tty); |
| 2188 | } | 2188 | down_read(&tty->termios_rwsem); |
| 2189 | if (tty_hung_up_p(file)) | 2189 | if (!input_available_p(tty, 0)) { |
| 2190 | break; | 2190 | retval = -EIO; |
| 2191 | if (!timeout) | 2191 | break; |
| 2192 | break; | 2192 | } |
| 2193 | if (file->f_flags & O_NONBLOCK) { | 2193 | } else { |
| 2194 | retval = -EAGAIN; | 2194 | if (tty_hung_up_p(file)) |
| 2195 | break; | 2195 | break; |
| 2196 | } | 2196 | if (!timeout) |
| 2197 | if (signal_pending(current)) { | 2197 | break; |
| 2198 | retval = -ERESTARTSYS; | 2198 | if (file->f_flags & O_NONBLOCK) { |
| 2199 | break; | 2199 | retval = -EAGAIN; |
| 2200 | } | 2200 | break; |
| 2201 | n_tty_set_room(tty); | 2201 | } |
| 2202 | up_read(&tty->termios_rwsem); | 2202 | if (signal_pending(current)) { |
| 2203 | retval = -ERESTARTSYS; | ||
| 2204 | break; | ||
| 2205 | } | ||
| 2206 | n_tty_set_room(tty); | ||
| 2207 | up_read(&tty->termios_rwsem); | ||
| 2203 | 2208 | ||
| 2204 | timeout = schedule_timeout(timeout); | 2209 | timeout = schedule_timeout(timeout); |
| 2205 | 2210 | ||
| 2206 | down_read(&tty->termios_rwsem); | 2211 | down_read(&tty->termios_rwsem); |
| 2207 | continue; | 2212 | continue; |
| 2213 | } | ||
| 2208 | } | 2214 | } |
| 2209 | __set_current_state(TASK_RUNNING); | 2215 | __set_current_state(TASK_RUNNING); |
| 2210 | 2216 | ||
diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c index 042320a6c6c7..d514332ac081 100644 --- a/drivers/usb/chipidea/ci_hdrc_pci.c +++ b/drivers/usb/chipidea/ci_hdrc_pci.c | |||
| @@ -129,7 +129,12 @@ static DEFINE_PCI_DEVICE_TABLE(ci_hdrc_pci_id_table) = { | |||
| 129 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), | 129 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), |
| 130 | .driver_data = (kernel_ulong_t)&penwell_pci_platdata, | 130 | .driver_data = (kernel_ulong_t)&penwell_pci_platdata, |
| 131 | }, | 131 | }, |
| 132 | { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } | 132 | { |
| 133 | /* Intel Clovertrail */ | ||
| 134 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006), | ||
| 135 | .driver_data = (kernel_ulong_t)&penwell_pci_platdata, | ||
| 136 | }, | ||
| 137 | { 0 } /* end: all zeroes */ | ||
| 133 | }; | 138 | }; |
| 134 | MODULE_DEVICE_TABLE(pci, ci_hdrc_pci_id_table); | 139 | MODULE_DEVICE_TABLE(pci, ci_hdrc_pci_id_table); |
| 135 | 140 | ||
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 0658908d8968..44cf775a8627 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
| @@ -2256,6 +2256,8 @@ static int ffs_func_bind(struct usb_configuration *c, | |||
| 2256 | data->raw_descs + ret, | 2256 | data->raw_descs + ret, |
| 2257 | (sizeof data->raw_descs) - ret, | 2257 | (sizeof data->raw_descs) - ret, |
| 2258 | __ffs_func_bind_do_descs, func); | 2258 | __ffs_func_bind_do_descs, func); |
| 2259 | if (unlikely(ret < 0)) | ||
| 2260 | goto error; | ||
| 2259 | } | 2261 | } |
| 2260 | 2262 | ||
| 2261 | /* | 2263 | /* |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index cc9207473dbc..0ac6064aa3b8 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
| @@ -2054,7 +2054,7 @@ static struct pxa25x_udc memory = { | |||
| 2054 | /* | 2054 | /* |
| 2055 | * probe - binds to the platform device | 2055 | * probe - binds to the platform device |
| 2056 | */ | 2056 | */ |
| 2057 | static int __init pxa25x_udc_probe(struct platform_device *pdev) | 2057 | static int pxa25x_udc_probe(struct platform_device *pdev) |
| 2058 | { | 2058 | { |
| 2059 | struct pxa25x_udc *dev = &memory; | 2059 | struct pxa25x_udc *dev = &memory; |
| 2060 | int retval, irq; | 2060 | int retval, irq; |
| @@ -2203,7 +2203,7 @@ static void pxa25x_udc_shutdown(struct platform_device *_dev) | |||
| 2203 | pullup_off(); | 2203 | pullup_off(); |
| 2204 | } | 2204 | } |
| 2205 | 2205 | ||
| 2206 | static int __exit pxa25x_udc_remove(struct platform_device *pdev) | 2206 | static int pxa25x_udc_remove(struct platform_device *pdev) |
| 2207 | { | 2207 | { |
| 2208 | struct pxa25x_udc *dev = platform_get_drvdata(pdev); | 2208 | struct pxa25x_udc *dev = platform_get_drvdata(pdev); |
| 2209 | 2209 | ||
| @@ -2294,7 +2294,8 @@ static int pxa25x_udc_resume(struct platform_device *dev) | |||
| 2294 | 2294 | ||
| 2295 | static struct platform_driver udc_driver = { | 2295 | static struct platform_driver udc_driver = { |
| 2296 | .shutdown = pxa25x_udc_shutdown, | 2296 | .shutdown = pxa25x_udc_shutdown, |
| 2297 | .remove = __exit_p(pxa25x_udc_remove), | 2297 | .probe = pxa25x_udc_probe, |
| 2298 | .remove = pxa25x_udc_remove, | ||
| 2298 | .suspend = pxa25x_udc_suspend, | 2299 | .suspend = pxa25x_udc_suspend, |
| 2299 | .resume = pxa25x_udc_resume, | 2300 | .resume = pxa25x_udc_resume, |
| 2300 | .driver = { | 2301 | .driver = { |
| @@ -2303,7 +2304,7 @@ static struct platform_driver udc_driver = { | |||
| 2303 | }, | 2304 | }, |
| 2304 | }; | 2305 | }; |
| 2305 | 2306 | ||
| 2306 | module_platform_driver_probe(udc_driver, pxa25x_udc_probe); | 2307 | module_platform_driver(udc_driver); |
| 2307 | 2308 | ||
| 2308 | MODULE_DESCRIPTION(DRIVER_DESC); | 2309 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 2309 | MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); | 2310 | MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 6bddf1aa2347..a8a99e4748d5 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
| @@ -543,7 +543,7 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg, | |||
| 543 | * FIFO, requests of >512 cause the endpoint to get stuck with a | 543 | * FIFO, requests of >512 cause the endpoint to get stuck with a |
| 544 | * fragment of the end of the transfer in it. | 544 | * fragment of the end of the transfer in it. |
| 545 | */ | 545 | */ |
| 546 | if (can_write > 512) | 546 | if (can_write > 512 && !periodic) |
| 547 | can_write = 512; | 547 | can_write = 512; |
| 548 | 548 | ||
| 549 | /* | 549 | /* |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 4047cbb91bac..bd4138d80a48 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
| @@ -535,6 +535,9 @@ static int dsps_probe(struct platform_device *pdev) | |||
| 535 | struct dsps_glue *glue; | 535 | struct dsps_glue *glue; |
| 536 | int ret; | 536 | int ret; |
| 537 | 537 | ||
| 538 | if (!strcmp(pdev->name, "musb-hdrc")) | ||
| 539 | return -ENODEV; | ||
| 540 | |||
| 538 | match = of_match_node(musb_dsps_of_match, pdev->dev.of_node); | 541 | match = of_match_node(musb_dsps_of_match, pdev->dev.of_node); |
| 539 | if (!match) { | 542 | if (!match) { |
| 540 | dev_err(&pdev->dev, "fail to get matching of_match struct\n"); | 543 | dev_err(&pdev->dev, "fail to get matching of_match struct\n"); |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 9a08679d204d..b19ed213ab85 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -1790,6 +1790,10 @@ int musb_gadget_setup(struct musb *musb) | |||
| 1790 | musb->g.max_speed = USB_SPEED_HIGH; | 1790 | musb->g.max_speed = USB_SPEED_HIGH; |
| 1791 | musb->g.speed = USB_SPEED_UNKNOWN; | 1791 | musb->g.speed = USB_SPEED_UNKNOWN; |
| 1792 | 1792 | ||
| 1793 | MUSB_DEV_MODE(musb); | ||
| 1794 | musb->xceiv->otg->default_a = 0; | ||
| 1795 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
| 1796 | |||
| 1793 | /* this "gadget" abstracts/virtualizes the controller */ | 1797 | /* this "gadget" abstracts/virtualizes the controller */ |
| 1794 | musb->g.name = musb_driver_name; | 1798 | musb->g.name = musb_driver_name; |
| 1795 | musb->g.is_otg = 1; | 1799 | musb->g.is_otg = 1; |
| @@ -1849,7 +1853,6 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
| 1849 | musb->gadget_driver = driver; | 1853 | musb->gadget_driver = driver; |
| 1850 | 1854 | ||
| 1851 | spin_lock_irqsave(&musb->lock, flags); | 1855 | spin_lock_irqsave(&musb->lock, flags); |
| 1852 | musb->is_active = 1; | ||
| 1853 | 1856 | ||
| 1854 | otg_set_peripheral(otg, &musb->g); | 1857 | otg_set_peripheral(otg, &musb->g); |
| 1855 | musb->xceiv->state = OTG_STATE_B_IDLE; | 1858 | musb->xceiv->state = OTG_STATE_B_IDLE; |
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index b2f29c9aebbf..02799a5efcd4 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c | |||
| @@ -241,7 +241,7 @@ static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) | |||
| 241 | 241 | ||
| 242 | /* platform driver interface */ | 242 | /* platform driver interface */ |
| 243 | 243 | ||
| 244 | static int __init gpio_vbus_probe(struct platform_device *pdev) | 244 | static int gpio_vbus_probe(struct platform_device *pdev) |
| 245 | { | 245 | { |
| 246 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); | 246 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); |
| 247 | struct gpio_vbus_data *gpio_vbus; | 247 | struct gpio_vbus_data *gpio_vbus; |
| @@ -349,7 +349,7 @@ err_gpio: | |||
| 349 | return err; | 349 | return err; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static int __exit gpio_vbus_remove(struct platform_device *pdev) | 352 | static int gpio_vbus_remove(struct platform_device *pdev) |
| 353 | { | 353 | { |
| 354 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | 354 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); |
| 355 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); | 355 | struct gpio_vbus_mach_info *pdata = dev_get_platdata(&pdev->dev); |
| @@ -398,8 +398,6 @@ static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { | |||
| 398 | }; | 398 | }; |
| 399 | #endif | 399 | #endif |
| 400 | 400 | ||
| 401 | /* NOTE: the gpio-vbus device may *NOT* be hotplugged */ | ||
| 402 | |||
| 403 | MODULE_ALIAS("platform:gpio-vbus"); | 401 | MODULE_ALIAS("platform:gpio-vbus"); |
| 404 | 402 | ||
| 405 | static struct platform_driver gpio_vbus_driver = { | 403 | static struct platform_driver gpio_vbus_driver = { |
| @@ -410,10 +408,11 @@ static struct platform_driver gpio_vbus_driver = { | |||
| 410 | .pm = &gpio_vbus_dev_pm_ops, | 408 | .pm = &gpio_vbus_dev_pm_ops, |
| 411 | #endif | 409 | #endif |
| 412 | }, | 410 | }, |
| 413 | .remove = __exit_p(gpio_vbus_remove), | 411 | .probe = gpio_vbus_probe, |
| 412 | .remove = gpio_vbus_remove, | ||
| 414 | }; | 413 | }; |
| 415 | 414 | ||
| 416 | module_platform_driver_probe(gpio_vbus_driver, gpio_vbus_probe); | 415 | module_platform_driver(gpio_vbus_driver); |
| 417 | 416 | ||
| 418 | MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); | 417 | MODULE_DESCRIPTION("simple GPIO controlled OTG transceiver driver"); |
| 419 | MODULE_AUTHOR("Philipp Zabel"); | 418 | MODULE_AUTHOR("Philipp Zabel"); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 1cf6f125f5f0..80a7104d5ddb 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 81 | 81 | ||
| 82 | #define HUAWEI_VENDOR_ID 0x12D1 | 82 | #define HUAWEI_VENDOR_ID 0x12D1 |
| 83 | #define HUAWEI_PRODUCT_E173 0x140C | 83 | #define HUAWEI_PRODUCT_E173 0x140C |
| 84 | #define HUAWEI_PRODUCT_E1750 0x1406 | ||
| 84 | #define HUAWEI_PRODUCT_K4505 0x1464 | 85 | #define HUAWEI_PRODUCT_K4505 0x1464 |
| 85 | #define HUAWEI_PRODUCT_K3765 0x1465 | 86 | #define HUAWEI_PRODUCT_K3765 0x1465 |
| 86 | #define HUAWEI_PRODUCT_K4605 0x14C6 | 87 | #define HUAWEI_PRODUCT_K4605 0x14C6 |
| @@ -567,6 +568,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 567 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, | 568 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, |
| 568 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), | 569 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), |
| 569 | .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, | 570 | .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, |
| 571 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), | ||
| 572 | .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, | ||
| 570 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, | 573 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, |
| 571 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, | 574 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, |
| 572 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 575 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 592b31698fc8..ce5221fa393a 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
| @@ -728,7 +728,12 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, | |||
| 728 | } | 728 | } |
| 729 | se_sess = tv_nexus->tvn_se_sess; | 729 | se_sess = tv_nexus->tvn_se_sess; |
| 730 | 730 | ||
| 731 | tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_KERNEL); | 731 | tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC); |
| 732 | if (tag < 0) { | ||
| 733 | pr_err("Unable to obtain tag for tcm_vhost_cmd\n"); | ||
| 734 | return ERR_PTR(-ENOMEM); | ||
| 735 | } | ||
| 736 | |||
| 732 | cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag]; | 737 | cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag]; |
| 733 | sg = cmd->tvc_sgl; | 738 | sg = cmd->tvc_sgl; |
| 734 | pages = cmd->tvc_upages; | 739 | pages = cmd->tvc_upages; |
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 58b7d14b08ee..08cc08f037a6 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
| @@ -107,7 +107,8 @@ static void check_idle_worker(struct btrfs_worker_thread *worker) | |||
| 107 | worker->idle = 1; | 107 | worker->idle = 1; |
| 108 | 108 | ||
| 109 | /* the list may be empty if the worker is just starting */ | 109 | /* the list may be empty if the worker is just starting */ |
| 110 | if (!list_empty(&worker->worker_list)) { | 110 | if (!list_empty(&worker->worker_list) && |
| 111 | !worker->workers->stopping) { | ||
| 111 | list_move(&worker->worker_list, | 112 | list_move(&worker->worker_list, |
| 112 | &worker->workers->idle_list); | 113 | &worker->workers->idle_list); |
| 113 | } | 114 | } |
| @@ -127,7 +128,8 @@ static void check_busy_worker(struct btrfs_worker_thread *worker) | |||
| 127 | spin_lock_irqsave(&worker->workers->lock, flags); | 128 | spin_lock_irqsave(&worker->workers->lock, flags); |
| 128 | worker->idle = 0; | 129 | worker->idle = 0; |
| 129 | 130 | ||
| 130 | if (!list_empty(&worker->worker_list)) { | 131 | if (!list_empty(&worker->worker_list) && |
| 132 | !worker->workers->stopping) { | ||
| 131 | list_move_tail(&worker->worker_list, | 133 | list_move_tail(&worker->worker_list, |
| 132 | &worker->workers->worker_list); | 134 | &worker->workers->worker_list); |
| 133 | } | 135 | } |
| @@ -412,6 +414,7 @@ void btrfs_stop_workers(struct btrfs_workers *workers) | |||
| 412 | int can_stop; | 414 | int can_stop; |
| 413 | 415 | ||
| 414 | spin_lock_irq(&workers->lock); | 416 | spin_lock_irq(&workers->lock); |
| 417 | workers->stopping = 1; | ||
| 415 | list_splice_init(&workers->idle_list, &workers->worker_list); | 418 | list_splice_init(&workers->idle_list, &workers->worker_list); |
| 416 | while (!list_empty(&workers->worker_list)) { | 419 | while (!list_empty(&workers->worker_list)) { |
| 417 | cur = workers->worker_list.next; | 420 | cur = workers->worker_list.next; |
| @@ -455,6 +458,7 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max, | |||
| 455 | workers->ordered = 0; | 458 | workers->ordered = 0; |
| 456 | workers->atomic_start_pending = 0; | 459 | workers->atomic_start_pending = 0; |
| 457 | workers->atomic_worker_start = async_helper; | 460 | workers->atomic_worker_start = async_helper; |
| 461 | workers->stopping = 0; | ||
| 458 | } | 462 | } |
| 459 | 463 | ||
| 460 | /* | 464 | /* |
| @@ -480,15 +484,19 @@ static int __btrfs_start_workers(struct btrfs_workers *workers) | |||
| 480 | atomic_set(&worker->num_pending, 0); | 484 | atomic_set(&worker->num_pending, 0); |
| 481 | atomic_set(&worker->refs, 1); | 485 | atomic_set(&worker->refs, 1); |
| 482 | worker->workers = workers; | 486 | worker->workers = workers; |
| 483 | worker->task = kthread_run(worker_loop, worker, | 487 | worker->task = kthread_create(worker_loop, worker, |
| 484 | "btrfs-%s-%d", workers->name, | 488 | "btrfs-%s-%d", workers->name, |
| 485 | workers->num_workers + 1); | 489 | workers->num_workers + 1); |
| 486 | if (IS_ERR(worker->task)) { | 490 | if (IS_ERR(worker->task)) { |
| 487 | ret = PTR_ERR(worker->task); | 491 | ret = PTR_ERR(worker->task); |
| 488 | kfree(worker); | ||
| 489 | goto fail; | 492 | goto fail; |
| 490 | } | 493 | } |
| 494 | |||
| 491 | spin_lock_irq(&workers->lock); | 495 | spin_lock_irq(&workers->lock); |
| 496 | if (workers->stopping) { | ||
| 497 | spin_unlock_irq(&workers->lock); | ||
| 498 | goto fail_kthread; | ||
| 499 | } | ||
| 492 | list_add_tail(&worker->worker_list, &workers->idle_list); | 500 | list_add_tail(&worker->worker_list, &workers->idle_list); |
| 493 | worker->idle = 1; | 501 | worker->idle = 1; |
| 494 | workers->num_workers++; | 502 | workers->num_workers++; |
| @@ -496,8 +504,13 @@ static int __btrfs_start_workers(struct btrfs_workers *workers) | |||
| 496 | WARN_ON(workers->num_workers_starting < 0); | 504 | WARN_ON(workers->num_workers_starting < 0); |
| 497 | spin_unlock_irq(&workers->lock); | 505 | spin_unlock_irq(&workers->lock); |
| 498 | 506 | ||
| 507 | wake_up_process(worker->task); | ||
| 499 | return 0; | 508 | return 0; |
| 509 | |||
| 510 | fail_kthread: | ||
| 511 | kthread_stop(worker->task); | ||
| 500 | fail: | 512 | fail: |
| 513 | kfree(worker); | ||
| 501 | spin_lock_irq(&workers->lock); | 514 | spin_lock_irq(&workers->lock); |
| 502 | workers->num_workers_starting--; | 515 | workers->num_workers_starting--; |
| 503 | spin_unlock_irq(&workers->lock); | 516 | spin_unlock_irq(&workers->lock); |
diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index 063698b90ce2..1f26792683ed 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h | |||
| @@ -107,6 +107,8 @@ struct btrfs_workers { | |||
| 107 | 107 | ||
| 108 | /* extra name for this worker, used for current->name */ | 108 | /* extra name for this worker, used for current->name */ |
| 109 | char *name; | 109 | char *name; |
| 110 | |||
| 111 | int stopping; | ||
| 110 | }; | 112 | }; |
| 111 | 113 | ||
| 112 | void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); | 114 | void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); |
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 70681686e8dc..9efb94e95858 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
| @@ -535,10 +535,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
| 535 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); | 535 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); |
| 536 | 536 | ||
| 537 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); | 537 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); |
| 538 | if (src_device->bdev) { | 538 | |
| 539 | /* zero out the old super */ | ||
| 540 | btrfs_scratch_superblock(src_device); | ||
| 541 | } | ||
| 542 | /* | 539 | /* |
| 543 | * this is again a consistent state where no dev_replace procedure | 540 | * this is again a consistent state where no dev_replace procedure |
| 544 | * is running, the target device is part of the filesystem, the | 541 | * is running, the target device is part of the filesystem, the |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c09a40db53db..22bda32acb89 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -145,8 +145,16 @@ int __init extent_io_init(void) | |||
| 145 | offsetof(struct btrfs_io_bio, bio)); | 145 | offsetof(struct btrfs_io_bio, bio)); |
| 146 | if (!btrfs_bioset) | 146 | if (!btrfs_bioset) |
| 147 | goto free_buffer_cache; | 147 | goto free_buffer_cache; |
| 148 | |||
| 149 | if (bioset_integrity_create(btrfs_bioset, BIO_POOL_SIZE)) | ||
| 150 | goto free_bioset; | ||
| 151 | |||
| 148 | return 0; | 152 | return 0; |
| 149 | 153 | ||
| 154 | free_bioset: | ||
| 155 | bioset_free(btrfs_bioset); | ||
| 156 | btrfs_bioset = NULL; | ||
| 157 | |||
| 150 | free_buffer_cache: | 158 | free_buffer_cache: |
| 151 | kmem_cache_destroy(extent_buffer_cache); | 159 | kmem_cache_destroy(extent_buffer_cache); |
| 152 | extent_buffer_cache = NULL; | 160 | extent_buffer_cache = NULL; |
| @@ -1614,7 +1622,7 @@ again: | |||
| 1614 | *start = delalloc_start; | 1622 | *start = delalloc_start; |
| 1615 | *end = delalloc_end; | 1623 | *end = delalloc_end; |
| 1616 | free_extent_state(cached_state); | 1624 | free_extent_state(cached_state); |
| 1617 | return found; | 1625 | return 0; |
| 1618 | } | 1626 | } |
| 1619 | 1627 | ||
| 1620 | /* | 1628 | /* |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index e7a95356df83..8c81bdc1ef9b 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -1838,11 +1838,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1838 | assert_qgroups_uptodate(trans); | 1838 | assert_qgroups_uptodate(trans); |
| 1839 | update_super_roots(root); | 1839 | update_super_roots(root); |
| 1840 | 1840 | ||
| 1841 | if (!root->fs_info->log_root_recovering) { | 1841 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); |
| 1842 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); | 1842 | btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); |
| 1843 | btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, | 1843 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, |
| 1847 | sizeof(*root->fs_info->super_copy)); | 1844 | sizeof(*root->fs_info->super_copy)); |
| 1848 | 1845 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a10645830223..043b215769c2 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -1716,6 +1716,7 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, | |||
| 1716 | struct btrfs_device *srcdev) | 1716 | struct btrfs_device *srcdev) |
| 1717 | { | 1717 | { |
| 1718 | WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex)); | 1718 | WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex)); |
| 1719 | |||
| 1719 | list_del_rcu(&srcdev->dev_list); | 1720 | list_del_rcu(&srcdev->dev_list); |
| 1720 | list_del_rcu(&srcdev->dev_alloc_list); | 1721 | list_del_rcu(&srcdev->dev_alloc_list); |
| 1721 | fs_info->fs_devices->num_devices--; | 1722 | fs_info->fs_devices->num_devices--; |
| @@ -1725,9 +1726,13 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, | |||
| 1725 | } | 1726 | } |
| 1726 | if (srcdev->can_discard) | 1727 | if (srcdev->can_discard) |
| 1727 | fs_info->fs_devices->num_can_discard--; | 1728 | fs_info->fs_devices->num_can_discard--; |
| 1728 | if (srcdev->bdev) | 1729 | if (srcdev->bdev) { |
| 1729 | fs_info->fs_devices->open_devices--; | 1730 | fs_info->fs_devices->open_devices--; |
| 1730 | 1731 | ||
| 1732 | /* zero out the old super */ | ||
| 1733 | btrfs_scratch_superblock(srcdev); | ||
| 1734 | } | ||
| 1735 | |||
| 1731 | call_rcu(&srcdev->rcu, free_device); | 1736 | call_rcu(&srcdev->rcu, free_device); |
| 1732 | } | 1737 | } |
| 1733 | 1738 | ||
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index ea723a5e8226..6d0b07217ac9 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -132,5 +132,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
| 132 | extern const struct export_operations cifs_export_ops; | 132 | extern const struct export_operations cifs_export_ops; |
| 133 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ | 133 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ |
| 134 | 134 | ||
| 135 | #define CIFS_VERSION "2.01" | 135 | #define CIFS_VERSION "2.02" |
| 136 | #endif /* _CIFSFS_H */ | 136 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cfa14c80ef3b..52b6f6c26bfc 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -547,9 +547,6 @@ struct TCP_Server_Info { | |||
| 547 | unsigned int max_rw; /* maxRw specifies the maximum */ | 547 | unsigned int max_rw; /* maxRw specifies the maximum */ |
| 548 | /* message size the server can send or receive for */ | 548 | /* message size the server can send or receive for */ |
| 549 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ | 549 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ |
| 550 | unsigned int max_vcs; /* maximum number of smb sessions, at least | ||
| 551 | those that can be specified uniquely with | ||
| 552 | vcnumbers */ | ||
| 553 | unsigned int capabilities; /* selective disabling of caps by smb sess */ | 550 | unsigned int capabilities; /* selective disabling of caps by smb sess */ |
| 554 | int timeAdj; /* Adjust for difference in server time zone in sec */ | 551 | int timeAdj; /* Adjust for difference in server time zone in sec */ |
| 555 | __u64 CurrentMid; /* multiplex id - rotating counter */ | 552 | __u64 CurrentMid; /* multiplex id - rotating counter */ |
| @@ -715,7 +712,6 @@ struct cifs_ses { | |||
| 715 | enum statusEnum status; | 712 | enum statusEnum status; |
| 716 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ | 713 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ |
| 717 | __u16 ipc_tid; /* special tid for connection to IPC share */ | 714 | __u16 ipc_tid; /* special tid for connection to IPC share */ |
| 718 | __u16 vcnum; | ||
| 719 | char *serverOS; /* name of operating system underlying server */ | 715 | char *serverOS; /* name of operating system underlying server */ |
| 720 | char *serverNOS; /* name of network operating system of server */ | 716 | char *serverNOS; /* name of network operating system of server */ |
| 721 | char *serverDomain; /* security realm of server */ | 717 | char *serverDomain; /* security realm of server */ |
| @@ -1272,6 +1268,7 @@ struct dfs_info3_param { | |||
| 1272 | #define CIFS_FATTR_DELETE_PENDING 0x2 | 1268 | #define CIFS_FATTR_DELETE_PENDING 0x2 |
| 1273 | #define CIFS_FATTR_NEED_REVAL 0x4 | 1269 | #define CIFS_FATTR_NEED_REVAL 0x4 |
| 1274 | #define CIFS_FATTR_INO_COLLISION 0x8 | 1270 | #define CIFS_FATTR_INO_COLLISION 0x8 |
| 1271 | #define CIFS_FATTR_UNKNOWN_NLINK 0x10 | ||
| 1275 | 1272 | ||
| 1276 | struct cifs_fattr { | 1273 | struct cifs_fattr { |
| 1277 | u32 cf_flags; | 1274 | u32 cf_flags; |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 948676db8e2e..a630475e421c 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
| @@ -2652,26 +2652,7 @@ typedef struct file_xattr_info { | |||
| 2652 | } __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info | 2652 | } __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info |
| 2653 | level 0x205 */ | 2653 | level 0x205 */ |
| 2654 | 2654 | ||
| 2655 | 2655 | /* flags for lsattr and chflags commands removed arein uapi/linux/fs.h */ | |
| 2656 | /* flags for chattr command */ | ||
| 2657 | #define EXT_SECURE_DELETE 0x00000001 /* EXT3_SECRM_FL */ | ||
| 2658 | #define EXT_ENABLE_UNDELETE 0x00000002 /* EXT3_UNRM_FL */ | ||
| 2659 | /* Reserved for compress file 0x4 */ | ||
| 2660 | #define EXT_SYNCHRONOUS 0x00000008 /* EXT3_SYNC_FL */ | ||
| 2661 | #define EXT_IMMUTABLE_FL 0x00000010 /* EXT3_IMMUTABLE_FL */ | ||
| 2662 | #define EXT_OPEN_APPEND_ONLY 0x00000020 /* EXT3_APPEND_FL */ | ||
| 2663 | #define EXT_DO_NOT_BACKUP 0x00000040 /* EXT3_NODUMP_FL */ | ||
| 2664 | #define EXT_NO_UPDATE_ATIME 0x00000080 /* EXT3_NOATIME_FL */ | ||
| 2665 | /* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */ | ||
| 2666 | #define EXT_HASH_TREE_INDEXED_DIR 0x00001000 /* GET-ONLY EXT3_INDEX_FL */ | ||
| 2667 | /* 0x2000 reserved for IMAGIC_FL */ | ||
| 2668 | #define EXT_JOURNAL_THIS_FILE 0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */ | ||
| 2669 | /* 0x8000 reserved for EXT3_NOTAIL_FL */ | ||
| 2670 | #define EXT_SYNCHRONOUS_DIR 0x00010000 /* EXT3_DIRSYNC_FL */ | ||
| 2671 | #define EXT_TOPDIR 0x00020000 /* EXT3_TOPDIR_FL */ | ||
| 2672 | |||
| 2673 | #define EXT_SET_MASK 0x000300FF | ||
| 2674 | #define EXT_GET_MASK 0x0003DFFF | ||
| 2675 | 2656 | ||
| 2676 | typedef struct file_chattr_info { | 2657 | typedef struct file_chattr_info { |
| 2677 | __le64 mask; /* list of all possible attribute bits */ | 2658 | __le64 mask; /* list of all possible attribute bits */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a3d74fea1623..4baf35949b51 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -463,7 +463,6 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) | |||
| 463 | cifs_max_pending); | 463 | cifs_max_pending); |
| 464 | set_credits(server, server->maxReq); | 464 | set_credits(server, server->maxReq); |
| 465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); | 465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); |
| 466 | server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); | ||
| 467 | /* even though we do not use raw we might as well set this | 466 | /* even though we do not use raw we might as well set this |
| 468 | accurately, in case we ever find a need for it */ | 467 | accurately, in case we ever find a need for it */ |
| 469 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { | 468 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index eb955b525e55..7ddddf2e2504 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -3254,6 +3254,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 3254 | /* | 3254 | /* |
| 3255 | * Reads as many pages as possible from fscache. Returns -ENOBUFS | 3255 | * Reads as many pages as possible from fscache. Returns -ENOBUFS |
| 3256 | * immediately if the cookie is negative | 3256 | * immediately if the cookie is negative |
| 3257 | * | ||
| 3258 | * After this point, every page in the list might have PG_fscache set, | ||
| 3259 | * so we will need to clean that up off of every page we don't use. | ||
| 3257 | */ | 3260 | */ |
| 3258 | rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list, | 3261 | rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list, |
| 3259 | &num_pages); | 3262 | &num_pages); |
| @@ -3376,6 +3379,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 3376 | kref_put(&rdata->refcount, cifs_readdata_release); | 3379 | kref_put(&rdata->refcount, cifs_readdata_release); |
| 3377 | } | 3380 | } |
| 3378 | 3381 | ||
| 3382 | /* Any pages that have been shown to fscache but didn't get added to | ||
| 3383 | * the pagecache must be uncached before they get returned to the | ||
| 3384 | * allocator. | ||
| 3385 | */ | ||
| 3386 | cifs_fscache_readpages_cancel(mapping->host, page_list); | ||
| 3379 | return rc; | 3387 | return rc; |
| 3380 | } | 3388 | } |
| 3381 | 3389 | ||
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index 2f4bc5a58054..b3258f35e88a 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c | |||
| @@ -223,6 +223,13 @@ void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) | |||
| 223 | fscache_uncache_page(CIFS_I(inode)->fscache, page); | 223 | fscache_uncache_page(CIFS_I(inode)->fscache, page); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | void __cifs_fscache_readpages_cancel(struct inode *inode, struct list_head *pages) | ||
| 227 | { | ||
| 228 | cifs_dbg(FYI, "%s: (fsc: %p, i: %p)\n", | ||
| 229 | __func__, CIFS_I(inode)->fscache, inode); | ||
| 230 | fscache_readpages_cancel(CIFS_I(inode)->fscache, pages); | ||
| 231 | } | ||
| 232 | |||
| 226 | void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) | 233 | void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode) |
| 227 | { | 234 | { |
| 228 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 235 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h index 63539323e0b9..24794b6cd8ec 100644 --- a/fs/cifs/fscache.h +++ b/fs/cifs/fscache.h | |||
| @@ -54,6 +54,7 @@ extern int __cifs_readpages_from_fscache(struct inode *, | |||
| 54 | struct address_space *, | 54 | struct address_space *, |
| 55 | struct list_head *, | 55 | struct list_head *, |
| 56 | unsigned *); | 56 | unsigned *); |
| 57 | extern void __cifs_fscache_readpages_cancel(struct inode *, struct list_head *); | ||
| 57 | 58 | ||
| 58 | extern void __cifs_readpage_to_fscache(struct inode *, struct page *); | 59 | extern void __cifs_readpage_to_fscache(struct inode *, struct page *); |
| 59 | 60 | ||
| @@ -91,6 +92,13 @@ static inline void cifs_readpage_to_fscache(struct inode *inode, | |||
| 91 | __cifs_readpage_to_fscache(inode, page); | 92 | __cifs_readpage_to_fscache(inode, page); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 95 | static inline void cifs_fscache_readpages_cancel(struct inode *inode, | ||
| 96 | struct list_head *pages) | ||
| 97 | { | ||
| 98 | if (CIFS_I(inode)->fscache) | ||
| 99 | return __cifs_fscache_readpages_cancel(inode, pages); | ||
| 100 | } | ||
| 101 | |||
| 94 | #else /* CONFIG_CIFS_FSCACHE */ | 102 | #else /* CONFIG_CIFS_FSCACHE */ |
| 95 | static inline int cifs_fscache_register(void) { return 0; } | 103 | static inline int cifs_fscache_register(void) { return 0; } |
| 96 | static inline void cifs_fscache_unregister(void) {} | 104 | static inline void cifs_fscache_unregister(void) {} |
| @@ -131,6 +139,11 @@ static inline int cifs_readpages_from_fscache(struct inode *inode, | |||
| 131 | static inline void cifs_readpage_to_fscache(struct inode *inode, | 139 | static inline void cifs_readpage_to_fscache(struct inode *inode, |
| 132 | struct page *page) {} | 140 | struct page *page) {} |
| 133 | 141 | ||
| 142 | static inline void cifs_fscache_readpages_cancel(struct inode *inode, | ||
| 143 | struct list_head *pages) | ||
| 144 | { | ||
| 145 | } | ||
| 146 | |||
| 134 | #endif /* CONFIG_CIFS_FSCACHE */ | 147 | #endif /* CONFIG_CIFS_FSCACHE */ |
| 135 | 148 | ||
| 136 | #endif /* _CIFS_FSCACHE_H */ | 149 | #endif /* _CIFS_FSCACHE_H */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index f9ff9c173f78..867b7cdc794a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -120,6 +120,33 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) | |||
| 120 | cifs_i->invalid_mapping = true; | 120 | cifs_i->invalid_mapping = true; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /* | ||
| 124 | * copy nlink to the inode, unless it wasn't provided. Provide | ||
| 125 | * sane values if we don't have an existing one and none was provided | ||
| 126 | */ | ||
| 127 | static void | ||
| 128 | cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | ||
| 129 | { | ||
| 130 | /* | ||
| 131 | * if we're in a situation where we can't trust what we | ||
| 132 | * got from the server (readdir, some non-unix cases) | ||
| 133 | * fake reasonable values | ||
| 134 | */ | ||
| 135 | if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) { | ||
| 136 | /* only provide fake values on a new inode */ | ||
| 137 | if (inode->i_state & I_NEW) { | ||
| 138 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) | ||
| 139 | set_nlink(inode, 2); | ||
| 140 | else | ||
| 141 | set_nlink(inode, 1); | ||
| 142 | } | ||
| 143 | return; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* we trust the server, so update it */ | ||
| 147 | set_nlink(inode, fattr->cf_nlink); | ||
| 148 | } | ||
| 149 | |||
| 123 | /* populate an inode with info from a cifs_fattr struct */ | 150 | /* populate an inode with info from a cifs_fattr struct */ |
| 124 | void | 151 | void |
| 125 | cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | 152 | cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) |
| @@ -134,7 +161,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) | |||
| 134 | inode->i_mtime = fattr->cf_mtime; | 161 | inode->i_mtime = fattr->cf_mtime; |
| 135 | inode->i_ctime = fattr->cf_ctime; | 162 | inode->i_ctime = fattr->cf_ctime; |
| 136 | inode->i_rdev = fattr->cf_rdev; | 163 | inode->i_rdev = fattr->cf_rdev; |
| 137 | set_nlink(inode, fattr->cf_nlink); | 164 | cifs_nlink_fattr_to_inode(inode, fattr); |
| 138 | inode->i_uid = fattr->cf_uid; | 165 | inode->i_uid = fattr->cf_uid; |
| 139 | inode->i_gid = fattr->cf_gid; | 166 | inode->i_gid = fattr->cf_gid; |
| 140 | 167 | ||
| @@ -541,6 +568,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
| 541 | fattr->cf_bytes = le64_to_cpu(info->AllocationSize); | 568 | fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
| 542 | fattr->cf_createtime = le64_to_cpu(info->CreationTime); | 569 | fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
| 543 | 570 | ||
| 571 | fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); | ||
| 544 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { | 572 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
| 545 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; | 573 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; |
| 546 | fattr->cf_dtype = DT_DIR; | 574 | fattr->cf_dtype = DT_DIR; |
| @@ -548,7 +576,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
| 548 | * Server can return wrong NumberOfLinks value for directories | 576 | * Server can return wrong NumberOfLinks value for directories |
| 549 | * when Unix extensions are disabled - fake it. | 577 | * when Unix extensions are disabled - fake it. |
| 550 | */ | 578 | */ |
| 551 | fattr->cf_nlink = 2; | 579 | if (!tcon->unix_ext) |
| 580 | fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; | ||
| 552 | } else if (fattr->cf_cifsattrs & ATTR_REPARSE) { | 581 | } else if (fattr->cf_cifsattrs & ATTR_REPARSE) { |
| 553 | fattr->cf_mode = S_IFLNK; | 582 | fattr->cf_mode = S_IFLNK; |
| 554 | fattr->cf_dtype = DT_LNK; | 583 | fattr->cf_dtype = DT_LNK; |
| @@ -561,11 +590,15 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
| 561 | if (fattr->cf_cifsattrs & ATTR_READONLY) | 590 | if (fattr->cf_cifsattrs & ATTR_READONLY) |
| 562 | fattr->cf_mode &= ~(S_IWUGO); | 591 | fattr->cf_mode &= ~(S_IWUGO); |
| 563 | 592 | ||
| 564 | fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); | 593 | /* |
| 565 | if (fattr->cf_nlink < 1) { | 594 | * Don't accept zero nlink from non-unix servers unless |
| 566 | cifs_dbg(1, "replacing bogus file nlink value %u\n", | 595 | * delete is pending. Instead mark it as unknown. |
| 596 | */ | ||
| 597 | if ((fattr->cf_nlink < 1) && !tcon->unix_ext && | ||
| 598 | !info->DeletePending) { | ||
| 599 | cifs_dbg(1, "bogus file nlink value %u\n", | ||
| 567 | fattr->cf_nlink); | 600 | fattr->cf_nlink); |
| 568 | fattr->cf_nlink = 1; | 601 | fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; |
| 569 | } | 602 | } |
| 570 | } | 603 | } |
| 571 | 604 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 42ef03be089f..53a75f3d0179 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -180,6 +180,9 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) | |||
| 180 | fattr->cf_dtype = DT_REG; | 180 | fattr->cf_dtype = DT_REG; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /* non-unix readdir doesn't provide nlink */ | ||
| 184 | fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK; | ||
| 185 | |||
| 183 | if (fattr->cf_cifsattrs & ATTR_READONLY) | 186 | if (fattr->cf_cifsattrs & ATTR_READONLY) |
| 184 | fattr->cf_mode &= ~S_IWUGO; | 187 | fattr->cf_mode &= ~S_IWUGO; |
| 185 | 188 | ||
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 5f99b7f19e78..352358de1d7e 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -32,88 +32,6 @@ | |||
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include "cifs_spnego.h" | 33 | #include "cifs_spnego.h" |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * Checks if this is the first smb session to be reconnected after | ||
| 37 | * the socket has been reestablished (so we know whether to use vc 0). | ||
| 38 | * Called while holding the cifs_tcp_ses_lock, so do not block | ||
| 39 | */ | ||
| 40 | static bool is_first_ses_reconnect(struct cifs_ses *ses) | ||
| 41 | { | ||
| 42 | struct list_head *tmp; | ||
| 43 | struct cifs_ses *tmp_ses; | ||
| 44 | |||
| 45 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 46 | tmp_ses = list_entry(tmp, struct cifs_ses, | ||
| 47 | smb_ses_list); | ||
| 48 | if (tmp_ses->need_reconnect == false) | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | /* could not find a session that was already connected, | ||
| 52 | this must be the first one we are reconnecting */ | ||
| 53 | return true; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * vc number 0 is treated specially by some servers, and should be the | ||
| 58 | * first one we request. After that we can use vcnumbers up to maxvcs, | ||
| 59 | * one for each smb session (some Windows versions set maxvcs incorrectly | ||
| 60 | * so maxvc=1 can be ignored). If we have too many vcs, we can reuse | ||
| 61 | * any vc but zero (some servers reset the connection on vcnum zero) | ||
| 62 | * | ||
| 63 | */ | ||
| 64 | static __le16 get_next_vcnum(struct cifs_ses *ses) | ||
| 65 | { | ||
| 66 | __u16 vcnum = 0; | ||
| 67 | struct list_head *tmp; | ||
| 68 | struct cifs_ses *tmp_ses; | ||
| 69 | __u16 max_vcs = ses->server->max_vcs; | ||
| 70 | __u16 i; | ||
| 71 | int free_vc_found = 0; | ||
| 72 | |||
| 73 | /* Quoting the MS-SMB specification: "Windows-based SMB servers set this | ||
| 74 | field to one but do not enforce this limit, which allows an SMB client | ||
| 75 | to establish more virtual circuits than allowed by this value ... but | ||
| 76 | other server implementations can enforce this limit." */ | ||
| 77 | if (max_vcs < 2) | ||
| 78 | max_vcs = 0xFFFF; | ||
| 79 | |||
| 80 | spin_lock(&cifs_tcp_ses_lock); | ||
| 81 | if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) | ||
| 82 | goto get_vc_num_exit; /* vcnum will be zero */ | ||
| 83 | for (i = ses->server->srv_count - 1; i < max_vcs; i++) { | ||
| 84 | if (i == 0) /* this is the only connection, use vc 0 */ | ||
| 85 | break; | ||
| 86 | |||
| 87 | free_vc_found = 1; | ||
| 88 | |||
| 89 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 90 | tmp_ses = list_entry(tmp, struct cifs_ses, | ||
| 91 | smb_ses_list); | ||
| 92 | if (tmp_ses->vcnum == i) { | ||
| 93 | free_vc_found = 0; | ||
| 94 | break; /* found duplicate, try next vcnum */ | ||
| 95 | } | ||
| 96 | } | ||
| 97 | if (free_vc_found) | ||
| 98 | break; /* we found a vcnumber that will work - use it */ | ||
| 99 | } | ||
| 100 | |||
| 101 | if (i == 0) | ||
| 102 | vcnum = 0; /* for most common case, ie if one smb session, use | ||
| 103 | vc zero. Also for case when no free vcnum, zero | ||
| 104 | is safest to send (some clients only send zero) */ | ||
| 105 | else if (free_vc_found == 0) | ||
| 106 | vcnum = 1; /* we can not reuse vc=0 safely, since some servers | ||
| 107 | reset all uids on that, but 1 is ok. */ | ||
| 108 | else | ||
| 109 | vcnum = i; | ||
| 110 | ses->vcnum = vcnum; | ||
| 111 | get_vc_num_exit: | ||
| 112 | spin_unlock(&cifs_tcp_ses_lock); | ||
| 113 | |||
| 114 | return cpu_to_le16(vcnum); | ||
| 115 | } | ||
| 116 | |||
| 117 | static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) | 35 | static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) |
| 118 | { | 36 | { |
| 119 | __u32 capabilities = 0; | 37 | __u32 capabilities = 0; |
| @@ -128,7 +46,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) | |||
| 128 | CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4, | 46 | CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4, |
| 129 | USHRT_MAX)); | 47 | USHRT_MAX)); |
| 130 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); | 48 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); |
| 131 | pSMB->req.VcNumber = get_next_vcnum(ses); | 49 | pSMB->req.VcNumber = __constant_cpu_to_le16(1); |
| 132 | 50 | ||
| 133 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ | 51 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ |
| 134 | 52 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 62b43b577bfc..b7989f2ab4c4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -182,6 +182,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) | |||
| 182 | struct inode *inode; | 182 | struct inode *inode; |
| 183 | struct dentry *parent; | 183 | struct dentry *parent; |
| 184 | struct fuse_conn *fc; | 184 | struct fuse_conn *fc; |
| 185 | struct fuse_inode *fi; | ||
| 185 | int ret; | 186 | int ret; |
| 186 | 187 | ||
| 187 | inode = ACCESS_ONCE(entry->d_inode); | 188 | inode = ACCESS_ONCE(entry->d_inode); |
| @@ -228,7 +229,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) | |||
| 228 | if (!err && !outarg.nodeid) | 229 | if (!err && !outarg.nodeid) |
| 229 | err = -ENOENT; | 230 | err = -ENOENT; |
| 230 | if (!err) { | 231 | if (!err) { |
| 231 | struct fuse_inode *fi = get_fuse_inode(inode); | 232 | fi = get_fuse_inode(inode); |
| 232 | if (outarg.nodeid != get_node_id(inode)) { | 233 | if (outarg.nodeid != get_node_id(inode)) { |
| 233 | fuse_queue_forget(fc, forget, outarg.nodeid, 1); | 234 | fuse_queue_forget(fc, forget, outarg.nodeid, 1); |
| 234 | goto invalid; | 235 | goto invalid; |
| @@ -246,8 +247,11 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) | |||
| 246 | attr_version); | 247 | attr_version); |
| 247 | fuse_change_entry_timeout(entry, &outarg); | 248 | fuse_change_entry_timeout(entry, &outarg); |
| 248 | } else if (inode) { | 249 | } else if (inode) { |
| 249 | fc = get_fuse_conn(inode); | 250 | fi = get_fuse_inode(inode); |
| 250 | if (fc->readdirplus_auto) { | 251 | if (flags & LOOKUP_RCU) { |
| 252 | if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state)) | ||
| 253 | return -ECHILD; | ||
| 254 | } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) { | ||
| 251 | parent = dget_parent(entry); | 255 | parent = dget_parent(entry); |
| 252 | fuse_advise_use_readdirplus(parent->d_inode); | 256 | fuse_advise_use_readdirplus(parent->d_inode); |
| 253 | dput(parent); | 257 | dput(parent); |
| @@ -259,7 +263,8 @@ out: | |||
| 259 | 263 | ||
| 260 | invalid: | 264 | invalid: |
| 261 | ret = 0; | 265 | ret = 0; |
| 262 | if (check_submounts_and_drop(entry) != 0) | 266 | |
| 267 | if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0) | ||
| 263 | ret = 1; | 268 | ret = 1; |
| 264 | goto out; | 269 | goto out; |
| 265 | } | 270 | } |
| @@ -1063,6 +1068,8 @@ static int fuse_access(struct inode *inode, int mask) | |||
| 1063 | struct fuse_access_in inarg; | 1068 | struct fuse_access_in inarg; |
| 1064 | int err; | 1069 | int err; |
| 1065 | 1070 | ||
| 1071 | BUG_ON(mask & MAY_NOT_BLOCK); | ||
| 1072 | |||
| 1066 | if (fc->no_access) | 1073 | if (fc->no_access) |
| 1067 | return 0; | 1074 | return 0; |
| 1068 | 1075 | ||
| @@ -1150,9 +1157,6 @@ static int fuse_permission(struct inode *inode, int mask) | |||
| 1150 | noticed immediately, only after the attribute | 1157 | noticed immediately, only after the attribute |
| 1151 | timeout has expired */ | 1158 | timeout has expired */ |
| 1152 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { | 1159 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { |
| 1153 | if (mask & MAY_NOT_BLOCK) | ||
| 1154 | return -ECHILD; | ||
| 1155 | |||
| 1156 | err = fuse_access(inode, mask); | 1160 | err = fuse_access(inode, mask); |
| 1157 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { | 1161 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
| 1158 | if (!(inode->i_mode & S_IXUGO)) { | 1162 | if (!(inode->i_mode & S_IXUGO)) { |
| @@ -1291,6 +1295,8 @@ static int fuse_direntplus_link(struct file *file, | |||
| 1291 | } | 1295 | } |
| 1292 | 1296 | ||
| 1293 | found: | 1297 | found: |
| 1298 | if (fc->readdirplus_auto) | ||
| 1299 | set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); | ||
| 1294 | fuse_change_entry_timeout(dentry, o); | 1300 | fuse_change_entry_timeout(dentry, o); |
| 1295 | 1301 | ||
| 1296 | err = 0; | 1302 | err = 0; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d409deafc67b..4598345ab87d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -2467,6 +2467,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2467 | { | 2467 | { |
| 2468 | struct fuse_file *ff = file->private_data; | 2468 | struct fuse_file *ff = file->private_data; |
| 2469 | struct inode *inode = file->f_inode; | 2469 | struct inode *inode = file->f_inode; |
| 2470 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
| 2470 | struct fuse_conn *fc = ff->fc; | 2471 | struct fuse_conn *fc = ff->fc; |
| 2471 | struct fuse_req *req; | 2472 | struct fuse_req *req; |
| 2472 | struct fuse_fallocate_in inarg = { | 2473 | struct fuse_fallocate_in inarg = { |
| @@ -2484,10 +2485,20 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2484 | 2485 | ||
| 2485 | if (lock_inode) { | 2486 | if (lock_inode) { |
| 2486 | mutex_lock(&inode->i_mutex); | 2487 | mutex_lock(&inode->i_mutex); |
| 2487 | if (mode & FALLOC_FL_PUNCH_HOLE) | 2488 | if (mode & FALLOC_FL_PUNCH_HOLE) { |
| 2488 | fuse_set_nowrite(inode); | 2489 | loff_t endbyte = offset + length - 1; |
| 2490 | err = filemap_write_and_wait_range(inode->i_mapping, | ||
| 2491 | offset, endbyte); | ||
| 2492 | if (err) | ||
| 2493 | goto out; | ||
| 2494 | |||
| 2495 | fuse_sync_writes(inode); | ||
| 2496 | } | ||
| 2489 | } | 2497 | } |
| 2490 | 2498 | ||
| 2499 | if (!(mode & FALLOC_FL_KEEP_SIZE)) | ||
| 2500 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); | ||
| 2501 | |||
| 2491 | req = fuse_get_req_nopages(fc); | 2502 | req = fuse_get_req_nopages(fc); |
| 2492 | if (IS_ERR(req)) { | 2503 | if (IS_ERR(req)) { |
| 2493 | err = PTR_ERR(req); | 2504 | err = PTR_ERR(req); |
| @@ -2520,11 +2531,11 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2520 | fuse_invalidate_attr(inode); | 2531 | fuse_invalidate_attr(inode); |
| 2521 | 2532 | ||
| 2522 | out: | 2533 | out: |
| 2523 | if (lock_inode) { | 2534 | if (!(mode & FALLOC_FL_KEEP_SIZE)) |
| 2524 | if (mode & FALLOC_FL_PUNCH_HOLE) | 2535 | clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); |
| 2525 | fuse_release_nowrite(inode); | 2536 | |
| 2537 | if (lock_inode) | ||
| 2526 | mutex_unlock(&inode->i_mutex); | 2538 | mutex_unlock(&inode->i_mutex); |
| 2527 | } | ||
| 2528 | 2539 | ||
| 2529 | return err; | 2540 | return err; |
| 2530 | } | 2541 | } |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 5ced199b50bb..5b9e6f3b6aef 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -115,6 +115,8 @@ struct fuse_inode { | |||
| 115 | enum { | 115 | enum { |
| 116 | /** Advise readdirplus */ | 116 | /** Advise readdirplus */ |
| 117 | FUSE_I_ADVISE_RDPLUS, | 117 | FUSE_I_ADVISE_RDPLUS, |
| 118 | /** Initialized with readdirplus */ | ||
| 119 | FUSE_I_INIT_RDPLUS, | ||
| 118 | /** An operation changing file size is in progress */ | 120 | /** An operation changing file size is in progress */ |
| 119 | FUSE_I_SIZE_UNSTABLE, | 121 | FUSE_I_SIZE_UNSTABLE, |
| 120 | }; | 122 | }; |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 0957aa98b6c0..12dad188939d 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
| @@ -1158,7 +1158,7 @@ xfs_dir2_sf_to_block( | |||
| 1158 | /* | 1158 | /* |
| 1159 | * Create entry for . | 1159 | * Create entry for . |
| 1160 | */ | 1160 | */ |
| 1161 | dep = xfs_dir3_data_dot_entry_p(hdr); | 1161 | dep = xfs_dir3_data_dot_entry_p(mp, hdr); |
| 1162 | dep->inumber = cpu_to_be64(dp->i_ino); | 1162 | dep->inumber = cpu_to_be64(dp->i_ino); |
| 1163 | dep->namelen = 1; | 1163 | dep->namelen = 1; |
| 1164 | dep->name[0] = '.'; | 1164 | dep->name[0] = '.'; |
| @@ -1172,7 +1172,7 @@ xfs_dir2_sf_to_block( | |||
| 1172 | /* | 1172 | /* |
| 1173 | * Create entry for .. | 1173 | * Create entry for .. |
| 1174 | */ | 1174 | */ |
| 1175 | dep = xfs_dir3_data_dotdot_entry_p(hdr); | 1175 | dep = xfs_dir3_data_dotdot_entry_p(mp, hdr); |
| 1176 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); | 1176 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); |
| 1177 | dep->namelen = 2; | 1177 | dep->namelen = 2; |
| 1178 | dep->name[0] = dep->name[1] = '.'; | 1178 | dep->name[0] = dep->name[1] = '.'; |
| @@ -1183,7 +1183,7 @@ xfs_dir2_sf_to_block( | |||
| 1183 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); | 1183 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); |
| 1184 | blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, | 1184 | blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
| 1185 | (char *)dep - (char *)hdr)); | 1185 | (char *)dep - (char *)hdr)); |
| 1186 | offset = xfs_dir3_data_first_offset(hdr); | 1186 | offset = xfs_dir3_data_first_offset(mp); |
| 1187 | /* | 1187 | /* |
| 1188 | * Loop over existing entries, stuff them in. | 1188 | * Loop over existing entries, stuff them in. |
| 1189 | */ | 1189 | */ |
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h index a0961a61ac1a..9cf67381adf6 100644 --- a/fs/xfs/xfs_dir2_format.h +++ b/fs/xfs/xfs_dir2_format.h | |||
| @@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) | |||
| 497 | /* | 497 | /* |
| 498 | * Offsets of . and .. in data space (always block 0) | 498 | * Offsets of . and .. in data space (always block 0) |
| 499 | * | 499 | * |
| 500 | * The macros are used for shortform directories as they have no headers to read | ||
| 501 | * the magic number out of. Shortform directories need to know the size of the | ||
| 502 | * data block header because the sfe embeds the block offset of the entry into | ||
| 503 | * it so that it doesn't change when format conversion occurs. Bad Things Happen | ||
| 504 | * if we don't follow this rule. | ||
| 505 | * | ||
| 506 | * XXX: there is scope for significant optimisation of the logic here. Right | 500 | * XXX: there is scope for significant optimisation of the logic here. Right |
| 507 | * now we are checking for "dir3 format" over and over again. Ideally we should | 501 | * now we are checking for "dir3 format" over and over again. Ideally we should |
| 508 | * only do it once for each operation. | 502 | * only do it once for each operation. |
| 509 | */ | 503 | */ |
| 510 | #define XFS_DIR3_DATA_DOT_OFFSET(mp) \ | ||
| 511 | xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb)) | ||
| 512 | #define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \ | ||
| 513 | (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 1)) | ||
| 514 | #define XFS_DIR3_DATA_FIRST_OFFSET(mp) \ | ||
| 515 | (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2)) | ||
| 516 | |||
| 517 | static inline xfs_dir2_data_aoff_t | 504 | static inline xfs_dir2_data_aoff_t |
| 518 | xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr) | 505 | xfs_dir3_data_dot_offset(struct xfs_mount *mp) |
| 519 | { | 506 | { |
| 520 | return xfs_dir3_data_entry_offset(hdr); | 507 | return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); |
| 521 | } | 508 | } |
| 522 | 509 | ||
| 523 | static inline xfs_dir2_data_aoff_t | 510 | static inline xfs_dir2_data_aoff_t |
| 524 | xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr) | 511 | xfs_dir3_data_dotdot_offset(struct xfs_mount *mp) |
| 525 | { | 512 | { |
| 526 | bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || | 513 | return xfs_dir3_data_dot_offset(mp) + |
| 527 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); | 514 | xfs_dir3_data_entsize(mp, 1); |
| 528 | return xfs_dir3_data_dot_offset(hdr) + | ||
| 529 | __xfs_dir3_data_entsize(dir3, 1); | ||
| 530 | } | 515 | } |
| 531 | 516 | ||
| 532 | static inline xfs_dir2_data_aoff_t | 517 | static inline xfs_dir2_data_aoff_t |
| 533 | xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr) | 518 | xfs_dir3_data_first_offset(struct xfs_mount *mp) |
| 534 | { | 519 | { |
| 535 | bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || | 520 | return xfs_dir3_data_dotdot_offset(mp) + |
| 536 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); | 521 | xfs_dir3_data_entsize(mp, 2); |
| 537 | return xfs_dir3_data_dotdot_offset(hdr) + | ||
| 538 | __xfs_dir3_data_entsize(dir3, 2); | ||
| 539 | } | 522 | } |
| 540 | 523 | ||
| 541 | /* | 524 | /* |
| 542 | * location of . and .. in data space (always block 0) | 525 | * location of . and .. in data space (always block 0) |
| 543 | */ | 526 | */ |
| 544 | static inline struct xfs_dir2_data_entry * | 527 | static inline struct xfs_dir2_data_entry * |
| 545 | xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr) | 528 | xfs_dir3_data_dot_entry_p( |
| 529 | struct xfs_mount *mp, | ||
| 530 | struct xfs_dir2_data_hdr *hdr) | ||
| 546 | { | 531 | { |
| 547 | return (struct xfs_dir2_data_entry *) | 532 | return (struct xfs_dir2_data_entry *) |
| 548 | ((char *)hdr + xfs_dir3_data_dot_offset(hdr)); | 533 | ((char *)hdr + xfs_dir3_data_dot_offset(mp)); |
| 549 | } | 534 | } |
| 550 | 535 | ||
| 551 | static inline struct xfs_dir2_data_entry * | 536 | static inline struct xfs_dir2_data_entry * |
| 552 | xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr) | 537 | xfs_dir3_data_dotdot_entry_p( |
| 538 | struct xfs_mount *mp, | ||
| 539 | struct xfs_dir2_data_hdr *hdr) | ||
| 553 | { | 540 | { |
| 554 | return (struct xfs_dir2_data_entry *) | 541 | return (struct xfs_dir2_data_entry *) |
| 555 | ((char *)hdr + xfs_dir3_data_dotdot_offset(hdr)); | 542 | ((char *)hdr + xfs_dir3_data_dotdot_offset(mp)); |
| 556 | } | 543 | } |
| 557 | 544 | ||
| 558 | static inline struct xfs_dir2_data_entry * | 545 | static inline struct xfs_dir2_data_entry * |
| 559 | xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr) | 546 | xfs_dir3_data_first_entry_p( |
| 547 | struct xfs_mount *mp, | ||
| 548 | struct xfs_dir2_data_hdr *hdr) | ||
| 560 | { | 549 | { |
| 561 | return (struct xfs_dir2_data_entry *) | 550 | return (struct xfs_dir2_data_entry *) |
| 562 | ((char *)hdr + xfs_dir3_data_first_offset(hdr)); | 551 | ((char *)hdr + xfs_dir3_data_first_offset(mp)); |
| 563 | } | 552 | } |
| 564 | 553 | ||
| 565 | /* | 554 | /* |
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 8993ec17452c..8f84153e98a8 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c | |||
| @@ -119,9 +119,9 @@ xfs_dir2_sf_getdents( | |||
| 119 | * mp->m_dirdatablk. | 119 | * mp->m_dirdatablk. |
| 120 | */ | 120 | */ |
| 121 | dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 121 | dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
| 122 | XFS_DIR3_DATA_DOT_OFFSET(mp)); | 122 | xfs_dir3_data_dot_offset(mp)); |
| 123 | dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 123 | dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
| 124 | XFS_DIR3_DATA_DOTDOT_OFFSET(mp)); | 124 | xfs_dir3_data_dotdot_offset(mp)); |
| 125 | 125 | ||
| 126 | /* | 126 | /* |
| 127 | * Put . entry unless we're starting past it. | 127 | * Put . entry unless we're starting past it. |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index bb6e2848f473..3ef6d402084c 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
| @@ -557,7 +557,7 @@ xfs_dir2_sf_addname_hard( | |||
| 557 | * to insert the new entry. | 557 | * to insert the new entry. |
| 558 | * If it's going to end up at the end then oldsfep will point there. | 558 | * If it's going to end up at the end then oldsfep will point there. |
| 559 | */ | 559 | */ |
| 560 | for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp), | 560 | for (offset = xfs_dir3_data_first_offset(mp), |
| 561 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), | 561 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), |
| 562 | add_datasize = xfs_dir3_data_entsize(mp, args->namelen), | 562 | add_datasize = xfs_dir3_data_entsize(mp, args->namelen), |
| 563 | eof = (char *)oldsfep == &buf[old_isize]; | 563 | eof = (char *)oldsfep == &buf[old_isize]; |
| @@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick( | |||
| 640 | 640 | ||
| 641 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 641 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
| 642 | size = xfs_dir3_data_entsize(mp, args->namelen); | 642 | size = xfs_dir3_data_entsize(mp, args->namelen); |
| 643 | offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); | 643 | offset = xfs_dir3_data_first_offset(mp); |
| 644 | sfep = xfs_dir2_sf_firstentry(sfp); | 644 | sfep = xfs_dir2_sf_firstentry(sfp); |
| 645 | holefit = 0; | 645 | holefit = 0; |
| 646 | /* | 646 | /* |
| @@ -713,7 +713,7 @@ xfs_dir2_sf_check( | |||
| 713 | mp = dp->i_mount; | 713 | mp = dp->i_mount; |
| 714 | 714 | ||
| 715 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 715 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
| 716 | offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); | 716 | offset = xfs_dir3_data_first_offset(mp); |
| 717 | ino = xfs_dir2_sf_get_parent_ino(sfp); | 717 | ino = xfs_dir2_sf_get_parent_ino(sfp); |
| 718 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; | 718 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; |
| 719 | 719 | ||
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 71520e6e5d65..1ee776d477c3 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
| @@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33; | |||
| 64 | struct kmem_zone *xfs_qm_dqtrxzone; | 64 | struct kmem_zone *xfs_qm_dqtrxzone; |
| 65 | static struct kmem_zone *xfs_qm_dqzone; | 65 | static struct kmem_zone *xfs_qm_dqzone; |
| 66 | 66 | ||
| 67 | static struct lock_class_key xfs_dquot_other_class; | 67 | static struct lock_class_key xfs_dquot_group_class; |
| 68 | static struct lock_class_key xfs_dquot_project_class; | ||
| 68 | 69 | ||
| 69 | /* | 70 | /* |
| 70 | * This is called to free all the memory associated with a dquot | 71 | * This is called to free all the memory associated with a dquot |
| @@ -703,8 +704,20 @@ xfs_qm_dqread( | |||
| 703 | * Make sure group quotas have a different lock class than user | 704 | * Make sure group quotas have a different lock class than user |
| 704 | * quotas. | 705 | * quotas. |
| 705 | */ | 706 | */ |
| 706 | if (!(type & XFS_DQ_USER)) | 707 | switch (type) { |
| 707 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); | 708 | case XFS_DQ_USER: |
| 709 | /* uses the default lock class */ | ||
| 710 | break; | ||
| 711 | case XFS_DQ_GROUP: | ||
| 712 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class); | ||
| 713 | break; | ||
| 714 | case XFS_DQ_PROJ: | ||
| 715 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class); | ||
| 716 | break; | ||
| 717 | default: | ||
| 718 | ASSERT(0); | ||
| 719 | break; | ||
| 720 | } | ||
| 708 | 721 | ||
| 709 | XFS_STATS_INC(xs_qm_dquot); | 722 | XFS_STATS_INC(xs_qm_dquot); |
| 710 | 723 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index cc179878fe41..39797490a1f1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -1585,6 +1585,7 @@ xlog_recover_add_to_trans( | |||
| 1585 | "bad number of regions (%d) in inode log format", | 1585 | "bad number of regions (%d) in inode log format", |
| 1586 | in_f->ilf_size); | 1586 | in_f->ilf_size); |
| 1587 | ASSERT(0); | 1587 | ASSERT(0); |
| 1588 | kmem_free(ptr); | ||
| 1588 | return XFS_ERROR(EIO); | 1589 | return XFS_ERROR(EIO); |
| 1589 | } | 1590 | } |
| 1590 | 1591 | ||
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 78e2ada50cd5..d380c5e68008 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
| @@ -55,7 +55,7 @@ | |||
| 55 | #define DMAR_IQT_REG 0x88 /* Invalidation queue tail register */ | 55 | #define DMAR_IQT_REG 0x88 /* Invalidation queue tail register */ |
| 56 | #define DMAR_IQ_SHIFT 4 /* Invalidation queue head/tail shift */ | 56 | #define DMAR_IQ_SHIFT 4 /* Invalidation queue head/tail shift */ |
| 57 | #define DMAR_IQA_REG 0x90 /* Invalidation queue addr register */ | 57 | #define DMAR_IQA_REG 0x90 /* Invalidation queue addr register */ |
| 58 | #define DMAR_ICS_REG 0x98 /* Invalidation complete status register */ | 58 | #define DMAR_ICS_REG 0x9c /* Invalidation complete status register */ |
| 59 | #define DMAR_IRTA_REG 0xb8 /* Interrupt remapping table addr register */ | 59 | #define DMAR_IRTA_REG 0xb8 /* Interrupt remapping table addr register */ |
| 60 | 60 | ||
| 61 | #define OFFSET_STRIDE (9) | 61 | #define OFFSET_STRIDE (9) |
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 09c2300ddb37..cb358355ef43 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #define MAPPER_CTRL_MINOR 236 | 45 | #define MAPPER_CTRL_MINOR 236 |
| 46 | #define LOOP_CTRL_MINOR 237 | 46 | #define LOOP_CTRL_MINOR 237 |
| 47 | #define VHOST_NET_MINOR 238 | 47 | #define VHOST_NET_MINOR 238 |
| 48 | #define UHID_MINOR 239 | ||
| 48 | #define MISC_DYNAMIC_MINOR 255 | 49 | #define MISC_DYNAMIC_MINOR 255 |
| 49 | 50 | ||
| 50 | struct device; | 51 | struct device; |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 866e85c5eb94..c8ba627c1d60 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -294,9 +294,31 @@ struct ring_buffer; | |||
| 294 | */ | 294 | */ |
| 295 | struct perf_event { | 295 | struct perf_event { |
| 296 | #ifdef CONFIG_PERF_EVENTS | 296 | #ifdef CONFIG_PERF_EVENTS |
| 297 | struct list_head group_entry; | 297 | /* |
| 298 | * entry onto perf_event_context::event_list; | ||
| 299 | * modifications require ctx->lock | ||
| 300 | * RCU safe iterations. | ||
| 301 | */ | ||
| 298 | struct list_head event_entry; | 302 | struct list_head event_entry; |
| 303 | |||
| 304 | /* | ||
| 305 | * XXX: group_entry and sibling_list should be mutually exclusive; | ||
| 306 | * either you're a sibling on a group, or you're the group leader. | ||
| 307 | * Rework the code to always use the same list element. | ||
| 308 | * | ||
| 309 | * Locked for modification by both ctx->mutex and ctx->lock; holding | ||
| 310 | * either sufficies for read. | ||
| 311 | */ | ||
| 312 | struct list_head group_entry; | ||
| 299 | struct list_head sibling_list; | 313 | struct list_head sibling_list; |
| 314 | |||
| 315 | /* | ||
| 316 | * We need storage to track the entries in perf_pmu_migrate_context; we | ||
| 317 | * cannot use the event_entry because of RCU and we want to keep the | ||
| 318 | * group in tact which avoids us using the other two entries. | ||
| 319 | */ | ||
| 320 | struct list_head migrate_entry; | ||
| 321 | |||
| 300 | struct hlist_node hlist_entry; | 322 | struct hlist_node hlist_entry; |
| 301 | int nr_siblings; | 323 | int nr_siblings; |
| 302 | int group_flags; | 324 | int group_flags; |
diff --git a/kernel/events/core.c b/kernel/events/core.c index cb4238e85b38..d49a9d29334c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -7234,15 +7234,15 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) | |||
| 7234 | perf_remove_from_context(event); | 7234 | perf_remove_from_context(event); |
| 7235 | unaccount_event_cpu(event, src_cpu); | 7235 | unaccount_event_cpu(event, src_cpu); |
| 7236 | put_ctx(src_ctx); | 7236 | put_ctx(src_ctx); |
| 7237 | list_add(&event->event_entry, &events); | 7237 | list_add(&event->migrate_entry, &events); |
| 7238 | } | 7238 | } |
| 7239 | mutex_unlock(&src_ctx->mutex); | 7239 | mutex_unlock(&src_ctx->mutex); |
| 7240 | 7240 | ||
| 7241 | synchronize_rcu(); | 7241 | synchronize_rcu(); |
| 7242 | 7242 | ||
| 7243 | mutex_lock(&dst_ctx->mutex); | 7243 | mutex_lock(&dst_ctx->mutex); |
| 7244 | list_for_each_entry_safe(event, tmp, &events, event_entry) { | 7244 | list_for_each_entry_safe(event, tmp, &events, migrate_entry) { |
| 7245 | list_del(&event->event_entry); | 7245 | list_del(&event->migrate_entry); |
| 7246 | if (event->state >= PERF_EVENT_STATE_OFF) | 7246 | if (event->state >= PERF_EVENT_STATE_OFF) |
| 7247 | event->state = PERF_EVENT_STATE_INACTIVE; | 7247 | event->state = PERF_EVENT_STATE_INACTIVE; |
| 7248 | account_event_cpu(event, dst_cpu); | 7248 | account_event_cpu(event, dst_cpu); |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 358a146fd4da..98c3b34a4cff 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
| @@ -743,7 +743,10 @@ int create_basic_memory_bitmaps(void) | |||
| 743 | struct memory_bitmap *bm1, *bm2; | 743 | struct memory_bitmap *bm1, *bm2; |
| 744 | int error = 0; | 744 | int error = 0; |
| 745 | 745 | ||
| 746 | BUG_ON(forbidden_pages_map || free_pages_map); | 746 | if (forbidden_pages_map && free_pages_map) |
| 747 | return 0; | ||
| 748 | else | ||
| 749 | BUG_ON(forbidden_pages_map || free_pages_map); | ||
| 747 | 750 | ||
| 748 | bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL); | 751 | bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL); |
| 749 | if (!bm1) | 752 | if (!bm1) |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 72e8f4fd616d..957f06164ad1 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
| @@ -39,6 +39,7 @@ static struct snapshot_data { | |||
| 39 | char frozen; | 39 | char frozen; |
| 40 | char ready; | 40 | char ready; |
| 41 | char platform_support; | 41 | char platform_support; |
| 42 | bool free_bitmaps; | ||
| 42 | } snapshot_state; | 43 | } snapshot_state; |
| 43 | 44 | ||
| 44 | atomic_t snapshot_device_available = ATOMIC_INIT(1); | 45 | atomic_t snapshot_device_available = ATOMIC_INIT(1); |
| @@ -82,6 +83,10 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
| 82 | data->swap = -1; | 83 | data->swap = -1; |
| 83 | data->mode = O_WRONLY; | 84 | data->mode = O_WRONLY; |
| 84 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | 85 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
| 86 | if (!error) { | ||
| 87 | error = create_basic_memory_bitmaps(); | ||
| 88 | data->free_bitmaps = !error; | ||
| 89 | } | ||
| 85 | if (error) | 90 | if (error) |
| 86 | pm_notifier_call_chain(PM_POST_RESTORE); | 91 | pm_notifier_call_chain(PM_POST_RESTORE); |
| 87 | } | 92 | } |
| @@ -111,6 +116,8 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
| 111 | pm_restore_gfp_mask(); | 116 | pm_restore_gfp_mask(); |
| 112 | free_basic_memory_bitmaps(); | 117 | free_basic_memory_bitmaps(); |
| 113 | thaw_processes(); | 118 | thaw_processes(); |
| 119 | } else if (data->free_bitmaps) { | ||
| 120 | free_basic_memory_bitmaps(); | ||
| 114 | } | 121 | } |
| 115 | pm_notifier_call_chain(data->mode == O_RDONLY ? | 122 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
| 116 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 123 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
| @@ -231,6 +238,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
| 231 | break; | 238 | break; |
| 232 | pm_restore_gfp_mask(); | 239 | pm_restore_gfp_mask(); |
| 233 | free_basic_memory_bitmaps(); | 240 | free_basic_memory_bitmaps(); |
| 241 | data->free_bitmaps = false; | ||
| 234 | thaw_processes(); | 242 | thaw_processes(); |
| 235 | data->frozen = 0; | 243 | data->frozen = 0; |
| 236 | break; | 244 | break; |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 53cc09ceb0b8..d7d498d8cc4f 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -328,10 +328,19 @@ void irq_enter(void) | |||
| 328 | 328 | ||
| 329 | static inline void invoke_softirq(void) | 329 | static inline void invoke_softirq(void) |
| 330 | { | 330 | { |
| 331 | if (!force_irqthreads) | 331 | if (!force_irqthreads) { |
| 332 | __do_softirq(); | 332 | /* |
| 333 | else | 333 | * We can safely execute softirq on the current stack if |
| 334 | * it is the irq stack, because it should be near empty | ||
| 335 | * at this stage. But we have no way to know if the arch | ||
| 336 | * calls irq_exit() on the irq stack. So call softirq | ||
| 337 | * in its own stack to prevent from any overrun on top | ||
| 338 | * of a potentially deep task stack. | ||
| 339 | */ | ||
| 340 | do_softirq(); | ||
| 341 | } else { | ||
| 334 | wakeup_softirqd(); | 342 | wakeup_softirqd(); |
| 343 | } | ||
| 335 | } | 344 | } |
| 336 | 345 | ||
| 337 | static inline void tick_irq_exit(void) | 346 | static inline void tick_irq_exit(void) |
diff --git a/net/sysctl_net.c b/net/sysctl_net.c index 9bc6db04be3e..e7000be321b0 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c | |||
| @@ -47,12 +47,12 @@ static int net_ctl_permissions(struct ctl_table_header *head, | |||
| 47 | 47 | ||
| 48 | /* Allow network administrator to have same access as root. */ | 48 | /* Allow network administrator to have same access as root. */ |
| 49 | if (ns_capable(net->user_ns, CAP_NET_ADMIN) || | 49 | if (ns_capable(net->user_ns, CAP_NET_ADMIN) || |
| 50 | uid_eq(root_uid, current_uid())) { | 50 | uid_eq(root_uid, current_euid())) { |
| 51 | int mode = (table->mode >> 6) & 7; | 51 | int mode = (table->mode >> 6) & 7; |
| 52 | return (mode << 6) | (mode << 3) | mode; | 52 | return (mode << 6) | (mode << 3) | mode; |
| 53 | } | 53 | } |
| 54 | /* Allow netns root group to have the same access as the root group */ | 54 | /* Allow netns root group to have the same access as the root group */ |
| 55 | if (gid_eq(root_gid, current_gid())) { | 55 | if (in_egroup_p(root_gid)) { |
| 56 | int mode = (table->mode >> 3) & 7; | 56 | int mode = (table->mode >> 3) & 7; |
| 57 | return (mode << 3) | mode; | 57 | return (mode << 3) | mode; |
| 58 | } | 58 | } |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index dad36a6ab45f..fc3e6628a864 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -746,7 +746,6 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 746 | * @tclass: target security class | 746 | * @tclass: target security class |
| 747 | * @requested: requested permissions, interpreted based on @tclass | 747 | * @requested: requested permissions, interpreted based on @tclass |
| 748 | * @auditdata: auxiliary audit data | 748 | * @auditdata: auxiliary audit data |
| 749 | * @flags: VFS walk flags | ||
| 750 | * | 749 | * |
| 751 | * Check the AVC to determine whether the @requested permissions are granted | 750 | * Check the AVC to determine whether the @requested permissions are granted |
| 752 | * for the SID pair (@ssid, @tsid), interpreting the permissions | 751 | * for the SID pair (@ssid, @tsid), interpreting the permissions |
| @@ -756,17 +755,15 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 756 | * permissions are granted, -%EACCES if any permissions are denied, or | 755 | * permissions are granted, -%EACCES if any permissions are denied, or |
| 757 | * another -errno upon other errors. | 756 | * another -errno upon other errors. |
| 758 | */ | 757 | */ |
| 759 | int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, | 758 | int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, |
| 760 | u32 requested, struct common_audit_data *auditdata, | 759 | u32 requested, struct common_audit_data *auditdata) |
| 761 | unsigned flags) | ||
| 762 | { | 760 | { |
| 763 | struct av_decision avd; | 761 | struct av_decision avd; |
| 764 | int rc, rc2; | 762 | int rc, rc2; |
| 765 | 763 | ||
| 766 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); | 764 | rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); |
| 767 | 765 | ||
| 768 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, | 766 | rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); |
| 769 | flags); | ||
| 770 | if (rc2) | 767 | if (rc2) |
| 771 | return rc2; | 768 | return rc2; |
| 772 | return rc; | 769 | return rc; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a5091ec06aa6..5b5231068516 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1502,7 +1502,7 @@ static int cred_has_capability(const struct cred *cred, | |||
| 1502 | 1502 | ||
| 1503 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); | 1503 | rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); |
| 1504 | if (audit == SECURITY_CAP_AUDIT) { | 1504 | if (audit == SECURITY_CAP_AUDIT) { |
| 1505 | int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0); | 1505 | int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad); |
| 1506 | if (rc2) | 1506 | if (rc2) |
| 1507 | return rc2; | 1507 | return rc2; |
| 1508 | } | 1508 | } |
| @@ -1525,8 +1525,7 @@ static int task_has_system(struct task_struct *tsk, | |||
| 1525 | static int inode_has_perm(const struct cred *cred, | 1525 | static int inode_has_perm(const struct cred *cred, |
| 1526 | struct inode *inode, | 1526 | struct inode *inode, |
| 1527 | u32 perms, | 1527 | u32 perms, |
| 1528 | struct common_audit_data *adp, | 1528 | struct common_audit_data *adp) |
| 1529 | unsigned flags) | ||
| 1530 | { | 1529 | { |
| 1531 | struct inode_security_struct *isec; | 1530 | struct inode_security_struct *isec; |
| 1532 | u32 sid; | 1531 | u32 sid; |
| @@ -1539,7 +1538,7 @@ static int inode_has_perm(const struct cred *cred, | |||
| 1539 | sid = cred_sid(cred); | 1538 | sid = cred_sid(cred); |
| 1540 | isec = inode->i_security; | 1539 | isec = inode->i_security; |
| 1541 | 1540 | ||
| 1542 | return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); | 1541 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); |
| 1543 | } | 1542 | } |
| 1544 | 1543 | ||
| 1545 | /* Same as inode_has_perm, but pass explicit audit data containing | 1544 | /* Same as inode_has_perm, but pass explicit audit data containing |
| @@ -1554,7 +1553,7 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
| 1554 | 1553 | ||
| 1555 | ad.type = LSM_AUDIT_DATA_DENTRY; | 1554 | ad.type = LSM_AUDIT_DATA_DENTRY; |
| 1556 | ad.u.dentry = dentry; | 1555 | ad.u.dentry = dentry; |
| 1557 | return inode_has_perm(cred, inode, av, &ad, 0); | 1556 | return inode_has_perm(cred, inode, av, &ad); |
| 1558 | } | 1557 | } |
| 1559 | 1558 | ||
| 1560 | /* Same as inode_has_perm, but pass explicit audit data containing | 1559 | /* Same as inode_has_perm, but pass explicit audit data containing |
| @@ -1569,7 +1568,7 @@ static inline int path_has_perm(const struct cred *cred, | |||
| 1569 | 1568 | ||
| 1570 | ad.type = LSM_AUDIT_DATA_PATH; | 1569 | ad.type = LSM_AUDIT_DATA_PATH; |
| 1571 | ad.u.path = *path; | 1570 | ad.u.path = *path; |
| 1572 | return inode_has_perm(cred, inode, av, &ad, 0); | 1571 | return inode_has_perm(cred, inode, av, &ad); |
| 1573 | } | 1572 | } |
| 1574 | 1573 | ||
| 1575 | /* Same as path_has_perm, but uses the inode from the file struct. */ | 1574 | /* Same as path_has_perm, but uses the inode from the file struct. */ |
| @@ -1581,7 +1580,7 @@ static inline int file_path_has_perm(const struct cred *cred, | |||
| 1581 | 1580 | ||
| 1582 | ad.type = LSM_AUDIT_DATA_PATH; | 1581 | ad.type = LSM_AUDIT_DATA_PATH; |
| 1583 | ad.u.path = file->f_path; | 1582 | ad.u.path = file->f_path; |
| 1584 | return inode_has_perm(cred, file_inode(file), av, &ad, 0); | 1583 | return inode_has_perm(cred, file_inode(file), av, &ad); |
| 1585 | } | 1584 | } |
| 1586 | 1585 | ||
| 1587 | /* Check whether a task can use an open file descriptor to | 1586 | /* Check whether a task can use an open file descriptor to |
| @@ -1617,7 +1616,7 @@ static int file_has_perm(const struct cred *cred, | |||
| 1617 | /* av is zero if only checking access to the descriptor. */ | 1616 | /* av is zero if only checking access to the descriptor. */ |
| 1618 | rc = 0; | 1617 | rc = 0; |
| 1619 | if (av) | 1618 | if (av) |
| 1620 | rc = inode_has_perm(cred, inode, av, &ad, 0); | 1619 | rc = inode_has_perm(cred, inode, av, &ad); |
| 1621 | 1620 | ||
| 1622 | out: | 1621 | out: |
| 1623 | return rc; | 1622 | return rc; |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 92d0ab561db8..f53ee3c58d0f 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
| @@ -130,7 +130,7 @@ static inline int avc_audit(u32 ssid, u32 tsid, | |||
| 130 | u16 tclass, u32 requested, | 130 | u16 tclass, u32 requested, |
| 131 | struct av_decision *avd, | 131 | struct av_decision *avd, |
| 132 | int result, | 132 | int result, |
| 133 | struct common_audit_data *a, unsigned flags) | 133 | struct common_audit_data *a) |
| 134 | { | 134 | { |
| 135 | u32 audited, denied; | 135 | u32 audited, denied; |
| 136 | audited = avc_audit_required(requested, avd, result, 0, &denied); | 136 | audited = avc_audit_required(requested, avd, result, 0, &denied); |
| @@ -138,7 +138,7 @@ static inline int avc_audit(u32 ssid, u32 tsid, | |||
| 138 | return 0; | 138 | return 0; |
| 139 | return slow_avc_audit(ssid, tsid, tclass, | 139 | return slow_avc_audit(ssid, tsid, tclass, |
| 140 | requested, audited, denied, | 140 | requested, audited, denied, |
| 141 | a, flags); | 141 | a, 0); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | #define AVC_STRICT 1 /* Ignore permissive mode. */ | 144 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
| @@ -147,17 +147,9 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
| 147 | unsigned flags, | 147 | unsigned flags, |
| 148 | struct av_decision *avd); | 148 | struct av_decision *avd); |
| 149 | 149 | ||
| 150 | int avc_has_perm_flags(u32 ssid, u32 tsid, | 150 | int avc_has_perm(u32 ssid, u32 tsid, |
| 151 | u16 tclass, u32 requested, | 151 | u16 tclass, u32 requested, |
| 152 | struct common_audit_data *auditdata, | 152 | struct common_audit_data *auditdata); |
| 153 | unsigned); | ||
| 154 | |||
| 155 | static inline int avc_has_perm(u32 ssid, u32 tsid, | ||
| 156 | u16 tclass, u32 requested, | ||
| 157 | struct common_audit_data *auditdata) | ||
| 158 | { | ||
| 159 | return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0); | ||
| 160 | } | ||
| 161 | 153 | ||
| 162 | u32 avc_policy_seqno(void); | 154 | u32 avc_policy_seqno(void); |
| 163 | 155 | ||
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 3a0ff7fb71b6..64c043b7a438 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h | |||
| 770 | install-bin: all | 770 | install-bin: all |
| 771 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' | 771 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' |
| 772 | $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' | 772 | $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' |
| 773 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' | ||
| 773 | $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' | 774 | $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' |
| 774 | ifndef NO_LIBPERL | 775 | ifndef NO_LIBPERL |
| 775 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' | 776 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f686d5ff594e..5098f144b92d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -457,6 +457,7 @@ static int __run_perf_stat(int argc, const char **argv) | |||
| 457 | perror("failed to prepare workload"); | 457 | perror("failed to prepare workload"); |
| 458 | return -1; | 458 | return -1; |
| 459 | } | 459 | } |
| 460 | child_pid = evsel_list->workload.pid; | ||
| 460 | } | 461 | } |
| 461 | 462 | ||
| 462 | if (group) | 463 | if (group) |
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index d5a8dd44945f..f79305739ecc 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak | |||
| @@ -219,7 +219,7 @@ define SOURCE_LIBAUDIT | |||
| 219 | 219 | ||
| 220 | int main(void) | 220 | int main(void) |
| 221 | { | 221 | { |
| 222 | printf(\"error message: %s\n\", audit_errno_to_name(0)); | 222 | printf(\"error message: %s\", audit_errno_to_name(0)); |
| 223 | return audit_open(); | 223 | return audit_open(); |
| 224 | } | 224 | } |
| 225 | endef | 225 | endef |
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index e23bde19d590..7defd77105d0 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
| @@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) | |||
| 426 | * @die_mem: a buffer for result DIE | 426 | * @die_mem: a buffer for result DIE |
| 427 | * | 427 | * |
| 428 | * Search a non-inlined function DIE which includes @addr. Stores the | 428 | * Search a non-inlined function DIE which includes @addr. Stores the |
| 429 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 429 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
| 430 | */ | 430 | */ |
| 431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
| 432 | Dwarf_Die *die_mem) | 432 | Dwarf_Die *die_mem) |
| @@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) | |||
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | /** | 456 | /** |
| 457 | * die_find_top_inlinefunc - Search the top inlined function at given address | ||
| 458 | * @sp_die: a subprogram DIE which including @addr | ||
| 459 | * @addr: target address | ||
| 460 | * @die_mem: a buffer for result DIE | ||
| 461 | * | ||
| 462 | * Search an inlined function DIE which includes @addr. Stores the | ||
| 463 | * DIE to @die_mem and returns it if found. Returns NULL if failed. | ||
| 464 | * Even if several inlined functions are expanded recursively, this | ||
| 465 | * doesn't trace it down, and returns the topmost one. | ||
| 466 | */ | ||
| 467 | Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
| 468 | Dwarf_Die *die_mem) | ||
| 469 | { | ||
| 470 | return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); | ||
| 471 | } | ||
| 472 | |||
| 473 | /** | ||
| 457 | * die_find_inlinefunc - Search an inlined function at given address | 474 | * die_find_inlinefunc - Search an inlined function at given address |
| 458 | * @cu_die: a CU DIE which including @addr | 475 | * @sp_die: a subprogram DIE which including @addr |
| 459 | * @addr: target address | 476 | * @addr: target address |
| 460 | * @die_mem: a buffer for result DIE | 477 | * @die_mem: a buffer for result DIE |
| 461 | * | 478 | * |
| 462 | * Search an inlined function DIE which includes @addr. Stores the | 479 | * Search an inlined function DIE which includes @addr. Stores the |
| 463 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 480 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
| 464 | * If several inlined functions are expanded recursively, this trace | 481 | * If several inlined functions are expanded recursively, this trace |
| 465 | * it and returns deepest one. | 482 | * it down and returns deepest one. |
| 466 | */ | 483 | */ |
| 467 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 484 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
| 468 | Dwarf_Die *die_mem) | 485 | Dwarf_Die *die_mem) |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 8658d41697d2..b4fe90c6cb2d 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
| @@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die, | |||
| 79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
| 80 | Dwarf_Die *die_mem); | 80 | Dwarf_Die *die_mem); |
| 81 | 81 | ||
| 82 | /* Search an inlined function including given address */ | 82 | /* Search the top inlined function including given address */ |
| 83 | extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
| 84 | Dwarf_Die *die_mem); | ||
| 85 | |||
| 86 | /* Search the deepest inlined function including given address */ | ||
| 83 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 87 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
| 84 | Dwarf_Die *die_mem); | 88 | Dwarf_Die *die_mem); |
| 85 | 89 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ce69901176d8..c3e5a3b817ab 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session) | |||
| 2768 | if (perf_file_header__read(&f_header, header, fd) < 0) | 2768 | if (perf_file_header__read(&f_header, header, fd) < 0) |
| 2769 | return -EINVAL; | 2769 | return -EINVAL; |
| 2770 | 2770 | ||
| 2771 | /* | ||
| 2772 | * Sanity check that perf.data was written cleanly; data size is | ||
| 2773 | * initialized to 0 and updated only if the on_exit function is run. | ||
| 2774 | * If data size is still 0 then the file contains only partial | ||
| 2775 | * information. Just warn user and process it as much as it can. | ||
| 2776 | */ | ||
| 2777 | if (f_header.data.size == 0) { | ||
| 2778 | pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n" | ||
| 2779 | "Was the 'perf record' command properly terminated?\n", | ||
| 2780 | session->filename); | ||
| 2781 | } | ||
| 2782 | |||
| 2771 | nr_attrs = f_header.attrs.size / f_header.attr_size; | 2783 | nr_attrs = f_header.attrs.size / f_header.attr_size; |
| 2772 | lseek(fd, f_header.attrs.offset, SEEK_SET); | 2784 | lseek(fd, f_header.attrs.offset, SEEK_SET); |
| 2773 | 2785 | ||
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 371476cb8ddc..c09e0a9fdf4c 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -1327,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
| 1327 | struct perf_probe_point *ppt) | 1327 | struct perf_probe_point *ppt) |
| 1328 | { | 1328 | { |
| 1329 | Dwarf_Die cudie, spdie, indie; | 1329 | Dwarf_Die cudie, spdie, indie; |
| 1330 | Dwarf_Addr _addr, baseaddr; | 1330 | Dwarf_Addr _addr = 0, baseaddr = 0; |
| 1331 | const char *fname = NULL, *func = NULL, *tmp; | 1331 | const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; |
| 1332 | int baseline = 0, lineno = 0, ret = 0; | 1332 | int baseline = 0, lineno = 0, ret = 0; |
| 1333 | 1333 | ||
| 1334 | /* Adjust address with bias */ | 1334 | /* Adjust address with bias */ |
| @@ -1349,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
| 1349 | /* Find a corresponding function (name, baseline and baseaddr) */ | 1349 | /* Find a corresponding function (name, baseline and baseaddr) */ |
| 1350 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { | 1350 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { |
| 1351 | /* Get function entry information */ | 1351 | /* Get function entry information */ |
| 1352 | tmp = dwarf_diename(&spdie); | 1352 | func = basefunc = dwarf_diename(&spdie); |
| 1353 | if (!tmp || | 1353 | if (!func || |
| 1354 | dwarf_entrypc(&spdie, &baseaddr) != 0 || | 1354 | dwarf_entrypc(&spdie, &baseaddr) != 0 || |
| 1355 | dwarf_decl_line(&spdie, &baseline) != 0) | 1355 | dwarf_decl_line(&spdie, &baseline) != 0) { |
| 1356 | lineno = 0; | ||
| 1356 | goto post; | 1357 | goto post; |
| 1357 | func = tmp; | 1358 | } |
| 1358 | 1359 | ||
| 1359 | if (addr == (unsigned long)baseaddr) | 1360 | if (addr == (unsigned long)baseaddr) { |
| 1360 | /* Function entry - Relative line number is 0 */ | 1361 | /* Function entry - Relative line number is 0 */ |
| 1361 | lineno = baseline; | 1362 | lineno = baseline; |
| 1362 | else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, | 1363 | fname = dwarf_decl_file(&spdie); |
| 1363 | &indie)) { | 1364 | goto post; |
| 1365 | } | ||
| 1366 | |||
| 1367 | /* Track down the inline functions step by step */ | ||
| 1368 | while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr, | ||
| 1369 | &indie)) { | ||
| 1370 | /* There is an inline function */ | ||
| 1364 | if (dwarf_entrypc(&indie, &_addr) == 0 && | 1371 | if (dwarf_entrypc(&indie, &_addr) == 0 && |
| 1365 | _addr == addr) | 1372 | _addr == addr) { |
| 1366 | /* | 1373 | /* |
| 1367 | * addr is at an inline function entry. | 1374 | * addr is at an inline function entry. |
| 1368 | * In this case, lineno should be the call-site | 1375 | * In this case, lineno should be the call-site |
| 1369 | * line number. | 1376 | * line number. (overwrite lineinfo) |
| 1370 | */ | 1377 | */ |
| 1371 | lineno = die_get_call_lineno(&indie); | 1378 | lineno = die_get_call_lineno(&indie); |
| 1372 | else { | 1379 | fname = die_get_call_file(&indie); |
| 1380 | break; | ||
| 1381 | } else { | ||
| 1373 | /* | 1382 | /* |
| 1374 | * addr is in an inline function body. | 1383 | * addr is in an inline function body. |
| 1375 | * Since lineno points one of the lines | 1384 | * Since lineno points one of the lines |
| @@ -1377,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
| 1377 | * be the entry line of the inline function. | 1386 | * be the entry line of the inline function. |
| 1378 | */ | 1387 | */ |
| 1379 | tmp = dwarf_diename(&indie); | 1388 | tmp = dwarf_diename(&indie); |
| 1380 | if (tmp && | 1389 | if (!tmp || |
| 1381 | dwarf_decl_line(&spdie, &baseline) == 0) | 1390 | dwarf_decl_line(&indie, &baseline) != 0) |
| 1382 | func = tmp; | 1391 | break; |
| 1392 | func = tmp; | ||
| 1393 | spdie = indie; | ||
| 1383 | } | 1394 | } |
| 1384 | } | 1395 | } |
| 1396 | /* Verify the lineno and baseline are in a same file */ | ||
| 1397 | tmp = dwarf_decl_file(&spdie); | ||
| 1398 | if (!tmp || strcmp(tmp, fname) != 0) | ||
| 1399 | lineno = 0; | ||
| 1385 | } | 1400 | } |
| 1386 | 1401 | ||
| 1387 | post: | 1402 | post: |
| 1388 | /* Make a relative line number or an offset */ | 1403 | /* Make a relative line number or an offset */ |
| 1389 | if (lineno) | 1404 | if (lineno) |
| 1390 | ppt->line = lineno - baseline; | 1405 | ppt->line = lineno - baseline; |
| 1391 | else if (func) | 1406 | else if (basefunc) { |
| 1392 | ppt->offset = addr - (unsigned long)baseaddr; | 1407 | ppt->offset = addr - (unsigned long)baseaddr; |
| 1408 | func = basefunc; | ||
| 1409 | } | ||
| 1393 | 1410 | ||
| 1394 | /* Duplicate strings */ | 1411 | /* Duplicate strings */ |
| 1395 | if (func) { | 1412 | if (func) { |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 70ffa41518f3..568b750c01f6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) | |||
| 256 | tool->sample = process_event_sample_stub; | 256 | tool->sample = process_event_sample_stub; |
| 257 | if (tool->mmap == NULL) | 257 | if (tool->mmap == NULL) |
| 258 | tool->mmap = process_event_stub; | 258 | tool->mmap = process_event_stub; |
| 259 | if (tool->mmap2 == NULL) | ||
| 260 | tool->mmap2 = process_event_stub; | ||
| 259 | if (tool->comm == NULL) | 261 | if (tool->comm == NULL) |
| 260 | tool->comm = process_event_stub; | 262 | tool->comm = process_event_stub; |
| 261 | if (tool->fork == NULL) | 263 | if (tool->fork == NULL) |
| @@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session, | |||
| 1310 | file_offset = page_offset; | 1312 | file_offset = page_offset; |
| 1311 | head = data_offset - page_offset; | 1313 | head = data_offset - page_offset; |
| 1312 | 1314 | ||
| 1313 | if (data_offset + data_size < file_size) | 1315 | if (data_size && (data_offset + data_size < file_size)) |
| 1314 | file_size = data_offset + data_size; | 1316 | file_size = data_offset + data_size; |
| 1315 | 1317 | ||
| 1316 | progress_next = file_size / 16; | 1318 | progress_next = file_size / 16; |
