Unified · Split
| @@ -51,6 +51,7 @@ Greg Kroah-Hartman <gregkh@suse.de> · 50 unmodified lines | ||
| 51 | 51 | Greg Kroah-Hartman <greg@kroah.com> |
| 52 | 52 | Henk Vergonet <Henk.Vergonet@gmail.com> |
| 53 | 53 | Henrik Kretzschmar <henne@nachtwindheim.de> |
| 54 | +Henrik Rydberg <rydberg@bitmath.org> | |
| 54 | 55 | Herbert Xu <herbert@gondor.apana.org.au> |
| 55 | 56 | Jacob Shin <Jacob.Shin@amd.com> |
| 56 | 57 | James Bottomley <jejb@mulgrave.(none)> |
| @@ -724,15 +724,15 @@ F: include/uapi/linux/apm_bios.h · 723 unmodified lines | ||
| 724 | 724 | F: drivers/char/apm-emulation.c |
| 725 | 725 | |
| 726 | 726 | APPLE BCM5974 MULTITOUCH DRIVER |
| 727 | −M: Henrik Rydberg <rydberg@euromail.se> | |
| 727 | +M: Henrik Rydberg <rydberg@bitmath.org> | |
| 728 | 728 | L: linux-input@vger.kernel.org |
| 729 | −S: Maintained | |
| 729 | +S: Odd fixes | |
| 730 | 730 | F: drivers/input/mouse/bcm5974.c |
| 731 | 731 | |
| 732 | 732 | APPLE SMC DRIVER |
| 733 | −M: Henrik Rydberg <rydberg@euromail.se> | |
| 733 | +M: Henrik Rydberg <rydberg@bitmath.org> | |
| 734 | 734 | L: lm-sensors@lm-sensors.org |
| 735 | −S: Maintained | |
| 735 | +S: Odd fixes | |
| 736 | 736 | F: drivers/hwmon/applesmc.c |
| 737 | 737 | |
| 738 | 738 | APPLETALK NETWORK LAYER |
| @@ -2259,6 +2259,7 @@ F: drivers/gpio/gpio-bt8xx.c · 1520 unmodified lines | ||
| 2259 | 2259 | BTRFS FILE SYSTEM |
| 2260 | 2260 | M: Chris Mason <clm@fb.com> |
| 2261 | 2261 | M: Josef Bacik <jbacik@fb.com> |
| 2262 | +M: David Sterba <dsterba@suse.cz> | |
| 2262 | 2263 | L: linux-btrfs@vger.kernel.org |
| 2263 | 2264 | W: http://btrfs.wiki.kernel.org/ |
| 2264 | 2265 | Q: http://patchwork.kernel.org/project/linux-btrfs/list/ |
| @@ -4940,10 +4941,10 @@ F: include/uapi/linux/input.h · 2675 unmodified lines | ||
| 4940 | 4941 | F: include/linux/input/ |
| 4941 | 4942 | |
| 4942 | 4943 | INPUT MULTITOUCH (MT) PROTOCOL |
| 4943 | −M: Henrik Rydberg <rydberg@euromail.se> | |
| 4944 | +M: Henrik Rydberg <rydberg@bitmath.org> | |
| 4944 | 4945 | L: linux-input@vger.kernel.org |
| 4945 | 4946 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git |
| 4946 | −S: Maintained | |
| 4947 | +S: Odd fixes | |
| 4947 | 4948 | F: Documentation/input/multi-touch-protocol.txt |
| 4948 | 4949 | F: drivers/input/input-mt.c |
| 4949 | 4950 | K: \b(ABS|SYN)_MT_ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 3 |
| 2 | 2 | PATCHLEVEL = 19 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc3 | |
| 4 | +EXTRAVERSION = -rc4 | |
| 5 | 5 | NAME = Diseased Newt |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -391,6 +391,7 @@ USERINCLUDE := \ · 383 unmodified lines | ||
| 391 | 391 | # Needed to be compatible with the O= option |
| 392 | 392 | LINUXINCLUDE := \ |
| 393 | 393 | -I$(srctree)/arch/$(hdr-arch)/include \ |
| 394 | + -Iarch/$(hdr-arch)/include/generated/uapi \ | |
| 394 | 395 | -Iarch/$(hdr-arch)/include/generated \ |
| 395 | 396 | $(if $(KBUILD_SRC), -I$(srctree)/include) \ |
| 396 | 397 | -Iinclude \ |
| @@ -413,6 +413,7 @@ · 412 unmodified lines | ||
| 413 | 413 | #define __NR_getrandom (__NR_SYSCALL_BASE+384) |
| 414 | 414 | #define __NR_memfd_create (__NR_SYSCALL_BASE+385) |
| 415 | 415 | #define __NR_bpf (__NR_SYSCALL_BASE+386) |
| 416 | +#define __NR_execveat (__NR_SYSCALL_BASE+387) | |
| 416 | 417 | |
| 417 | 418 | /* |
| 418 | 419 | * The following SWIs are ARM private. |
| @@ -396,6 +396,7 @@ · 395 unmodified lines | ||
| 396 | 396 | CALL(sys_getrandom) |
| 397 | 397 | /* 385 */ CALL(sys_memfd_create) |
| 398 | 398 | CALL(sys_bpf) |
| 399 | + CALL(sys_execveat) | |
| 399 | 400 | #ifndef syscalls_counted |
| 400 | 401 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
| 401 | 402 | #define syscalls_counted |
| @@ -28,3 +28,11 @@ u64 perf_reg_abi(struct task_struct *task) · 27 unmodified lines | ||
| 28 | 28 | { |
| 29 | 29 | return PERF_SAMPLE_REGS_ABI_32; |
| 30 | 30 | } |
| 31 | + | |
| 32 | +void perf_get_regs_user(struct perf_regs *regs_user, | |
| 33 | + struct pt_regs *regs, | |
| 34 | + struct pt_regs *regs_user_copy) | |
| 35 | +{ | |
| 36 | + regs_user->regs = task_pt_regs(current); | |
| 37 | + regs_user->abi = perf_reg_abi(current); | |
| 38 | +} | |
| @@ -220,9 +220,6 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u · 219 unmodified lines | ||
| 220 | 220 | static const char units[] = "KMGTPE"; |
| 221 | 221 | u64 prot = val & pg_level[level].mask; |
| 222 | 222 | |
| 223 | − if (addr < USER_PGTABLES_CEILING) | |
| 224 | − return; | |
| 225 | − | |
| 226 | 223 | if (!st->level) { |
| 227 | 224 | st->level = level; |
| 228 | 225 | st->current_prot = prot; |
| @@ -308,15 +305,13 @@ static void walk_pgd(struct seq_file *m) · 79 unmodified lines | ||
| 308 | 305 | pgd_t *pgd = swapper_pg_dir; |
| 309 | 306 | struct pg_state st; |
| 310 | 307 | unsigned long addr; |
| 311 | − unsigned i, pgdoff = USER_PGTABLES_CEILING / PGDIR_SIZE; | |
| 308 | + unsigned i; | |
| 312 | 309 | |
| 313 | 310 | memset(&st, 0, sizeof(st)); |
| 314 | 311 | st.seq = m; |
| 315 | 312 | st.marker = address_markers; |
| 316 | 313 | |
| 317 | − pgd += pgdoff; | |
| 318 | − | |
| 319 | − for (i = pgdoff; i < PTRS_PER_PGD; i++, pgd++) { | |
| 314 | + for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { | |
| 320 | 315 | addr = i * PGDIR_SIZE; |
| 321 | 316 | if (!pgd_none(*pgd)) { |
| 322 | 317 | walk_pud(&st, pgd, addr); |
| @@ -658,8 +658,8 @@ static struct section_perm ro_perms[] = { · 657 unmodified lines | ||
| 658 | 658 | .start = (unsigned long)_stext, |
| 659 | 659 | .end = (unsigned long)__init_begin, |
| 660 | 660 | #ifdef CONFIG_ARM_LPAE |
| 661 | − .mask = ~PMD_SECT_RDONLY, | |
| 662 | − .prot = PMD_SECT_RDONLY, | |
| 661 | + .mask = ~L_PMD_SECT_RDONLY, | |
| 662 | + .prot = L_PMD_SECT_RDONLY, | |
| 663 | 663 | #else |
| 664 | 664 | .mask = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE), |
| 665 | 665 | .prot = PMD_SECT_APX | PMD_SECT_AP_WRITE, |
| @@ -1329,8 +1329,8 @@ static void __init kmap_init(void) · 1328 unmodified lines | ||
| 1329 | 1329 | static void __init map_lowmem(void) |
| 1330 | 1330 | { |
| 1331 | 1331 | struct memblock_region *reg; |
| 1332 | − unsigned long kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); | |
| 1333 | − unsigned long kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); | |
| 1332 | + phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); | |
| 1333 | + phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); | |
| 1334 | 1334 | |
| 1335 | 1335 | /* Map all the lowmem memory banks. */ |
| 1336 | 1336 | for_each_memblock(memory, reg) { |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include <asm/barrier.h> |
| 23 | 23 | |
| 24 | +#include <linux/bug.h> | |
| 24 | 25 | #include <linux/init.h> |
| 25 | 26 | #include <linux/types.h> |
| 26 | 27 | |
| @@ -39,6 +39,7 @@ struct cpuinfo_arm64 { · 38 unmodified lines | ||
| 39 | 39 | u64 reg_id_aa64pfr0; |
| 40 | 40 | u64 reg_id_aa64pfr1; |
| 41 | 41 | |
| 42 | + u32 reg_id_dfr0; | |
| 42 | 43 | u32 reg_id_isar0; |
| 43 | 44 | u32 reg_id_isar1; |
| 44 | 45 | u32 reg_id_isar2; |
| @@ -51,6 +52,10 @@ struct cpuinfo_arm64 { · 6 unmodified lines | ||
| 51 | 52 | u32 reg_id_mmfr3; |
| 52 | 53 | u32 reg_id_pfr0; |
| 53 | 54 | u32 reg_id_pfr1; |
| 55 | + | |
| 56 | + u32 reg_mvfr0; | |
| 57 | + u32 reg_mvfr1; | |
| 58 | + u32 reg_mvfr2; | |
| 54 | 59 | }; |
| 55 | 60 | |
| 56 | 61 | DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data); |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | #include <asm/fpsimd.h> |
| 33 | 33 | #include <asm/hw_breakpoint.h> |
| 34 | +#include <asm/pgtable-hwdef.h> | |
| 34 | 35 | #include <asm/ptrace.h> |
| 35 | 36 | #include <asm/types.h> |
| 36 | 37 | |
| @@ -123,9 +124,6 @@ struct task_struct; · 86 unmodified lines | ||
| 123 | 124 | /* Free all resources held by a thread. */ |
| 124 | 125 | extern void release_thread(struct task_struct *); |
| 125 | 126 | |
| 126 | −/* Prepare to copy thread state - unlazy all lazy status */ | |
| 127 | −#define prepare_to_copy(tsk) do { } while (0) | |
| 128 | − | |
| 129 | 127 | unsigned long get_wchan(struct task_struct *p); |
| 130 | 128 | |
| 131 | 129 | #define cpu_relax() barrier() |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) |
| 45 | 45 | #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) |
| 46 | 46 | |
| 47 | −#define __NR_compat_syscalls 386 | |
| 47 | +#define __NR_compat_syscalls 387 | |
| 48 | 48 | #endif |
| 49 | 49 | |
| 50 | 50 | #define __ARCH_WANT_SYS_CLONE |
| @@ -147,6 +147,7 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) · 146 unmodified lines | ||
| 147 | 147 | * If we have AArch32, we care about 32-bit features for compat. These |
| 148 | 148 | * registers should be RES0 otherwise. |
| 149 | 149 | */ |
| 150 | + diff |= CHECK(id_dfr0, boot, cur, cpu); | |
| 150 | 151 | diff |= CHECK(id_isar0, boot, cur, cpu); |
| 151 | 152 | diff |= CHECK(id_isar1, boot, cur, cpu); |
| 152 | 153 | diff |= CHECK(id_isar2, boot, cur, cpu); |
| @@ -165,6 +166,10 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) · 12 unmodified lines | ||
| 165 | 166 | diff |= CHECK(id_pfr0, boot, cur, cpu); |
| 166 | 167 | diff |= CHECK(id_pfr1, boot, cur, cpu); |
| 167 | 168 | |
| 169 | + diff |= CHECK(mvfr0, boot, cur, cpu); | |
| 170 | + diff |= CHECK(mvfr1, boot, cur, cpu); | |
| 171 | + diff |= CHECK(mvfr2, boot, cur, cpu); | |
| 172 | + | |
| 168 | 173 | /* |
| 169 | 174 | * Mismatched CPU features are a recipe for disaster. Don't even |
| 170 | 175 | * pretend to support them. |
| @@ -189,6 +194,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) · 18 unmodified lines | ||
| 189 | 194 | info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1); |
| 190 | 195 | info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1); |
| 191 | 196 | |
| 197 | + info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1); | |
| 192 | 198 | info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1); |
| 193 | 199 | info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1); |
| 194 | 200 | info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1); |
| @@ -202,6 +208,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) · 7 unmodified lines | ||
| 202 | 208 | info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1); |
| 203 | 209 | info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1); |
| 204 | 210 | |
| 211 | + info->reg_mvfr0 = read_cpuid(MVFR0_EL1); | |
| 212 | + info->reg_mvfr1 = read_cpuid(MVFR1_EL1); | |
| 213 | + info->reg_mvfr2 = read_cpuid(MVFR2_EL1); | |
| 214 | + | |
| 205 | 215 | cpuinfo_detect_icache_policy(info); |
| 206 | 216 | |
| 207 | 217 | check_local_cpu_errata(); |
| @@ -326,6 +326,7 @@ void __init efi_idmap_init(void) · 325 unmodified lines | ||
| 326 | 326 | |
| 327 | 327 | /* boot time idmap_pg_dir is incomplete, so fill in missing parts */ |
| 328 | 328 | efi_setup_idmap(); |
| 329 | + early_memunmap(memmap.map, memmap.map_end - memmap.map); | |
| 329 | 330 | } |
| 330 | 331 | |
| 331 | 332 | static int __init remap_region(efi_memory_desc_t *md, void **new) |
| @@ -380,7 +381,6 @@ static int __init arm64_enter_virtual_mode(void) · 48 unmodified lines | ||
| 380 | 381 | } |
| 381 | 382 | |
| 382 | 383 | mapsize = memmap.map_end - memmap.map; |
| 383 | − early_memunmap(memmap.map, mapsize); | |
| 384 | 384 | |
| 385 | 385 | if (efi_runtime_disabled()) { |
| 386 | 386 | pr_info("EFI runtime services will be disabled.\n"); |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/mm.h> |
| 26 | 26 | #include <linux/moduleloader.h> |
| 27 | 27 | #include <linux/vmalloc.h> |
| 28 | +#include <asm/alternative.h> | |
| 28 | 29 | #include <asm/insn.h> |
| 29 | 30 | #include <asm/sections.h> |
| 30 | 31 | |
| @@ -50,3 +50,11 @@ u64 perf_reg_abi(struct task_struct *task) · 49 unmodified lines | ||
| 50 | 50 | else |
| 51 | 51 | return PERF_SAMPLE_REGS_ABI_64; |
| 52 | 52 | } |
| 53 | + | |
| 54 | +void perf_get_regs_user(struct perf_regs *regs_user, | |
| 55 | + struct pt_regs *regs, | |
| 56 | + struct pt_regs *regs_user_copy) | |
| 57 | +{ | |
| 58 | + regs_user->regs = task_pt_regs(current); | |
| 59 | + regs_user->abi = perf_reg_abi(current); | |
| 60 | +} | |
| @@ -402,6 +402,7 @@ void __init setup_arch(char **cmdline_p) · 401 unmodified lines | ||
| 402 | 402 | request_standard_resources(); |
| 403 | 403 | |
| 404 | 404 | efi_idmap_init(); |
| 405 | + early_ioremap_reset(); | |
| 405 | 406 | |
| 406 | 407 | unflatten_device_tree(); |
| 407 | 408 | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/cacheflush.h> |
| 26 | 26 | #include <asm/cpu_ops.h> |
| 27 | 27 | #include <asm/cputype.h> |
| 28 | +#include <asm/io.h> | |
| 28 | 29 | #include <asm/smp_plat.h> |
| 29 | 30 | |
| 30 | 31 | extern void secondary_holding_pen(void); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/device.h> |
| 10 | +#include <linux/delay.h> | |
| 10 | 11 | #include <linux/platform_device.h> |
| 11 | 12 | #include <linux/mtd/mtd.h> |
| 12 | 13 | #include <linux/mtd/partitions.h> |
| @@ -893,13 +893,13 @@ static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) · 892 unmodified lines | ||
| 893 | 893 | } |
| 894 | 894 | |
| 895 | 895 | /* wrapper to silence section mismatch warning */ |
| 896 | −int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) | |
| 896 | +int __ref acpi_map_cpu(acpi_handle handle, int physid, int *pcpu) | |
| 897 | 897 | { |
| 898 | 898 | return _acpi_map_lsapic(handle, physid, pcpu); |
| 899 | 899 | } |
| 900 | −EXPORT_SYMBOL(acpi_map_lsapic); | |
| 900 | +EXPORT_SYMBOL(acpi_map_cpu); | |
| 901 | 901 | |
| 902 | −int acpi_unmap_lsapic(int cpu) | |
| 902 | +int acpi_unmap_cpu(int cpu) | |
| 903 | 903 | { |
| 904 | 904 | ia64_cpu_to_sapicid[cpu] = -1; |
| 905 | 905 | set_cpu_present(cpu, false); |
| @@ -910,8 +910,7 @@ int acpi_unmap_lsapic(int cpu) · 4 unmodified lines | ||
| 910 | 910 | |
| 911 | 911 | return (0); |
| 912 | 912 | } |
| 913 | − | |
| 914 | −EXPORT_SYMBOL(acpi_unmap_lsapic); | |
| 913 | +EXPORT_SYMBOL(acpi_unmap_cpu); | |
| 915 | 914 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
| 916 | 915 | |
| 917 | 916 | #ifdef CONFIG_ACPI_NUMA |
| @@ -51,6 +51,7 @@ targets += cpustr.h · 50 unmodified lines | ||
| 51 | 51 | $(obj)/cpustr.h: $(obj)/mkcpustr FORCE |
| 52 | 52 | $(call if_changed,cpustr) |
| 53 | 53 | endif |
| 54 | +clean-files += cpustr.h | |
| 54 | 55 | |
| 55 | 56 | # --------------------------------------------------------------------------- |
| 56 | 57 | |
| @@ -26,7 +26,6 @@ obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o |
| 28 | 28 | obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o |
| 29 | −obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/ | |
| 30 | 29 | obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o |
| 31 | 30 | obj-$(CONFIG_CRYPTO_SHA256_SSSE3) += sha256-ssse3.o |
| 32 | 31 | obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o |
| @@ -46,6 +45,7 @@ endif · 13 unmodified lines | ||
| 46 | 45 | ifeq ($(avx2_supported),yes) |
| 47 | 46 | obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o |
| 48 | 47 | obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o |
| 48 | + obj-$(CONFIG_CRYPTO_SHA1_MB) += sha-mb/ | |
| 49 | 49 | endif |
| 50 | 50 | |
| 51 | 51 | aes-i586-y := aes-i586-asm_32.o aes_glue.o |
| @@ -208,7 +208,7 @@ ddq_add_8: · 207 unmodified lines | ||
| 208 | 208 | |
| 209 | 209 | .if (klen == KEY_128) |
| 210 | 210 | .if (load_keys) |
| 211 | − vmovdqa 3*16(p_keys), xkeyA | |
| 211 | + vmovdqa 3*16(p_keys), xkey4 | |
| 212 | 212 | .endif |
| 213 | 213 | .else |
| 214 | 214 | vmovdqa 3*16(p_keys), xkeyA |
| @@ -224,7 +224,7 @@ ddq_add_8: · 9 unmodified lines | ||
| 224 | 224 | add $(16*by), p_in |
| 225 | 225 | |
| 226 | 226 | .if (klen == KEY_128) |
| 227 | − vmovdqa 4*16(p_keys), xkey4 | |
| 227 | + vmovdqa 4*16(p_keys), xkeyB | |
| 228 | 228 | .else |
| 229 | 229 | .if (load_keys) |
| 230 | 230 | vmovdqa 4*16(p_keys), xkey4 |
| @@ -234,7 +234,12 @@ ddq_add_8: · 3 unmodified lines | ||
| 234 | 234 | .set i, 0 |
| 235 | 235 | .rept by |
| 236 | 236 | club XDATA, i |
| 237 | − vaesenc xkeyA, var_xdata, var_xdata /* key 3 */ | |
| 237 | + /* key 3 */ | |
| 238 | + .if (klen == KEY_128) | |
| 239 | + vaesenc xkey4, var_xdata, var_xdata | |
| 240 | + .else | |
| 241 | + vaesenc xkeyA, var_xdata, var_xdata | |
| 242 | + .endif | |
| 238 | 243 | .set i, (i +1) |
| 239 | 244 | .endr |
| 240 | 245 | |
| @@ -243,13 +248,18 @@ ddq_add_8: · 2 unmodified lines | ||
| 243 | 248 | .set i, 0 |
| 244 | 249 | .rept by |
| 245 | 250 | club XDATA, i |
| 246 | − vaesenc xkey4, var_xdata, var_xdata /* key 4 */ | |
| 251 | + /* key 4 */ | |
| 252 | + .if (klen == KEY_128) | |
| 253 | + vaesenc xkeyB, var_xdata, var_xdata | |
| 254 | + .else | |
| 255 | + vaesenc xkey4, var_xdata, var_xdata | |
| 256 | + .endif | |
| 247 | 257 | .set i, (i +1) |
| 248 | 258 | .endr |
| 249 | 259 | |
| 250 | 260 | .if (klen == KEY_128) |
| 251 | 261 | .if (load_keys) |
| 252 | − vmovdqa 6*16(p_keys), xkeyB | |
| 262 | + vmovdqa 6*16(p_keys), xkey8 | |
| 253 | 263 | .endif |
| 254 | 264 | .else |
| 255 | 265 | vmovdqa 6*16(p_keys), xkeyB |
| @@ -267,12 +277,17 @@ ddq_add_8: · 11 unmodified lines | ||
| 267 | 277 | .set i, 0 |
| 268 | 278 | .rept by |
| 269 | 279 | club XDATA, i |
| 270 | − vaesenc xkeyB, var_xdata, var_xdata /* key 6 */ | |
| 280 | + /* key 6 */ | |
| 281 | + .if (klen == KEY_128) | |
| 282 | + vaesenc xkey8, var_xdata, var_xdata | |
| 283 | + .else | |
| 284 | + vaesenc xkeyB, var_xdata, var_xdata | |
| 285 | + .endif | |
| 271 | 286 | .set i, (i +1) |
| 272 | 287 | .endr |
| 273 | 288 | |
| 274 | 289 | .if (klen == KEY_128) |
| 275 | − vmovdqa 8*16(p_keys), xkey8 | |
| 290 | + vmovdqa 8*16(p_keys), xkeyB | |
| 276 | 291 | .else |
| 277 | 292 | .if (load_keys) |
| 278 | 293 | vmovdqa 8*16(p_keys), xkey8 |
| @@ -288,7 +303,7 @@ ddq_add_8: · 9 unmodified lines | ||
| 288 | 303 | |
| 289 | 304 | .if (klen == KEY_128) |
| 290 | 305 | .if (load_keys) |
| 291 | − vmovdqa 9*16(p_keys), xkeyA | |
| 306 | + vmovdqa 9*16(p_keys), xkey12 | |
| 292 | 307 | .endif |
| 293 | 308 | .else |
| 294 | 309 | vmovdqa 9*16(p_keys), xkeyA |
| @@ -297,7 +312,12 @@ ddq_add_8: · 2 unmodified lines | ||
| 297 | 312 | .set i, 0 |
| 298 | 313 | .rept by |
| 299 | 314 | club XDATA, i |
| 300 | − vaesenc xkey8, var_xdata, var_xdata /* key 8 */ | |
| 315 | + /* key 8 */ | |
| 316 | + .if (klen == KEY_128) | |
| 317 | + vaesenc xkeyB, var_xdata, var_xdata | |
| 318 | + .else | |
| 319 | + vaesenc xkey8, var_xdata, var_xdata | |
| 320 | + .endif | |
| 301 | 321 | .set i, (i +1) |
| 302 | 322 | .endr |
| 303 | 323 | |
| @@ -306,7 +326,12 @@ ddq_add_8: · 2 unmodified lines | ||
| 306 | 326 | .set i, 0 |
| 307 | 327 | .rept by |
| 308 | 328 | club XDATA, i |
| 309 | − vaesenc xkeyA, var_xdata, var_xdata /* key 9 */ | |
| 329 | + /* key 9 */ | |
| 330 | + .if (klen == KEY_128) | |
| 331 | + vaesenc xkey12, var_xdata, var_xdata | |
| 332 | + .else | |
| 333 | + vaesenc xkeyA, var_xdata, var_xdata | |
| 334 | + .endif | |
| 310 | 335 | .set i, (i +1) |
| 311 | 336 | .endr |
| 312 | 337 | |
| @@ -412,7 +437,6 @@ ddq_add_8: · 99 unmodified lines | ||
| 412 | 437 | /* main body of aes ctr load */ |
| 413 | 438 | |
| 414 | 439 | .macro do_aes_ctrmain key_len |
| 415 | − | |
| 416 | 440 | cmp $16, num_bytes |
| 417 | 441 | jb .Ldo_return2\key_len |
| 418 | 442 | |
| @@ -80,9 +80,11 @@ static inline unsigned int __getcpu(void) · 79 unmodified lines | ||
| 80 | 80 | |
| 81 | 81 | /* |
| 82 | 82 | * Load per CPU data from GDT. LSL is faster than RDTSCP and |
| 83 | − * works on all CPUs. | |
| 83 | + * works on all CPUs. This is volatile so that it orders | |
| 84 | + * correctly wrt barrier() and to keep gcc from cleverly | |
| 85 | + * hoisting it out of the calling function. | |
| 84 | 86 | */ |
| 85 | − asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | |
| 87 | + asm volatile ("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); | |
| 86 | 88 | |
| 87 | 89 | return p; |
| 88 | 90 | } |
| @@ -750,13 +750,13 @@ static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) · 749 unmodified lines | ||
| 750 | 750 | } |
| 751 | 751 | |
| 752 | 752 | /* wrapper to silence section mismatch warning */ |
| 753 | −int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) | |
| 753 | +int __ref acpi_map_cpu(acpi_handle handle, int physid, int *pcpu) | |
| 754 | 754 | { |
| 755 | 755 | return _acpi_map_lsapic(handle, physid, pcpu); |
| 756 | 756 | } |
| 757 | −EXPORT_SYMBOL(acpi_map_lsapic); | |
| 757 | +EXPORT_SYMBOL(acpi_map_cpu); | |
| 758 | 758 | |
| 759 | −int acpi_unmap_lsapic(int cpu) | |
| 759 | +int acpi_unmap_cpu(int cpu) | |
| 760 | 760 | { |
| 761 | 761 | #ifdef CONFIG_ACPI_NUMA |
| 762 | 762 | set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE); |
| @@ -768,8 +768,7 @@ int acpi_unmap_lsapic(int cpu) · 5 unmodified lines | ||
| 768 | 768 | |
| 769 | 769 | return (0); |
| 770 | 770 | } |
| 771 | − | |
| 772 | −EXPORT_SYMBOL(acpi_unmap_lsapic); | |
| 771 | +EXPORT_SYMBOL(acpi_unmap_cpu); | |
| 773 | 772 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
| 774 | 773 | |
| 775 | 774 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) |
| @@ -66,3 +66,4 @@ targets += capflags.c · 65 unmodified lines | ||
| 66 | 66 | $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE |
| 67 | 67 | $(call if_changed,mkcapflags) |
| 68 | 68 | endif |
| 69 | +clean-files += capflags.c | |
| @@ -28,7 +28,7 @@ function dump_array() · 27 unmodified lines | ||
| 28 | 28 | # If the /* comment */ starts with a quote string, grab that. |
| 29 | 29 | VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')" |
| 30 | 30 | [ -z "$VALUE" ] && VALUE="\"$NAME\"" |
| 31 | − [ "$VALUE" == '""' ] && continue | |
| 31 | + [ "$VALUE" = '""' ] && continue | |
| 32 | 32 | |
| 33 | 33 | # Name is uppercase, VALUE is all lowercase |
| 34 | 34 | VALUE="$(echo "$VALUE" | tr A-Z a-z)" |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff) |
| 18 | 18 | #define UNCORE_PCI_DEV_IDX(data) (data & 0xff) |
| 19 | 19 | #define UNCORE_EXTRA_PCI_DEV 0xff |
| 20 | −#define UNCORE_EXTRA_PCI_DEV_MAX 2 | |
| 20 | +#define UNCORE_EXTRA_PCI_DEV_MAX 3 | |
| 21 | 21 | |
| 22 | 22 | /* support up to 8 sockets */ |
| 23 | 23 | #define UNCORE_SOCKET_MAX 8 |
| @@ -891,6 +891,7 @@ void snbep_uncore_cpu_init(void) · 890 unmodified lines | ||
| 891 | 891 | enum { |
| 892 | 892 | SNBEP_PCI_QPI_PORT0_FILTER, |
| 893 | 893 | SNBEP_PCI_QPI_PORT1_FILTER, |
| 894 | + HSWEP_PCI_PCU_3, | |
| 894 | 895 | }; |
| 895 | 896 | |
| 896 | 897 | static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) |
| @@ -2026,6 +2027,17 @@ void hswep_uncore_cpu_init(void) · 1129 unmodified lines | ||
| 2026 | 2027 | { |
| 2027 | 2028 | if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) |
| 2028 | 2029 | hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; |
| 2030 | + | |
| 2031 | + /* Detect 6-8 core systems with only two SBOXes */ | |
| 2032 | + if (uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3]) { | |
| 2033 | + u32 capid4; | |
| 2034 | + | |
| 2035 | + pci_read_config_dword(uncore_extra_pci_dev[0][HSWEP_PCI_PCU_3], | |
| 2036 | + 0x94, &capid4); | |
| 2037 | + if (((capid4 >> 6) & 0x3) == 0) | |
| 2038 | + hswep_uncore_sbox.num_boxes = 2; | |
| 2039 | + } | |
| 2040 | + | |
| 2029 | 2041 | uncore_msr_uncores = hswep_msr_uncores; |
| 2030 | 2042 | } |
| 2031 | 2043 | |
| @@ -2287,6 +2299,11 @@ static DEFINE_PCI_DEVICE_TABLE(hswep_uncore_pci_ids) = { · 255 unmodified lines | ||
| 2287 | 2299 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, |
| 2288 | 2300 | SNBEP_PCI_QPI_PORT1_FILTER), |
| 2289 | 2301 | }, |
| 2302 | + { /* PCU.3 (for Capability registers) */ | |
| 2303 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0), | |
| 2304 | + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | |
| 2305 | + HSWEP_PCI_PCU_3), | |
| 2306 | + }, | |
| 2290 | 2307 | { /* end: all zeroes */ } |
| 2291 | 2308 | }; |
| 2292 | 2309 | |
| @@ -78,6 +78,14 @@ u64 perf_reg_abi(struct task_struct *task) · 77 unmodified lines | ||
| 78 | 78 | { |
| 79 | 79 | return PERF_SAMPLE_REGS_ABI_32; |
| 80 | 80 | } |
| 81 | + | |
| 82 | +void perf_get_regs_user(struct perf_regs *regs_user, | |
| 83 | + struct pt_regs *regs, | |
| 84 | + struct pt_regs *regs_user_copy) | |
| 85 | +{ | |
| 86 | + regs_user->regs = task_pt_regs(current); | |
| 87 | + regs_user->abi = perf_reg_abi(current); | |
| 88 | +} | |
| 81 | 89 | #else /* CONFIG_X86_64 */ |
| 82 | 90 | #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \ |
| 83 | 91 | (1ULL << PERF_REG_X86_ES) | \ |
| @@ -102,4 +110,86 @@ u64 perf_reg_abi(struct task_struct *task) · 18 unmodified lines | ||
| 102 | 110 | else |
| 103 | 111 | return PERF_SAMPLE_REGS_ABI_64; |
| 104 | 112 | } |
| 113 | + | |
| 114 | +void perf_get_regs_user(struct perf_regs *regs_user, | |
| 115 | + struct pt_regs *regs, | |
| 116 | + struct pt_regs *regs_user_copy) | |
| 117 | +{ | |
| 118 | + struct pt_regs *user_regs = task_pt_regs(current); | |
| 119 | + | |
| 120 | + /* | |
| 121 | + * If we're in an NMI that interrupted task_pt_regs setup, then | |
| 122 | + * we can't sample user regs at all. This check isn't really | |
| 123 | + * sufficient, though, as we could be in an NMI inside an interrupt | |
| 124 | + * that happened during task_pt_regs setup. | |
| 125 | + */ | |
| 126 | + if (regs->sp > (unsigned long)&user_regs->r11 && | |
| 127 | + regs->sp <= (unsigned long)(user_regs + 1)) { | |
| 128 | + regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; | |
| 129 | + regs_user->regs = NULL; | |
| 130 | + return; | |
| 131 | + } | |
| 132 | + | |
| 133 | + /* | |
| 134 | + * RIP, flags, and the argument registers are usually saved. | |
| 135 | + * orig_ax is probably okay, too. | |
| 136 | + */ | |
| 137 | + regs_user_copy->ip = user_regs->ip; | |
| 138 | + regs_user_copy->cx = user_regs->cx; | |
| 139 | + regs_user_copy->dx = user_regs->dx; | |
| 140 | + regs_user_copy->si = user_regs->si; | |
| 141 | + regs_user_copy->di = user_regs->di; | |
| 142 | + regs_user_copy->r8 = user_regs->r8; | |
| 143 | + regs_user_copy->r9 = user_regs->r9; | |
| 144 | + regs_user_copy->r10 = user_regs->r10; | |
| 145 | + regs_user_copy->r11 = user_regs->r11; | |
| 146 | + regs_user_copy->orig_ax = user_regs->orig_ax; | |
| 147 | + regs_user_copy->flags = user_regs->flags; | |
| 148 | + | |
| 149 | + /* | |
| 150 | + * Don't even try to report the "rest" regs. | |
| 151 | + */ | |
| 152 | + regs_user_copy->bx = -1; | |
| 153 | + regs_user_copy->bp = -1; | |
| 154 | + regs_user_copy->r12 = -1; | |
| 155 | + regs_user_copy->r13 = -1; | |
| 156 | + regs_user_copy->r14 = -1; | |
| 157 | + regs_user_copy->r15 = -1; | |
| 158 | + | |
| 159 | + /* | |
| 160 | + * For this to be at all useful, we need a reasonable guess for | |
| 161 | + * sp and the ABI. Be careful: we're in NMI context, and we're | |
| 162 | + * considering current to be the current task, so we should | |
| 163 | + * be careful not to look at any other percpu variables that might | |
| 164 | + * change during context switches. | |
| 165 | + */ | |
| 166 | + if (IS_ENABLED(CONFIG_IA32_EMULATION) && | |
| 167 | + task_thread_info(current)->status & TS_COMPAT) { | |
| 168 | + /* Easy case: we're in a compat syscall. */ | |
| 169 | + regs_user->abi = PERF_SAMPLE_REGS_ABI_32; | |
| 170 | + regs_user_copy->sp = user_regs->sp; | |
| 171 | + regs_user_copy->cs = user_regs->cs; | |
| 172 | + regs_user_copy->ss = user_regs->ss; | |
| 173 | + } else if (user_regs->orig_ax != -1) { | |
| 174 | + /* | |
| 175 | + * We're probably in a 64-bit syscall. | |
| 176 | + * Warning: this code is severely racy. At least it's better | |
| 177 | + * than just blindly copying user_regs. | |
| 178 | + */ | |
| 179 | + regs_user->abi = PERF_SAMPLE_REGS_ABI_64; | |
| 180 | + regs_user_copy->sp = this_cpu_read(old_rsp); | |
| 181 | + regs_user_copy->cs = __USER_CS; | |
| 182 | + regs_user_copy->ss = __USER_DS; | |
| 183 | + regs_user_copy->cx = -1; /* usually contains garbage */ | |
| 184 | + } else { | |
| 185 | + /* We're probably in an interrupt or exception. */ | |
| 186 | + regs_user->abi = user_64bit_mode(user_regs) ? | |
| 187 | + PERF_SAMPLE_REGS_ABI_64 : PERF_SAMPLE_REGS_ABI_32; | |
| 188 | + regs_user_copy->sp = user_regs->sp; | |
| 189 | + regs_user_copy->cs = user_regs->cs; | |
| 190 | + regs_user_copy->ss = user_regs->ss; | |
| 191 | + } | |
| 192 | + | |
| 193 | + regs_user->regs = regs_user_copy; | |
| 194 | +} | |
| 105 | 195 | #endif /* CONFIG_X86_32 */ |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | /* Verify next sizeof(t) bytes can be on the same instruction */ |
| 30 | 30 | #define validate_next(t, insn, n) \ |
| 31 | − ((insn)->next_byte + sizeof(t) + n < (insn)->end_kaddr) | |
| 31 | + ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) | |
| 32 | 32 | |
| 33 | 33 | #define __get_next(t, insn) \ |
| 34 | 34 | ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) |
| @@ -438,20 +438,20 @@ static unsigned long __init init_range_memory_mapping( · 437 unmodified lines | ||
| 438 | 438 | static unsigned long __init get_new_step_size(unsigned long step_size) |
| 439 | 439 | { |
| 440 | 440 | /* |
| 441 | − * Explain why we shift by 5 and why we don't have to worry about | |
| 442 | − * 'step_size << 5' overflowing: | |
| 443 | − * | |
| 444 | − * initial mapped size is PMD_SIZE (2M). | |
| 441 | + * Initial mapped size is PMD_SIZE (2M). | |
| 445 | 442 | * We can not set step_size to be PUD_SIZE (1G) yet. |
| 446 | 443 | * In worse case, when we cross the 1G boundary, and |
| 447 | 444 | * PG_LEVEL_2M is not set, we will need 1+1+512 pages (2M + 8k) |
| 448 | − * to map 1G range with PTE. Use 5 as shift for now. | |
| 445 | + * to map 1G range with PTE. Hence we use one less than the | |
| 446 | + * difference of page table level shifts. | |
| 449 | 447 | * |
| 450 | − * Don't need to worry about overflow, on 32bit, when step_size | |
| 451 | − * is 0, round_down() returns 0 for start, and that turns it | |
| 452 | − * into 0x100000000ULL. | |
| 448 | + * Don't need to worry about overflow in the top-down case, on 32bit, | |
| 449 | + * when step_size is 0, round_down() returns 0 for start, and that | |
| 450 | + * turns it into 0x100000000ULL. | |
| 451 | + * In the bottom-up case, round_up(x, 0) returns 0 though too, which | |
| 452 | + * needs to be taken into consideration by the code below. | |
| 453 | 453 | */ |
| 454 | − return step_size << 5; | |
| 454 | + return step_size << (PMD_SHIFT - PAGE_SHIFT - 1); | |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | 457 | /** |
| @@ -471,7 +471,6 @@ static void __init memory_map_top_down(unsigned long map_start, · 13 unmodified lines | ||
| 471 | 471 | unsigned long step_size; |
| 472 | 472 | unsigned long addr; |
| 473 | 473 | unsigned long mapped_ram_size = 0; |
| 474 | − unsigned long new_mapped_ram_size; | |
| 475 | 474 | |
| 476 | 475 | /* xen has big range in reserved near end of ram, skip it at first.*/ |
| 477 | 476 | addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE); |
| @@ -496,14 +495,12 @@ static void __init memory_map_top_down(unsigned long map_start, · 18 unmodified lines | ||
| 496 | 495 | start = map_start; |
| 497 | 496 | } else |
| 498 | 497 | start = map_start; |
| 499 | − new_mapped_ram_size = init_range_memory_mapping(start, | |
| 498 | + mapped_ram_size += init_range_memory_mapping(start, | |
| 500 | 499 | last_start); |
| 501 | 500 | last_start = start; |
| 502 | 501 | min_pfn_mapped = last_start >> PAGE_SHIFT; |
| 503 | − /* only increase step_size after big range get mapped */ | |
| 504 | − if (new_mapped_ram_size > mapped_ram_size) | |
| 502 | + if (mapped_ram_size >= step_size) | |
| 505 | 503 | step_size = get_new_step_size(step_size); |
| 506 | − mapped_ram_size += new_mapped_ram_size; | |
| 507 | 504 | } |
| 508 | 505 | |
| 509 | 506 | if (real_end < map_end) |
| @@ -524,7 +521,7 @@ static void __init memory_map_top_down(unsigned long map_start, · 14 unmodified lines | ||
| 524 | 521 | static void __init memory_map_bottom_up(unsigned long map_start, |
| 525 | 522 | unsigned long map_end) |
| 526 | 523 | { |
| 527 | − unsigned long next, new_mapped_ram_size, start; | |
| 524 | + unsigned long next, start; | |
| 528 | 525 | unsigned long mapped_ram_size = 0; |
| 529 | 526 | /* step_size need to be small so pgt_buf from BRK could cover it */ |
| 530 | 527 | unsigned long step_size = PMD_SIZE; |
| @@ -539,19 +536,19 @@ static void __init memory_map_bottom_up(unsigned long map_start, · 8 unmodified lines | ||
| 539 | 536 | * for page table. |
| 540 | 537 | */ |
| 541 | 538 | while (start < map_end) { |
| 542 | − if (map_end - start > step_size) { | |
| 539 | + if (step_size && map_end - start > step_size) { | |
| 543 | 540 | next = round_up(start + 1, step_size); |
| 544 | 541 | if (next > map_end) |
| 545 | 542 | next = map_end; |
| 546 | − } else | |
| 543 | + } else { | |
| 547 | 544 | next = map_end; |
| 545 | + } | |
| 548 | 546 | |
| 549 | − new_mapped_ram_size = init_range_memory_mapping(start, next); | |
| 547 | + mapped_ram_size += init_range_memory_mapping(start, next); | |
| 550 | 548 | start = next; |
| 551 | 549 | |
| 552 | − if (new_mapped_ram_size > mapped_ram_size) | |
| 550 | + if (mapped_ram_size >= step_size) | |
| 553 | 551 | step_size = get_new_step_size(step_size); |
| 554 | − mapped_ram_size += new_mapped_ram_size; | |
| 555 | 552 | } |
| 556 | 553 | } |
| 557 | 554 | |
| @@ -41,12 +41,17 @@ void __init init_vdso_image(const struct vdso_image *image) · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | struct linux_binprm; |
| 43 | 43 | |
| 44 | −/* Put the vdso above the (randomized) stack with another randomized offset. | |
| 45 | − This way there is no hole in the middle of address space. | |
| 46 | − To save memory make sure it is still in the same PTE as the stack top. | |
| 47 | − This doesn't give that many random bits. | |
| 48 | − | |
| 49 | − Only used for the 64-bit and x32 vdsos. */ | |
| 44 | +/* | |
| 45 | + * Put the vdso above the (randomized) stack with another randomized | |
| 46 | + * offset. This way there is no hole in the middle of address space. | |
| 47 | + * To save memory make sure it is still in the same PTE as the stack | |
| 48 | + * top. This doesn't give that many random bits. | |
| 49 | + * | |
| 50 | + * Note that this algorithm is imperfect: the distribution of the vdso | |
| 51 | + * start address within a PMD is biased toward the end. | |
| 52 | + * | |
| 53 | + * Only used for the 64-bit and x32 vdsos. | |
| 54 | + */ | |
| 50 | 55 | static unsigned long vdso_addr(unsigned long start, unsigned len) |
| 51 | 56 | { |
| 52 | 57 | #ifdef CONFIG_X86_32 |
| @@ -54,22 +59,30 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) · 1 unmodified line | ||
| 54 | 59 | #else |
| 55 | 60 | unsigned long addr, end; |
| 56 | 61 | unsigned offset; |
| 57 | − end = (start + PMD_SIZE - 1) & PMD_MASK; | |
| 62 | + | |
| 63 | + /* | |
| 64 | + * Round up the start address. It can start out unaligned as a result | |
| 65 | + * of stack start randomization. | |
| 66 | + */ | |
| 67 | + start = PAGE_ALIGN(start); | |
| 68 | + | |
| 69 | + /* Round the lowest possible end address up to a PMD boundary. */ | |
| 70 | + end = (start + len + PMD_SIZE - 1) & PMD_MASK; | |
| 58 | 71 | if (end >= TASK_SIZE_MAX) |
| 59 | 72 | end = TASK_SIZE_MAX; |
| 60 | 73 | end -= len; |
| 61 | − /* This loses some more bits than a modulo, but is cheaper */ | |
| 62 | − offset = get_random_int() & (PTRS_PER_PTE - 1); | |
| 63 | − addr = start + (offset << PAGE_SHIFT); | |
| 64 | − if (addr >= end) | |
| 65 | − addr = end; | |
| 74 | + | |
| 75 | + if (end > start) { | |
| 76 | + offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1); | |
| 77 | + addr = start + (offset << PAGE_SHIFT); | |
| 78 | + } else { | |
| 79 | + addr = start; | |
| 80 | + } | |
| 66 | 81 | |
| 67 | 82 | /* |
| 68 | − * page-align it here so that get_unmapped_area doesn't | |
| 69 | − * align it wrongfully again to the next page. addr can come in 4K | |
| 70 | − * unaligned here as a result of stack start randomization. | |
| 83 | + * Forcibly align the final address in case we have a hardware | |
| 84 | + * issue that requires alignment for performance reasons. | |
| 71 | 85 | */ |
| 72 | − addr = PAGE_ALIGN(addr); | |
| 73 | 86 | addr = align_vdso_addr(addr); |
| 74 | 87 | |
| 75 | 88 | return addr; |
| @@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/ · 49 unmodified lines | ||
| 50 | 50 | obj-y += tty/ |
| 51 | 51 | obj-y += char/ |
| 52 | 52 | |
| 53 | −# gpu/ comes after char for AGP vs DRM startup | |
| 53 | +# iommu/ comes before gpu as gpu are using iommu controllers | |
| 54 | +obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | |
| 55 | + | |
| 56 | +# gpu/ comes after char for AGP vs DRM startup and after iommu | |
| 54 | 57 | obj-y += gpu/ |
| 55 | 58 | |
| 56 | 59 | obj-$(CONFIG_CONNECTOR) += connector/ |
| @@ -141,7 +144,6 @@ obj-y += clk/ · 84 unmodified lines | ||
| 141 | 144 | |
| 142 | 145 | obj-$(CONFIG_MAILBOX) += mailbox/ |
| 143 | 146 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ |
| 144 | −obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | |
| 145 | 147 | obj-$(CONFIG_REMOTEPROC) += remoteproc/ |
| 146 | 148 | obj-$(CONFIG_RPMSG) += rpmsg/ |
| 147 | 149 | |
| @@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) · 169 unmodified lines | ||
| 170 | 170 | acpi_status status; |
| 171 | 171 | int ret; |
| 172 | 172 | |
| 173 | − if (pr->apic_id == -1) | |
| 173 | + if (pr->phys_id == -1) | |
| 174 | 174 | return -ENODEV; |
| 175 | 175 | |
| 176 | 176 | status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); |
| @@ -180,13 +180,13 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) · 3 unmodified lines | ||
| 180 | 180 | cpu_maps_update_begin(); |
| 181 | 181 | cpu_hotplug_begin(); |
| 182 | 182 | |
| 183 | − ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id); | |
| 183 | + ret = acpi_map_cpu(pr->handle, pr->phys_id, &pr->id); | |
| 184 | 184 | if (ret) |
| 185 | 185 | goto out; |
| 186 | 186 | |
| 187 | 187 | ret = arch_register_cpu(pr->id); |
| 188 | 188 | if (ret) { |
| 189 | − acpi_unmap_lsapic(pr->id); | |
| 189 | + acpi_unmap_cpu(pr->id); | |
| 190 | 190 | goto out; |
| 191 | 191 | } |
| 192 | 192 | |
| @@ -215,7 +215,7 @@ static int acpi_processor_get_info(struct acpi_device *device) · 22 unmodified lines | ||
| 215 | 215 | union acpi_object object = { 0 }; |
| 216 | 216 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
| 217 | 217 | struct acpi_processor *pr = acpi_driver_data(device); |
| 218 | − int apic_id, cpu_index, device_declaration = 0; | |
| 218 | + int phys_id, cpu_index, device_declaration = 0; | |
| 219 | 219 | acpi_status status = AE_OK; |
| 220 | 220 | static int cpu0_initialized; |
| 221 | 221 | unsigned long long value; |
| @@ -262,15 +262,18 @@ static int acpi_processor_get_info(struct acpi_device *device) · 40 unmodified lines | ||
| 262 | 262 | pr->acpi_id = value; |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | − apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); | |
| 266 | − if (apic_id < 0) | |
| 267 | − acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); | |
| 268 | − pr->apic_id = apic_id; | |
| 265 | + phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id); | |
| 266 | + if (phys_id < 0) | |
| 267 | + acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n"); | |
| 268 | + pr->phys_id = phys_id; | |
| 269 | 269 | |
| 270 | − cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | |
| 270 | + cpu_index = acpi_map_cpuid(pr->phys_id, pr->acpi_id); | |
| 271 | 271 | if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { |
| 272 | 272 | cpu0_initialized = 1; |
| 273 | − /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | |
| 273 | + /* | |
| 274 | + * Handle UP system running SMP kernel, with no CPU | |
| 275 | + * entry in MADT | |
| 276 | + */ | |
| 274 | 277 | if ((cpu_index == -1) && (num_online_cpus() == 1)) |
| 275 | 278 | cpu_index = 0; |
| 276 | 279 | } |
| @@ -458,7 +461,7 @@ static void acpi_processor_remove(struct acpi_device *device) · 181 unmodified lines | ||
| 458 | 461 | |
| 459 | 462 | /* Remove the CPU. */ |
| 460 | 463 | arch_unregister_cpu(pr->id); |
| 461 | − acpi_unmap_lsapic(pr->id); | |
| 464 | + acpi_unmap_cpu(pr->id); | |
| 462 | 465 | |
| 463 | 466 | cpu_hotplug_done(); |
| 464 | 467 | cpu_maps_update_done(); |
| @@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_device *device) · 256 unmodified lines | ||
| 257 | 257 | |
| 258 | 258 | device->power.state = ACPI_STATE_UNKNOWN; |
| 259 | 259 | if (!acpi_device_is_present(device)) |
| 260 | − return 0; | |
| 260 | + return -ENXIO; | |
| 261 | 261 | |
| 262 | 262 | result = acpi_device_get_power(device, &state); |
| 263 | 263 | if (result) |
| @@ -69,7 +69,7 @@ static int map_madt_entry(int type, u32 acpi_id) · 68 unmodified lines | ||
| 69 | 69 | unsigned long madt_end, entry; |
| 70 | 70 | static struct acpi_table_madt *madt; |
| 71 | 71 | static int read_madt; |
| 72 | − int apic_id = -1; | |
| 72 | + int phys_id = -1; /* CPU hardware ID */ | |
| 73 | 73 | |
| 74 | 74 | if (!read_madt) { |
| 75 | 75 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, |
| @@ -79,7 +79,7 @@ static int map_madt_entry(int type, u32 acpi_id) · 3 unmodified lines | ||
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | if (!madt) |
| 82 | − return apic_id; | |
| 82 | + return phys_id; | |
| 83 | 83 | |
| 84 | 84 | entry = (unsigned long)madt; |
| 85 | 85 | madt_end = entry + madt->header.length; |
| @@ -91,18 +91,18 @@ static int map_madt_entry(int type, u32 acpi_id) · 5 unmodified lines | ||
| 91 | 91 | struct acpi_subtable_header *header = |
| 92 | 92 | (struct acpi_subtable_header *)entry; |
| 93 | 93 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
| 94 | − if (!map_lapic_id(header, acpi_id, &apic_id)) | |
| 94 | + if (!map_lapic_id(header, acpi_id, &phys_id)) | |
| 95 | 95 | break; |
| 96 | 96 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { |
| 97 | − if (!map_x2apic_id(header, type, acpi_id, &apic_id)) | |
| 97 | + if (!map_x2apic_id(header, type, acpi_id, &phys_id)) | |
| 98 | 98 | break; |
| 99 | 99 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
| 100 | − if (!map_lsapic_id(header, type, acpi_id, &apic_id)) | |
| 100 | + if (!map_lsapic_id(header, type, acpi_id, &phys_id)) | |
| 101 | 101 | break; |
| 102 | 102 | } |
| 103 | 103 | entry += header->length; |
| 104 | 104 | } |
| 105 | − return apic_id; | |
| 105 | + return phys_id; | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
| @@ -110,7 +110,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) · 1 unmodified line | ||
| 110 | 110 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 111 | 111 | union acpi_object *obj; |
| 112 | 112 | struct acpi_subtable_header *header; |
| 113 | − int apic_id = -1; | |
| 113 | + int phys_id = -1; | |
| 114 | 114 | |
| 115 | 115 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
| 116 | 116 | goto exit; |
| @@ -126,38 +126,38 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) · 9 unmodified lines | ||
| 126 | 126 | |
| 127 | 127 | header = (struct acpi_subtable_header *)obj->buffer.pointer; |
| 128 | 128 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) |
| 129 | − map_lapic_id(header, acpi_id, &apic_id); | |
| 129 | + map_lapic_id(header, acpi_id, &phys_id); | |
| 130 | 130 | else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) |
| 131 | − map_lsapic_id(header, type, acpi_id, &apic_id); | |
| 131 | + map_lsapic_id(header, type, acpi_id, &phys_id); | |
| 132 | 132 | else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) |
| 133 | − map_x2apic_id(header, type, acpi_id, &apic_id); | |
| 133 | + map_x2apic_id(header, type, acpi_id, &phys_id); | |
| 134 | 134 | |
| 135 | 135 | exit: |
| 136 | 136 | kfree(buffer.pointer); |
| 137 | − return apic_id; | |
| 137 | + return phys_id; | |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | −int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) | |
| 140 | +int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) | |
| 141 | 141 | { |
| 142 | − int apic_id; | |
| 142 | + int phys_id; | |
| 143 | 143 | |
| 144 | − apic_id = map_mat_entry(handle, type, acpi_id); | |
| 145 | − if (apic_id == -1) | |
| 146 | − apic_id = map_madt_entry(type, acpi_id); | |
| 144 | + phys_id = map_mat_entry(handle, type, acpi_id); | |
| 145 | + if (phys_id == -1) | |
| 146 | + phys_id = map_madt_entry(type, acpi_id); | |
| 147 | 147 | |
| 148 | − return apic_id; | |
| 148 | + return phys_id; | |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | −int acpi_map_cpuid(int apic_id, u32 acpi_id) | |
| 151 | +int acpi_map_cpuid(int phys_id, u32 acpi_id) | |
| 152 | 152 | { |
| 153 | 153 | #ifdef CONFIG_SMP |
| 154 | 154 | int i; |
| 155 | 155 | #endif |
| 156 | 156 | |
| 157 | − if (apic_id == -1) { | |
| 157 | + if (phys_id == -1) { | |
| 158 | 158 | /* |
| 159 | 159 | * On UP processor, there is no _MAT or MADT table. |
| 160 | − * So above apic_id is always set to -1. | |
| 160 | + * So above phys_id is always set to -1. | |
| 161 | 161 | * |
| 162 | 162 | * BIOS may define multiple CPU handles even for UP processor. |
| 163 | 163 | * For example, |
| @@ -170,7 +170,7 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) · 6 unmodified lines | ||
| 170 | 170 | * Processor (CPU3, 0x03, 0x00000410, 0x06) {} |
| 171 | 171 | * } |
| 172 | 172 | * |
| 173 | − * Ignores apic_id and always returns 0 for the processor | |
| 173 | + * Ignores phys_id and always returns 0 for the processor | |
| 174 | 174 | * handle with acpi id 0 if nr_cpu_ids is 1. |
| 175 | 175 | * This should be the case if SMP tables are not found. |
| 176 | 176 | * Return -1 for other CPU's handle. |
| @@ -178,28 +178,28 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) · 1 unmodified line | ||
| 178 | 178 | if (nr_cpu_ids <= 1 && acpi_id == 0) |
| 179 | 179 | return acpi_id; |
| 180 | 180 | else |
| 181 | − return apic_id; | |
| 181 | + return phys_id; | |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | #ifdef CONFIG_SMP |
| 185 | 185 | for_each_possible_cpu(i) { |
| 186 | − if (cpu_physical_id(i) == apic_id) | |
| 186 | + if (cpu_physical_id(i) == phys_id) | |
| 187 | 187 | return i; |
| 188 | 188 | } |
| 189 | 189 | #else |
| 190 | 190 | /* In UP kernel, only processor 0 is valid */ |
| 191 | − if (apic_id == 0) | |
| 192 | − return apic_id; | |
| 191 | + if (phys_id == 0) | |
| 192 | + return phys_id; | |
| 193 | 193 | #endif |
| 194 | 194 | return -1; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | 197 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) |
| 198 | 198 | { |
| 199 | − int apic_id; | |
| 199 | + int phys_id; | |
| 200 | 200 | |
| 201 | − apic_id = acpi_get_apicid(handle, type, acpi_id); | |
| 201 | + phys_id = acpi_get_phys_id(handle, type, acpi_id); | |
| 202 | 202 | |
| 203 | − return acpi_map_cpuid(apic_id, acpi_id); | |
| 203 | + return acpi_map_cpuid(phys_id, acpi_id); | |
| 204 | 204 | } |
| 205 | 205 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
| @@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_lists(struct acpi_device *device) · 1000 unmodified lines | ||
| 1001 | 1001 | if (device->wakeup.flags.valid) |
| 1002 | 1002 | acpi_power_resources_list_free(&device->wakeup.resources); |
| 1003 | 1003 | |
| 1004 | − if (!device->flags.power_manageable) | |
| 1004 | + if (!device->power.flags.power_resources) | |
| 1005 | 1005 | return; |
| 1006 | 1006 | |
| 1007 | 1007 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { |
| @@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) · 736 unmodified lines | ||
| 1744 | 1744 | device->power.flags.power_resources) |
| 1745 | 1745 | device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; |
| 1746 | 1746 | |
| 1747 | − if (acpi_bus_init_power(device)) { | |
| 1748 | − acpi_free_power_resources_lists(device); | |
| 1747 | + if (acpi_bus_init_power(device)) | |
| 1749 | 1748 | device->flags.power_manageable = 0; |
| 1750 | − } | |
| 1751 | 1749 | } |
| 1752 | 1750 | |
| 1753 | 1751 | static void acpi_bus_get_flags(struct acpi_device *device) |
| @@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_device *device) · 617 unmodified lines | ||
| 2371 | 2369 | /* Skip devices that are not present. */ |
| 2372 | 2370 | if (!acpi_device_is_present(device)) { |
| 2373 | 2371 | device->flags.visited = false; |
| 2372 | + device->flags.power_manageable = 0; | |
| 2374 | 2373 | return; |
| 2375 | 2374 | } |
| 2376 | 2375 | if (device->handler) |
| 2377 | 2376 | goto ok; |
| 2378 | 2377 | |
| 2379 | 2378 | if (!device->flags.initialized) { |
| 2380 | − acpi_bus_update_power(device, NULL); | |
| 2379 | + device->flags.power_manageable = | |
| 2380 | + device->power.states[ACPI_STATE_D0].flags.valid; | |
| 2381 | + if (acpi_bus_init_power(device)) | |
| 2382 | + device->flags.power_manageable = 0; | |
| 2383 | + | |
| 2381 | 2384 | device->flags.initialized = true; |
| 2382 | 2385 | } |
| 2383 | 2386 | device->flags.visited = false; |
| @@ -522,6 +522,16 @@ static struct dmi_system_id video_dmi_table[] __initdata = { · 521 unmodified lines | ||
| 522 | 522 | DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), |
| 523 | 523 | }, |
| 524 | 524 | }, |
| 525 | + | |
| 526 | + { | |
| 527 | + /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ | |
| 528 | + .callback = video_disable_native_backlight, | |
| 529 | + .ident = "Dell XPS15 L521X", | |
| 530 | + .matches = { | |
| 531 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 532 | + DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), | |
| 533 | + }, | |
| 534 | + }, | |
| 525 | 535 | {} |
| 526 | 536 | }; |
| 527 | 537 | |
| @@ -969,7 +969,8 @@ static void sender(void *send_info, · 968 unmodified lines | ||
| 969 | 969 | |
| 970 | 970 | do_gettimeofday(&t); |
| 971 | 971 | pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", |
| 972 | − msg->data[0], msg->data[1], t.tv_sec, t.tv_usec); | |
| 972 | + msg->data[0], msg->data[1], | |
| 973 | + (long) t.tv_sec, (long) t.tv_usec); | |
| 973 | 974 | } |
| 974 | 975 | } |
| 975 | 976 | |
| @@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o · 36 unmodified lines | ||
| 37 | 37 | obj-$(CONFIG_DRM_TTM) += ttm/ |
| 38 | 38 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
| 39 | 39 | obj-$(CONFIG_DRM_R128) += r128/ |
| 40 | +obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | |
| 40 | 41 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
| 41 | 42 | obj-$(CONFIG_DRM_MGA) += mga/ |
| 42 | 43 | obj-$(CONFIG_DRM_I810) += i810/ |
| @@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/ · 24 unmodified lines | ||
| 67 | 68 | obj-y += i2c/ |
| 68 | 69 | obj-y += panel/ |
| 69 | 70 | obj-y += bridge/ |
| 70 | −obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | |
| @@ -31,7 +31,6 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <uapi/linux/kfd_ioctl.h> |
| 32 | 32 | #include <linux/time.h> |
| 33 | 33 | #include <linux/mm.h> |
| 34 | −#include <linux/uaccess.h> | |
| 35 | 34 | #include <uapi/asm-generic/mman-common.h> |
| 36 | 35 | #include <asm/processor.h> |
| 37 | 36 | #include "kfd_priv.h" |
| @@ -127,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep) · 89 unmodified lines | ||
| 127 | 126 | return 0; |
| 128 | 127 | } |
| 129 | 128 | |
| 130 | −static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, | |
| 131 | − void __user *arg) | |
| 129 | +static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, | |
| 130 | + void *data) | |
| 132 | 131 | { |
| 133 | − struct kfd_ioctl_get_version_args args; | |
| 132 | + struct kfd_ioctl_get_version_args *args = data; | |
| 134 | 133 | int err = 0; |
| 135 | 134 | |
| 136 | − args.major_version = KFD_IOCTL_MAJOR_VERSION; | |
| 137 | − args.minor_version = KFD_IOCTL_MINOR_VERSION; | |
| 138 | − | |
| 139 | − if (copy_to_user(arg, &args, sizeof(args))) | |
| 140 | − err = -EFAULT; | |
| 135 | + args->major_version = KFD_IOCTL_MAJOR_VERSION; | |
| 136 | + args->minor_version = KFD_IOCTL_MINOR_VERSION; | |
| 141 | 137 | |
| 142 | 138 | return err; |
| 143 | 139 | } |
| @@ -221,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, · 77 unmodified lines | ||
| 221 | 217 | return 0; |
| 222 | 218 | } |
| 223 | 219 | |
| 224 | −static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |
| 225 | − void __user *arg) | |
| 220 | +static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |
| 221 | + void *data) | |
| 226 | 222 | { |
| 227 | − struct kfd_ioctl_create_queue_args args; | |
| 223 | + struct kfd_ioctl_create_queue_args *args = data; | |
| 228 | 224 | struct kfd_dev *dev; |
| 229 | 225 | int err = 0; |
| 230 | 226 | unsigned int queue_id; |
| @@ -233,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, · 2 unmodified lines | ||
| 233 | 229 | |
| 234 | 230 | memset(&q_properties, 0, sizeof(struct queue_properties)); |
| 235 | 231 | |
| 236 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 237 | − return -EFAULT; | |
| 238 | − | |
| 239 | 232 | pr_debug("kfd: creating queue ioctl\n"); |
| 240 | 233 | |
| 241 | − err = set_queue_properties_from_user(&q_properties, &args); | |
| 234 | + err = set_queue_properties_from_user(&q_properties, args); | |
| 242 | 235 | if (err) |
| 243 | 236 | return err; |
| 244 | 237 | |
| 245 | − dev = kfd_device_by_id(args.gpu_id); | |
| 238 | + dev = kfd_device_by_id(args->gpu_id); | |
| 246 | 239 | if (dev == NULL) |
| 247 | 240 | return -EINVAL; |
| 248 | 241 | |
| @@ -250,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, · 1 unmodified line | ||
| 250 | 243 | |
| 251 | 244 | pdd = kfd_bind_process_to_device(dev, p); |
| 252 | 245 | if (IS_ERR(pdd)) { |
| 253 | − err = PTR_ERR(pdd); | |
| 246 | + err = -ESRCH; | |
| 254 | 247 | goto err_bind_process; |
| 255 | 248 | } |
| 256 | 249 | |
| @@ -263,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, · 6 unmodified lines | ||
| 263 | 256 | if (err != 0) |
| 264 | 257 | goto err_create_queue; |
| 265 | 258 | |
| 266 | − args.queue_id = queue_id; | |
| 259 | + args->queue_id = queue_id; | |
| 267 | 260 | |
| 268 | 261 | /* Return gpu_id as doorbell offset for mmap usage */ |
| 269 | − args.doorbell_offset = args.gpu_id << PAGE_SHIFT; | |
| 270 | − | |
| 271 | − if (copy_to_user(arg, &args, sizeof(args))) { | |
| 272 | − err = -EFAULT; | |
| 273 | − goto err_copy_args_out; | |
| 274 | − } | |
| 262 | + args->doorbell_offset = args->gpu_id << PAGE_SHIFT; | |
| 275 | 263 | |
| 276 | 264 | mutex_unlock(&p->mutex); |
| 277 | 265 | |
| 278 | − pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); | |
| 266 | + pr_debug("kfd: queue id %d was created successfully\n", args->queue_id); | |
| 279 | 267 | |
| 280 | 268 | pr_debug("ring buffer address == 0x%016llX\n", |
| 281 | − args.ring_base_address); | |
| 269 | + args->ring_base_address); | |
| 282 | 270 | |
| 283 | 271 | pr_debug("read ptr address == 0x%016llX\n", |
| 284 | − args.read_pointer_address); | |
| 272 | + args->read_pointer_address); | |
| 285 | 273 | |
| 286 | 274 | pr_debug("write ptr address == 0x%016llX\n", |
| 287 | − args.write_pointer_address); | |
| 275 | + args->write_pointer_address); | |
| 288 | 276 | |
| 289 | 277 | return 0; |
| 290 | 278 | |
| 291 | −err_copy_args_out: | |
| 292 | − pqm_destroy_queue(&p->pqm, queue_id); | |
| 293 | 279 | err_create_queue: |
| 294 | 280 | err_bind_process: |
| 295 | 281 | mutex_unlock(&p->mutex); |
| @@ -297,99 +283,90 @@ err_bind_process: · 1 unmodified line | ||
| 297 | 283 | } |
| 298 | 284 | |
| 299 | 285 | static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, |
| 300 | − void __user *arg) | |
| 286 | + void *data) | |
| 301 | 287 | { |
| 302 | 288 | int retval; |
| 303 | − struct kfd_ioctl_destroy_queue_args args; | |
| 304 | − | |
| 305 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 306 | − return -EFAULT; | |
| 289 | + struct kfd_ioctl_destroy_queue_args *args = data; | |
| 307 | 290 | |
| 308 | 291 | pr_debug("kfd: destroying queue id %d for PASID %d\n", |
| 309 | − args.queue_id, | |
| 292 | + args->queue_id, | |
| 310 | 293 | p->pasid); |
| 311 | 294 | |
| 312 | 295 | mutex_lock(&p->mutex); |
| 313 | 296 | |
| 314 | − retval = pqm_destroy_queue(&p->pqm, args.queue_id); | |
| 297 | + retval = pqm_destroy_queue(&p->pqm, args->queue_id); | |
| 315 | 298 | |
| 316 | 299 | mutex_unlock(&p->mutex); |
| 317 | 300 | return retval; |
| 318 | 301 | } |
| 319 | 302 | |
| 320 | 303 | static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, |
| 321 | − void __user *arg) | |
| 304 | + void *data) | |
| 322 | 305 | { |
| 323 | 306 | int retval; |
| 324 | − struct kfd_ioctl_update_queue_args args; | |
| 307 | + struct kfd_ioctl_update_queue_args *args = data; | |
| 325 | 308 | struct queue_properties properties; |
| 326 | 309 | |
| 327 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 328 | − return -EFAULT; | |
| 329 | − | |
| 330 | − if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { | |
| 310 | + if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { | |
| 331 | 311 | pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); |
| 332 | 312 | return -EINVAL; |
| 333 | 313 | } |
| 334 | 314 | |
| 335 | − if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { | |
| 315 | + if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) { | |
| 336 | 316 | pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); |
| 337 | 317 | return -EINVAL; |
| 338 | 318 | } |
| 339 | 319 | |
| 340 | − if ((args.ring_base_address) && | |
| 320 | + if ((args->ring_base_address) && | |
| 341 | 321 | (!access_ok(VERIFY_WRITE, |
| 342 | − (const void __user *) args.ring_base_address, | |
| 322 | + (const void __user *) args->ring_base_address, | |
| 343 | 323 | sizeof(uint64_t)))) { |
| 344 | 324 | pr_err("kfd: can't access ring base address\n"); |
| 345 | 325 | return -EFAULT; |
| 346 | 326 | } |
| 347 | 327 | |
| 348 | − if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { | |
| 328 | + if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) { | |
| 349 | 329 | pr_err("kfd: ring size must be a power of 2 or 0\n"); |
| 350 | 330 | return -EINVAL; |
| 351 | 331 | } |
| 352 | 332 | |
| 353 | − properties.queue_address = args.ring_base_address; | |
| 354 | − properties.queue_size = args.ring_size; | |
| 355 | − properties.queue_percent = args.queue_percentage; | |
| 356 | − properties.priority = args.queue_priority; | |
| 333 | + properties.queue_address = args->ring_base_address; | |
| 334 | + properties.queue_size = args->ring_size; | |
| 335 | + properties.queue_percent = args->queue_percentage; | |
| 336 | + properties.priority = args->queue_priority; | |
| 357 | 337 | |
| 358 | 338 | pr_debug("kfd: updating queue id %d for PASID %d\n", |
| 359 | − args.queue_id, p->pasid); | |
| 339 | + args->queue_id, p->pasid); | |
| 360 | 340 | |
| 361 | 341 | mutex_lock(&p->mutex); |
| 362 | 342 | |
| 363 | − retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); | |
| 343 | + retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); | |
| 364 | 344 | |
| 365 | 345 | mutex_unlock(&p->mutex); |
| 366 | 346 | |
| 367 | 347 | return retval; |
| 368 | 348 | } |
| 369 | 349 | |
| 370 | −static long kfd_ioctl_set_memory_policy(struct file *filep, | |
| 371 | − struct kfd_process *p, void __user *arg) | |
| 350 | +static int kfd_ioctl_set_memory_policy(struct file *filep, | |
| 351 | + struct kfd_process *p, void *data) | |
| 372 | 352 | { |
| 373 | − struct kfd_ioctl_set_memory_policy_args args; | |
| 353 | + struct kfd_ioctl_set_memory_policy_args *args = data; | |
| 374 | 354 | struct kfd_dev *dev; |
| 375 | 355 | int err = 0; |
| 376 | 356 | struct kfd_process_device *pdd; |
| 377 | 357 | enum cache_policy default_policy, alternate_policy; |
| 378 | 358 | |
| 379 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 380 | − return -EFAULT; | |
| 381 | − | |
| 382 | − if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT | |
| 383 | − && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | |
| 359 | + if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT | |
| 360 | + && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | |
| 384 | 361 | return -EINVAL; |
| 385 | 362 | } |
| 386 | 363 | |
| 387 | − if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT | |
| 388 | − && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | |
| 364 | + if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT | |
| 365 | + && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | |
| 389 | 366 | return -EINVAL; |
| 390 | 367 | } |
| 391 | 368 | |
| 392 | − dev = kfd_device_by_id(args.gpu_id); | |
| 369 | + dev = kfd_device_by_id(args->gpu_id); | |
| 393 | 370 | if (dev == NULL) |
| 394 | 371 | return -EINVAL; |
| 395 | 372 | |
| @@ -397,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, · 1 unmodified line | ||
| 397 | 374 | |
| 398 | 375 | pdd = kfd_bind_process_to_device(dev, p); |
| 399 | 376 | if (IS_ERR(pdd)) { |
| 400 | − err = PTR_ERR(pdd); | |
| 377 | + err = -ESRCH; | |
| 401 | 378 | goto out; |
| 402 | 379 | } |
| 403 | 380 | |
| 404 | − default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) | |
| 381 | + default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT) | |
| 405 | 382 | ? cache_policy_coherent : cache_policy_noncoherent; |
| 406 | 383 | |
| 407 | 384 | alternate_policy = |
| 408 | − (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) | |
| 385 | + (args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) | |
| 409 | 386 | ? cache_policy_coherent : cache_policy_noncoherent; |
| 410 | 387 | |
| 411 | 388 | if (!dev->dqm->set_cache_memory_policy(dev->dqm, |
| 412 | 389 | &pdd->qpd, |
| 413 | 390 | default_policy, |
| 414 | 391 | alternate_policy, |
| 415 | − (void __user *)args.alternate_aperture_base, | |
| 416 | − args.alternate_aperture_size)) | |
| 392 | + (void __user *)args->alternate_aperture_base, | |
| 393 | + args->alternate_aperture_size)) | |
| 417 | 394 | err = -EINVAL; |
| 418 | 395 | |
| 419 | 396 | out: |
| @@ -422,53 +399,44 @@ out: · 2 unmodified lines | ||
| 422 | 399 | return err; |
| 423 | 400 | } |
| 424 | 401 | |
| 425 | −static long kfd_ioctl_get_clock_counters(struct file *filep, | |
| 426 | − struct kfd_process *p, void __user *arg) | |
| 402 | +static int kfd_ioctl_get_clock_counters(struct file *filep, | |
| 403 | + struct kfd_process *p, void *data) | |
| 427 | 404 | { |
| 428 | − struct kfd_ioctl_get_clock_counters_args args; | |
| 405 | + struct kfd_ioctl_get_clock_counters_args *args = data; | |
| 429 | 406 | struct kfd_dev *dev; |
| 430 | 407 | struct timespec time; |
| 431 | 408 | |
| 432 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 433 | − return -EFAULT; | |
| 434 | − | |
| 435 | − dev = kfd_device_by_id(args.gpu_id); | |
| 409 | + dev = kfd_device_by_id(args->gpu_id); | |
| 436 | 410 | if (dev == NULL) |
| 437 | 411 | return -EINVAL; |
| 438 | 412 | |
| 439 | 413 | /* Reading GPU clock counter from KGD */ |
| 440 | − args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); | |
| 414 | + args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); | |
| 441 | 415 | |
| 442 | 416 | /* No access to rdtsc. Using raw monotonic time */ |
| 443 | 417 | getrawmonotonic(&time); |
| 444 | − args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); | |
| 418 | + args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time); | |
| 445 | 419 | |
| 446 | 420 | get_monotonic_boottime(&time); |
| 447 | − args.system_clock_counter = (uint64_t)timespec_to_ns(&time); | |
| 421 | + args->system_clock_counter = (uint64_t)timespec_to_ns(&time); | |
| 448 | 422 | |
| 449 | 423 | /* Since the counter is in nano-seconds we use 1GHz frequency */ |
| 450 | − args.system_clock_freq = 1000000000; | |
| 451 | − | |
| 452 | − if (copy_to_user(arg, &args, sizeof(args))) | |
| 453 | − return -EFAULT; | |
| 424 | + args->system_clock_freq = 1000000000; | |
| 454 | 425 | |
| 455 | 426 | return 0; |
| 456 | 427 | } |
| 457 | 428 | |
| 458 | 429 | |
| 459 | 430 | static int kfd_ioctl_get_process_apertures(struct file *filp, |
| 460 | − struct kfd_process *p, void __user *arg) | |
| 431 | + struct kfd_process *p, void *data) | |
| 461 | 432 | { |
| 462 | − struct kfd_ioctl_get_process_apertures_args args; | |
| 433 | + struct kfd_ioctl_get_process_apertures_args *args = data; | |
| 463 | 434 | struct kfd_process_device_apertures *pAperture; |
| 464 | 435 | struct kfd_process_device *pdd; |
| 465 | 436 | |
| 466 | 437 | dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); |
| 467 | 438 | |
| 468 | − if (copy_from_user(&args, arg, sizeof(args))) | |
| 469 | − return -EFAULT; | |
| 470 | − | |
| 471 | − args.num_of_nodes = 0; | |
| 439 | + args->num_of_nodes = 0; | |
| 472 | 440 | |
| 473 | 441 | mutex_lock(&p->mutex); |
| 474 | 442 | |
| @@ -477,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, · 2 unmodified lines | ||
| 477 | 445 | /* Run over all pdd of the process */ |
| 478 | 446 | pdd = kfd_get_first_process_device_data(p); |
| 479 | 447 | do { |
| 480 | − pAperture = &args.process_apertures[args.num_of_nodes]; | |
| 448 | + pAperture = | |
| 449 | + &args->process_apertures[args->num_of_nodes]; | |
| 481 | 450 | pAperture->gpu_id = pdd->dev->id; |
| 482 | 451 | pAperture->lds_base = pdd->lds_base; |
| 483 | 452 | pAperture->lds_limit = pdd->lds_limit; |
| @@ -487,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, · 3 unmodified lines | ||
| 487 | 456 | pAperture->scratch_limit = pdd->scratch_limit; |
| 488 | 457 | |
| 489 | 458 | dev_dbg(kfd_device, |
| 490 | − "node id %u\n", args.num_of_nodes); | |
| 459 | + "node id %u\n", args->num_of_nodes); | |
| 491 | 460 | dev_dbg(kfd_device, |
| 492 | 461 | "gpu id %u\n", pdd->dev->id); |
| 493 | 462 | dev_dbg(kfd_device, |
| @@ -503,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, · 9 unmodified lines | ||
| 503 | 472 | dev_dbg(kfd_device, |
| 504 | 473 | "scratch_limit %llX\n", pdd->scratch_limit); |
| 505 | 474 | |
| 506 | − args.num_of_nodes++; | |
| 475 | + args->num_of_nodes++; | |
| 507 | 476 | } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && |
| 508 | − (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); | |
| 477 | + (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS)); | |
| 509 | 478 | } |
| 510 | 479 | |
| 511 | 480 | mutex_unlock(&p->mutex); |
| 512 | 481 | |
| 513 | − if (copy_to_user(arg, &args, sizeof(args))) | |
| 514 | − return -EFAULT; | |
| 515 | − | |
| 516 | 482 | return 0; |
| 517 | 483 | } |
| 518 | 484 | |
| 485 | +#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ | |
| 486 | + [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | |
| 487 | + | |
| 488 | +/** Ioctl table */ | |
| 489 | +static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { | |
| 490 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, | |
| 491 | + kfd_ioctl_get_version, 0), | |
| 492 | + | |
| 493 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, | |
| 494 | + kfd_ioctl_create_queue, 0), | |
| 495 | + | |
| 496 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, | |
| 497 | + kfd_ioctl_destroy_queue, 0), | |
| 498 | + | |
| 499 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, | |
| 500 | + kfd_ioctl_set_memory_policy, 0), | |
| 501 | + | |
| 502 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, | |
| 503 | + kfd_ioctl_get_clock_counters, 0), | |
| 504 | + | |
| 505 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, | |
| 506 | + kfd_ioctl_get_process_apertures, 0), | |
| 507 | + | |
| 508 | + AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, | |
| 509 | + kfd_ioctl_update_queue, 0), | |
| 510 | +}; | |
| 511 | + | |
| 512 | +#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) | |
| 513 | + | |
| 519 | 514 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
| 520 | 515 | { |
| 521 | 516 | struct kfd_process *process; |
| 522 | − long err = -EINVAL; | |
| 517 | + amdkfd_ioctl_t *func; | |
| 518 | + const struct amdkfd_ioctl_desc *ioctl = NULL; | |
| 519 | + unsigned int nr = _IOC_NR(cmd); | |
| 520 | + char stack_kdata[128]; | |
| 521 | + char *kdata = NULL; | |
| 522 | + unsigned int usize, asize; | |
| 523 | + int retcode = -EINVAL; | |
| 523 | 524 | |
| 524 | − dev_dbg(kfd_device, | |
| 525 | − "ioctl cmd 0x%x (#%d), arg 0x%lx\n", | |
| 526 | − cmd, _IOC_NR(cmd), arg); | |
| 525 | + if (nr >= AMDKFD_CORE_IOCTL_COUNT) | |
| 526 | + goto err_i1; | |
| 527 | + | |
| 528 | + if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { | |
| 529 | + u32 amdkfd_size; | |
| 530 | + | |
| 531 | + ioctl = &amdkfd_ioctls[nr]; | |
| 532 | + | |
| 533 | + amdkfd_size = _IOC_SIZE(ioctl->cmd); | |
| 534 | + usize = asize = _IOC_SIZE(cmd); | |
| 535 | + if (amdkfd_size > asize) | |
| 536 | + asize = amdkfd_size; | |
| 537 | + | |
| 538 | + cmd = ioctl->cmd; | |
| 539 | + } else | |
| 540 | + goto err_i1; | |
| 541 | + | |
| 542 | + dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg); | |
| 527 | 543 | |
| 528 | 544 | process = kfd_get_process(current); |
| 529 | − if (IS_ERR(process)) | |
| 530 | − return PTR_ERR(process); | |
| 545 | + if (IS_ERR(process)) { | |
| 546 | + dev_dbg(kfd_device, "no process\n"); | |
| 547 | + goto err_i1; | |
| 548 | + } | |
| 531 | 549 | |
| 532 | − switch (cmd) { | |
| 533 | − case KFD_IOC_GET_VERSION: | |
| 534 | − err = kfd_ioctl_get_version(filep, process, (void __user *)arg); | |
| 535 | − break; | |
| 536 | − case KFD_IOC_CREATE_QUEUE: | |
| 537 | − err = kfd_ioctl_create_queue(filep, process, | |
| 538 | − (void __user *)arg); | |
| 539 | − break; | |
| 540 | − | |
| 541 | − case KFD_IOC_DESTROY_QUEUE: | |
| 542 | − err = kfd_ioctl_destroy_queue(filep, process, | |
| 543 | − (void __user *)arg); | |
| 544 | − break; | |
| 545 | − | |
| 546 | − case KFD_IOC_SET_MEMORY_POLICY: | |
| 547 | − err = kfd_ioctl_set_memory_policy(filep, process, | |
| 548 | − (void __user *)arg); | |
| 549 | − break; | |
| 550 | − | |
| 551 | − case KFD_IOC_GET_CLOCK_COUNTERS: | |
| 552 | − err = kfd_ioctl_get_clock_counters(filep, process, | |
| 553 | − (void __user *)arg); | |
| 554 | − break; | |
| 555 | − | |
| 556 | − case KFD_IOC_GET_PROCESS_APERTURES: | |
| 557 | − err = kfd_ioctl_get_process_apertures(filep, process, | |
| 558 | − (void __user *)arg); | |
| 559 | − break; | |
| 560 | − | |
| 561 | − case KFD_IOC_UPDATE_QUEUE: | |
| 562 | − err = kfd_ioctl_update_queue(filep, process, | |
| 563 | − (void __user *)arg); | |
| 564 | − break; | |
| 565 | − | |
| 566 | − default: | |
| 567 | − dev_err(kfd_device, | |
| 568 | − "unknown ioctl cmd 0x%x, arg 0x%lx)\n", | |
| 569 | − cmd, arg); | |
| 570 | − err = -EINVAL; | |
| 571 | − break; | |
| 550 | + /* Do not trust userspace, use our own definition */ | |
| 551 | + func = ioctl->func; | |
| 552 | + | |
| 553 | + if (unlikely(!func)) { | |
| 554 | + dev_dbg(kfd_device, "no function\n"); | |
| 555 | + retcode = -EINVAL; | |
| 556 | + goto err_i1; | |
| 572 | 557 | } |
| 573 | 558 | |
| 574 | − if (err < 0) | |
| 575 | − dev_err(kfd_device, | |
| 576 | − "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", | |
| 577 | − err, cmd, _IOC_NR(cmd)); | |
| 559 | + if (cmd & (IOC_IN | IOC_OUT)) { | |
| 560 | + if (asize <= sizeof(stack_kdata)) { | |
| 561 | + kdata = stack_kdata; | |
| 562 | + } else { | |
| 563 | + kdata = kmalloc(asize, GFP_KERNEL); | |
| 564 | + if (!kdata) { | |
| 565 | + retcode = -ENOMEM; | |
| 566 | + goto err_i1; | |
| 567 | + } | |
| 568 | + } | |
| 569 | + if (asize > usize) | |
| 570 | + memset(kdata + usize, 0, asize - usize); | |
| 571 | + } | |
| 578 | 572 | |
| 579 | − return err; | |
| 573 | + if (cmd & IOC_IN) { | |
| 574 | + if (copy_from_user(kdata, (void __user *)arg, usize) != 0) { | |
| 575 | + retcode = -EFAULT; | |
| 576 | + goto err_i1; | |
| 577 | + } | |
| 578 | + } else if (cmd & IOC_OUT) { | |
| 579 | + memset(kdata, 0, usize); | |
| 580 | + } | |
| 581 | + | |
| 582 | + retcode = func(filep, process, kdata); | |
| 583 | + | |
| 584 | + if (cmd & IOC_OUT) | |
| 585 | + if (copy_to_user((void __user *)arg, kdata, usize) != 0) | |
| 586 | + retcode = -EFAULT; | |
| 587 | + | |
| 588 | +err_i1: | |
| 589 | + if (!ioctl) | |
| 590 | + dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", | |
| 591 | + task_pid_nr(current), cmd, nr); | |
| 592 | + | |
| 593 | + if (kdata != stack_kdata) | |
| 594 | + kfree(kdata); | |
| 595 | + | |
| 596 | + if (retcode) | |
| 597 | + dev_dbg(kfd_device, "ret = %d\n", retcode); | |
| 598 | + | |
| 599 | + return retcode; | |
| 580 | 600 | } |
| 581 | 601 | |
| 582 | 602 | static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) |
| @@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm, · 160 unmodified lines | ||
| 161 | 161 | { |
| 162 | 162 | int bit = qpd->vmid - KFD_VMID_START_OFFSET; |
| 163 | 163 | |
| 164 | + /* Release the vmid mapping */ | |
| 165 | + set_pasid_vmid_mapping(dqm, 0, qpd->vmid); | |
| 166 | + | |
| 164 | 167 | set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); |
| 165 | 168 | qpd->vmid = 0; |
| 166 | 169 | q->properties.vmid = 0; |
| @@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, · 105 unmodified lines | ||
| 272 | 275 | return retval; |
| 273 | 276 | } |
| 274 | 277 | |
| 278 | + pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n", | |
| 279 | + q->pipe, | |
| 280 | + q->queue); | |
| 281 | + | |
| 282 | + retval = mqd->load_mqd(mqd, q->mqd, q->pipe, | |
| 283 | + q->queue, q->properties.write_ptr); | |
| 284 | + if (retval != 0) { | |
| 285 | + deallocate_hqd(dqm, q); | |
| 286 | + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); | |
| 287 | + return retval; | |
| 288 | + } | |
| 289 | + | |
| 275 | 290 | return 0; |
| 276 | 291 | } |
| 277 | 292 | |
| @@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) · 42 unmodified lines | ||
| 320 | 335 | { |
| 321 | 336 | int retval; |
| 322 | 337 | struct mqd_manager *mqd; |
| 338 | + bool prev_active = false; | |
| 323 | 339 | |
| 324 | 340 | BUG_ON(!dqm || !q || !q->mqd); |
| 325 | 341 | |
| @@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) · 4 unmodified lines | ||
| 330 | 346 | return -ENOMEM; |
| 331 | 347 | } |
| 332 | 348 | |
| 333 | − retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | |
| 334 | 349 | if (q->properties.is_active == true) |
| 350 | + prev_active = true; | |
| 351 | + | |
| 352 | + /* | |
| 353 | + * | |
| 354 | + * check active state vs. the previous state | |
| 355 | + * and modify counter accordingly | |
| 356 | + */ | |
| 357 | + retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | |
| 358 | + if ((q->properties.is_active == true) && (prev_active == false)) | |
| 335 | 359 | dqm->queue_count++; |
| 336 | − else | |
| 360 | + else if ((q->properties.is_active == false) && (prev_active == true)) | |
| 337 | 361 | dqm->queue_count--; |
| 338 | 362 | |
| 339 | 363 | if (sched_policy != KFD_SCHED_POLICY_NO_HWS) |
| @@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, · 183 unmodified lines | ||
| 184 | 184 | uint32_t queue_id) |
| 185 | 185 | { |
| 186 | 186 | |
| 187 | − return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, | |
| 187 | + return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, | |
| 188 | 188 | pipe_id, queue_id); |
| 189 | 189 | |
| 190 | 190 | } |
| @@ -32,7 +32,7 @@ int kfd_pasid_init(void) · 31 unmodified lines | ||
| 32 | 32 | { |
| 33 | 33 | pasid_limit = max_num_of_processes; |
| 34 | 34 | |
| 35 | − pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); | |
| 35 | + pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL); | |
| 36 | 36 | if (!pasid_bitmap) |
| 37 | 37 | return -ENOMEM; |
| 38 | 38 | |
| @@ -463,6 +463,24 @@ struct kfd_process { · 462 unmodified lines | ||
| 463 | 463 | bool is_32bit_user_mode; |
| 464 | 464 | }; |
| 465 | 465 | |
| 466 | +/** | |
| 467 | + * Ioctl function type. | |
| 468 | + * | |
| 469 | + * \param filep pointer to file structure. | |
| 470 | + * \param p amdkfd process pointer. | |
| 471 | + * \param data pointer to arg that was copied from user. | |
| 472 | + */ | |
| 473 | +typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, | |
| 474 | + void *data); | |
| 475 | + | |
| 476 | +struct amdkfd_ioctl_desc { | |
| 477 | + unsigned int cmd; | |
| 478 | + int flags; | |
| 479 | + amdkfd_ioctl_t *func; | |
| 480 | + unsigned int cmd_drv; | |
| 481 | + const char *name; | |
| 482 | +}; | |
| 483 | + | |
| 466 | 484 | void kfd_process_create_wq(void); |
| 467 | 485 | void kfd_process_destroy_wq(void); |
| 468 | 486 | struct kfd_process *kfd_create_process(const struct task_struct *); |
| @@ -921,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void) · 920 unmodified lines | ||
| 921 | 921 | uint32_t i = 0; |
| 922 | 922 | |
| 923 | 923 | list_for_each_entry(dev, &topology_device_list, list) { |
| 924 | − ret = kfd_build_sysfs_node_entry(dev, 0); | |
| 924 | + ret = kfd_build_sysfs_node_entry(dev, i); | |
| 925 | 925 | if (ret < 0) |
| 926 | 926 | return ret; |
| 927 | 927 | i++; |
| @@ -183,7 +183,7 @@ struct kfd2kgd_calls { · 182 unmodified lines | ||
| 183 | 183 | int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
| 184 | 184 | uint32_t queue_id, uint32_t __user *wptr); |
| 185 | 185 | |
| 186 | − bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, | |
| 186 | + bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address, | |
| 187 | 187 | uint32_t pipe_id, uint32_t queue_id); |
| 188 | 188 | |
| 189 | 189 | int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, |
| @@ -1756,8 +1756,6 @@ struct drm_i915_private { · 1755 unmodified lines | ||
| 1756 | 1756 | */ |
| 1757 | 1757 | struct workqueue_struct *dp_wq; |
| 1758 | 1758 | |
| 1759 | − uint32_t bios_vgacntr; | |
| 1760 | − | |
| 1761 | 1759 | /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ |
| 1762 | 1760 | struct { |
| 1763 | 1761 | int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, |
| @@ -1048,6 +1048,7 @@ int · 1047 unmodified lines | ||
| 1048 | 1048 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, |
| 1049 | 1049 | struct drm_file *file) |
| 1050 | 1050 | { |
| 1051 | + struct drm_i915_private *dev_priv = dev->dev_private; | |
| 1051 | 1052 | struct drm_i915_gem_pwrite *args = data; |
| 1052 | 1053 | struct drm_i915_gem_object *obj; |
| 1053 | 1054 | int ret; |
| @@ -1067,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines | ||
| 1067 | 1068 | return -EFAULT; |
| 1068 | 1069 | } |
| 1069 | 1070 | |
| 1071 | + intel_runtime_pm_get(dev_priv); | |
| 1072 | + | |
| 1070 | 1073 | ret = i915_mutex_lock_interruptible(dev); |
| 1071 | 1074 | if (ret) |
| 1072 | − return ret; | |
| 1075 | + goto put_rpm; | |
| 1073 | 1076 | |
| 1074 | 1077 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
| 1075 | 1078 | if (&obj->base == NULL) { |
| @@ -1121,6 +1124,9 @@ out: · 45 unmodified lines | ||
| 1121 | 1124 | drm_gem_object_unreference(&obj->base); |
| 1122 | 1125 | unlock: |
| 1123 | 1126 | mutex_unlock(&dev->struct_mutex); |
| 1127 | +put_rpm: | |
| 1128 | + intel_runtime_pm_put(dev_priv); | |
| 1129 | + | |
| 1124 | 1130 | return ret; |
| 1125 | 1131 | } |
| 1126 | 1132 | |
| @@ -3725,8 +3725,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev, · 3724 unmodified lines | ||
| 3725 | 3725 | if ((iir & flip_pending) == 0) |
| 3726 | 3726 | goto check_page_flip; |
| 3727 | 3727 | |
| 3728 | − intel_prepare_page_flip(dev, plane); | |
| 3729 | − | |
| 3730 | 3728 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
| 3731 | 3729 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
| 3732 | 3730 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
| @@ -3736,6 +3734,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, · 3 unmodified lines | ||
| 3736 | 3734 | if (I915_READ16(ISR) & flip_pending) |
| 3737 | 3735 | goto check_page_flip; |
| 3738 | 3736 | |
| 3737 | + intel_prepare_page_flip(dev, plane); | |
| 3739 | 3738 | intel_finish_page_flip(dev, pipe); |
| 3740 | 3739 | return true; |
| 3741 | 3740 | |
| @@ -3907,8 +3906,6 @@ static bool i915_handle_vblank(struct drm_device *dev, · 165 unmodified lines | ||
| 3907 | 3906 | if ((iir & flip_pending) == 0) |
| 3908 | 3907 | goto check_page_flip; |
| 3909 | 3908 | |
| 3910 | − intel_prepare_page_flip(dev, plane); | |
| 3911 | − | |
| 3912 | 3909 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
| 3913 | 3910 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
| 3914 | 3911 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
| @@ -3918,6 +3915,7 @@ static bool i915_handle_vblank(struct drm_device *dev, · 3 unmodified lines | ||
| 3918 | 3915 | if (I915_READ(ISR) & flip_pending) |
| 3919 | 3916 | goto check_page_flip; |
| 3920 | 3917 | |
| 3918 | + intel_prepare_page_flip(dev, plane); | |
| 3921 | 3919 | intel_finish_page_flip(dev, pipe); |
| 3922 | 3920 | return true; |
| 3923 | 3921 | |
| @@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev) · 13056 unmodified lines | ||
| 13057 | 13057 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
| 13058 | 13058 | udelay(300); |
| 13059 | 13059 | |
| 13060 | − /* | |
| 13061 | − * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming | |
| 13062 | − * from S3 without preserving (some of?) the other bits. | |
| 13063 | − */ | |
| 13064 | − I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE); | |
| 13060 | + I915_WRITE(vga_reg, VGA_DISP_DISABLE); | |
| 13065 | 13061 | POSTING_READ(vga_reg); |
| 13066 | 13062 | } |
| 13067 | 13063 | |
| @@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev) · 78 unmodified lines | ||
| 13146 | 13142 | |
| 13147 | 13143 | intel_shared_dpll_init(dev); |
| 13148 | 13144 | |
| 13149 | − /* save the BIOS value before clobbering it */ | |
| 13150 | − dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev)); | |
| 13151 | 13145 | /* Just disable it once at startup */ |
| 13152 | 13146 | i915_disable_vga(dev); |
| 13153 | 13147 | intel_setup_outputs(dev); |
| @@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, · 614 unmodified lines | ||
| 615 | 615 | vlv_power_sequencer_reset(dev_priv); |
| 616 | 616 | } |
| 617 | 617 | |
| 618 | −static void check_power_well_state(struct drm_i915_private *dev_priv, | |
| 619 | − struct i915_power_well *power_well) | |
| 620 | −{ | |
| 621 | − bool enabled = power_well->ops->is_enabled(dev_priv, power_well); | |
| 622 | − | |
| 623 | − if (power_well->always_on || !i915.disable_power_well) { | |
| 624 | − if (!enabled) | |
| 625 | − goto mismatch; | |
| 626 | − | |
| 627 | − return; | |
| 628 | − } | |
| 629 | − | |
| 630 | − if (enabled != (power_well->count > 0)) | |
| 631 | − goto mismatch; | |
| 632 | − | |
| 633 | − return; | |
| 634 | − | |
| 635 | −mismatch: | |
| 636 | − WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", | |
| 637 | − power_well->name, power_well->always_on, enabled, | |
| 638 | − power_well->count, i915.disable_power_well); | |
| 639 | −} | |
| 640 | − | |
| 641 | 618 | /** |
| 642 | 619 | * intel_display_power_get - grab a power domain reference |
| 643 | 620 | * @dev_priv: i915 device instance |
| @@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, · 25 unmodified lines | ||
| 669 | 646 | power_well->ops->enable(dev_priv, power_well); |
| 670 | 647 | power_well->hw_enabled = true; |
| 671 | 648 | } |
| 672 | − | |
| 673 | − check_power_well_state(dev_priv, power_well); | |
| 674 | 649 | } |
| 675 | 650 | |
| 676 | 651 | power_domains->domain_use_count[domain]++; |
| @@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, · 32 unmodified lines | ||
| 709 | 684 | power_well->hw_enabled = false; |
| 710 | 685 | power_well->ops->disable(dev_priv, power_well); |
| 711 | 686 | } |
| 712 | − | |
| 713 | − check_power_well_state(dev_priv, power_well); | |
| 714 | 687 | } |
| 715 | 688 | |
| 716 | 689 | mutex_unlock(&power_domains->lock); |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | void |
| 27 | 27 | nvkm_event_put(struct nvkm_event *event, u32 types, int index) |
| 28 | 28 | { |
| 29 | − BUG_ON(!spin_is_locked(&event->refs_lock)); | |
| 29 | + assert_spin_locked(&event->refs_lock); | |
| 30 | 30 | while (types) { |
| 31 | 31 | int type = __ffs(types); types &= ~(1 << type); |
| 32 | 32 | if (--event->refs[index * event->types_nr + type] == 0) { |
| @@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index) · 6 unmodified lines | ||
| 39 | 39 | void |
| 40 | 40 | nvkm_event_get(struct nvkm_event *event, u32 types, int index) |
| 41 | 41 | { |
| 42 | − BUG_ON(!spin_is_locked(&event->refs_lock)); | |
| 42 | + assert_spin_locked(&event->refs_lock); | |
| 43 | 43 | while (types) { |
| 44 | 44 | int type = __ffs(types); types &= ~(1 << type); |
| 45 | 45 | if (++event->refs[index * event->types_nr + type] == 1) { |
| @@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size) · 97 unmodified lines | ||
| 98 | 98 | struct nvkm_event *event = notify->event; |
| 99 | 99 | unsigned long flags; |
| 100 | 100 | |
| 101 | − BUG_ON(!spin_is_locked(&event->list_lock)); | |
| 101 | + assert_spin_locked(&event->list_lock); | |
| 102 | 102 | BUG_ON(size != notify->size); |
| 103 | 103 | |
| 104 | 104 | spin_lock_irqsave(&event->refs_lock, flags); |
| @@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device) · 248 unmodified lines | ||
| 249 | 249 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
| 250 | 250 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; |
| 251 | 251 | break; |
| 252 | + case 0x106: | |
| 253 | + device->cname = "GK208B"; | |
| 254 | + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | |
| 255 | + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; | |
| 256 | + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; | |
| 257 | + device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass; | |
| 258 | + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; | |
| 259 | + device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; | |
| 260 | + device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | |
| 261 | + device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass; | |
| 262 | + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; | |
| 263 | + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | |
| 264 | + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | |
| 265 | + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | |
| 266 | + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; | |
| 267 | + device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | |
| 268 | + device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | |
| 269 | + device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | |
| 270 | + device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; | |
| 271 | + device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; | |
| 272 | + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | |
| 273 | + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; | |
| 274 | + device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; | |
| 275 | + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; | |
| 276 | + device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; | |
| 277 | + device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass; | |
| 278 | + device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; | |
| 279 | + device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; | |
| 280 | + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; | |
| 281 | + device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | |
| 282 | + device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | |
| 283 | + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | |
| 284 | + break; | |
| 252 | 285 | case 0x108: |
| 253 | 286 | device->cname = "GK208"; |
| 254 | 287 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; |
| @@ -44,8 +44,10 @@ static void · 43 unmodified lines | ||
| 44 | 44 | pramin_fini(void *data) |
| 45 | 45 | { |
| 46 | 46 | struct priv *priv = data; |
| 47 | − nv_wr32(priv->bios, 0x001700, priv->bar0); | |
| 48 | − kfree(priv); | |
| 47 | + if (priv) { | |
| 48 | + nv_wr32(priv->bios, 0x001700, priv->bar0); | |
| 49 | + kfree(priv); | |
| 50 | + } | |
| 49 | 51 | } |
| 50 | 52 | |
| 51 | 53 | static void * |
| @@ -24,34 +24,71 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include "nv50.h" |
| 26 | 26 | |
| 27 | +struct nvaa_ram_priv { | |
| 28 | + struct nouveau_ram base; | |
| 29 | + u64 poller_base; | |
| 30 | +}; | |
| 31 | + | |
| 27 | 32 | static int |
| 28 | 33 | nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
| 29 | 34 | struct nouveau_oclass *oclass, void *data, u32 datasize, |
| 30 | 35 | struct nouveau_object **pobject) |
| 31 | 36 | { |
| 32 | − const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ | |
| 33 | − const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ | |
| 37 | + u32 rsvd_head = ( 256 * 1024); /* vga memory */ | |
| 38 | + u32 rsvd_tail = (1024 * 1024); /* vbios etc */ | |
| 34 | 39 | struct nouveau_fb *pfb = nouveau_fb(parent); |
| 35 | − struct nouveau_ram *ram; | |
| 40 | + struct nvaa_ram_priv *priv; | |
| 36 | 41 | int ret; |
| 37 | 42 | |
| 38 | − ret = nouveau_ram_create(parent, engine, oclass, &ram); | |
| 39 | − *pobject = nv_object(ram); | |
| 43 | + ret = nouveau_ram_create(parent, engine, oclass, &priv); | |
| 44 | + *pobject = nv_object(priv); | |
| 40 | 45 | if (ret) |
| 41 | 46 | return ret; |
| 42 | 47 | |
| 43 | − ram->size = nv_rd32(pfb, 0x10020c); | |
| 44 | − ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); | |
| 48 | + priv->base.type = NV_MEM_TYPE_STOLEN; | |
| 49 | + priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; | |
| 50 | + priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12; | |
| 45 | 51 | |
| 46 | − ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - | |
| 47 | − (rsvd_head + rsvd_tail), 1); | |
| 52 | + rsvd_tail += 0x1000; | |
| 53 | + priv->poller_base = priv->base.size - rsvd_tail; | |
| 54 | + | |
| 55 | + ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12, | |
| 56 | + (priv->base.size - (rsvd_head + rsvd_tail)) >> 12, | |
| 57 | + 1); | |
| 48 | 58 | if (ret) |
| 49 | 59 | return ret; |
| 50 | 60 | |
| 51 | − ram->type = NV_MEM_TYPE_STOLEN; | |
| 52 | − ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; | |
| 53 | − ram->get = nv50_ram_get; | |
| 54 | − ram->put = nv50_ram_put; | |
| 61 | + priv->base.get = nv50_ram_get; | |
| 62 | + priv->base.put = nv50_ram_put; | |
| 63 | + return 0; | |
| 64 | +} | |
| 65 | + | |
| 66 | +static int | |
| 67 | +nvaa_ram_init(struct nouveau_object *object) | |
| 68 | +{ | |
| 69 | + struct nouveau_fb *pfb = nouveau_fb(object); | |
| 70 | + struct nvaa_ram_priv *priv = (void *)object; | |
| 71 | + int ret; | |
| 72 | + u64 dniso, hostnb, flush; | |
| 73 | + | |
| 74 | + ret = nouveau_ram_init(&priv->base); | |
| 75 | + if (ret) | |
| 76 | + return ret; | |
| 77 | + | |
| 78 | + dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1; | |
| 79 | + hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1; | |
| 80 | + flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1; | |
| 81 | + | |
| 82 | + /* Enable NISO poller for various clients and set their associated | |
| 83 | + * read address, only for MCP77/78 and MCP79/7A. (fd#25701) | |
| 84 | + */ | |
| 85 | + nv_wr32(pfb, 0x100c18, dniso); | |
| 86 | + nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001); | |
| 87 | + nv_wr32(pfb, 0x100c1c, hostnb); | |
| 88 | + nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002); | |
| 89 | + nv_wr32(pfb, 0x100c24, flush); | |
| 90 | + nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000); | |
| 91 | + | |
| 55 | 92 | return 0; |
| 56 | 93 | } |
| 57 | 94 | |
| @@ -60,7 +97,7 @@ nvaa_ram_oclass = { · 2 unmodified lines | ||
| 60 | 97 | .ofuncs = &(struct nouveau_ofuncs) { |
| 61 | 98 | .ctor = nvaa_ram_ctor, |
| 62 | 99 | .dtor = _nouveau_ram_dtor, |
| 63 | − .init = _nouveau_ram_init, | |
| 100 | + .init = nvaa_ram_init, | |
| 64 | 101 | .fini = _nouveau_ram_fini, |
| 65 | 102 | }, |
| 66 | 103 | }; |
| @@ -24,13 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include "nv04.h" |
| 26 | 26 | |
| 27 | −static void | |
| 28 | −nv4c_mc_msi_rearm(struct nouveau_mc *pmc) | |
| 29 | −{ | |
| 30 | − struct nv04_mc_priv *priv = (void *)pmc; | |
| 31 | − nv_wr08(priv, 0x088050, 0xff); | |
| 32 | −} | |
| 33 | − | |
| 34 | 27 | struct nouveau_oclass * |
| 35 | 28 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { |
| 36 | 29 | .base.handle = NV_SUBDEV(MC, 0x4c), |
| @@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) { · 4 unmodified lines | ||
| 41 | 34 | .fini = _nouveau_mc_fini, |
| 42 | 35 | }, |
| 43 | 36 | .intr = nv04_mc_intr, |
| 44 | − .msi_rearm = nv4c_mc_msi_rearm, | |
| 45 | 37 | }.base; |
| @@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) · 1571 unmodified lines | ||
| 1572 | 1572 | * so use the DMA API for them. |
| 1573 | 1573 | */ |
| 1574 | 1574 | if (!nv_device_is_cpu_coherent(device) && |
| 1575 | − ttm->caching_state == tt_uncached) | |
| 1575 | + ttm->caching_state == tt_uncached) { | |
| 1576 | 1576 | ttm_dma_unpopulate(ttm_dma, dev->dev); |
| 1577 | + return; | |
| 1578 | + } | |
| 1577 | 1579 | |
| 1578 | 1580 | #if __OS_HAS_AGP |
| 1579 | 1581 | if (drm->agp.stat == ENABLED) { |
| @@ -36,7 +36,14 @@ void · 35 unmodified lines | ||
| 36 | 36 | nouveau_gem_object_del(struct drm_gem_object *gem) |
| 37 | 37 | { |
| 38 | 38 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
| 39 | + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | |
| 39 | 40 | struct ttm_buffer_object *bo = &nvbo->bo; |
| 41 | + struct device *dev = drm->dev->dev; | |
| 42 | + int ret; | |
| 43 | + | |
| 44 | + ret = pm_runtime_get_sync(dev); | |
| 45 | + if (WARN_ON(ret < 0 && ret != -EACCES)) | |
| 46 | + return; | |
| 40 | 47 | |
| 41 | 48 | if (gem->import_attach) |
| 42 | 49 | drm_prime_gem_destroy(gem, nvbo->bo.sg); |
| @@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem) · 3 unmodified lines | ||
| 46 | 53 | /* reset filp so nouveau_bo_del_ttm() can test for it */ |
| 47 | 54 | gem->filp = NULL; |
| 48 | 55 | ttm_bo_unref(&bo); |
| 56 | + | |
| 57 | + pm_runtime_mark_last_busy(dev); | |
| 58 | + pm_runtime_put_autosuspend(dev); | |
| 49 | 59 | } |
| 50 | 60 | |
| 51 | 61 | int |
| @@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) · 1 unmodified line | ||
| 53 | 63 | { |
| 54 | 64 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
| 55 | 65 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
| 66 | + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | |
| 56 | 67 | struct nouveau_vma *vma; |
| 68 | + struct device *dev = drm->dev->dev; | |
| 57 | 69 | int ret; |
| 58 | 70 | |
| 59 | 71 | if (!cli->vm) |
| @@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) · 11 unmodified lines | ||
| 71 | 83 | goto out; |
| 72 | 84 | } |
| 73 | 85 | |
| 86 | + ret = pm_runtime_get_sync(dev); | |
| 87 | + if (ret < 0 && ret != -EACCES) | |
| 88 | + goto out; | |
| 89 | + | |
| 74 | 90 | ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); |
| 75 | − if (ret) { | |
| 91 | + if (ret) | |
| 76 | 92 | kfree(vma); |
| 77 | − goto out; | |
| 78 | − } | |
| 93 | + | |
| 94 | + pm_runtime_mark_last_busy(dev); | |
| 95 | + pm_runtime_put_autosuspend(dev); | |
| 79 | 96 | } else { |
| 80 | 97 | vma->refcount++; |
| 81 | 98 | } |
| @@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) · 47 unmodified lines | ||
| 129 | 146 | { |
| 130 | 147 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
| 131 | 148 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
| 149 | + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | |
| 150 | + struct device *dev = drm->dev->dev; | |
| 132 | 151 | struct nouveau_vma *vma; |
| 133 | 152 | int ret; |
| 134 | 153 | |
| @@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) · 6 unmodified lines | ||
| 141 | 160 | |
| 142 | 161 | vma = nouveau_bo_vma_find(nvbo, cli->vm); |
| 143 | 162 | if (vma) { |
| 144 | − if (--vma->refcount == 0) | |
| 145 | − nouveau_gem_object_unmap(nvbo, vma); | |
| 163 | + if (--vma->refcount == 0) { | |
| 164 | + ret = pm_runtime_get_sync(dev); | |
| 165 | + if (!WARN_ON(ret < 0 && ret != -EACCES)) { | |
| 166 | + nouveau_gem_object_unmap(nvbo, vma); | |
| 167 | + pm_runtime_mark_last_busy(dev); | |
| 168 | + pm_runtime_put_autosuspend(dev); | |
| 169 | + } | |
| 170 | + } | |
| 146 | 171 | } |
| 147 | 172 | ttm_bo_unreserve(&nvbo->bo); |
| 148 | 173 | } |
| @@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) · 1850 unmodified lines | ||
| 1851 | 1851 | return pll; |
| 1852 | 1852 | } |
| 1853 | 1853 | /* otherwise, pick one of the plls */ |
| 1854 | − if ((rdev->family == CHIP_KAVERI) || | |
| 1855 | − (rdev->family == CHIP_KABINI) || | |
| 1854 | + if ((rdev->family == CHIP_KABINI) || | |
| 1856 | 1855 | (rdev->family == CHIP_MULLINS)) { |
| 1857 | − /* KB/KV/ML has PPLL1 and PPLL2 */ | |
| 1856 | + /* KB/ML has PPLL1 and PPLL2 */ | |
| 1858 | 1857 | pll_in_use = radeon_get_pll_use_mask(crtc); |
| 1859 | 1858 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
| 1860 | 1859 | return ATOM_PPLL2; |
| @@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) · 2 unmodified lines | ||
| 1863 | 1862 | DRM_ERROR("unable to allocate a PPLL\n"); |
| 1864 | 1863 | return ATOM_PPLL_INVALID; |
| 1865 | 1864 | } else { |
| 1866 | − /* CI has PPLL0, PPLL1, and PPLL2 */ | |
| 1865 | + /* CI/KV has PPLL0, PPLL1, and PPLL2 */ | |
| 1867 | 1866 | pll_in_use = radeon_get_pll_use_mask(crtc); |
| 1868 | 1867 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
| 1869 | 1868 | return ATOM_PPLL2; |
| @@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) · 285 unmodified lines | ||
| 2155 | 2154 | case ATOM_PPLL0: |
| 2156 | 2155 | /* disable the ppll */ |
| 2157 | 2156 | if ((rdev->family == CHIP_ARUBA) || |
| 2157 | + (rdev->family == CHIP_KAVERI) || | |
| 2158 | 2158 | (rdev->family == CHIP_BONAIRE) || |
| 2159 | 2159 | (rdev->family == CHIP_HAWAII)) |
| 2160 | 2160 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
| @@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, · 491 unmodified lines | ||
| 492 | 492 | struct radeon_connector_atom_dig *dig_connector; |
| 493 | 493 | int dp_clock; |
| 494 | 494 | |
| 495 | + if ((mode->clock > 340000) && | |
| 496 | + (!radeon_connector_is_dp12_capable(connector))) | |
| 497 | + return MODE_CLOCK_HIGH; | |
| 498 | + | |
| 495 | 499 | if (!radeon_connector->con_priv) |
| 496 | 500 | return MODE_CLOCK_HIGH; |
| 497 | 501 | dig_connector = radeon_connector->con_priv; |
| @@ -2156,4 +2156,6 @@ · 2155 unmodified lines | ||
| 2156 | 2156 | #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu |
| 2157 | 2157 | #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u |
| 2158 | 2158 | |
| 2159 | +#define IH_VMID_0_LUT 0x3D40u | |
| 2160 | + | |
| 2159 | 2161 | #endif |
| @@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) · 102 unmodified lines | ||
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
| 106 | − if (sad_count < 0) { | |
| 106 | + if (sad_count <= 0) { | |
| 107 | 107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
| 108 | 108 | return; |
| 109 | 109 | } |
| @@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev) · 2744 unmodified lines | ||
| 2745 | 2745 | pi->enable_auto_thermal_throttling = true; |
| 2746 | 2746 | pi->disable_nb_ps3_in_battery = false; |
| 2747 | 2747 | if (radeon_bapm == -1) { |
| 2748 | − /* There are stability issues reported on with | |
| 2749 | − * bapm enabled on an asrock system. | |
| 2750 | − */ | |
| 2751 | − if (rdev->pdev->subsystem_vendor == 0x1849) | |
| 2752 | − pi->bapm_enable = false; | |
| 2753 | − else | |
| 2748 | + /* only enable bapm on KB, ML by default */ | |
| 2749 | + if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) | |
| 2754 | 2750 | pi->bapm_enable = true; |
| 2751 | + else | |
| 2752 | + pi->bapm_enable = false; | |
| 2755 | 2753 | } else if (radeon_bapm == 0) { |
| 2756 | 2754 | pi->bapm_enable = false; |
| 2757 | 2755 | } else { |
| @@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, · 71 unmodified lines | ||
| 72 | 72 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
| 73 | 73 | uint32_t queue_id, uint32_t __user *wptr); |
| 74 | 74 | |
| 75 | −static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | |
| 75 | +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, | |
| 76 | 76 | uint32_t pipe_id, uint32_t queue_id); |
| 77 | 77 | |
| 78 | 78 | static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, |
| @@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = { · 13 unmodified lines | ||
| 92 | 92 | .init_memory = kgd_init_memory, |
| 93 | 93 | .init_pipeline = kgd_init_pipeline, |
| 94 | 94 | .hqd_load = kgd_hqd_load, |
| 95 | − .hqd_is_occupies = kgd_hqd_is_occupies, | |
| 95 | + .hqd_is_occupied = kgd_hqd_is_occupied, | |
| 96 | 96 | .hqd_destroy = kgd_hqd_destroy, |
| 97 | 97 | .get_fw_version = get_fw_version |
| 98 | 98 | }; |
| @@ -101,6 +101,7 @@ static const struct kgd2kfd_calls *kgd2kfd; · 2 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | bool radeon_kfd_init(void) |
| 103 | 103 | { |
| 104 | +#if defined(CONFIG_HSA_AMD_MODULE) | |
| 104 | 105 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, |
| 105 | 106 | const struct kgd2kfd_calls**); |
| 106 | 107 | |
| @@ -117,6 +118,17 @@ bool radeon_kfd_init(void) · 10 unmodified lines | ||
| 117 | 118 | } |
| 118 | 119 | |
| 119 | 120 | return true; |
| 121 | +#elif defined(CONFIG_HSA_AMD) | |
| 122 | + if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { | |
| 123 | + kgd2kfd = NULL; | |
| 124 | + | |
| 125 | + return false; | |
| 126 | + } | |
| 127 | + | |
| 128 | + return true; | |
| 129 | +#else | |
| 130 | + return false; | |
| 131 | +#endif | |
| 120 | 132 | } |
| 121 | 133 | |
| 122 | 134 | void radeon_kfd_fini(void) |
| @@ -378,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, · 255 unmodified lines | ||
| 378 | 390 | cpu_relax(); |
| 379 | 391 | write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); |
| 380 | 392 | |
| 393 | + /* Mapping vmid to pasid also for IH block */ | |
| 394 | + write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), | |
| 395 | + pasid_mapping); | |
| 396 | + | |
| 381 | 397 | return 0; |
| 382 | 398 | } |
| 383 | 399 | |
| @@ -517,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, · 133 unmodified lines | ||
| 517 | 533 | return 0; |
| 518 | 534 | } |
| 519 | 535 | |
| 520 | −static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | |
| 536 | +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, | |
| 521 | 537 | uint32_t pipe_id, uint32_t queue_id) |
| 522 | 538 | { |
| 523 | 539 | uint32_t act; |
| @@ -556,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, · 32 unmodified lines | ||
| 556 | 572 | if (timeout == 0) { |
| 557 | 573 | pr_err("kfd: cp queue preemption time out (%dms)\n", |
| 558 | 574 | temp); |
| 575 | + release_queue(kgd); | |
| 559 | 576 | return -ETIME; |
| 560 | 577 | } |
| 561 | 578 | msleep(20); |
| @@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, · 1702 unmodified lines | ||
| 1703 | 1703 | u32 format; |
| 1704 | 1704 | u32 *buffer; |
| 1705 | 1705 | const u8 __user *data; |
| 1706 | − int size, dwords, tex_width, blit_width, spitch; | |
| 1706 | + unsigned int size, dwords, tex_width, blit_width, spitch; | |
| 1707 | 1707 | u32 height; |
| 1708 | 1708 | int i; |
| 1709 | 1709 | u32 texpitch, microtile; |
| @@ -27,7 +27,8 @@ if HID · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | config HID_BATTERY_STRENGTH |
| 29 | 29 | bool "Battery level reporting for HID devices" |
| 30 | − depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY | |
| 30 | + depends on HID | |
| 31 | + select POWER_SUPPLY | |
| 31 | 32 | default n |
| 32 | 33 | ---help--- |
| 33 | 34 | This option adds support of reporting battery strength (for HID devices |
| @@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 1804 unmodified lines | ||
| 1805 | 1805 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
| 1806 | 1806 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, |
| 1807 | 1807 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
| 1808 | + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, | |
| 1808 | 1809 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
| 1809 | 1810 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
| 1810 | 1811 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
| @@ -526,6 +526,7 @@ · 525 unmodified lines | ||
| 526 | 526 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
| 527 | 527 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 |
| 528 | 528 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 |
| 529 | +#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a | |
| 529 | 530 | #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 |
| 530 | 531 | |
| 531 | 532 | #define USB_VENDOR_ID_LABTEC 0x1020 |
| @@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = { · 310 unmodified lines | ||
| 311 | 311 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 312 | 312 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
| 313 | 313 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
| 314 | + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | |
| 315 | + USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), | |
| 316 | + HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | |
| 314 | 317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 315 | 318 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
| 316 | 319 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
| @@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, · 322 unmodified lines | ||
| 323 | 323 | } |
| 324 | 324 | break; |
| 325 | 325 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: |
| 326 | + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: | |
| 326 | 327 | if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { |
| 327 | 328 | rdesc = mousepen_i608x_rdesc_fixed; |
| 328 | 329 | *rsize = sizeof(mousepen_i608x_rdesc_fixed); |
| @@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) · 86 unmodified lines | ||
| 415 | 416 | switch (id->product) { |
| 416 | 417 | case USB_DEVICE_ID_KYE_EASYPEN_I405X: |
| 417 | 418 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: |
| 419 | + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: | |
| 418 | 420 | case USB_DEVICE_ID_KYE_EASYPEN_M610X: |
| 419 | 421 | ret = kye_tablet_enable(hdev); |
| 420 | 422 | if (ret) { |
| @@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = { · 24 unmodified lines | ||
| 445 | 447 | USB_DEVICE_ID_KYE_EASYPEN_I405X) }, |
| 446 | 448 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
| 447 | 449 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
| 450 | + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | |
| 451 | + USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, | |
| 448 | 452 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
| 449 | 453 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
| 450 | 454 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
| @@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, · 961 unmodified lines | ||
| 962 | 962 | |
| 963 | 963 | switch (data[0]) { |
| 964 | 964 | case REPORT_ID_DJ_SHORT: |
| 965 | + if (size != DJREPORT_SHORT_LENGTH) { | |
| 966 | + dev_err(&hdev->dev, "DJ report of bad size (%d)", size); | |
| 967 | + return false; | |
| 968 | + } | |
| 965 | 969 | return logi_dj_dj_event(hdev, report, data, size); |
| 966 | 970 | case REPORT_ID_HIDPP_SHORT: |
| 967 | − /* intentional fallthrough */ | |
| 971 | + if (size != HIDPP_REPORT_SHORT_LENGTH) { | |
| 972 | + dev_err(&hdev->dev, | |
| 973 | + "Short HID++ report of bad size (%d)", size); | |
| 974 | + return false; | |
| 975 | + } | |
| 976 | + return logi_dj_hidpp_event(hdev, report, data, size); | |
| 968 | 977 | case REPORT_ID_HIDPP_LONG: |
| 978 | + if (size != HIDPP_REPORT_LONG_LENGTH) { | |
| 979 | + dev_err(&hdev->dev, | |
| 980 | + "Long HID++ report of bad size (%d)", size); | |
| 981 | + return false; | |
| 982 | + } | |
| 969 | 983 | return logi_dj_hidpp_event(hdev, report, data, size); |
| 970 | 984 | } |
| 971 | 985 | |
| @@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) · 281 unmodified lines | ||
| 282 | 282 | (report->rap.sub_id == 0x41); |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | +/** | |
| 286 | + * hidpp_prefix_name() prefixes the current given name with "Logitech ". | |
| 287 | + */ | |
| 288 | +static void hidpp_prefix_name(char **name, int name_length) | |
| 289 | +{ | |
| 290 | +#define PREFIX_LENGTH 9 /* "Logitech " */ | |
| 291 | + | |
| 292 | + int new_length; | |
| 293 | + char *new_name; | |
| 294 | + | |
| 295 | + if (name_length > PREFIX_LENGTH && | |
| 296 | + strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0) | |
| 297 | + /* The prefix has is already in the name */ | |
| 298 | + return; | |
| 299 | + | |
| 300 | + new_length = PREFIX_LENGTH + name_length; | |
| 301 | + new_name = kzalloc(new_length, GFP_KERNEL); | |
| 302 | + if (!new_name) | |
| 303 | + return; | |
| 304 | + | |
| 305 | + snprintf(new_name, new_length, "Logitech %s", *name); | |
| 306 | + | |
| 307 | + kfree(*name); | |
| 308 | + | |
| 309 | + *name = new_name; | |
| 310 | +} | |
| 311 | + | |
| 285 | 312 | /* -------------------------------------------------------------------------- */ |
| 286 | 313 | /* HIDP++ 1.0 commands */ |
| 287 | 314 | /* -------------------------------------------------------------------------- */ |
| @@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) · 33 unmodified lines | ||
| 321 | 348 | return NULL; |
| 322 | 349 | |
| 323 | 350 | memcpy(name, &response.rap.params[2], len); |
| 351 | + | |
| 352 | + /* include the terminating '\0' */ | |
| 353 | + hidpp_prefix_name(&name, len + 1); | |
| 354 | + | |
| 324 | 355 | return name; |
| 325 | 356 | } |
| 326 | 357 | |
| @@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp) · 171 unmodified lines | ||
| 498 | 529 | index += ret; |
| 499 | 530 | } |
| 500 | 531 | |
| 532 | + /* include the terminating '\0' */ | |
| 533 | + hidpp_prefix_name(&name, __name_length + 1); | |
| 534 | + | |
| 501 | 535 | return name; |
| 502 | 536 | } |
| 503 | 537 | |
| @@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) · 290 unmodified lines | ||
| 794 | 828 | |
| 795 | 829 | switch (data[0]) { |
| 796 | 830 | case 0x02: |
| 831 | + if (size < 2) { | |
| 832 | + hid_err(hdev, "Received HID report of bad size (%d)", | |
| 833 | + size); | |
| 834 | + return 1; | |
| 835 | + } | |
| 797 | 836 | if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { |
| 798 | 837 | input_event(wd->input, EV_KEY, BTN_LEFT, |
| 799 | 838 | !!(data[1] & 0x01)); |
| 800 | 839 | input_event(wd->input, EV_KEY, BTN_RIGHT, |
| 801 | 840 | !!(data[1] & 0x02)); |
| 802 | 841 | input_sync(wd->input); |
| 842 | + return 0; | |
| 803 | 843 | } else { |
| 804 | 844 | if (size < 21) |
| 805 | 845 | return 1; |
| 806 | 846 | return wtp_mouse_raw_xy_event(hidpp, &data[7]); |
| 807 | 847 | } |
| 808 | 848 | case REPORT_ID_HIDPP_LONG: |
| 849 | + /* size is already checked in hidpp_raw_event. */ | |
| 809 | 850 | if ((report->fap.feature_index != wd->mt_feature_index) || |
| 810 | 851 | (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) |
| 811 | 852 | return 1; |
| @@ -35,6 +35,8 @@ static struct class *pyra_class; · 34 unmodified lines | ||
| 35 | 35 | static void profile_activated(struct pyra_device *pyra, |
| 36 | 36 | unsigned int new_profile) |
| 37 | 37 | { |
| 38 | + if (new_profile >= ARRAY_SIZE(pyra->profile_settings)) | |
| 39 | + return; | |
| 38 | 40 | pyra->actual_profile = new_profile; |
| 39 | 41 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; |
| 40 | 42 | } |
| @@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, · 216 unmodified lines | ||
| 257 | 259 | if (off != 0 || count != PYRA_SIZE_SETTINGS) |
| 258 | 260 | return -EINVAL; |
| 259 | 261 | |
| 260 | − mutex_lock(&pyra->pyra_lock); | |
| 261 | − | |
| 262 | 262 | settings = (struct pyra_settings const *)buf; |
| 263 | + if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings)) | |
| 264 | + return -EINVAL; | |
| 265 | + | |
| 266 | + mutex_lock(&pyra->pyra_lock); | |
| 263 | 267 | |
| 264 | 268 | retval = pyra_set_settings(usb_dev, settings); |
| 265 | 269 | if (retval) { |
| @@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid) · 705 unmodified lines | ||
| 706 | 706 | |
| 707 | 707 | static void i2c_hid_stop(struct hid_device *hid) |
| 708 | 708 | { |
| 709 | − struct i2c_client *client = hid->driver_data; | |
| 710 | − struct i2c_hid *ihid = i2c_get_clientdata(client); | |
| 711 | − | |
| 712 | 709 | hid->claimed = 0; |
| 713 | − | |
| 714 | − i2c_hid_free_buffers(ihid); | |
| 715 | 710 | } |
| 716 | 711 | |
| 717 | 712 | static int i2c_hid_open(struct hid_device *hid) |
| @@ -124,6 +124,7 @@ static const struct hid_blacklist { · 123 unmodified lines | ||
| 124 | 124 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, |
| 125 | 125 | { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, |
| 126 | 126 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, |
| 127 | + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT }, | |
| 127 | 128 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, |
| 128 | 129 | { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, |
| 129 | 130 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, |
| @@ -4029,14 +4029,6 @@ static int device_notifier(struct notifier_block *nb, · 4028 unmodified lines | ||
| 4029 | 4029 | if (action != BUS_NOTIFY_REMOVED_DEVICE) |
| 4030 | 4030 | return 0; |
| 4031 | 4031 | |
| 4032 | − /* | |
| 4033 | − * If the device is still attached to a device driver we can't | |
| 4034 | − * tear down the domain yet as DMA mappings may still be in use. | |
| 4035 | − * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. | |
| 4036 | − */ | |
| 4037 | − if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) | |
| 4038 | − return 0; | |
| 4039 | − | |
| 4040 | 4032 | domain = find_domain(dev); |
| 4041 | 4033 | if (!domain) |
| 4042 | 4034 | return 0; |
| @@ -4428,6 +4420,10 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, · 385 unmodified lines | ||
| 4428 | 4420 | domain_remove_one_dev_info(old_domain, dev); |
| 4429 | 4421 | else |
| 4430 | 4422 | domain_remove_dev_info(old_domain); |
| 4423 | + | |
| 4424 | + if (!domain_type_is_vm_or_si(old_domain) && | |
| 4425 | + list_empty(&old_domain->devices)) | |
| 4426 | + domain_exit(old_domain); | |
| 4431 | 4427 | } |
| 4432 | 4428 | } |
| 4433 | 4429 | |
| @@ -558,7 +558,7 @@ static pmd_t *ipmmu_alloc_pmd(struct ipmmu_vmsa_device *mmu, pgd_t *pgd, · 557 unmodified lines | ||
| 558 | 558 | |
| 559 | 559 | static u64 ipmmu_page_prot(unsigned int prot, u64 type) |
| 560 | 560 | { |
| 561 | − u64 pgprot = ARM_VMSA_PTE_XN | ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF | |
| 561 | + u64 pgprot = ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF | |
| 562 | 562 | | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV |
| 563 | 563 | | ARM_VMSA_PTE_NS | type; |
| 564 | 564 | |
| @@ -568,8 +568,8 @@ static u64 ipmmu_page_prot(unsigned int prot, u64 type) · 3 unmodified lines | ||
| 568 | 568 | if (prot & IOMMU_CACHE) |
| 569 | 569 | pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT; |
| 570 | 570 | |
| 571 | − if (prot & IOMMU_EXEC) | |
| 572 | − pgprot &= ~ARM_VMSA_PTE_XN; | |
| 571 | + if (prot & IOMMU_NOEXEC) | |
| 572 | + pgprot |= ARM_VMSA_PTE_XN; | |
| 573 | 573 | else if (!(prot & (IOMMU_READ | IOMMU_WRITE))) |
| 574 | 574 | /* If no access create a faulting entry to avoid TLB fills. */ |
| 575 | 575 | pgprot &= ~ARM_VMSA_PTE_PAGE; |
| @@ -1009,7 +1009,6 @@ static struct platform_driver rk_iommu_driver = { · 1008 unmodified lines | ||
| 1009 | 1009 | .remove = rk_iommu_remove, |
| 1010 | 1010 | .driver = { |
| 1011 | 1011 | .name = "rk_iommu", |
| 1012 | − .owner = THIS_MODULE, | |
| 1013 | 1012 | .of_match_table = of_match_ptr(rk_iommu_dt_ids), |
| 1014 | 1013 | }, |
| 1015 | 1014 | }; |
| @@ -850,8 +850,10 @@ static int emac_probe(struct platform_device *pdev) · 849 unmodified lines | ||
| 850 | 850 | } |
| 851 | 851 | |
| 852 | 852 | db->clk = devm_clk_get(&pdev->dev, NULL); |
| 853 | − if (IS_ERR(db->clk)) | |
| 853 | + if (IS_ERR(db->clk)) { | |
| 854 | + ret = PTR_ERR(db->clk); | |
| 854 | 855 | goto out; |
| 856 | + } | |
| 855 | 857 | |
| 856 | 858 | clk_prepare_enable(db->clk); |
| 857 | 859 | |
| @@ -1170,10 +1170,6 @@ tx_request_irq_error: · 1169 unmodified lines | ||
| 1170 | 1170 | init_error: |
| 1171 | 1171 | free_skbufs(dev); |
| 1172 | 1172 | alloc_skbuf_error: |
| 1173 | − if (priv->phydev) { | |
| 1174 | − phy_disconnect(priv->phydev); | |
| 1175 | − priv->phydev = NULL; | |
| 1176 | − } | |
| 1177 | 1173 | phy_error: |
| 1178 | 1174 | return ret; |
| 1179 | 1175 | } |
| @@ -1186,12 +1182,9 @@ static int tse_shutdown(struct net_device *dev) · 6 unmodified lines | ||
| 1186 | 1182 | int ret; |
| 1187 | 1183 | unsigned long int flags; |
| 1188 | 1184 | |
| 1189 | − /* Stop and disconnect the PHY */ | |
| 1190 | − if (priv->phydev) { | |
| 1185 | + /* Stop the PHY */ | |
| 1186 | + if (priv->phydev) | |
| 1191 | 1187 | phy_stop(priv->phydev); |
| 1192 | − phy_disconnect(priv->phydev); | |
| 1193 | − priv->phydev = NULL; | |
| 1194 | − } | |
| 1195 | 1188 | |
| 1196 | 1189 | netif_stop_queue(dev); |
| 1197 | 1190 | napi_disable(&priv->napi); |
| @@ -1525,6 +1518,10 @@ err_free_netdev: · 327 unmodified lines | ||
| 1525 | 1518 | static int altera_tse_remove(struct platform_device *pdev) |
| 1526 | 1519 | { |
| 1527 | 1520 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 1521 | + struct altera_tse_private *priv = netdev_priv(ndev); | |
| 1522 | + | |
| 1523 | + if (priv->phydev) | |
| 1524 | + phy_disconnect(priv->phydev); | |
| 1528 | 1525 | |
| 1529 | 1526 | platform_set_drvdata(pdev, NULL); |
| 1530 | 1527 | altera_tse_mdio_destroy(ndev); |
| @@ -1616,7 +1616,7 @@ static int enic_open(struct net_device *netdev) · 1615 unmodified lines | ||
| 1616 | 1616 | if (vnic_rq_desc_used(&enic->rq[i]) == 0) { |
| 1617 | 1617 | netdev_err(netdev, "Unable to alloc receive buffers\n"); |
| 1618 | 1618 | err = -ENOMEM; |
| 1619 | − goto err_out_notify_unset; | |
| 1619 | + goto err_out_free_rq; | |
| 1620 | 1620 | } |
| 1621 | 1621 | } |
| 1622 | 1622 | |
| @@ -1649,7 +1649,9 @@ static int enic_open(struct net_device *netdev) · 26 unmodified lines | ||
| 1649 | 1649 | |
| 1650 | 1650 | return 0; |
| 1651 | 1651 | |
| 1652 | −err_out_notify_unset: | |
| 1652 | +err_out_free_rq: | |
| 1653 | + for (i = 0; i < enic->rq_count; i++) | |
| 1654 | + vnic_rq_clean(&enic->rq[i], enic_free_rq_buf); | |
| 1653 | 1655 | enic_dev_notify_unset(enic); |
| 1654 | 1656 | err_out_free_intr: |
| 1655 | 1657 | enic_free_intr(enic); |
| @@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic) · 1542 unmodified lines | ||
| 1543 | 1543 | mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); |
| 1544 | 1544 | } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && |
| 1545 | 1545 | (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && |
| 1546 | − !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { | |
| 1546 | + (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { | |
| 1547 | 1547 | /* enable/disable MDI/MDI-X auto-switching. */ |
| 1548 | 1548 | mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, |
| 1549 | 1549 | nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); |
| @@ -829,7 +829,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, · 828 unmodified lines | ||
| 829 | 829 | if (desc_n >= ring->count || desc_n < 0) { |
| 830 | 830 | dev_info(&pf->pdev->dev, |
| 831 | 831 | "descriptor %d not found\n", desc_n); |
| 832 | − return; | |
| 832 | + goto out; | |
| 833 | 833 | } |
| 834 | 834 | if (!is_rx_ring) { |
| 835 | 835 | txd = I40E_TX_DESC(ring, desc_n); |
| @@ -855,6 +855,8 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, · 19 unmodified lines | ||
| 855 | 855 | } else { |
| 856 | 856 | dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n"); |
| 857 | 857 | } |
| 858 | + | |
| 859 | +out: | |
| 858 | 860 | kfree(ring); |
| 859 | 861 | } |
| 860 | 862 | |
| @@ -1125,7 +1125,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) · 1124 unmodified lines | ||
| 1125 | 1125 | u32 swmask = mask; |
| 1126 | 1126 | u32 fwmask = mask << 16; |
| 1127 | 1127 | s32 ret_val = 0; |
| 1128 | − s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ | |
| 1128 | + s32 i = 0, timeout = 200; | |
| 1129 | 1129 | |
| 1130 | 1130 | while (i < timeout) { |
| 1131 | 1131 | if (igb_get_hw_semaphore(hw)) { |
| @@ -1829,7 +1829,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) · 1828 unmodified lines | ||
| 1829 | 1829 | err = mlx4_dev_cap(dev, &dev_cap); |
| 1830 | 1830 | if (err) { |
| 1831 | 1831 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); |
| 1832 | − goto err_stop_fw; | |
| 1832 | + return err; | |
| 1833 | 1833 | } |
| 1834 | 1834 | |
| 1835 | 1835 | choose_steering_mode(dev, &dev_cap); |
| @@ -1860,7 +1860,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) · 24 unmodified lines | ||
| 1860 | 1860 | &init_hca); |
| 1861 | 1861 | if ((long long) icm_size < 0) { |
| 1862 | 1862 | err = icm_size; |
| 1863 | − goto err_stop_fw; | |
| 1863 | + return err; | |
| 1864 | 1864 | } |
| 1865 | 1865 | |
| 1866 | 1866 | dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; |
| @@ -1874,7 +1874,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) · 7 unmodified lines | ||
| 1874 | 1874 | |
| 1875 | 1875 | err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); |
| 1876 | 1876 | if (err) |
| 1877 | − goto err_stop_fw; | |
| 1877 | + return err; | |
| 1878 | 1878 | |
| 1879 | 1879 | err = mlx4_INIT_HCA(dev, &init_hca); |
| 1880 | 1880 | if (err) { |
| @@ -1886,7 +1886,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) · 5 unmodified lines | ||
| 1886 | 1886 | err = mlx4_query_func(dev, &dev_cap); |
| 1887 | 1887 | if (err < 0) { |
| 1888 | 1888 | mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); |
| 1889 | − goto err_stop_fw; | |
| 1889 | + goto err_close; | |
| 1890 | 1890 | } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { |
| 1891 | 1891 | dev->caps.num_eqs = dev_cap.max_eqs; |
| 1892 | 1892 | dev->caps.reserved_eqs = dev_cap.reserved_eqs; |
| @@ -2006,11 +2006,6 @@ err_free_icm: · 113 unmodified lines | ||
| 2006 | 2006 | if (!mlx4_is_slave(dev)) |
| 2007 | 2007 | mlx4_free_icms(dev); |
| 2008 | 2008 | |
| 2009 | −err_stop_fw: | |
| 2010 | − if (!mlx4_is_slave(dev)) { | |
| 2011 | − mlx4_UNMAP_FA(dev); | |
| 2012 | − mlx4_free_icm(dev, priv->fw.fw_icm, 0); | |
| 2013 | − } | |
| 2014 | 2009 | return err; |
| 2015 | 2010 | } |
| 2016 | 2011 | |
| @@ -584,6 +584,7 @@ EXPORT_SYMBOL_GPL(mlx4_mr_free); · 583 unmodified lines | ||
| 584 | 584 | void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) |
| 585 | 585 | { |
| 586 | 586 | mlx4_mtt_cleanup(dev, &mr->mtt); |
| 587 | + mr->mtt.order = -1; | |
| 587 | 588 | } |
| 588 | 589 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); |
| 589 | 590 | |
| @@ -593,14 +594,14 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, · 3 unmodified lines | ||
| 593 | 594 | { |
| 594 | 595 | int err; |
| 595 | 596 | |
| 596 | − mpt_entry->start = cpu_to_be64(iova); | |
| 597 | − mpt_entry->length = cpu_to_be64(size); | |
| 598 | − mpt_entry->entity_size = cpu_to_be32(page_shift); | |
| 599 | − | |
| 600 | 597 | err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); |
| 601 | 598 | if (err) |
| 602 | 599 | return err; |
| 603 | 600 | |
| 601 | + mpt_entry->start = cpu_to_be64(mr->iova); | |
| 602 | + mpt_entry->length = cpu_to_be64(mr->size); | |
| 603 | + mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); | |
| 604 | + | |
| 604 | 605 | mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK | |
| 605 | 606 | MLX4_MPT_PD_FLAG_EN_INV); |
| 606 | 607 | mpt_entry->flags &= cpu_to_be32(MLX4_MPT_FLAG_FREE | |
| @@ -4033,8 +4033,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 4032 unmodified lines | ||
| 4033 | 4033 | (void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
| 4034 | 4034 | mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), |
| 4035 | 4035 | &mgp->cmd_bus, GFP_KERNEL); |
| 4036 | − if (mgp->cmd == NULL) | |
| 4036 | + if (!mgp->cmd) { | |
| 4037 | + status = -ENOMEM; | |
| 4037 | 4038 | goto abort_with_enabled; |
| 4039 | + } | |
| 4038 | 4040 | |
| 4039 | 4041 | mgp->board_span = pci_resource_len(pdev, 0); |
| 4040 | 4042 | mgp->iomem_base = pci_resource_start(pdev, 0); |
| @@ -146,10 +146,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) · 145 unmodified lines | ||
| 146 | 146 | { |
| 147 | 147 | int i = 0; |
| 148 | 148 | |
| 149 | − while (i < 10) { | |
| 150 | − if (i) | |
| 151 | − ssleep(1); | |
| 152 | − | |
| 149 | + do { | |
| 153 | 150 | if (ql_sem_lock(qdev, |
| 154 | 151 | QL_DRVR_SEM_MASK, |
| 155 | 152 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) |
| @@ -158,7 +155,8 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) · 2 unmodified lines | ||
| 158 | 155 | "driver lock acquired\n"); |
| 159 | 156 | return 1; |
| 160 | 157 | } |
| 161 | − } | |
| 158 | + ssleep(1); | |
| 159 | + } while (++i < 10); | |
| 162 | 160 | |
| 163 | 161 | netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); |
| 164 | 162 | return 0; |
| @@ -2605,6 +2605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 2604 unmodified lines | ||
| 2605 | 2605 | } else { |
| 2606 | 2606 | dev_err(&pdev->dev, |
| 2607 | 2607 | "%s: failed. Please Reboot\n", __func__); |
| 2608 | + err = -ENODEV; | |
| 2608 | 2609 | goto err_out_free_hw; |
| 2609 | 2610 | } |
| 2610 | 2611 | |
| @@ -757,6 +757,14 @@ requeue: · 756 unmodified lines | ||
| 757 | 757 | static irqreturn_t cpsw_interrupt(int irq, void *dev_id) |
| 758 | 758 | { |
| 759 | 759 | struct cpsw_priv *priv = dev_id; |
| 760 | + int value = irq - priv->irqs_table[0]; | |
| 761 | + | |
| 762 | + /* NOTICE: Ending IRQ here. The trick with the 'value' variable above | |
| 763 | + * is to make sure we will always write the correct value to the EOI | |
| 764 | + * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2 | |
| 765 | + * for TX Interrupt and 3 for MISC Interrupt. | |
| 766 | + */ | |
| 767 | + cpdma_ctlr_eoi(priv->dma, value); | |
| 760 | 768 | |
| 761 | 769 | cpsw_intr_disable(priv); |
| 762 | 770 | if (priv->irq_enabled == true) { |
| @@ -786,8 +794,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) · 23 unmodified lines | ||
| 786 | 794 | int num_tx, num_rx; |
| 787 | 795 | |
| 788 | 796 | num_tx = cpdma_chan_process(priv->txch, 128); |
| 789 | − if (num_tx) | |
| 790 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | |
| 791 | 797 | |
| 792 | 798 | num_rx = cpdma_chan_process(priv->rxch, budget); |
| 793 | 799 | if (num_rx < budget) { |
| @@ -795,7 +801,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) · 1 unmodified line | ||
| 795 | 801 | |
| 796 | 802 | napi_complete(napi); |
| 797 | 803 | cpsw_intr_enable(priv); |
| 798 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | |
| 799 | 804 | prim_cpsw = cpsw_get_slave_priv(priv, 0); |
| 800 | 805 | if (prim_cpsw->irq_enabled == false) { |
| 801 | 806 | prim_cpsw->irq_enabled = true; |
| @@ -1310,8 +1315,6 @@ static int cpsw_ndo_open(struct net_device *ndev) · 508 unmodified lines | ||
| 1310 | 1315 | napi_enable(&priv->napi); |
| 1311 | 1316 | cpdma_ctlr_start(priv->dma); |
| 1312 | 1317 | cpsw_intr_enable(priv); |
| 1313 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | |
| 1314 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | |
| 1315 | 1318 | |
| 1316 | 1319 | prim_cpsw = cpsw_get_slave_priv(priv, 0); |
| 1317 | 1320 | if (prim_cpsw->irq_enabled == false) { |
| @@ -1578,9 +1581,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev) · 260 unmodified lines | ||
| 1578 | 1581 | cpdma_chan_start(priv->txch); |
| 1579 | 1582 | cpdma_ctlr_int_ctrl(priv->dma, true); |
| 1580 | 1583 | cpsw_intr_enable(priv); |
| 1581 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | |
| 1582 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | |
| 1583 | − | |
| 1584 | 1584 | } |
| 1585 | 1585 | |
| 1586 | 1586 | static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) |
| @@ -1620,9 +1620,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev) · 33 unmodified lines | ||
| 1620 | 1620 | cpsw_interrupt(ndev->irq, priv); |
| 1621 | 1621 | cpdma_ctlr_int_ctrl(priv->dma, true); |
| 1622 | 1622 | cpsw_intr_enable(priv); |
| 1623 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | |
| 1624 | − cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | |
| 1625 | − | |
| 1626 | 1623 | } |
| 1627 | 1624 | #endif |
| 1628 | 1625 | |
| @@ -1043,6 +1043,7 @@ static int temac_of_probe(struct platform_device *op) · 1042 unmodified lines | ||
| 1043 | 1043 | lp->regs = of_iomap(op->dev.of_node, 0); |
| 1044 | 1044 | if (!lp->regs) { |
| 1045 | 1045 | dev_err(&op->dev, "could not map temac regs.\n"); |
| 1046 | + rc = -ENOMEM; | |
| 1046 | 1047 | goto nodev; |
| 1047 | 1048 | } |
| 1048 | 1049 | |
| @@ -1062,6 +1063,7 @@ static int temac_of_probe(struct platform_device *op) · 13 unmodified lines | ||
| 1062 | 1063 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); |
| 1063 | 1064 | if (!np) { |
| 1064 | 1065 | dev_err(&op->dev, "could not find DMA node\n"); |
| 1066 | + rc = -ENODEV; | |
| 1065 | 1067 | goto err_iounmap; |
| 1066 | 1068 | } |
| 1067 | 1069 | |
| @@ -1501,6 +1501,7 @@ static int axienet_of_probe(struct platform_device *op) · 1500 unmodified lines | ||
| 1501 | 1501 | lp->regs = of_iomap(op->dev.of_node, 0); |
| 1502 | 1502 | if (!lp->regs) { |
| 1503 | 1503 | dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); |
| 1504 | + ret = -ENOMEM; | |
| 1504 | 1505 | goto nodev; |
| 1505 | 1506 | } |
| 1506 | 1507 | /* Setup checksum offload, but default to off if not specified */ |
| @@ -1563,6 +1564,7 @@ static int axienet_of_probe(struct platform_device *op) · 56 unmodified lines | ||
| 1563 | 1564 | np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); |
| 1564 | 1565 | if (!np) { |
| 1565 | 1566 | dev_err(&op->dev, "could not find DMA node\n"); |
| 1567 | + ret = -ENODEV; | |
| 1566 | 1568 | goto err_iounmap; |
| 1567 | 1569 | } |
| 1568 | 1570 | lp->dma_regs = of_iomap(np, 0); |
| @@ -1109,6 +1109,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) · 1108 unmodified lines | ||
| 1109 | 1109 | res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); |
| 1110 | 1110 | if (!res) { |
| 1111 | 1111 | dev_err(dev, "no IRQ found\n"); |
| 1112 | + rc = -ENXIO; | |
| 1112 | 1113 | goto error; |
| 1113 | 1114 | } |
| 1114 | 1115 | |
| @@ -56,6 +56,8 @@ struct qmi_wwan_state { · 55 unmodified lines | ||
| 56 | 56 | /* default ethernet address used by the modem */ |
| 57 | 57 | static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; |
| 58 | 58 | |
| 59 | +static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}; | |
| 60 | + | |
| 59 | 61 | /* Make up an ethernet header if the packet doesn't have one. |
| 60 | 62 | * |
| 61 | 63 | * A firmware bug common among several devices cause them to send raw |
| @@ -332,10 +334,12 @@ next_desc: · 270 unmodified lines | ||
| 332 | 334 | usb_driver_release_interface(driver, info->data); |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | − /* Never use the same address on both ends of the link, even | |
| 336 | − * if the buggy firmware told us to. | |
| 337 | + /* Never use the same address on both ends of the link, even if the | |
| 338 | + * buggy firmware told us to. Or, if device is assigned the well-known | |
| 339 | + * buggy firmware MAC address, replace it with a random address, | |
| 337 | 340 | */ |
| 338 | − if (ether_addr_equal(dev->net->dev_addr, default_modem_addr)) | |
| 341 | + if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) || | |
| 342 | + ether_addr_equal(dev->net->dev_addr, buggy_fw_addr)) | |
| 339 | 343 | eth_hw_addr_random(dev->net); |
| 340 | 344 | |
| 341 | 345 | /* make MAC addr easily distinguishable from an IP header */ |
| @@ -1897,6 +1897,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) · 1896 unmodified lines | ||
| 1897 | 1897 | netif_wake_queue(netdev); |
| 1898 | 1898 | } |
| 1899 | 1899 | |
| 1900 | +static netdev_features_t | |
| 1901 | +rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, | |
| 1902 | + netdev_features_t features) | |
| 1903 | +{ | |
| 1904 | + u32 mss = skb_shinfo(skb)->gso_size; | |
| 1905 | + int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; | |
| 1906 | + int offset = skb_transport_offset(skb); | |
| 1907 | + | |
| 1908 | + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) | |
| 1909 | + features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); | |
| 1910 | + else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) | |
| 1911 | + features &= ~NETIF_F_GSO_MASK; | |
| 1912 | + | |
| 1913 | + return features; | |
| 1914 | +} | |
| 1915 | + | |
| 1900 | 1916 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, |
| 1901 | 1917 | struct net_device *netdev) |
| 1902 | 1918 | { |
| @@ -3706,6 +3722,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { · 1803 unmodified lines | ||
| 3706 | 3722 | .ndo_set_mac_address = rtl8152_set_mac_address, |
| 3707 | 3723 | .ndo_change_mtu = rtl8152_change_mtu, |
| 3708 | 3724 | .ndo_validate_addr = eth_validate_addr, |
| 3725 | + .ndo_features_check = rtl8152_features_check, | |
| 3709 | 3726 | }; |
| 3710 | 3727 | |
| 3711 | 3728 | static void r8152b_get_version(struct r8152 *tp) |
| @@ -737,6 +737,7 @@ static void connect(struct backend_info *be) · 736 unmodified lines | ||
| 737 | 737 | } |
| 738 | 738 | |
| 739 | 739 | queue->remaining_credit = credit_bytes; |
| 740 | + queue->credit_usec = credit_usec; | |
| 740 | 741 | |
| 741 | 742 | err = connect_rings(be, queue); |
| 742 | 743 | if (err) { |
| @@ -89,6 +89,7 @@ struct rockchip_iomux { · 88 unmodified lines | ||
| 89 | 89 | * @reg_pull: optional separate register for additional pull settings |
| 90 | 90 | * @clk: clock of the gpio bank |
| 91 | 91 | * @irq: interrupt of the gpio bank |
| 92 | + * @saved_enables: Saved content of GPIO_INTEN at suspend time. | |
| 92 | 93 | * @pin_base: first pin number |
| 93 | 94 | * @nr_pins: number of pins in this bank |
| 94 | 95 | * @name: name of the bank |
| @@ -107,6 +108,7 @@ struct rockchip_pin_bank { · 12 unmodified lines | ||
| 107 | 108 | struct regmap *regmap_pull; |
| 108 | 109 | struct clk *clk; |
| 109 | 110 | int irq; |
| 111 | + u32 saved_enables; | |
| 110 | 112 | u32 pin_base; |
| 111 | 113 | u8 nr_pins; |
| 112 | 114 | char *name; |
| @@ -1543,6 +1545,51 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) · 1430 unmodified lines | ||
| 1543 | 1545 | return 0; |
| 1544 | 1546 | } |
| 1545 | 1547 | |
| 1548 | +static void rockchip_irq_suspend(struct irq_data *d) | |
| 1549 | +{ | |
| 1550 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 1551 | + struct rockchip_pin_bank *bank = gc->private; | |
| 1552 | + | |
| 1553 | + bank->saved_enables = irq_reg_readl(gc, GPIO_INTEN); | |
| 1554 | + irq_reg_writel(gc, gc->wake_active, GPIO_INTEN); | |
| 1555 | +} | |
| 1556 | + | |
| 1557 | +static void rockchip_irq_resume(struct irq_data *d) | |
| 1558 | +{ | |
| 1559 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 1560 | + struct rockchip_pin_bank *bank = gc->private; | |
| 1561 | + | |
| 1562 | + irq_reg_writel(gc, bank->saved_enables, GPIO_INTEN); | |
| 1563 | +} | |
| 1564 | + | |
| 1565 | +static void rockchip_irq_disable(struct irq_data *d) | |
| 1566 | +{ | |
| 1567 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 1568 | + u32 val; | |
| 1569 | + | |
| 1570 | + irq_gc_lock(gc); | |
| 1571 | + | |
| 1572 | + val = irq_reg_readl(gc, GPIO_INTEN); | |
| 1573 | + val &= ~d->mask; | |
| 1574 | + irq_reg_writel(gc, val, GPIO_INTEN); | |
| 1575 | + | |
| 1576 | + irq_gc_unlock(gc); | |
| 1577 | +} | |
| 1578 | + | |
| 1579 | +static void rockchip_irq_enable(struct irq_data *d) | |
| 1580 | +{ | |
| 1581 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | |
| 1582 | + u32 val; | |
| 1583 | + | |
| 1584 | + irq_gc_lock(gc); | |
| 1585 | + | |
| 1586 | + val = irq_reg_readl(gc, GPIO_INTEN); | |
| 1587 | + val |= d->mask; | |
| 1588 | + irq_reg_writel(gc, val, GPIO_INTEN); | |
| 1589 | + | |
| 1590 | + irq_gc_unlock(gc); | |
| 1591 | +} | |
| 1592 | + | |
| 1546 | 1593 | static int rockchip_interrupts_register(struct platform_device *pdev, |
| 1547 | 1594 | struct rockchip_pinctrl *info) |
| 1548 | 1595 | { |
| @@ -1581,12 +1628,16 @@ static int rockchip_interrupts_register(struct platform_device *pdev, · 32 unmodified lines | ||
| 1581 | 1628 | gc = irq_get_domain_generic_chip(bank->domain, 0); |
| 1582 | 1629 | gc->reg_base = bank->reg_base; |
| 1583 | 1630 | gc->private = bank; |
| 1584 | − gc->chip_types[0].regs.mask = GPIO_INTEN; | |
| 1631 | + gc->chip_types[0].regs.mask = GPIO_INTMASK; | |
| 1585 | 1632 | gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; |
| 1586 | 1633 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; |
| 1587 | − gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | |
| 1588 | − gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | |
| 1634 | + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; | |
| 1635 | + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; | |
| 1636 | + gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; | |
| 1637 | + gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; | |
| 1589 | 1638 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; |
| 1639 | + gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; | |
| 1640 | + gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; | |
| 1590 | 1641 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; |
| 1591 | 1642 | gc->wake_enabled = IRQ_MSK(bank->nr_pins); |
| 1592 | 1643 | |
| @@ -1012,8 +1012,10 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, · 1011 unmodified lines | ||
| 1012 | 1012 | struct seq_file *s, unsigned pin_id) |
| 1013 | 1013 | { |
| 1014 | 1014 | unsigned long config; |
| 1015 | − st_pinconf_get(pctldev, pin_id, &config); | |
| 1016 | 1015 | |
| 1016 | + mutex_unlock(&pctldev->mutex); | |
| 1017 | + st_pinconf_get(pctldev, pin_id, &config); | |
| 1018 | + mutex_lock(&pctldev->mutex); | |
| 1017 | 1019 | seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" |
| 1018 | 1020 | "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," |
| 1019 | 1021 | "de:%ld,rt-clk:%ld,rt-delay:%ld]", |
| @@ -1443,6 +1445,7 @@ static struct gpio_chip st_gpio_template = { · 423 unmodified lines | ||
| 1443 | 1445 | |
| 1444 | 1446 | static struct irq_chip st_gpio_irqchip = { |
| 1445 | 1447 | .name = "GPIO", |
| 1448 | + .irq_disable = st_gpio_irq_mask, | |
| 1446 | 1449 | .irq_mask = st_gpio_irq_mask, |
| 1447 | 1450 | .irq_unmask = st_gpio_irq_unmask, |
| 1448 | 1451 | .irq_set_type = st_gpio_irq_set_type, |
| @@ -734,7 +734,9 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) · 733 unmodified lines | ||
| 734 | 734 | * Return target busy if we've received a non-zero retry_delay_timer |
| 735 | 735 | * in a FCP_RSP. |
| 736 | 736 | */ |
| 737 | − if (time_after(jiffies, fcport->retry_delay_timestamp)) | |
| 737 | + if (fcport->retry_delay_timestamp == 0) { | |
| 738 | + /* retry delay not set */ | |
| 739 | + } else if (time_after(jiffies, fcport->retry_delay_timestamp)) | |
| 738 | 740 | fcport->retry_delay_timestamp = 0; |
| 739 | 741 | else |
| 740 | 742 | goto qc24_target_busy; |
| @@ -46,8 +46,6 @@ source "drivers/staging/rtl8723au/Kconfig" · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | source "drivers/staging/rts5208/Kconfig" |
| 48 | 48 | |
| 49 | −source "drivers/staging/line6/Kconfig" | |
| 50 | − | |
| 51 | 49 | source "drivers/staging/octeon/Kconfig" |
| 52 | 50 | |
| 53 | 51 | source "drivers/staging/octeon-usb/Kconfig" |
| @@ -15,7 +15,6 @@ obj-$(CONFIG_R8712U) += rtl8712/ · 14 unmodified lines | ||
| 15 | 15 | obj-$(CONFIG_R8188EU) += rtl8188eu/ |
| 16 | 16 | obj-$(CONFIG_R8723AU) += rtl8723au/ |
| 17 | 17 | obj-$(CONFIG_RTS5208) += rts5208/ |
| 18 | −obj-$(CONFIG_LINE6_USB) += line6/ | |
| 19 | 18 | obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/ |
| 20 | 19 | obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ |
| 21 | 20 | obj-$(CONFIG_OCTEON_USB) += octeon-usb/ |
| @@ -1,116 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Line6 Linux USB driver - 0.9.1beta | |
| 3 | − * | |
| 4 | − * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) | |
| 5 | − * | |
| 6 | − * This program is free software; you can redistribute it and/or | |
| 7 | − * modify it under the terms of the GNU General Public License as | |
| 8 | − * published by the Free Software Foundation, version 2. | |
| 9 | − * | |
| 10 | − */ | |
| 11 | − | |
| 12 | −#ifndef USBDEFS_H | |
| 13 | −#define USBDEFS_H | |
| 14 | − | |
| 15 | −#define LINE6_VENDOR_ID 0x0e41 | |
| 16 | − | |
| 17 | −#define USB_INTERVALS_PER_SECOND 1000 | |
| 18 | − | |
| 19 | −/* | |
| 20 | − Device ids. | |
| 21 | −*/ | |
| 22 | −#define LINE6_DEVID_BASSPODXT 0x4250 | |
| 23 | −#define LINE6_DEVID_BASSPODXTLIVE 0x4642 | |
| 24 | −#define LINE6_DEVID_BASSPODXTPRO 0x4252 | |
| 25 | −#define LINE6_DEVID_GUITARPORT 0x4750 | |
| 26 | −#define LINE6_DEVID_POCKETPOD 0x5051 | |
| 27 | −#define LINE6_DEVID_PODHD300 0x5057 | |
| 28 | −#define LINE6_DEVID_PODHD400 0x5058 | |
| 29 | −#define LINE6_DEVID_PODHD500 0x414D | |
| 30 | −#define LINE6_DEVID_PODSTUDIO_GX 0x4153 | |
| 31 | −#define LINE6_DEVID_PODSTUDIO_UX1 0x4150 | |
| 32 | −#define LINE6_DEVID_PODSTUDIO_UX2 0x4151 | |
| 33 | −#define LINE6_DEVID_PODX3 0x414a | |
| 34 | −#define LINE6_DEVID_PODX3LIVE 0x414b | |
| 35 | −#define LINE6_DEVID_PODXT 0x5044 | |
| 36 | −#define LINE6_DEVID_PODXTLIVE 0x4650 | |
| 37 | −#define LINE6_DEVID_PODXTPRO 0x5050 | |
| 38 | −#define LINE6_DEVID_TONEPORT_GX 0x4147 | |
| 39 | −#define LINE6_DEVID_TONEPORT_UX1 0x4141 | |
| 40 | −#define LINE6_DEVID_TONEPORT_UX2 0x4142 | |
| 41 | −#define LINE6_DEVID_VARIAX 0x534d | |
| 42 | − | |
| 43 | −#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x | |
| 44 | − | |
| 45 | −enum { | |
| 46 | − LINE6_INDEX_BASSPODXT, | |
| 47 | − LINE6_INDEX_BASSPODXTLIVE, | |
| 48 | − LINE6_INDEX_BASSPODXTPRO, | |
| 49 | − LINE6_INDEX_GUITARPORT, | |
| 50 | − LINE6_INDEX_POCKETPOD, | |
| 51 | − LINE6_INDEX_PODHD300, | |
| 52 | − LINE6_INDEX_PODHD400, | |
| 53 | − LINE6_INDEX_PODHD500, | |
| 54 | − LINE6_INDEX_PODSTUDIO_GX, | |
| 55 | − LINE6_INDEX_PODSTUDIO_UX1, | |
| 56 | − LINE6_INDEX_PODSTUDIO_UX2, | |
| 57 | − LINE6_INDEX_PODX3, | |
| 58 | − LINE6_INDEX_PODX3LIVE, | |
| 59 | − LINE6_INDEX_PODXT, | |
| 60 | − LINE6_INDEX_PODXTLIVE, | |
| 61 | − LINE6_INDEX_PODXTPRO, | |
| 62 | − LINE6_INDEX_TONEPORT_GX, | |
| 63 | − LINE6_INDEX_TONEPORT_UX1, | |
| 64 | − LINE6_INDEX_TONEPORT_UX2, | |
| 65 | − LINE6_INDEX_VARIAX, | |
| 66 | − | |
| 67 | − LINE6_BIT(BASSPODXT), | |
| 68 | − LINE6_BIT(BASSPODXTLIVE), | |
| 69 | − LINE6_BIT(BASSPODXTPRO), | |
| 70 | − LINE6_BIT(GUITARPORT), | |
| 71 | − LINE6_BIT(POCKETPOD), | |
| 72 | − LINE6_BIT(PODHD300), | |
| 73 | − LINE6_BIT(PODHD400), | |
| 74 | − LINE6_BIT(PODHD500), | |
| 75 | − LINE6_BIT(PODSTUDIO_GX), | |
| 76 | − LINE6_BIT(PODSTUDIO_UX1), | |
| 77 | − LINE6_BIT(PODSTUDIO_UX2), | |
| 78 | − LINE6_BIT(PODX3), | |
| 79 | − LINE6_BIT(PODX3LIVE), | |
| 80 | − LINE6_BIT(PODXT), | |
| 81 | − LINE6_BIT(PODXTLIVE), | |
| 82 | − LINE6_BIT(PODXTPRO), | |
| 83 | − LINE6_BIT(TONEPORT_GX), | |
| 84 | − LINE6_BIT(TONEPORT_UX1), | |
| 85 | − LINE6_BIT(TONEPORT_UX2), | |
| 86 | − LINE6_BIT(VARIAX), | |
| 87 | − | |
| 88 | − LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO, | |
| 89 | − LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | | |
| 90 | − LINE6_BIT_PODX3LIVE, | |
| 91 | − LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | | |
| 92 | − LINE6_BIT_PODXTPRO, | |
| 93 | − LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE, | |
| 94 | − LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 | | |
| 95 | − LINE6_BIT_PODHD400 | | |
| 96 | − LINE6_BIT_PODHD500, | |
| 97 | − LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT | | |
| 98 | − LINE6_BIT_BASSPODXTLIVE | | |
| 99 | − LINE6_BIT_BASSPODXTPRO | |
| 100 | −}; | |
| 101 | − | |
| 102 | −/* device supports settings parameter via USB */ | |
| 103 | −#define LINE6_BIT_CONTROL (1 << 0) | |
| 104 | −/* device supports PCM input/output via USB */ | |
| 105 | −#define LINE6_BIT_PCM (1 << 1) | |
| 106 | −/* device support hardware monitoring */ | |
| 107 | −#define LINE6_BIT_HWMON (1 << 2) | |
| 108 | − | |
| 109 | −#define LINE6_BIT_CTRL_PCM_HW (LINE6_BIT_CONTROL | \ | |
| 110 | − LINE6_BIT_PCM | \ | |
| 111 | − LINE6_BIT_HWMON) | |
| 112 | − | |
| 113 | −#define LINE6_FALLBACK_INTERVAL 10 | |
| 114 | −#define LINE6_FALLBACK_MAXPACKETSIZE 16 | |
| 115 | − | |
| 116 | −#endif | |
| @@ -840,13 +840,11 @@ static const struct vfio_device_ops vfio_pci_ops = { · 839 unmodified lines | ||
| 840 | 840 | |
| 841 | 841 | static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| 842 | 842 | { |
| 843 | − u8 type; | |
| 844 | 843 | struct vfio_pci_device *vdev; |
| 845 | 844 | struct iommu_group *group; |
| 846 | 845 | int ret; |
| 847 | 846 | |
| 848 | − pci_read_config_byte(pdev, PCI_HEADER_TYPE, &type); | |
| 849 | − if ((type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) | |
| 847 | + if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) | |
| 850 | 848 | return -EINVAL; |
| 851 | 849 | |
| 852 | 850 | group = iommu_group_get(&pdev->dev); |
| @@ -538,7 +538,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, · 537 unmodified lines | ||
| 538 | 538 | ++headcount; |
| 539 | 539 | seg += in; |
| 540 | 540 | } |
| 541 | − heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen); | |
| 541 | + heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen); | |
| 542 | 542 | *iovcount = seg; |
| 543 | 543 | if (unlikely(log)) |
| 544 | 544 | *log_num = nlogs; |
| @@ -282,6 +282,7 @@ void vp_del_vqs(struct virtio_device *vdev) · 281 unmodified lines | ||
| 282 | 282 | |
| 283 | 283 | vp_free_vectors(vdev); |
| 284 | 284 | kfree(vp_dev->vqs); |
| 285 | + vp_dev->vqs = NULL; | |
| 285 | 286 | } |
| 286 | 287 | |
| 287 | 288 | static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, |
| @@ -421,15 +422,6 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu) · 133 unmodified lines | ||
| 421 | 422 | return 0; |
| 422 | 423 | } |
| 423 | 424 | |
| 424 | −void virtio_pci_release_dev(struct device *_d) | |
| 425 | −{ | |
| 426 | − /* | |
| 427 | − * No need for a release method as we allocate/free | |
| 428 | − * all devices together with the pci devices. | |
| 429 | − * Provide an empty one to avoid getting a warning from core. | |
| 430 | − */ | |
| 431 | −} | |
| 432 | − | |
| 433 | 425 | #ifdef CONFIG_PM_SLEEP |
| 434 | 426 | static int virtio_pci_freeze(struct device *dev) |
| 435 | 427 | { |
| @@ -126,7 +126,6 @@ const char *vp_bus_name(struct virtio_device *vdev); · 125 unmodified lines | ||
| 126 | 126 | * - ignore the affinity request if we're using INTX |
| 127 | 127 | */ |
| 128 | 128 | int vp_set_vq_affinity(struct virtqueue *vq, int cpu); |
| 129 | −void virtio_pci_release_dev(struct device *); | |
| 130 | 129 | |
| 131 | 130 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, |
| 132 | 131 | const struct pci_device_id *id); |
| @@ -211,6 +211,17 @@ static const struct virtio_config_ops virtio_pci_config_ops = { · 210 unmodified lines | ||
| 211 | 211 | .set_vq_affinity = vp_set_vq_affinity, |
| 212 | 212 | }; |
| 213 | 213 | |
| 214 | +static void virtio_pci_release_dev(struct device *_d) | |
| 215 | +{ | |
| 216 | + struct virtio_device *vdev = dev_to_virtio(_d); | |
| 217 | + struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
| 218 | + | |
| 219 | + /* As struct device is a kobject, it's not safe to | |
| 220 | + * free the memory (including the reference counter itself) | |
| 221 | + * until it's release callback. */ | |
| 222 | + kfree(vp_dev); | |
| 223 | +} | |
| 224 | + | |
| 214 | 225 | /* the PCI probing function */ |
| 215 | 226 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, |
| 216 | 227 | const struct pci_device_id *id) |
| @@ -302,5 +313,4 @@ void virtio_pci_legacy_remove(struct pci_dev *pci_dev) · 85 unmodified lines | ||
| 302 | 313 | pci_iounmap(pci_dev, vp_dev->ioaddr); |
| 303 | 314 | pci_release_regions(pci_dev); |
| 304 | 315 | pci_disable_device(pci_dev); |
| 305 | − kfree(vp_dev); | |
| 306 | 316 | } |
| @@ -1552,7 +1552,6 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, · 1551 unmodified lines | ||
| 1552 | 1552 | { |
| 1553 | 1553 | int ret; |
| 1554 | 1554 | int type; |
| 1555 | − struct btrfs_tree_block_info *info; | |
| 1556 | 1555 | struct btrfs_extent_inline_ref *eiref; |
| 1557 | 1556 | |
| 1558 | 1557 | if (*ptr == (unsigned long)-1) |
| @@ -1573,9 +1572,17 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, · 14 unmodified lines | ||
| 1573 | 1572 | } |
| 1574 | 1573 | |
| 1575 | 1574 | /* we can treat both ref types equally here */ |
| 1576 | − info = (struct btrfs_tree_block_info *)(ei + 1); | |
| 1577 | 1575 | *out_root = btrfs_extent_inline_ref_offset(eb, eiref); |
| 1578 | − *out_level = btrfs_tree_block_level(eb, info); | |
| 1576 | + | |
| 1577 | + if (key->type == BTRFS_EXTENT_ITEM_KEY) { | |
| 1578 | + struct btrfs_tree_block_info *info; | |
| 1579 | + | |
| 1580 | + info = (struct btrfs_tree_block_info *)(ei + 1); | |
| 1581 | + *out_level = btrfs_tree_block_level(eb, info); | |
| 1582 | + } else { | |
| 1583 | + ASSERT(key->type == BTRFS_METADATA_ITEM_KEY); | |
| 1584 | + *out_level = (u8)key->offset; | |
| 1585 | + } | |
| 1579 | 1586 | |
| 1580 | 1587 | if (ret == 1) |
| 1581 | 1588 | *ptr = (unsigned long)-1; |
| @@ -1857,6 +1857,14 @@ int btrfs_delayed_delete_inode_ref(struct inode *inode) · 1856 unmodified lines | ||
| 1857 | 1857 | { |
| 1858 | 1858 | struct btrfs_delayed_node *delayed_node; |
| 1859 | 1859 | |
| 1860 | + /* | |
| 1861 | + * we don't do delayed inode updates during log recovery because it | |
| 1862 | + * leads to enospc problems. This means we also can't do | |
| 1863 | + * delayed inode refs | |
| 1864 | + */ | |
| 1865 | + if (BTRFS_I(inode)->root->fs_info->log_root_recovering) | |
| 1866 | + return -EAGAIN; | |
| 1867 | + | |
| 1860 | 1868 | delayed_node = btrfs_get_or_create_delayed_node(inode); |
| 1861 | 1869 | if (IS_ERR(delayed_node)) |
| 1862 | 1870 | return PTR_ERR(delayed_node); |
| @@ -3139,9 +3139,11 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, · 3138 unmodified lines | ||
| 3139 | 3139 | struct extent_buffer *leaf; |
| 3140 | 3140 | |
| 3141 | 3141 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); |
| 3142 | − if (ret < 0) | |
| 3142 | + if (ret) { | |
| 3143 | + if (ret > 0) | |
| 3144 | + ret = -ENOENT; | |
| 3143 | 3145 | goto fail; |
| 3144 | − BUG_ON(ret); /* Corruption */ | |
| 3146 | + } | |
| 3145 | 3147 | |
| 3146 | 3148 | leaf = path->nodes[0]; |
| 3147 | 3149 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); |
| @@ -3149,11 +3151,9 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, · 1 unmodified line | ||
| 3149 | 3151 | btrfs_mark_buffer_dirty(leaf); |
| 3150 | 3152 | btrfs_release_path(path); |
| 3151 | 3153 | fail: |
| 3152 | − if (ret) { | |
| 3154 | + if (ret) | |
| 3153 | 3155 | btrfs_abort_transaction(trans, root, ret); |
| 3154 | − return ret; | |
| 3155 | − } | |
| 3156 | − return 0; | |
| 3156 | + return ret; | |
| 3157 | 3157 | |
| 3158 | 3158 | } |
| 3159 | 3159 | |
| @@ -6255,8 +6255,10 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) · 6254 unmodified lines | ||
| 6255 | 6255 | |
| 6256 | 6256 | out_fail: |
| 6257 | 6257 | btrfs_end_transaction(trans, root); |
| 6258 | − if (drop_on_err) | |
| 6258 | + if (drop_on_err) { | |
| 6259 | + inode_dec_link_count(inode); | |
| 6259 | 6260 | iput(inode); |
| 6261 | + } | |
| 6260 | 6262 | btrfs_balance_delayed_items(root); |
| 6261 | 6263 | btrfs_btree_balance_dirty(root); |
| 6262 | 6264 | return err; |
| @@ -2607,9 +2607,9 @@ static int scrub_extent_for_parity(struct scrub_parity *sparity, · 2606 unmodified lines | ||
| 2607 | 2607 | ret = scrub_pages_for_parity(sparity, logical, l, physical, dev, |
| 2608 | 2608 | flags, gen, mirror_num, |
| 2609 | 2609 | have_csum ? csum : NULL); |
| 2610 | −skip: | |
| 2611 | 2610 | if (ret) |
| 2612 | 2611 | return ret; |
| 2612 | +skip: | |
| 2613 | 2613 | len -= l; |
| 2614 | 2614 | logical += l; |
| 2615 | 2615 | physical += l; |
| @@ -1416,7 +1416,7 @@ void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, · 1415 unmodified lines | ||
| 1416 | 1416 | } |
| 1417 | 1417 | } |
| 1418 | 1418 | |
| 1419 | − dout("fill_inline_data %p %llx.%llx len %lu locked_page %p\n", | |
| 1419 | + dout("fill_inline_data %p %llx.%llx len %zu locked_page %p\n", | |
| 1420 | 1420 | inode, ceph_vinop(inode), len, locked_page); |
| 1421 | 1421 | |
| 1422 | 1422 | if (len > 0) { |
| @@ -5166,8 +5166,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, · 5165 unmodified lines | ||
| 5166 | 5166 | |
| 5167 | 5167 | /* fallback to generic here if not in extents fmt */ |
| 5168 | 5168 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
| 5169 | − return __generic_block_fiemap(inode, fieinfo, start, len, | |
| 5170 | − ext4_get_block); | |
| 5169 | + return generic_block_fiemap(inode, fieinfo, start, len, | |
| 5170 | + ext4_get_block); | |
| 5171 | 5171 | |
| 5172 | 5172 | if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS)) |
| 5173 | 5173 | return -EBADR; |
| @@ -273,19 +273,24 @@ static int ext4_file_open(struct inode * inode, struct file * filp) · 272 unmodified lines | ||
| 273 | 273 | * we determine this extent as a data or a hole according to whether the |
| 274 | 274 | * page cache has data or not. |
| 275 | 275 | */ |
| 276 | −static int ext4_find_unwritten_pgoff(struct inode *inode, int whence, | |
| 277 | − loff_t endoff, loff_t *offset) | |
| 276 | +static int ext4_find_unwritten_pgoff(struct inode *inode, | |
| 277 | + int whence, | |
| 278 | + struct ext4_map_blocks *map, | |
| 279 | + loff_t *offset) | |
| 278 | 280 | { |
| 279 | 281 | struct pagevec pvec; |
| 282 | + unsigned int blkbits; | |
| 280 | 283 | pgoff_t index; |
| 281 | 284 | pgoff_t end; |
| 285 | + loff_t endoff; | |
| 282 | 286 | loff_t startoff; |
| 283 | 287 | loff_t lastoff; |
| 284 | 288 | int found = 0; |
| 285 | 289 | |
| 290 | + blkbits = inode->i_sb->s_blocksize_bits; | |
| 286 | 291 | startoff = *offset; |
| 287 | 292 | lastoff = startoff; |
| 288 | − | |
| 293 | + endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits; | |
| 289 | 294 | |
| 290 | 295 | index = startoff >> PAGE_CACHE_SHIFT; |
| 291 | 296 | end = endoff >> PAGE_CACHE_SHIFT; |
| @@ -403,144 +408,147 @@ out: · 111 unmodified lines | ||
| 403 | 408 | static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) |
| 404 | 409 | { |
| 405 | 410 | struct inode *inode = file->f_mapping->host; |
| 406 | − struct fiemap_extent_info fie; | |
| 407 | − struct fiemap_extent ext[2]; | |
| 408 | − loff_t next; | |
| 409 | − int i, ret = 0; | |
| 411 | + struct ext4_map_blocks map; | |
| 412 | + struct extent_status es; | |
| 413 | + ext4_lblk_t start, last, end; | |
| 414 | + loff_t dataoff, isize; | |
| 415 | + int blkbits; | |
| 416 | + int ret = 0; | |
| 410 | 417 | |
| 411 | 418 | mutex_lock(&inode->i_mutex); |
| 412 | − if (offset >= inode->i_size) { | |
| 419 | + | |
| 420 | + isize = i_size_read(inode); | |
| 421 | + if (offset >= isize) { | |
| 413 | 422 | mutex_unlock(&inode->i_mutex); |
| 414 | 423 | return -ENXIO; |
| 415 | 424 | } |
| 416 | − fie.fi_flags = 0; | |
| 417 | − fie.fi_extents_max = 2; | |
| 418 | − fie.fi_extents_start = (struct fiemap_extent __user *) &ext; | |
| 419 | − while (1) { | |
| 420 | − mm_segment_t old_fs = get_fs(); | |
| 421 | − | |
| 422 | − fie.fi_extents_mapped = 0; | |
| 423 | − memset(ext, 0, sizeof(*ext) * fie.fi_extents_max); | |
| 424 | − | |
| 425 | − set_fs(get_ds()); | |
| 426 | − ret = ext4_fiemap(inode, &fie, offset, maxsize - offset); | |
| 427 | − set_fs(old_fs); | |
| 428 | − if (ret) | |
| 425 | + | |
| 426 | + blkbits = inode->i_sb->s_blocksize_bits; | |
| 427 | + start = offset >> blkbits; | |
| 428 | + last = start; | |
| 429 | + end = isize >> blkbits; | |
| 430 | + dataoff = offset; | |
| 431 | + | |
| 432 | + do { | |
| 433 | + map.m_lblk = last; | |
| 434 | + map.m_len = end - last + 1; | |
| 435 | + ret = ext4_map_blocks(NULL, inode, &map, 0); | |
| 436 | + if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) { | |
| 437 | + if (last != start) | |
| 438 | + dataoff = (loff_t)last << blkbits; | |
| 429 | 439 | break; |
| 440 | + } | |
| 430 | 441 | |
| 431 | − /* No extents found, EOF */ | |
| 432 | − if (!fie.fi_extents_mapped) { | |
| 433 | − ret = -ENXIO; | |
| 442 | + /* | |
| 443 | + * If there is a delay extent at this offset, | |
| 444 | + * it will be as a data. | |
| 445 | + */ | |
| 446 | + ext4_es_find_delayed_extent_range(inode, last, last, &es); | |
| 447 | + if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { | |
| 448 | + if (last != start) | |
| 449 | + dataoff = (loff_t)last << blkbits; | |
| 434 | 450 | break; |
| 435 | 451 | } |
| 436 | − for (i = 0; i < fie.fi_extents_mapped; i++) { | |
| 437 | − next = (loff_t)(ext[i].fe_length + ext[i].fe_logical); | |
| 438 | 452 | |
| 439 | − if (offset < (loff_t)ext[i].fe_logical) | |
| 440 | − offset = (loff_t)ext[i].fe_logical; | |
| 441 | − /* | |
| 442 | − * If extent is not unwritten, then it contains valid | |
| 443 | − * data, mapped or delayed. | |
| 444 | − */ | |
| 445 | − if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN)) | |
| 446 | − goto out; | |
| 453 | + /* | |
| 454 | + * If there is a unwritten extent at this offset, | |
| 455 | + * it will be as a data or a hole according to page | |
| 456 | + * cache that has data or not. | |
| 457 | + */ | |
| 458 | + if (map.m_flags & EXT4_MAP_UNWRITTEN) { | |
| 459 | + int unwritten; | |
| 460 | + unwritten = ext4_find_unwritten_pgoff(inode, SEEK_DATA, | |
| 461 | + &map, &dataoff); | |
| 462 | + if (unwritten) | |
| 463 | + break; | |
| 464 | + } | |
| 447 | 465 | |
| 448 | − /* | |
| 449 | − * If there is a unwritten extent at this offset, | |
| 450 | − * it will be as a data or a hole according to page | |
| 451 | − * cache that has data or not. | |
| 452 | − */ | |
| 453 | − if (ext4_find_unwritten_pgoff(inode, SEEK_DATA, | |
| 454 | − next, &offset)) | |
| 455 | − goto out; | |
| 466 | + last++; | |
| 467 | + dataoff = (loff_t)last << blkbits; | |
| 468 | + } while (last <= end); | |
| 456 | 469 | |
| 457 | − if (ext[i].fe_flags & FIEMAP_EXTENT_LAST) { | |
| 458 | − ret = -ENXIO; | |
| 459 | − goto out; | |
| 460 | − } | |
| 461 | − offset = next; | |
| 462 | − } | |
| 463 | − } | |
| 464 | − if (offset > inode->i_size) | |
| 465 | − offset = inode->i_size; | |
| 466 | −out: | |
| 467 | 470 | mutex_unlock(&inode->i_mutex); |
| 468 | − if (ret) | |
| 469 | − return ret; | |
| 470 | 471 | |
| 471 | − return vfs_setpos(file, offset, maxsize); | |
| 472 | + if (dataoff > isize) | |
| 473 | + return -ENXIO; | |
| 474 | + | |
| 475 | + return vfs_setpos(file, dataoff, maxsize); | |
| 472 | 476 | } |
| 473 | 477 | |
| 474 | 478 | /* |
| 475 | − * ext4_seek_hole() retrieves the offset for SEEK_HOLE | |
| 479 | + * ext4_seek_hole() retrieves the offset for SEEK_HOLE. | |
| 476 | 480 | */ |
| 477 | 481 | static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) |
| 478 | 482 | { |
| 479 | 483 | struct inode *inode = file->f_mapping->host; |
| 480 | − struct fiemap_extent_info fie; | |
| 481 | − struct fiemap_extent ext[2]; | |
| 482 | − loff_t next; | |
| 483 | − int i, ret = 0; | |
| 484 | + struct ext4_map_blocks map; | |
| 485 | + struct extent_status es; | |
| 486 | + ext4_lblk_t start, last, end; | |
| 487 | + loff_t holeoff, isize; | |
| 488 | + int blkbits; | |
| 489 | + int ret = 0; | |
| 484 | 490 | |
| 485 | 491 | mutex_lock(&inode->i_mutex); |
| 486 | − if (offset >= inode->i_size) { | |
| 492 | + | |
| 493 | + isize = i_size_read(inode); | |
| 494 | + if (offset >= isize) { | |
| 487 | 495 | mutex_unlock(&inode->i_mutex); |
| 488 | 496 | return -ENXIO; |
| 489 | 497 | } |
| 490 | 498 | |
| 491 | − fie.fi_flags = 0; | |
| 492 | − fie.fi_extents_max = 2; | |
| 493 | − fie.fi_extents_start = (struct fiemap_extent __user *)&ext; | |
| 494 | − while (1) { | |
| 495 | − mm_segment_t old_fs = get_fs(); | |
| 496 | − | |
| 497 | − fie.fi_extents_mapped = 0; | |
| 498 | − memset(ext, 0, sizeof(*ext)); | |
| 499 | + blkbits = inode->i_sb->s_blocksize_bits; | |
| 500 | + start = offset >> blkbits; | |
| 501 | + last = start; | |
| 502 | + end = isize >> blkbits; | |
| 503 | + holeoff = offset; | |
| 499 | 504 | |
| 500 | − set_fs(get_ds()); | |
| 501 | − ret = ext4_fiemap(inode, &fie, offset, maxsize - offset); | |
| 502 | − set_fs(old_fs); | |
| 503 | − if (ret) | |
| 504 | − break; | |
| 505 | + do { | |
| 506 | + map.m_lblk = last; | |
| 507 | + map.m_len = end - last + 1; | |
| 508 | + ret = ext4_map_blocks(NULL, inode, &map, 0); | |
| 509 | + if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) { | |
| 510 | + last += ret; | |
| 511 | + holeoff = (loff_t)last << blkbits; | |
| 512 | + continue; | |
| 513 | + } | |
| 505 | 514 | |
| 506 | − /* No extents found */ | |
| 507 | − if (!fie.fi_extents_mapped) | |
| 508 | − break; | |
| 515 | + /* | |
| 516 | + * If there is a delay extent at this offset, | |
| 517 | + * we will skip this extent. | |
| 518 | + */ | |
| 519 | + ext4_es_find_delayed_extent_range(inode, last, last, &es); | |
| 520 | + if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { | |
| 521 | + last = es.es_lblk + es.es_len; | |
| 522 | + holeoff = (loff_t)last << blkbits; | |
| 523 | + continue; | |
| 524 | + } | |
| 509 | 525 | |
| 510 | − for (i = 0; i < fie.fi_extents_mapped; i++) { | |
| 511 | − next = (loff_t)(ext[i].fe_logical + ext[i].fe_length); | |
| 512 | − /* | |
| 513 | − * If extent is not unwritten, then it contains valid | |
| 514 | − * data, mapped or delayed. | |
| 515 | − */ | |
| 516 | − if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN)) { | |
| 517 | − if (offset < (loff_t)ext[i].fe_logical) | |
| 518 | − goto out; | |
| 519 | − offset = next; | |
| 526 | + /* | |
| 527 | + * If there is a unwritten extent at this offset, | |
| 528 | + * it will be as a data or a hole according to page | |
| 529 | + * cache that has data or not. | |
| 530 | + */ | |
| 531 | + if (map.m_flags & EXT4_MAP_UNWRITTEN) { | |
| 532 | + int unwritten; | |
| 533 | + unwritten = ext4_find_unwritten_pgoff(inode, SEEK_HOLE, | |
| 534 | + &map, &holeoff); | |
| 535 | + if (!unwritten) { | |
| 536 | + last += ret; | |
| 537 | + holeoff = (loff_t)last << blkbits; | |
| 520 | 538 | continue; |
| 521 | 539 | } |
| 522 | − /* | |
| 523 | − * If there is a unwritten extent at this offset, | |
| 524 | − * it will be as a data or a hole according to page | |
| 525 | − * cache that has data or not. | |
| 526 | − */ | |
| 527 | − if (ext4_find_unwritten_pgoff(inode, SEEK_HOLE, | |
| 528 | − next, &offset)) | |
| 529 | − goto out; | |
| 530 | − | |
| 531 | − offset = next; | |
| 532 | − if (ext[i].fe_flags & FIEMAP_EXTENT_LAST) | |
| 533 | − goto out; | |
| 534 | 540 | } |
| 535 | − } | |
| 536 | − if (offset > inode->i_size) | |
| 537 | − offset = inode->i_size; | |
| 538 | −out: | |
| 541 | + | |
| 542 | + /* find a hole */ | |
| 543 | + break; | |
| 544 | + } while (last <= end); | |
| 545 | + | |
| 539 | 546 | mutex_unlock(&inode->i_mutex); |
| 540 | − if (ret) | |
| 541 | − return ret; | |
| 542 | 547 | |
| 543 | − return vfs_setpos(file, offset, maxsize); | |
| 548 | + if (holeoff > isize) | |
| 549 | + holeoff = isize; | |
| 550 | + | |
| 551 | + return vfs_setpos(file, holeoff, maxsize); | |
| 544 | 552 | } |
| 545 | 553 | |
| 546 | 554 | /* |
| @@ -23,6 +23,18 @@ int ext4_resize_begin(struct super_block *sb) · 22 unmodified lines | ||
| 23 | 23 | if (!capable(CAP_SYS_RESOURCE)) |
| 24 | 24 | return -EPERM; |
| 25 | 25 | |
| 26 | + /* | |
| 27 | + * If we are not using the primary superblock/GDT copy don't resize, | |
| 28 | + * because the user tools have no way of handling this. Probably a | |
| 29 | + * bad time to do it anyways. | |
| 30 | + */ | |
| 31 | + if (EXT4_SB(sb)->s_sbh->b_blocknr != | |
| 32 | + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { | |
| 33 | + ext4_warning(sb, "won't resize using backup superblock at %llu", | |
| 34 | + (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); | |
| 35 | + return -EPERM; | |
| 36 | + } | |
| 37 | + | |
| 26 | 38 | /* |
| 27 | 39 | * We are not allowed to do online-resizing on a filesystem mounted |
| 28 | 40 | * with error, because it can destroy the filesystem easily. |
| @@ -758,18 +770,6 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, · 729 unmodified lines | ||
| 758 | 770 | "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", |
| 759 | 771 | gdb_num); |
| 760 | 772 | |
| 761 | − /* | |
| 762 | − * If we are not using the primary superblock/GDT copy don't resize, | |
| 763 | − * because the user tools have no way of handling this. Probably a | |
| 764 | − * bad time to do it anyways. | |
| 765 | − */ | |
| 766 | − if (EXT4_SB(sb)->s_sbh->b_blocknr != | |
| 767 | − le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { | |
| 768 | − ext4_warning(sb, "won't resize using backup superblock at %llu", | |
| 769 | − (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); | |
| 770 | − return -EPERM; | |
| 771 | − } | |
| 772 | − | |
| 773 | 773 | gdb_bh = sb_bread(sb, gdblock); |
| 774 | 774 | if (!gdb_bh) |
| 775 | 775 | return -EIO; |
| @@ -3482,7 +3482,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) · 3481 unmodified lines | ||
| 3482 | 3482 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, |
| 3483 | 3483 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && |
| 3484 | 3484 | EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) |
| 3485 | − ext4_warning(sb, KERN_INFO "metadata_csum and uninit_bg are " | |
| 3485 | + ext4_warning(sb, "metadata_csum and uninit_bg are " | |
| 3486 | 3486 | "redundant flags; please run fsck."); |
| 3487 | 3487 | |
| 3488 | 3488 | /* Check for a known checksum algorithm */ |
| @@ -740,14 +740,15 @@ static int __init fcntl_init(void) · 739 unmodified lines | ||
| 740 | 740 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY |
| 741 | 741 | * is defined as O_NONBLOCK on some platforms and not on others. |
| 742 | 742 | */ |
| 743 | − BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | |
| 743 | + BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | |
| 744 | 744 | O_RDONLY | O_WRONLY | O_RDWR | |
| 745 | 745 | O_CREAT | O_EXCL | O_NOCTTY | |
| 746 | 746 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ |
| 747 | 747 | __O_SYNC | O_DSYNC | FASYNC | |
| 748 | 748 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
| 749 | 749 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
| 750 | − __FMODE_EXEC | O_PATH | __O_TMPFILE | |
| 750 | + __FMODE_EXEC | O_PATH | __O_TMPFILE | | |
| 751 | + __FMODE_NONOTIFY | |
| 751 | 752 | )); |
| 752 | 753 | |
| 753 | 754 | fasync_cache = kmem_cache_create("fasync_cache", |
| @@ -3897,11 +3897,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, · 3896 unmodified lines | ||
| 3897 | 3897 | status = nfs4_setlease(dp); |
| 3898 | 3898 | goto out; |
| 3899 | 3899 | } |
| 3900 | − atomic_inc(&fp->fi_delegees); | |
| 3901 | 3900 | if (fp->fi_had_conflict) { |
| 3902 | 3901 | status = -EAGAIN; |
| 3903 | 3902 | goto out_unlock; |
| 3904 | 3903 | } |
| 3904 | + atomic_inc(&fp->fi_delegees); | |
| 3905 | 3905 | hash_delegation_locked(dp, fp); |
| 3906 | 3906 | status = 0; |
| 3907 | 3907 | out_unlock: |
| @@ -259,16 +259,15 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, · 258 unmodified lines | ||
| 259 | 259 | struct fsnotify_event *kevent; |
| 260 | 260 | char __user *start; |
| 261 | 261 | int ret; |
| 262 | − DEFINE_WAIT(wait); | |
| 262 | + DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
| 263 | 263 | |
| 264 | 264 | start = buf; |
| 265 | 265 | group = file->private_data; |
| 266 | 266 | |
| 267 | 267 | pr_debug("%s: group=%p\n", __func__, group); |
| 268 | 268 | |
| 269 | + add_wait_queue(&group->notification_waitq, &wait); | |
| 269 | 270 | while (1) { |
| 270 | − prepare_to_wait(&group->notification_waitq, &wait, TASK_INTERRUPTIBLE); | |
| 271 | − | |
| 272 | 271 | mutex_lock(&group->notification_mutex); |
| 273 | 272 | kevent = get_one_event(group, count); |
| 274 | 273 | mutex_unlock(&group->notification_mutex); |
| @@ -289,7 +288,8 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, · 14 unmodified lines | ||
| 289 | 288 | |
| 290 | 289 | if (start != buf) |
| 291 | 290 | break; |
| 292 | − schedule(); | |
| 291 | + | |
| 292 | + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); | |
| 293 | 293 | continue; |
| 294 | 294 | } |
| 295 | 295 | |
| @@ -318,8 +318,8 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, · 22 unmodified lines | ||
| 318 | 318 | buf += ret; |
| 319 | 319 | count -= ret; |
| 320 | 320 | } |
| 321 | + remove_wait_queue(&group->notification_waitq, &wait); | |
| 321 | 322 | |
| 322 | − finish_wait(&group->notification_waitq, &wait); | |
| 323 | 323 | if (start != buf && ret != -EFAULT) |
| 324 | 324 | ret = buf - start; |
| 325 | 325 | return ret; |
| @@ -2023,11 +2023,8 @@ leave: · 2022 unmodified lines | ||
| 2023 | 2023 | dlm_lockres_drop_inflight_ref(dlm, res); |
| 2024 | 2024 | spin_unlock(&res->spinlock); |
| 2025 | 2025 | |
| 2026 | − if (ret < 0) { | |
| 2026 | + if (ret < 0) | |
| 2027 | 2027 | mlog_errno(ret); |
| 2028 | − if (newlock) | |
| 2029 | − dlm_lock_put(newlock); | |
| 2030 | − } | |
| 2031 | 2028 | |
| 2032 | 2029 | return ret; |
| 2033 | 2030 | } |
| @@ -94,6 +94,14 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, · 93 unmodified lines | ||
| 94 | 94 | struct inode *inode, |
| 95 | 95 | const char *symname); |
| 96 | 96 | |
| 97 | +static int ocfs2_double_lock(struct ocfs2_super *osb, | |
| 98 | + struct buffer_head **bh1, | |
| 99 | + struct inode *inode1, | |
| 100 | + struct buffer_head **bh2, | |
| 101 | + struct inode *inode2, | |
| 102 | + int rename); | |
| 103 | + | |
| 104 | +static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2); | |
| 97 | 105 | /* An orphan dir name is an 8 byte value, printed as a hex string */ |
| 98 | 106 | #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) |
| 99 | 107 | |
| @@ -678,8 +686,10 @@ static int ocfs2_link(struct dentry *old_dentry, · 578 unmodified lines | ||
| 678 | 686 | { |
| 679 | 687 | handle_t *handle; |
| 680 | 688 | struct inode *inode = old_dentry->d_inode; |
| 689 | + struct inode *old_dir = old_dentry->d_parent->d_inode; | |
| 681 | 690 | int err; |
| 682 | 691 | struct buffer_head *fe_bh = NULL; |
| 692 | + struct buffer_head *old_dir_bh = NULL; | |
| 683 | 693 | struct buffer_head *parent_fe_bh = NULL; |
| 684 | 694 | struct ocfs2_dinode *fe = NULL; |
| 685 | 695 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
| @@ -696,19 +706,33 @@ static int ocfs2_link(struct dentry *old_dentry, · 10 unmodified lines | ||
| 696 | 706 | |
| 697 | 707 | dquot_initialize(dir); |
| 698 | 708 | |
| 699 | − err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT); | |
| 709 | + err = ocfs2_double_lock(osb, &old_dir_bh, old_dir, | |
| 710 | + &parent_fe_bh, dir, 0); | |
| 700 | 711 | if (err < 0) { |
| 701 | 712 | if (err != -ENOENT) |
| 702 | 713 | mlog_errno(err); |
| 703 | 714 | return err; |
| 704 | 715 | } |
| 705 | 716 | |
| 717 | + /* make sure both dirs have bhs | |
| 718 | + * get an extra ref on old_dir_bh if old==new */ | |
| 719 | + if (!parent_fe_bh) { | |
| 720 | + if (old_dir_bh) { | |
| 721 | + parent_fe_bh = old_dir_bh; | |
| 722 | + get_bh(parent_fe_bh); | |
| 723 | + } else { | |
| 724 | + mlog(ML_ERROR, "%s: no old_dir_bh!\n", osb->uuid_str); | |
| 725 | + err = -EIO; | |
| 726 | + goto out; | |
| 727 | + } | |
| 728 | + } | |
| 729 | + | |
| 706 | 730 | if (!dir->i_nlink) { |
| 707 | 731 | err = -ENOENT; |
| 708 | 732 | goto out; |
| 709 | 733 | } |
| 710 | 734 | |
| 711 | − err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | |
| 735 | + err = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name, | |
| 712 | 736 | old_dentry->d_name.len, &old_de_ino); |
| 713 | 737 | if (err) { |
| 714 | 738 | err = -ENOENT; |
| @@ -801,10 +825,11 @@ out_unlock_inode: · 86 unmodified lines | ||
| 801 | 825 | ocfs2_inode_unlock(inode, 1); |
| 802 | 826 | |
| 803 | 827 | out: |
| 804 | − ocfs2_inode_unlock(dir, 1); | |
| 828 | + ocfs2_double_unlock(old_dir, dir); | |
| 805 | 829 | |
| 806 | 830 | brelse(fe_bh); |
| 807 | 831 | brelse(parent_fe_bh); |
| 832 | + brelse(old_dir_bh); | |
| 808 | 833 | |
| 809 | 834 | ocfs2_free_dir_lookup_result(&lookup); |
| 810 | 835 | |
| @@ -1072,14 +1097,15 @@ static int ocfs2_check_if_ancestor(struct ocfs2_super *osb, · 261 unmodified lines | ||
| 1072 | 1097 | } |
| 1073 | 1098 | |
| 1074 | 1099 | /* |
| 1075 | − * The only place this should be used is rename! | |
| 1100 | + * The only place this should be used is rename and link! | |
| 1076 | 1101 | * if they have the same id, then the 1st one is the only one locked. |
| 1077 | 1102 | */ |
| 1078 | 1103 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
| 1079 | 1104 | struct buffer_head **bh1, |
| 1080 | 1105 | struct inode *inode1, |
| 1081 | 1106 | struct buffer_head **bh2, |
| 1082 | − struct inode *inode2) | |
| 1107 | + struct inode *inode2, | |
| 1108 | + int rename) | |
| 1083 | 1109 | { |
| 1084 | 1110 | int status; |
| 1085 | 1111 | int inode1_is_ancestor, inode2_is_ancestor; |
| @@ -1127,7 +1153,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, · 41 unmodified lines | ||
| 1127 | 1153 | } |
| 1128 | 1154 | /* lock id2 */ |
| 1129 | 1155 | status = ocfs2_inode_lock_nested(inode2, bh2, 1, |
| 1130 | − OI_LS_RENAME1); | |
| 1156 | + rename == 1 ? OI_LS_RENAME1 : OI_LS_PARENT); | |
| 1131 | 1157 | if (status < 0) { |
| 1132 | 1158 | if (status != -ENOENT) |
| 1133 | 1159 | mlog_errno(status); |
| @@ -1136,7 +1162,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, · 2 unmodified lines | ||
| 1136 | 1162 | } |
| 1137 | 1163 | |
| 1138 | 1164 | /* lock id1 */ |
| 1139 | − status = ocfs2_inode_lock_nested(inode1, bh1, 1, OI_LS_RENAME2); | |
| 1165 | + status = ocfs2_inode_lock_nested(inode1, bh1, 1, | |
| 1166 | + rename == 1 ? OI_LS_RENAME2 : OI_LS_PARENT); | |
| 1140 | 1167 | if (status < 0) { |
| 1141 | 1168 | /* |
| 1142 | 1169 | * An error return must mean that no cluster locks |
| @@ -1252,7 +1279,7 @@ static int ocfs2_rename(struct inode *old_dir, · 109 unmodified lines | ||
| 1252 | 1279 | |
| 1253 | 1280 | /* if old and new are the same, this'll just do one lock. */ |
| 1254 | 1281 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
| 1255 | − &new_dir_bh, new_dir); | |
| 1282 | + &new_dir_bh, new_dir, 1); | |
| 1256 | 1283 | if (status < 0) { |
| 1257 | 1284 | mlog_errno(status); |
| 1258 | 1285 | goto bail; |
| @@ -196,8 +196,8 @@ struct acpi_processor_flags { · 195 unmodified lines | ||
| 196 | 196 | struct acpi_processor { |
| 197 | 197 | acpi_handle handle; |
| 198 | 198 | u32 acpi_id; |
| 199 | − u32 apic_id; | |
| 200 | − u32 id; | |
| 199 | + u32 phys_id; /* CPU hardware ID such as APIC ID for x86 */ | |
| 200 | + u32 id; /* CPU logical ID allocated by OS */ | |
| 201 | 201 | u32 pblk; |
| 202 | 202 | int performance_platform_limit; |
| 203 | 203 | int throttling_platform_limit; |
| @@ -310,8 +310,8 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) · 106 unmodified lines | ||
| 310 | 310 | #endif /* CONFIG_CPU_FREQ */ |
| 311 | 311 | |
| 312 | 312 | /* in processor_core.c */ |
| 313 | −int acpi_get_apicid(acpi_handle, int type, u32 acpi_id); | |
| 314 | −int acpi_map_cpuid(int apic_id, u32 acpi_id); | |
| 313 | +int acpi_get_phys_id(acpi_handle, int type, u32 acpi_id); | |
| 314 | +int acpi_map_cpuid(int phys_id, u32 acpi_id); | |
| 315 | 315 | int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); |
| 316 | 316 | |
| 317 | 317 | /* in processor_pdc.c */ |
| @@ -147,8 +147,8 @@ void acpi_numa_arch_fixup(void); · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
| 149 | 149 | /* Arch dependent functions for cpu hotplug support */ |
| 150 | −int acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu); | |
| 151 | −int acpi_unmap_lsapic(int cpu); | |
| 150 | +int acpi_map_cpu(acpi_handle handle, int physid, int *pcpu); | |
| 151 | +int acpi_unmap_cpu(int cpu); | |
| 152 | 152 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
| 153 | 153 | |
| 154 | 154 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); |
| @@ -87,8 +87,8 @@ struct ceph_osd_req_op { · 86 unmodified lines | ||
| 87 | 87 | struct ceph_osd_data osd_data; |
| 88 | 88 | } extent; |
| 89 | 89 | struct { |
| 90 | − __le32 name_len; | |
| 91 | − __le32 value_len; | |
| 90 | + u32 name_len; | |
| 91 | + u32 value_len; | |
| 92 | 92 | __u8 cmp_op; /* CEPH_OSD_CMPXATTR_OP_* */ |
| 93 | 93 | __u8 cmp_mode; /* CEPH_OSD_CMPXATTR_MODE_* */ |
| 94 | 94 | struct ceph_osd_data osd_data; |
| @@ -135,7 +135,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, · 134 unmodified lines | ||
| 135 | 135 | #define FMODE_CAN_WRITE ((__force fmode_t)0x40000) |
| 136 | 136 | |
| 137 | 137 | /* File was opened by fanotify and shouldn't generate fanotify events */ |
| 138 | −#define FMODE_NONOTIFY ((__force fmode_t)0x1000000) | |
| 138 | +#define FMODE_NONOTIFY ((__force fmode_t)0x4000000) | |
| 139 | 139 | |
| 140 | 140 | /* |
| 141 | 141 | * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector |
| @@ -13,11 +13,54 @@ · 12 unmodified lines | ||
| 13 | 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | +/* Shifted versions of the command enable bits are be used if the command | |
| 17 | + * has no arguments (see kdb_check_flags). This allows commands, such as | |
| 18 | + * go, to have different permissions depending upon whether it is called | |
| 19 | + * with an argument. | |
| 20 | + */ | |
| 21 | +#define KDB_ENABLE_NO_ARGS_SHIFT 10 | |
| 22 | + | |
| 16 | 23 | typedef enum { |
| 17 | − KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | |
| 18 | − KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | |
| 19 | − KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | |
| 20 | −} kdb_repeat_t; | |
| 24 | + KDB_ENABLE_ALL = (1 << 0), /* Enable everything */ | |
| 25 | + KDB_ENABLE_MEM_READ = (1 << 1), | |
| 26 | + KDB_ENABLE_MEM_WRITE = (1 << 2), | |
| 27 | + KDB_ENABLE_REG_READ = (1 << 3), | |
| 28 | + KDB_ENABLE_REG_WRITE = (1 << 4), | |
| 29 | + KDB_ENABLE_INSPECT = (1 << 5), | |
| 30 | + KDB_ENABLE_FLOW_CTRL = (1 << 6), | |
| 31 | + KDB_ENABLE_SIGNAL = (1 << 7), | |
| 32 | + KDB_ENABLE_REBOOT = (1 << 8), | |
| 33 | + /* User exposed values stop here, all remaining flags are | |
| 34 | + * exclusively used to describe a commands behaviour. | |
| 35 | + */ | |
| 36 | + | |
| 37 | + KDB_ENABLE_ALWAYS_SAFE = (1 << 9), | |
| 38 | + KDB_ENABLE_MASK = (1 << KDB_ENABLE_NO_ARGS_SHIFT) - 1, | |
| 39 | + | |
| 40 | + KDB_ENABLE_ALL_NO_ARGS = KDB_ENABLE_ALL << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 41 | + KDB_ENABLE_MEM_READ_NO_ARGS = KDB_ENABLE_MEM_READ | |
| 42 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 43 | + KDB_ENABLE_MEM_WRITE_NO_ARGS = KDB_ENABLE_MEM_WRITE | |
| 44 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 45 | + KDB_ENABLE_REG_READ_NO_ARGS = KDB_ENABLE_REG_READ | |
| 46 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 47 | + KDB_ENABLE_REG_WRITE_NO_ARGS = KDB_ENABLE_REG_WRITE | |
| 48 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 49 | + KDB_ENABLE_INSPECT_NO_ARGS = KDB_ENABLE_INSPECT | |
| 50 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 51 | + KDB_ENABLE_FLOW_CTRL_NO_ARGS = KDB_ENABLE_FLOW_CTRL | |
| 52 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 53 | + KDB_ENABLE_SIGNAL_NO_ARGS = KDB_ENABLE_SIGNAL | |
| 54 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 55 | + KDB_ENABLE_REBOOT_NO_ARGS = KDB_ENABLE_REBOOT | |
| 56 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 57 | + KDB_ENABLE_ALWAYS_SAFE_NO_ARGS = KDB_ENABLE_ALWAYS_SAFE | |
| 58 | + << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 59 | + KDB_ENABLE_MASK_NO_ARGS = KDB_ENABLE_MASK << KDB_ENABLE_NO_ARGS_SHIFT, | |
| 60 | + | |
| 61 | + KDB_REPEAT_NO_ARGS = 0x40000000, /* Repeat the command w/o arguments */ | |
| 62 | + KDB_REPEAT_WITH_ARGS = 0x80000000, /* Repeat the command with args */ | |
| 63 | +} kdb_cmdflags_t; | |
| 21 | 64 | |
| 22 | 65 | typedef int (*kdb_func_t)(int, const char **); |
| 23 | 66 | |
| @@ -62,6 +105,7 @@ extern atomic_t kdb_event; · 38 unmodified lines | ||
| 62 | 105 | #define KDB_BADLENGTH (-19) |
| 63 | 106 | #define KDB_NOBP (-20) |
| 64 | 107 | #define KDB_BADADDR (-21) |
| 108 | +#define KDB_NOPERM (-22) | |
| 65 | 109 | |
| 66 | 110 | /* |
| 67 | 111 | * kdb_diemsg |
| @@ -146,17 +190,17 @@ static inline const char *kdb_walk_kallsyms(loff_t *pos) · 78 unmodified lines | ||
| 146 | 190 | |
| 147 | 191 | /* Dynamic kdb shell command registration */ |
| 148 | 192 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); |
| 149 | −extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, | |
| 150 | − short, kdb_repeat_t); | |
| 193 | +extern int kdb_register_flags(char *, kdb_func_t, char *, char *, | |
| 194 | + short, kdb_cmdflags_t); | |
| 151 | 195 | extern int kdb_unregister(char *); |
| 152 | 196 | #else /* ! CONFIG_KGDB_KDB */ |
| 153 | 197 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } |
| 154 | 198 | static inline void kdb_init(int level) {} |
| 155 | 199 | static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, |
| 156 | 200 | char *help, short minlen) { return 0; } |
| 157 | −static inline int kdb_register_repeat(char *cmd, kdb_func_t func, char *usage, | |
| 158 | − char *help, short minlen, | |
| 159 | − kdb_repeat_t repeat) { return 0; } | |
| 201 | +static inline int kdb_register_flags(char *cmd, kdb_func_t func, char *usage, | |
| 202 | + char *help, short minlen, | |
| 203 | + kdb_cmdflags_t flags) { return 0; } | |
| 160 | 204 | static inline int kdb_unregister(char *cmd) { return 0; } |
| 161 | 205 | #endif /* CONFIG_KGDB_KDB */ |
| 162 | 206 | enum { |
| @@ -1952,7 +1952,7 @@ extern int expand_downwards(struct vm_area_struct *vma, · 1951 unmodified lines | ||
| 1952 | 1952 | #if VM_GROWSUP |
| 1953 | 1953 | extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); |
| 1954 | 1954 | #else |
| 1955 | − #define expand_upwards(vma, address) do { } while (0) | |
| 1955 | + #define expand_upwards(vma, address) (0) | |
| 1956 | 1956 | #endif |
| 1957 | 1957 | |
| 1958 | 1958 | /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ |
| @@ -79,11 +79,6 @@ struct perf_branch_stack { · 78 unmodified lines | ||
| 79 | 79 | struct perf_branch_entry entries[0]; |
| 80 | 80 | }; |
| 81 | 81 | |
| 82 | −struct perf_regs { | |
| 83 | − __u64 abi; | |
| 84 | − struct pt_regs *regs; | |
| 85 | −}; | |
| 86 | − | |
| 87 | 82 | struct task_struct; |
| 88 | 83 | |
| 89 | 84 | /* |
| @@ -610,7 +605,14 @@ struct perf_sample_data { · 520 unmodified lines | ||
| 610 | 605 | u32 reserved; |
| 611 | 606 | } cpu_entry; |
| 612 | 607 | struct perf_callchain_entry *callchain; |
| 608 | + | |
| 609 | + /* | |
| 610 | + * regs_user may point to task_pt_regs or to regs_user_copy, depending | |
| 611 | + * on arch details. | |
| 612 | + */ | |
| 613 | 613 | struct perf_regs regs_user; |
| 614 | + struct pt_regs regs_user_copy; | |
| 615 | + | |
| 614 | 616 | struct perf_regs regs_intr; |
| 615 | 617 | u64 stack_user_size; |
| 616 | 618 | } ____cacheline_aligned; |
| @@ -1,11 +1,19 @@ | ||
| 1 | 1 | #ifndef _LINUX_PERF_REGS_H |
| 2 | 2 | #define _LINUX_PERF_REGS_H |
| 3 | 3 | |
| 4 | +struct perf_regs { | |
| 5 | + __u64 abi; | |
| 6 | + struct pt_regs *regs; | |
| 7 | +}; | |
| 8 | + | |
| 4 | 9 | #ifdef CONFIG_HAVE_PERF_REGS |
| 5 | 10 | #include <asm/perf_regs.h> |
| 6 | 11 | u64 perf_reg_value(struct pt_regs *regs, int idx); |
| 7 | 12 | int perf_reg_validate(u64 mask); |
| 8 | 13 | u64 perf_reg_abi(struct task_struct *task); |
| 14 | +void perf_get_regs_user(struct perf_regs *regs_user, | |
| 15 | + struct pt_regs *regs, | |
| 16 | + struct pt_regs *regs_user_copy); | |
| 9 | 17 | #else |
| 10 | 18 | static inline u64 perf_reg_value(struct pt_regs *regs, int idx) |
| 11 | 19 | { |
| @@ -21,5 +29,13 @@ static inline u64 perf_reg_abi(struct task_struct *task) · 9 unmodified lines | ||
| 21 | 29 | { |
| 22 | 30 | return PERF_SAMPLE_REGS_ABI_NONE; |
| 23 | 31 | } |
| 32 | + | |
| 33 | +static inline void perf_get_regs_user(struct perf_regs *regs_user, | |
| 34 | + struct pt_regs *regs, | |
| 35 | + struct pt_regs *regs_user_copy) | |
| 36 | +{ | |
| 37 | + regs_user->regs = task_pt_regs(current); | |
| 38 | + regs_user->abi = perf_reg_abi(current); | |
| 39 | +} | |
| 24 | 40 | #endif /* CONFIG_HAVE_PERF_REGS */ |
| 25 | 41 | #endif /* _LINUX_PERF_REGS_H */ |
| @@ -36,6 +36,16 @@ struct anon_vma { · 35 unmodified lines | ||
| 36 | 36 | */ |
| 37 | 37 | atomic_t refcount; |
| 38 | 38 | |
| 39 | + /* | |
| 40 | + * Count of child anon_vmas and VMAs which points to this anon_vma. | |
| 41 | + * | |
| 42 | + * This counter is used for making decision about reusing anon_vma | |
| 43 | + * instead of forking new one. See comments in function anon_vma_clone. | |
| 44 | + */ | |
| 45 | + unsigned degree; | |
| 46 | + | |
| 47 | + struct anon_vma *parent; /* Parent of this anon_vma */ | |
| 48 | + | |
| 39 | 49 | /* |
| 40 | 50 | * NOTE: the LSB of the rb_root.rb_node is set by |
| 41 | 51 | * mm_take_all_locks() _after_ taking the above lock. So the |
| @@ -177,7 +177,6 @@ int write_cache_pages(struct address_space *mapping, · 176 unmodified lines | ||
| 177 | 177 | struct writeback_control *wbc, writepage_t writepage, |
| 178 | 178 | void *data); |
| 179 | 179 | int do_writepages(struct address_space *mapping, struct writeback_control *wbc); |
| 180 | −void set_page_dirty_balance(struct page *page); | |
| 181 | 180 | void writeback_set_ratelimit(void); |
| 182 | 181 | void tag_pages_for_writeback(struct address_space *mapping, |
| 183 | 182 | pgoff_t start, pgoff_t end); |
| @@ -1270,8 +1270,7 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); · 1269 unmodified lines | ||
| 1270 | 1270 | * |
| 1271 | 1271 | * @IEEE80211_KEY_FLAG_GENERATE_IV: This flag should be set by the |
| 1272 | 1272 | * driver to indicate that it requires IV generation for this |
| 1273 | − * particular key. Setting this flag does not necessarily mean that SKBs | |
| 1274 | − * will have sufficient tailroom for ICV or MIC. | |
| 1273 | + * particular key. | |
| 1275 | 1274 | * @IEEE80211_KEY_FLAG_GENERATE_MMIC: This flag should be set by |
| 1276 | 1275 | * the driver for a TKIP key if it requires Michael MIC |
| 1277 | 1276 | * generation in software. |
| @@ -1283,9 +1282,7 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); · 5 unmodified lines | ||
| 1283 | 1282 | * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver |
| 1284 | 1283 | * if space should be prepared for the IV, but the IV |
| 1285 | 1284 | * itself should not be generated. Do not set together with |
| 1286 | − * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. Setting this flag does | |
| 1287 | − * not necessarily mean that SKBs will have sufficient tailroom for ICV or | |
| 1288 | − * MIC. | |
| 1285 | + * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. | |
| 1289 | 1286 | * @IEEE80211_KEY_FLAG_RX_MGMT: This key will be used to decrypt received |
| 1290 | 1287 | * management frames. The flag can help drivers that have a hardware |
| 1291 | 1288 | * crypto implementation that doesn't deal with management frames |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | /* |
| 7 | 7 | * FMODE_EXEC is 0x20 |
| 8 | − * FMODE_NONOTIFY is 0x1000000 | |
| 8 | + * FMODE_NONOTIFY is 0x4000000 | |
| 9 | 9 | * These cannot be used by userspace O_* until internal and external open |
| 10 | 10 | * flags are split. |
| 11 | 11 | * -Eric Paris |
| @@ -128,27 +128,34 @@ struct kfd_ioctl_get_process_apertures_args { · 127 unmodified lines | ||
| 128 | 128 | uint32_t pad; |
| 129 | 129 | }; |
| 130 | 130 | |
| 131 | −#define KFD_IOC_MAGIC 'K' | |
| 131 | +#define AMDKFD_IOCTL_BASE 'K' | |
| 132 | +#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr) | |
| 133 | +#define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type) | |
| 134 | +#define AMDKFD_IOW(nr, type) _IOW(AMDKFD_IOCTL_BASE, nr, type) | |
| 135 | +#define AMDKFD_IOWR(nr, type) _IOWR(AMDKFD_IOCTL_BASE, nr, type) | |
| 132 | 136 | |
| 133 | −#define KFD_IOC_GET_VERSION \ | |
| 134 | − _IOR(KFD_IOC_MAGIC, 1, struct kfd_ioctl_get_version_args) | |
| 137 | +#define AMDKFD_IOC_GET_VERSION \ | |
| 138 | + AMDKFD_IOR(0x01, struct kfd_ioctl_get_version_args) | |
| 135 | 139 | |
| 136 | −#define KFD_IOC_CREATE_QUEUE \ | |
| 137 | − _IOWR(KFD_IOC_MAGIC, 2, struct kfd_ioctl_create_queue_args) | |
| 140 | +#define AMDKFD_IOC_CREATE_QUEUE \ | |
| 141 | + AMDKFD_IOWR(0x02, struct kfd_ioctl_create_queue_args) | |
| 138 | 142 | |
| 139 | −#define KFD_IOC_DESTROY_QUEUE \ | |
| 140 | − _IOWR(KFD_IOC_MAGIC, 3, struct kfd_ioctl_destroy_queue_args) | |
| 143 | +#define AMDKFD_IOC_DESTROY_QUEUE \ | |
| 144 | + AMDKFD_IOWR(0x03, struct kfd_ioctl_destroy_queue_args) | |
| 141 | 145 | |
| 142 | −#define KFD_IOC_SET_MEMORY_POLICY \ | |
| 143 | − _IOW(KFD_IOC_MAGIC, 4, struct kfd_ioctl_set_memory_policy_args) | |
| 146 | +#define AMDKFD_IOC_SET_MEMORY_POLICY \ | |
| 147 | + AMDKFD_IOW(0x04, struct kfd_ioctl_set_memory_policy_args) | |
| 144 | 148 | |
| 145 | −#define KFD_IOC_GET_CLOCK_COUNTERS \ | |
| 146 | − _IOWR(KFD_IOC_MAGIC, 5, struct kfd_ioctl_get_clock_counters_args) | |
| 149 | +#define AMDKFD_IOC_GET_CLOCK_COUNTERS \ | |
| 150 | + AMDKFD_IOWR(0x05, struct kfd_ioctl_get_clock_counters_args) | |
| 147 | 151 | |
| 148 | −#define KFD_IOC_GET_PROCESS_APERTURES \ | |
| 149 | − _IOR(KFD_IOC_MAGIC, 6, struct kfd_ioctl_get_process_apertures_args) | |
| 152 | +#define AMDKFD_IOC_GET_PROCESS_APERTURES \ | |
| 153 | + AMDKFD_IOR(0x06, struct kfd_ioctl_get_process_apertures_args) | |
| 150 | 154 | |
| 151 | −#define KFD_IOC_UPDATE_QUEUE \ | |
| 152 | − _IOW(KFD_IOC_MAGIC, 7, struct kfd_ioctl_update_queue_args) | |
| 155 | +#define AMDKFD_IOC_UPDATE_QUEUE \ | |
| 156 | + AMDKFD_IOW(0x07, struct kfd_ioctl_update_queue_args) | |
| 157 | + | |
| 158 | +#define AMDKFD_COMMAND_START 0x01 | |
| 159 | +#define AMDKFD_COMMAND_END 0x08 | |
| 153 | 160 | |
| 154 | 161 | #endif |
| @@ -27,6 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | * version 2. This program is licensed "as is" without any warranty of any |
| 28 | 28 | * kind, whether express or implied. |
| 29 | 29 | */ |
| 30 | + | |
| 31 | +#define pr_fmt(fmt) "KGDB: " fmt | |
| 32 | + | |
| 30 | 33 | #include <linux/pid_namespace.h> |
| 31 | 34 | #include <linux/clocksource.h> |
| 32 | 35 | #include <linux/serial_core.h> |
| @@ -196,8 +199,8 @@ int __weak kgdb_validate_break_address(unsigned long addr) · 163 unmodified lines | ||
| 196 | 199 | return err; |
| 197 | 200 | err = kgdb_arch_remove_breakpoint(&tmp); |
| 198 | 201 | if (err) |
| 199 | − printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " | |
| 200 | − "memory destroyed at: %lx", addr); | |
| 202 | + pr_err("Critical breakpoint error, kernel memory destroyed at: %lx\n", | |
| 203 | + addr); | |
| 201 | 204 | return err; |
| 202 | 205 | } |
| 203 | 206 | |
| @@ -256,8 +259,8 @@ int dbg_activate_sw_breakpoints(void) · 52 unmodified lines | ||
| 256 | 259 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); |
| 257 | 260 | if (error) { |
| 258 | 261 | ret = error; |
| 259 | − printk(KERN_INFO "KGDB: BP install failed: %lx", | |
| 260 | − kgdb_break[i].bpt_addr); | |
| 262 | + pr_info("BP install failed: %lx\n", | |
| 263 | + kgdb_break[i].bpt_addr); | |
| 261 | 264 | continue; |
| 262 | 265 | } |
| 263 | 266 | |
| @@ -319,8 +322,8 @@ int dbg_deactivate_sw_breakpoints(void) · 55 unmodified lines | ||
| 319 | 322 | continue; |
| 320 | 323 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
| 321 | 324 | if (error) { |
| 322 | − printk(KERN_INFO "KGDB: BP remove failed: %lx\n", | |
| 323 | − kgdb_break[i].bpt_addr); | |
| 325 | + pr_info("BP remove failed: %lx\n", | |
| 326 | + kgdb_break[i].bpt_addr); | |
| 324 | 327 | ret = error; |
| 325 | 328 | } |
| 326 | 329 | |
| @@ -367,7 +370,7 @@ int dbg_remove_all_break(void) · 40 unmodified lines | ||
| 367 | 370 | goto setundefined; |
| 368 | 371 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
| 369 | 372 | if (error) |
| 370 | − printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", | |
| 373 | + pr_err("breakpoint remove failed: %lx\n", | |
| 371 | 374 | kgdb_break[i].bpt_addr); |
| 372 | 375 | setundefined: |
| 373 | 376 | kgdb_break[i].state = BP_UNDEFINED; |
| @@ -400,9 +403,9 @@ static int kgdb_io_ready(int print_wait) · 26 unmodified lines | ||
| 400 | 403 | if (print_wait) { |
| 401 | 404 | #ifdef CONFIG_KGDB_KDB |
| 402 | 405 | if (!dbg_kdb_mode) |
| 403 | − printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); | |
| 406 | + pr_crit("waiting... or $3#33 for KDB\n"); | |
| 404 | 407 | #else |
| 405 | − printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); | |
| 408 | + pr_crit("Waiting for remote debugger\n"); | |
| 406 | 409 | #endif |
| 407 | 410 | } |
| 408 | 411 | return 1; |
| @@ -430,8 +433,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) · 21 unmodified lines | ||
| 430 | 433 | exception_level = 0; |
| 431 | 434 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); |
| 432 | 435 | dbg_activate_sw_breakpoints(); |
| 433 | − printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", | |
| 434 | − addr); | |
| 436 | + pr_crit("re-enter error: breakpoint removed %lx\n", addr); | |
| 435 | 437 | WARN_ON_ONCE(1); |
| 436 | 438 | |
| 437 | 439 | return 1; |
| @@ -444,7 +446,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) · 6 unmodified lines | ||
| 444 | 446 | panic("Recursive entry to debugger"); |
| 445 | 447 | } |
| 446 | 448 | |
| 447 | − printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); | |
| 449 | + pr_crit("re-enter exception: ALL breakpoints killed\n"); | |
| 448 | 450 | #ifdef CONFIG_KGDB_KDB |
| 449 | 451 | /* Allow kdb to debug itself one level */ |
| 450 | 452 | return 0; |
| @@ -471,6 +473,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, · 20 unmodified lines | ||
| 471 | 473 | int cpu; |
| 472 | 474 | int trace_on = 0; |
| 473 | 475 | int online_cpus = num_online_cpus(); |
| 476 | + u64 time_left; | |
| 474 | 477 | |
| 475 | 478 | kgdb_info[ks->cpu].enter_kgdb++; |
| 476 | 479 | kgdb_info[ks->cpu].exception_state |= exception_state; |
| @@ -595,9 +598,13 @@ return_normal: · 118 unmodified lines | ||
| 595 | 598 | /* |
| 596 | 599 | * Wait for the other CPUs to be notified and be waiting for us: |
| 597 | 600 | */ |
| 598 | − while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + | |
| 599 | − atomic_read(&slaves_in_kgdb)) != online_cpus) | |
| 601 | + time_left = loops_per_jiffy * HZ; | |
| 602 | + while (kgdb_do_roundup && --time_left && | |
| 603 | + (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) != | |
| 604 | + online_cpus) | |
| 600 | 605 | cpu_relax(); |
| 606 | + if (!time_left) | |
| 607 | + pr_crit("KGDB: Timed out waiting for secondary CPUs.\n"); | |
| 601 | 608 | |
| 602 | 609 | /* |
| 603 | 610 | * At this point the primary processor is completely |
| @@ -795,15 +802,15 @@ static struct console kgdbcons = { · 191 unmodified lines | ||
| 795 | 802 | static void sysrq_handle_dbg(int key) |
| 796 | 803 | { |
| 797 | 804 | if (!dbg_io_ops) { |
| 798 | − printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); | |
| 805 | + pr_crit("ERROR: No KGDB I/O module available\n"); | |
| 799 | 806 | return; |
| 800 | 807 | } |
| 801 | 808 | if (!kgdb_connected) { |
| 802 | 809 | #ifdef CONFIG_KGDB_KDB |
| 803 | 810 | if (!dbg_kdb_mode) |
| 804 | − printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); | |
| 811 | + pr_crit("KGDB or $3#33 for KDB\n"); | |
| 805 | 812 | #else |
| 806 | − printk(KERN_CRIT "Entering KGDB\n"); | |
| 813 | + pr_crit("Entering KGDB\n"); | |
| 807 | 814 | #endif |
| 808 | 815 | } |
| 809 | 816 | |
| @@ -945,7 +952,7 @@ static void kgdb_initial_breakpoint(void) · 135 unmodified lines | ||
| 945 | 952 | { |
| 946 | 953 | kgdb_break_asap = 0; |
| 947 | 954 | |
| 948 | − printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); | |
| 955 | + pr_crit("Waiting for connection from remote gdb...\n"); | |
| 949 | 956 | kgdb_breakpoint(); |
| 950 | 957 | } |
| 951 | 958 | |
| @@ -964,8 +971,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) · 12 unmodified lines | ||
| 964 | 971 | if (dbg_io_ops) { |
| 965 | 972 | spin_unlock(&kgdb_registration_lock); |
| 966 | 973 | |
| 967 | − printk(KERN_ERR "kgdb: Another I/O driver is already " | |
| 968 | − "registered with KGDB.\n"); | |
| 974 | + pr_err("Another I/O driver is already registered with KGDB\n"); | |
| 969 | 975 | return -EBUSY; |
| 970 | 976 | } |
| 971 | 977 | |
| @@ -981,8 +987,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) · 9 unmodified lines | ||
| 981 | 987 | |
| 982 | 988 | spin_unlock(&kgdb_registration_lock); |
| 983 | 989 | |
| 984 | − printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", | |
| 985 | − new_dbg_io_ops->name); | |
| 990 | + pr_info("Registered I/O driver %s\n", new_dbg_io_ops->name); | |
| 986 | 991 | |
| 987 | 992 | /* Arm KGDB now. */ |
| 988 | 993 | kgdb_register_callbacks(); |
| @@ -1017,8 +1022,7 @@ void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops) · 28 unmodified lines | ||
| 1017 | 1022 | |
| 1018 | 1023 | spin_unlock(&kgdb_registration_lock); |
| 1019 | 1024 | |
| 1020 | − printk(KERN_INFO | |
| 1021 | − "kgdb: Unregistered I/O driver %s, debugger disabled.\n", | |
| 1025 | + pr_info("Unregistered I/O driver %s, debugger disabled\n", | |
| 1022 | 1026 | old_dbg_io_ops->name); |
| 1023 | 1027 | } |
| 1024 | 1028 | EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); |
| @@ -531,22 +531,29 @@ void __init kdb_initbptab(void) · 530 unmodified lines | ||
| 531 | 531 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) |
| 532 | 532 | bp->bp_free = 1; |
| 533 | 533 | |
| 534 | − kdb_register_repeat("bp", kdb_bp, "[<vaddr>]", | |
| 535 | − "Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS); | |
| 536 | − kdb_register_repeat("bl", kdb_bp, "[<vaddr>]", | |
| 537 | − "Display breakpoints", 0, KDB_REPEAT_NO_ARGS); | |
| 534 | + kdb_register_flags("bp", kdb_bp, "[<vaddr>]", | |
| 535 | + "Set/Display breakpoints", 0, | |
| 536 | + KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | |
| 537 | + kdb_register_flags("bl", kdb_bp, "[<vaddr>]", | |
| 538 | + "Display breakpoints", 0, | |
| 539 | + KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | |
| 538 | 540 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) |
| 539 | − kdb_register_repeat("bph", kdb_bp, "[<vaddr>]", | |
| 540 | − "[datar [length]|dataw [length]] Set hw brk", 0, KDB_REPEAT_NO_ARGS); | |
| 541 | − kdb_register_repeat("bc", kdb_bc, "<bpnum>", | |
| 542 | − "Clear Breakpoint", 0, KDB_REPEAT_NONE); | |
| 543 | − kdb_register_repeat("be", kdb_bc, "<bpnum>", | |
| 544 | − "Enable Breakpoint", 0, KDB_REPEAT_NONE); | |
| 545 | − kdb_register_repeat("bd", kdb_bc, "<bpnum>", | |
| 546 | − "Disable Breakpoint", 0, KDB_REPEAT_NONE); | |
| 547 | − | |
| 548 | − kdb_register_repeat("ss", kdb_ss, "", | |
| 549 | − "Single Step", 1, KDB_REPEAT_NO_ARGS); | |
| 541 | + kdb_register_flags("bph", kdb_bp, "[<vaddr>]", | |
| 542 | + "[datar [length]|dataw [length]] Set hw brk", 0, | |
| 543 | + KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | |
| 544 | + kdb_register_flags("bc", kdb_bc, "<bpnum>", | |
| 545 | + "Clear Breakpoint", 0, | |
| 546 | + KDB_ENABLE_FLOW_CTRL); | |
| 547 | + kdb_register_flags("be", kdb_bc, "<bpnum>", | |
| 548 | + "Enable Breakpoint", 0, | |
| 549 | + KDB_ENABLE_FLOW_CTRL); | |
| 550 | + kdb_register_flags("bd", kdb_bc, "<bpnum>", | |
| 551 | + "Disable Breakpoint", 0, | |
| 552 | + KDB_ENABLE_FLOW_CTRL); | |
| 553 | + | |
| 554 | + kdb_register_flags("ss", kdb_ss, "", | |
| 555 | + "Single Step", 1, | |
| 556 | + KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); | |
| 550 | 557 | /* |
| 551 | 558 | * Architecture dependent initialization. |
| 552 | 559 | */ |
| @@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks) · 128 unmodified lines | ||
| 129 | 129 | ks->pass_exception = 1; |
| 130 | 130 | KDB_FLAG_SET(CATASTROPHIC); |
| 131 | 131 | } |
| 132 | + /* set CATASTROPHIC if the system contains unresponsive processors */ | |
| 133 | + for_each_online_cpu(i) | |
| 134 | + if (!kgdb_info[i].enter_kgdb) | |
| 135 | + KDB_FLAG_SET(CATASTROPHIC); | |
| 132 | 136 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { |
| 133 | 137 | KDB_STATE_CLEAR(SSBPT); |
| 134 | 138 | KDB_STATE_CLEAR(DOING_SS); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | #include <linux/ctype.h> |
| 15 | +#include <linux/types.h> | |
| 15 | 16 | #include <linux/string.h> |
| 16 | 17 | #include <linux/kernel.h> |
| 17 | 18 | #include <linux/kmsg_dump.h> |
| @@ -23,6 +24,7 @@ · 5 unmodified lines | ||
| 23 | 24 | #include <linux/vmalloc.h> |
| 24 | 25 | #include <linux/atomic.h> |
| 25 | 26 | #include <linux/module.h> |
| 27 | +#include <linux/moduleparam.h> | |
| 26 | 28 | #include <linux/mm.h> |
| 27 | 29 | #include <linux/init.h> |
| 28 | 30 | #include <linux/kallsyms.h> |
| @@ -42,6 +44,12 @@ · 13 unmodified lines | ||
| 42 | 44 | #include <linux/slab.h> |
| 43 | 45 | #include "kdb_private.h" |
| 44 | 46 | |
| 47 | +#undef MODULE_PARAM_PREFIX | |
| 48 | +#define MODULE_PARAM_PREFIX "kdb." | |
| 49 | + | |
| 50 | +static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; | |
| 51 | +module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); | |
| 52 | + | |
| 45 | 53 | #define GREP_LEN 256 |
| 46 | 54 | char kdb_grep_string[GREP_LEN]; |
| 47 | 55 | int kdb_grepping_flag; |
| @@ -121,6 +129,7 @@ static kdbmsg_t kdbmsgs[] = { · 73 unmodified lines | ||
| 121 | 129 | KDBMSG(BADLENGTH, "Invalid length field"), |
| 122 | 130 | KDBMSG(NOBP, "No Breakpoint exists"), |
| 123 | 131 | KDBMSG(BADADDR, "Invalid address"), |
| 132 | + KDBMSG(NOPERM, "Permission denied"), | |
| 124 | 133 | }; |
| 125 | 134 | #undef KDBMSG |
| 126 | 135 | |
| @@ -187,6 +196,26 @@ struct task_struct *kdb_curr_task(int cpu) · 60 unmodified lines | ||
| 187 | 196 | return p; |
| 188 | 197 | } |
| 189 | 198 | |
| 199 | +/* | |
| 200 | + * Check whether the flags of the current command and the permissions | |
| 201 | + * of the kdb console has allow a command to be run. | |
| 202 | + */ | |
| 203 | +static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions, | |
| 204 | + bool no_args) | |
| 205 | +{ | |
| 206 | + /* permissions comes from userspace so needs massaging slightly */ | |
| 207 | + permissions &= KDB_ENABLE_MASK; | |
| 208 | + permissions |= KDB_ENABLE_ALWAYS_SAFE; | |
| 209 | + | |
| 210 | + /* some commands change group when launched with no arguments */ | |
| 211 | + if (no_args) | |
| 212 | + permissions |= permissions << KDB_ENABLE_NO_ARGS_SHIFT; | |
| 213 | + | |
| 214 | + flags |= KDB_ENABLE_ALL; | |
| 215 | + | |
| 216 | + return permissions & flags; | |
| 217 | +} | |
| 218 | + | |
| 190 | 219 | /* |
| 191 | 220 | * kdbgetenv - This function will return the character string value of |
| 192 | 221 | * an environment variable. |
| @@ -475,6 +504,15 @@ int kdbgetaddrarg(int argc, const char **argv, int *nextarg, · 282 unmodified lines | ||
| 475 | 504 | char *cp; |
| 476 | 505 | kdb_symtab_t symtab; |
| 477 | 506 | |
| 507 | + /* | |
| 508 | + * If the enable flags prohibit both arbitrary memory access | |
| 509 | + * and flow control then there are no reasonable grounds to | |
| 510 | + * provide symbol lookup. | |
| 511 | + */ | |
| 512 | + if (!kdb_check_flags(KDB_ENABLE_MEM_READ | KDB_ENABLE_FLOW_CTRL, | |
| 513 | + kdb_cmd_enabled, false)) | |
| 514 | + return KDB_NOPERM; | |
| 515 | + | |
| 478 | 516 | /* |
| 479 | 517 | * Process arguments which follow the following syntax: |
| 480 | 518 | * |
| @@ -641,8 +679,13 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) · 160 unmodified lines | ||
| 641 | 679 | if (!s->count) |
| 642 | 680 | s->usable = 0; |
| 643 | 681 | if (s->usable) |
| 644 | − kdb_register(s->name, kdb_exec_defcmd, | |
| 645 | − s->usage, s->help, 0); | |
| 682 | + /* macros are always safe because when executed each | |
| 683 | + * internal command re-enters kdb_parse() and is | |
| 684 | + * safety checked individually. | |
| 685 | + */ | |
| 686 | + kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, | |
| 687 | + s->help, 0, | |
| 688 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 646 | 689 | return 0; |
| 647 | 690 | } |
| 648 | 691 | if (!s->usable) |
| @@ -1003,25 +1046,22 @@ int kdb_parse(const char *cmdstr) · 354 unmodified lines | ||
| 1003 | 1046 | |
| 1004 | 1047 | if (i < kdb_max_commands) { |
| 1005 | 1048 | int result; |
| 1049 | + | |
| 1050 | + if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) | |
| 1051 | + return KDB_NOPERM; | |
| 1052 | + | |
| 1006 | 1053 | KDB_STATE_SET(CMD); |
| 1007 | 1054 | result = (*tp->cmd_func)(argc-1, (const char **)argv); |
| 1008 | 1055 | if (result && ignore_errors && result > KDB_CMD_GO) |
| 1009 | 1056 | result = 0; |
| 1010 | 1057 | KDB_STATE_CLEAR(CMD); |
| 1011 | − switch (tp->cmd_repeat) { | |
| 1012 | − case KDB_REPEAT_NONE: | |
| 1013 | − argc = 0; | |
| 1014 | − if (argv[0]) | |
| 1015 | − *(argv[0]) = '\0'; | |
| 1016 | − break; | |
| 1017 | − case KDB_REPEAT_NO_ARGS: | |
| 1018 | − argc = 1; | |
| 1019 | − if (argv[1]) | |
| 1020 | − *(argv[1]) = '\0'; | |
| 1021 | − break; | |
| 1022 | − case KDB_REPEAT_WITH_ARGS: | |
| 1023 | − break; | |
| 1024 | − } | |
| 1058 | + | |
| 1059 | + if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) | |
| 1060 | + return result; | |
| 1061 | + | |
| 1062 | + argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; | |
| 1063 | + if (argv[argc]) | |
| 1064 | + *(argv[argc]) = '\0'; | |
| 1025 | 1065 | return result; |
| 1026 | 1066 | } |
| 1027 | 1067 | |
| @@ -1921,10 +1961,14 @@ static int kdb_rm(int argc, const char **argv) · 893 unmodified lines | ||
| 1921 | 1961 | */ |
| 1922 | 1962 | static int kdb_sr(int argc, const char **argv) |
| 1923 | 1963 | { |
| 1964 | + bool check_mask = | |
| 1965 | + !kdb_check_flags(KDB_ENABLE_ALL, kdb_cmd_enabled, false); | |
| 1966 | + | |
| 1924 | 1967 | if (argc != 1) |
| 1925 | 1968 | return KDB_ARGCOUNT; |
| 1969 | + | |
| 1926 | 1970 | kdb_trap_printk++; |
| 1927 | − __handle_sysrq(*argv[1], false); | |
| 1971 | + __handle_sysrq(*argv[1], check_mask); | |
| 1928 | 1972 | kdb_trap_printk--; |
| 1929 | 1973 | |
| 1930 | 1974 | return 0; |
| @@ -2157,6 +2201,8 @@ static void kdb_cpu_status(void) · 226 unmodified lines | ||
| 2157 | 2201 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { |
| 2158 | 2202 | if (!cpu_online(i)) { |
| 2159 | 2203 | state = 'F'; /* cpu is offline */ |
| 2204 | + } else if (!kgdb_info[i].enter_kgdb) { | |
| 2205 | + state = 'D'; /* cpu is online but unresponsive */ | |
| 2160 | 2206 | } else { |
| 2161 | 2207 | state = ' '; /* cpu is responding to kdb */ |
| 2162 | 2208 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') |
| @@ -2210,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv) · 47 unmodified lines | ||
| 2210 | 2256 | /* |
| 2211 | 2257 | * Validate cpunum |
| 2212 | 2258 | */ |
| 2213 | − if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) | |
| 2259 | + if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb) | |
| 2214 | 2260 | return KDB_BADCPUNUM; |
| 2215 | 2261 | |
| 2216 | 2262 | dbg_switch_cpu = cpunum; |
| @@ -2375,6 +2421,8 @@ static int kdb_help(int argc, const char **argv) · 158 unmodified lines | ||
| 2375 | 2421 | return 0; |
| 2376 | 2422 | if (!kt->cmd_name) |
| 2377 | 2423 | continue; |
| 2424 | + if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) | |
| 2425 | + continue; | |
| 2378 | 2426 | if (strlen(kt->cmd_usage) > 20) |
| 2379 | 2427 | space = "\n "; |
| 2380 | 2428 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, |
| @@ -2629,7 +2677,7 @@ static int kdb_grep_help(int argc, const char **argv) · 248 unmodified lines | ||
| 2629 | 2677 | } |
| 2630 | 2678 | |
| 2631 | 2679 | /* |
| 2632 | − * kdb_register_repeat - This function is used to register a kernel | |
| 2680 | + * kdb_register_flags - This function is used to register a kernel | |
| 2633 | 2681 | * debugger command. |
| 2634 | 2682 | * Inputs: |
| 2635 | 2683 | * cmd Command name |
| @@ -2641,12 +2689,12 @@ static int kdb_grep_help(int argc, const char **argv) · 5 unmodified lines | ||
| 2641 | 2689 | * zero for success, one if a duplicate command. |
| 2642 | 2690 | */ |
| 2643 | 2691 | #define kdb_command_extend 50 /* arbitrary */ |
| 2644 | −int kdb_register_repeat(char *cmd, | |
| 2645 | − kdb_func_t func, | |
| 2646 | − char *usage, | |
| 2647 | − char *help, | |
| 2648 | − short minlen, | |
| 2649 | − kdb_repeat_t repeat) | |
| 2692 | +int kdb_register_flags(char *cmd, | |
| 2693 | + kdb_func_t func, | |
| 2694 | + char *usage, | |
| 2695 | + char *help, | |
| 2696 | + short minlen, | |
| 2697 | + kdb_cmdflags_t flags) | |
| 2650 | 2698 | { |
| 2651 | 2699 | int i; |
| 2652 | 2700 | kdbtab_t *kp; |
| @@ -2694,19 +2742,18 @@ int kdb_register_repeat(char *cmd, · 41 unmodified lines | ||
| 2694 | 2742 | kp->cmd_func = func; |
| 2695 | 2743 | kp->cmd_usage = usage; |
| 2696 | 2744 | kp->cmd_help = help; |
| 2697 | − kp->cmd_flags = 0; | |
| 2698 | 2745 | kp->cmd_minlen = minlen; |
| 2699 | − kp->cmd_repeat = repeat; | |
| 2746 | + kp->cmd_flags = flags; | |
| 2700 | 2747 | |
| 2701 | 2748 | return 0; |
| 2702 | 2749 | } |
| 2703 | −EXPORT_SYMBOL_GPL(kdb_register_repeat); | |
| 2750 | +EXPORT_SYMBOL_GPL(kdb_register_flags); | |
| 2704 | 2751 | |
| 2705 | 2752 | |
| 2706 | 2753 | /* |
| 2707 | 2754 | * kdb_register - Compatibility register function for commands that do |
| 2708 | 2755 | * not need to specify a repeat state. Equivalent to |
| 2709 | − * kdb_register_repeat with KDB_REPEAT_NONE. | |
| 2756 | + * kdb_register_flags with flags set to 0. | |
| 2710 | 2757 | * Inputs: |
| 2711 | 2758 | * cmd Command name |
| 2712 | 2759 | * func Function to execute the command |
| @@ -2721,8 +2768,7 @@ int kdb_register(char *cmd, · 8 unmodified lines | ||
| 2721 | 2768 | char *help, |
| 2722 | 2769 | short minlen) |
| 2723 | 2770 | { |
| 2724 | − return kdb_register_repeat(cmd, func, usage, help, minlen, | |
| 2725 | − KDB_REPEAT_NONE); | |
| 2771 | + return kdb_register_flags(cmd, func, usage, help, minlen, 0); | |
| 2726 | 2772 | } |
| 2727 | 2773 | EXPORT_SYMBOL_GPL(kdb_register); |
| 2728 | 2774 | |
| @@ -2764,80 +2810,109 @@ static void __init kdb_inittab(void) · 35 unmodified lines | ||
| 2764 | 2810 | for_each_kdbcmd(kp, i) |
| 2765 | 2811 | kp->cmd_name = NULL; |
| 2766 | 2812 | |
| 2767 | − kdb_register_repeat("md", kdb_md, "<vaddr>", | |
| 2813 | + kdb_register_flags("md", kdb_md, "<vaddr>", | |
| 2768 | 2814 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, |
| 2769 | − KDB_REPEAT_NO_ARGS); | |
| 2770 | − kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", | |
| 2771 | − "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); | |
| 2772 | − kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", | |
| 2773 | − "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); | |
| 2774 | − kdb_register_repeat("mds", kdb_md, "<vaddr>", | |
| 2775 | − "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); | |
| 2776 | − kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", | |
| 2777 | − "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); | |
| 2778 | − kdb_register_repeat("go", kdb_go, "[<vaddr>]", | |
| 2779 | − "Continue Execution", 1, KDB_REPEAT_NONE); | |
| 2780 | − kdb_register_repeat("rd", kdb_rd, "", | |
| 2781 | − "Display Registers", 0, KDB_REPEAT_NONE); | |
| 2782 | − kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", | |
| 2783 | − "Modify Registers", 0, KDB_REPEAT_NONE); | |
| 2784 | − kdb_register_repeat("ef", kdb_ef, "<vaddr>", | |
| 2785 | − "Display exception frame", 0, KDB_REPEAT_NONE); | |
| 2786 | − kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", | |
| 2787 | − "Stack traceback", 1, KDB_REPEAT_NONE); | |
| 2788 | − kdb_register_repeat("btp", kdb_bt, "<pid>", | |
| 2789 | − "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | |
| 2790 | − kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", | |
| 2791 | − "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); | |
| 2792 | − kdb_register_repeat("btc", kdb_bt, "", | |
| 2793 | − "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | |
| 2794 | − kdb_register_repeat("btt", kdb_bt, "<vaddr>", | |
| 2815 | + KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); | |
| 2816 | + kdb_register_flags("mdr", kdb_md, "<vaddr> <bytes>", | |
| 2817 | + "Display Raw Memory", 0, | |
| 2818 | + KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); | |
| 2819 | + kdb_register_flags("mdp", kdb_md, "<paddr> <bytes>", | |
| 2820 | + "Display Physical Memory", 0, | |
| 2821 | + KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); | |
| 2822 | + kdb_register_flags("mds", kdb_md, "<vaddr>", | |
| 2823 | + "Display Memory Symbolically", 0, | |
| 2824 | + KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); | |
| 2825 | + kdb_register_flags("mm", kdb_mm, "<vaddr> <contents>", | |
| 2826 | + "Modify Memory Contents", 0, | |
| 2827 | + KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS); | |
| 2828 | + kdb_register_flags("go", kdb_go, "[<vaddr>]", | |
| 2829 | + "Continue Execution", 1, | |
| 2830 | + KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); | |
| 2831 | + kdb_register_flags("rd", kdb_rd, "", | |
| 2832 | + "Display Registers", 0, | |
| 2833 | + KDB_ENABLE_REG_READ); | |
| 2834 | + kdb_register_flags("rm", kdb_rm, "<reg> <contents>", | |
| 2835 | + "Modify Registers", 0, | |
| 2836 | + KDB_ENABLE_REG_WRITE); | |
| 2837 | + kdb_register_flags("ef", kdb_ef, "<vaddr>", | |
| 2838 | + "Display exception frame", 0, | |
| 2839 | + KDB_ENABLE_MEM_READ); | |
| 2840 | + kdb_register_flags("bt", kdb_bt, "[<vaddr>]", | |
| 2841 | + "Stack traceback", 1, | |
| 2842 | + KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); | |
| 2843 | + kdb_register_flags("btp", kdb_bt, "<pid>", | |
| 2844 | + "Display stack for process <pid>", 0, | |
| 2845 | + KDB_ENABLE_INSPECT); | |
| 2846 | + kdb_register_flags("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", | |
| 2847 | + "Backtrace all processes matching state flag", 0, | |
| 2848 | + KDB_ENABLE_INSPECT); | |
| 2849 | + kdb_register_flags("btc", kdb_bt, "", | |
| 2850 | + "Backtrace current process on each cpu", 0, | |
| 2851 | + KDB_ENABLE_INSPECT); | |
| 2852 | + kdb_register_flags("btt", kdb_bt, "<vaddr>", | |
| 2795 | 2853 | "Backtrace process given its struct task address", 0, |
| 2796 | − KDB_REPEAT_NONE); | |
| 2797 | − kdb_register_repeat("env", kdb_env, "", | |
| 2798 | − "Show environment variables", 0, KDB_REPEAT_NONE); | |
| 2799 | − kdb_register_repeat("set", kdb_set, "", | |
| 2800 | − "Set environment variables", 0, KDB_REPEAT_NONE); | |
| 2801 | − kdb_register_repeat("help", kdb_help, "", | |
| 2802 | − "Display Help Message", 1, KDB_REPEAT_NONE); | |
| 2803 | − kdb_register_repeat("?", kdb_help, "", | |
| 2804 | − "Display Help Message", 0, KDB_REPEAT_NONE); | |
| 2805 | − kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", | |
| 2806 | − "Switch to new cpu", 0, KDB_REPEAT_NONE); | |
| 2807 | − kdb_register_repeat("kgdb", kdb_kgdb, "", | |
| 2808 | − "Enter kgdb mode", 0, KDB_REPEAT_NONE); | |
| 2809 | − kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", | |
| 2810 | − "Display active task list", 0, KDB_REPEAT_NONE); | |
| 2811 | − kdb_register_repeat("pid", kdb_pid, "<pidnum>", | |
| 2812 | − "Switch to another task", 0, KDB_REPEAT_NONE); | |
| 2813 | − kdb_register_repeat("reboot", kdb_reboot, "", | |
| 2814 | − "Reboot the machine immediately", 0, KDB_REPEAT_NONE); | |
| 2854 | + KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); | |
| 2855 | + kdb_register_flags("env", kdb_env, "", | |
| 2856 | + "Show environment variables", 0, | |
| 2857 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2858 | + kdb_register_flags("set", kdb_set, "", | |
| 2859 | + "Set environment variables", 0, | |
| 2860 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2861 | + kdb_register_flags("help", kdb_help, "", | |
| 2862 | + "Display Help Message", 1, | |
| 2863 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2864 | + kdb_register_flags("?", kdb_help, "", | |
| 2865 | + "Display Help Message", 0, | |
| 2866 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2867 | + kdb_register_flags("cpu", kdb_cpu, "<cpunum>", | |
| 2868 | + "Switch to new cpu", 0, | |
| 2869 | + KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); | |
| 2870 | + kdb_register_flags("kgdb", kdb_kgdb, "", | |
| 2871 | + "Enter kgdb mode", 0, 0); | |
| 2872 | + kdb_register_flags("ps", kdb_ps, "[<flags>|A]", | |
| 2873 | + "Display active task list", 0, | |
| 2874 | + KDB_ENABLE_INSPECT); | |
| 2875 | + kdb_register_flags("pid", kdb_pid, "<pidnum>", | |
| 2876 | + "Switch to another task", 0, | |
| 2877 | + KDB_ENABLE_INSPECT); | |
| 2878 | + kdb_register_flags("reboot", kdb_reboot, "", | |
| 2879 | + "Reboot the machine immediately", 0, | |
| 2880 | + KDB_ENABLE_REBOOT); | |
| 2815 | 2881 | #if defined(CONFIG_MODULES) |
| 2816 | − kdb_register_repeat("lsmod", kdb_lsmod, "", | |
| 2817 | − "List loaded kernel modules", 0, KDB_REPEAT_NONE); | |
| 2882 | + kdb_register_flags("lsmod", kdb_lsmod, "", | |
| 2883 | + "List loaded kernel modules", 0, | |
| 2884 | + KDB_ENABLE_INSPECT); | |
| 2818 | 2885 | #endif |
| 2819 | 2886 | #if defined(CONFIG_MAGIC_SYSRQ) |
| 2820 | − kdb_register_repeat("sr", kdb_sr, "<key>", | |
| 2821 | − "Magic SysRq key", 0, KDB_REPEAT_NONE); | |
| 2887 | + kdb_register_flags("sr", kdb_sr, "<key>", | |
| 2888 | + "Magic SysRq key", 0, | |
| 2889 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2822 | 2890 | #endif |
| 2823 | 2891 | #if defined(CONFIG_PRINTK) |
| 2824 | − kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | |
| 2825 | − "Display syslog buffer", 0, KDB_REPEAT_NONE); | |
| 2892 | + kdb_register_flags("dmesg", kdb_dmesg, "[lines]", | |
| 2893 | + "Display syslog buffer", 0, | |
| 2894 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2826 | 2895 | #endif |
| 2827 | 2896 | if (arch_kgdb_ops.enable_nmi) { |
| 2828 | − kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", | |
| 2829 | − "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); | |
| 2830 | − } | |
| 2831 | − kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | |
| 2832 | − "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | |
| 2833 | − kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | |
| 2834 | − "Send a signal to a process", 0, KDB_REPEAT_NONE); | |
| 2835 | − kdb_register_repeat("summary", kdb_summary, "", | |
| 2836 | − "Summarize the system", 4, KDB_REPEAT_NONE); | |
| 2837 | − kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", | |
| 2838 | − "Display per_cpu variables", 3, KDB_REPEAT_NONE); | |
| 2839 | − kdb_register_repeat("grephelp", kdb_grep_help, "", | |
| 2840 | − "Display help on | grep", 0, KDB_REPEAT_NONE); | |
| 2897 | + kdb_register_flags("disable_nmi", kdb_disable_nmi, "", | |
| 2898 | + "Disable NMI entry to KDB", 0, | |
| 2899 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2900 | + } | |
| 2901 | + kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | |
| 2902 | + "Define a set of commands, down to endefcmd", 0, | |
| 2903 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2904 | + kdb_register_flags("kill", kdb_kill, "<-signal> <pid>", | |
| 2905 | + "Send a signal to a process", 0, | |
| 2906 | + KDB_ENABLE_SIGNAL); | |
| 2907 | + kdb_register_flags("summary", kdb_summary, "", | |
| 2908 | + "Summarize the system", 4, | |
| 2909 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2910 | + kdb_register_flags("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", | |
| 2911 | + "Display per_cpu variables", 3, | |
| 2912 | + KDB_ENABLE_MEM_READ); | |
| 2913 | + kdb_register_flags("grephelp", kdb_grep_help, "", | |
| 2914 | + "Display help on | grep", 0, | |
| 2915 | + KDB_ENABLE_ALWAYS_SAFE); | |
| 2841 | 2916 | } |
| 2842 | 2917 | |
| 2843 | 2918 | /* Execute any commands defined in kdb_cmds. */ |
| @@ -172,10 +172,9 @@ typedef struct _kdbtab { · 171 unmodified lines | ||
| 172 | 172 | kdb_func_t cmd_func; /* Function to execute command */ |
| 173 | 173 | char *cmd_usage; /* Usage String for this command */ |
| 174 | 174 | char *cmd_help; /* Help message for this command */ |
| 175 | − short cmd_flags; /* Parsing flags */ | |
| 176 | 175 | short cmd_minlen; /* Minimum legal # command |
| 177 | 176 | * chars required */ |
| 178 | − kdb_repeat_t cmd_repeat; /* Does command auto repeat on enter? */ | |
| 177 | + kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ | |
| 179 | 178 | } kdbtab_t; |
| 180 | 179 | |
| 181 | 180 | extern int kdb_bt(int, const char **); /* KDB display back trace */ |
| @@ -4461,18 +4461,14 @@ perf_output_sample_regs(struct perf_output_handle *handle, · 4460 unmodified lines | ||
| 4461 | 4461 | } |
| 4462 | 4462 | |
| 4463 | 4463 | static void perf_sample_regs_user(struct perf_regs *regs_user, |
| 4464 | − struct pt_regs *regs) | |
| 4464 | + struct pt_regs *regs, | |
| 4465 | + struct pt_regs *regs_user_copy) | |
| 4465 | 4466 | { |
| 4466 | − if (!user_mode(regs)) { | |
| 4467 | − if (current->mm) | |
| 4468 | − regs = task_pt_regs(current); | |
| 4469 | − else | |
| 4470 | − regs = NULL; | |
| 4471 | − } | |
| 4472 | − | |
| 4473 | − if (regs) { | |
| 4474 | − regs_user->abi = perf_reg_abi(current); | |
| 4467 | + if (user_mode(regs)) { | |
| 4468 | + regs_user->abi = perf_reg_abi(current); | |
| 4475 | 4469 | regs_user->regs = regs; |
| 4470 | + } else if (current->mm) { | |
| 4471 | + perf_get_regs_user(regs_user, regs, regs_user_copy); | |
| 4476 | 4472 | } else { |
| 4477 | 4473 | regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; |
| 4478 | 4474 | regs_user->regs = NULL; |
| @@ -4951,7 +4947,8 @@ void perf_prepare_sample(struct perf_event_header *header, · 472 unmodified lines | ||
| 4951 | 4947 | } |
| 4952 | 4948 | |
| 4953 | 4949 | if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) |
| 4954 | − perf_sample_regs_user(&data->regs_user, regs); | |
| 4950 | + perf_sample_regs_user(&data->regs_user, regs, | |
| 4951 | + &data->regs_user_copy); | |
| 4955 | 4952 | |
| 4956 | 4953 | if (sample_type & PERF_SAMPLE_REGS_USER) { |
| 4957 | 4954 | /* regs dump ABI info */ |
| @@ -1287,9 +1287,15 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) · 1286 unmodified lines | ||
| 1287 | 1287 | static int wait_consider_task(struct wait_opts *wo, int ptrace, |
| 1288 | 1288 | struct task_struct *p) |
| 1289 | 1289 | { |
| 1290 | + /* | |
| 1291 | + * We can race with wait_task_zombie() from another thread. | |
| 1292 | + * Ensure that EXIT_ZOMBIE -> EXIT_DEAD/EXIT_TRACE transition | |
| 1293 | + * can't confuse the checks below. | |
| 1294 | + */ | |
| 1295 | + int exit_state = ACCESS_ONCE(p->exit_state); | |
| 1290 | 1296 | int ret; |
| 1291 | 1297 | |
| 1292 | − if (unlikely(p->exit_state == EXIT_DEAD)) | |
| 1298 | + if (unlikely(exit_state == EXIT_DEAD)) | |
| 1293 | 1299 | return 0; |
| 1294 | 1300 | |
| 1295 | 1301 | ret = eligible_child(wo, p); |
| @@ -1310,7 +1316,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, · 14 unmodified lines | ||
| 1310 | 1316 | return 0; |
| 1311 | 1317 | } |
| 1312 | 1318 | |
| 1313 | − if (unlikely(p->exit_state == EXIT_TRACE)) { | |
| 1319 | + if (unlikely(exit_state == EXIT_TRACE)) { | |
| 1314 | 1320 | /* |
| 1315 | 1321 | * ptrace == 0 means we are the natural parent. In this case |
| 1316 | 1322 | * we should clear notask_error, debugger will notify us. |
| @@ -1337,7 +1343,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, · 20 unmodified lines | ||
| 1337 | 1343 | } |
| 1338 | 1344 | |
| 1339 | 1345 | /* slay zombie? */ |
| 1340 | − if (p->exit_state == EXIT_ZOMBIE) { | |
| 1346 | + if (exit_state == EXIT_ZOMBIE) { | |
| 1341 | 1347 | /* we don't reap group leaders with subthreads */ |
| 1342 | 1348 | if (!delay_group_leader(p)) { |
| 1343 | 1349 | /* |
| @@ -80,13 +80,13 @@ void debug_mutex_unlock(struct mutex *lock) · 79 unmodified lines | ||
| 80 | 80 | DEBUG_LOCKS_WARN_ON(lock->owner != current); |
| 81 | 81 | |
| 82 | 82 | DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); |
| 83 | − mutex_clear_owner(lock); | |
| 84 | 83 | } |
| 85 | 84 | |
| 86 | 85 | /* |
| 87 | 86 | * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug |
| 88 | 87 | * mutexes so that we can do it here after we've verified state. |
| 89 | 88 | */ |
| 89 | + mutex_clear_owner(lock); | |
| 90 | 90 | atomic_set(&lock->count, 1); |
| 91 | 91 | } |
| 92 | 92 | |
| @@ -7112,9 +7112,6 @@ void __init sched_init(void) · 7111 unmodified lines | ||
| 7112 | 7112 | #endif |
| 7113 | 7113 | #ifdef CONFIG_RT_GROUP_SCHED |
| 7114 | 7114 | alloc_size += 2 * nr_cpu_ids * sizeof(void **); |
| 7115 | −#endif | |
| 7116 | −#ifdef CONFIG_CPUMASK_OFFSTACK | |
| 7117 | − alloc_size += num_possible_cpus() * cpumask_size(); | |
| 7118 | 7115 | #endif |
| 7119 | 7116 | if (alloc_size) { |
| 7120 | 7117 | ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT); |
| @@ -7135,13 +7132,13 @@ void __init sched_init(void) · 14 unmodified lines | ||
| 7135 | 7132 | ptr += nr_cpu_ids * sizeof(void **); |
| 7136 | 7133 | |
| 7137 | 7134 | #endif /* CONFIG_RT_GROUP_SCHED */ |
| 7135 | + } | |
| 7138 | 7136 | #ifdef CONFIG_CPUMASK_OFFSTACK |
| 7139 | − for_each_possible_cpu(i) { | |
| 7140 | − per_cpu(load_balance_mask, i) = (void *)ptr; | |
| 7141 | − ptr += cpumask_size(); | |
| 7142 | − } | |
| 7143 | −#endif /* CONFIG_CPUMASK_OFFSTACK */ | |
| 7137 | + for_each_possible_cpu(i) { | |
| 7138 | + per_cpu(load_balance_mask, i) = (cpumask_var_t)kzalloc_node( | |
| 7139 | + cpumask_size(), GFP_KERNEL, cpu_to_node(i)); | |
| 7144 | 7140 | } |
| 7141 | +#endif /* CONFIG_CPUMASK_OFFSTACK */ | |
| 7145 | 7142 | |
| 7146 | 7143 | init_rt_bandwidth(&def_rt_bandwidth, |
| 7147 | 7144 | global_rt_period(), global_rt_runtime()); |
| @@ -570,24 +570,7 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se) · 569 unmodified lines | ||
| 570 | 570 | static |
| 571 | 571 | int dl_runtime_exceeded(struct rq *rq, struct sched_dl_entity *dl_se) |
| 572 | 572 | { |
| 573 | − int dmiss = dl_time_before(dl_se->deadline, rq_clock(rq)); | |
| 574 | − int rorun = dl_se->runtime <= 0; | |
| 575 | − | |
| 576 | − if (!rorun && !dmiss) | |
| 577 | − return 0; | |
| 578 | − | |
| 579 | − /* | |
| 580 | − * If we are beyond our current deadline and we are still | |
| 581 | − * executing, then we have already used some of the runtime of | |
| 582 | − * the next instance. Thus, if we do not account that, we are | |
| 583 | − * stealing bandwidth from the system at each deadline miss! | |
| 584 | − */ | |
| 585 | − if (dmiss) { | |
| 586 | − dl_se->runtime = rorun ? dl_se->runtime : 0; | |
| 587 | − dl_se->runtime -= rq_clock(rq) - dl_se->deadline; | |
| 588 | − } | |
| 589 | − | |
| 590 | − return 1; | |
| 573 | + return (dl_se->runtime <= 0); | |
| 591 | 574 | } |
| 592 | 575 | |
| 593 | 576 | extern bool sched_rt_bandwidth_account(struct rt_rq *rt_rq); |
| @@ -826,10 +809,10 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se, · 232 unmodified lines | ||
| 826 | 809 | * parameters of the task might need updating. Otherwise, |
| 827 | 810 | * we want a replenishment of its runtime. |
| 828 | 811 | */ |
| 829 | − if (!dl_se->dl_new && flags & ENQUEUE_REPLENISH) | |
| 830 | − replenish_dl_entity(dl_se, pi_se); | |
| 831 | − else | |
| 812 | + if (dl_se->dl_new || flags & ENQUEUE_WAKEUP) | |
| 832 | 813 | update_dl_entity(dl_se, pi_se); |
| 814 | + else if (flags & ENQUEUE_REPLENISH) | |
| 815 | + replenish_dl_entity(dl_se, pi_se); | |
| 833 | 816 | |
| 834 | 817 | __enqueue_dl_entity(dl_se); |
| 835 | 818 | } |
| @@ -4005,6 +4005,10 @@ void __start_cfs_bandwidth(struct cfs_bandwidth *cfs_b, bool force) · 4004 unmodified lines | ||
| 4005 | 4005 | |
| 4006 | 4006 | static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) |
| 4007 | 4007 | { |
| 4008 | + /* init_cfs_bandwidth() was not called */ | |
| 4009 | + if (!cfs_b->throttled_cfs_rq.next) | |
| 4010 | + return; | |
| 4011 | + | |
| 4008 | 4012 | hrtimer_cancel(&cfs_b->period_timer); |
| 4009 | 4013 | hrtimer_cancel(&cfs_b->slack_timer); |
| 4010 | 4014 | } |
| @@ -4424,7 +4428,7 @@ static long effective_load(struct task_group *tg, int cpu, long wl, long wg) · 413 unmodified lines | ||
| 4424 | 4428 | * wl = S * s'_i; see (2) |
| 4425 | 4429 | */ |
| 4426 | 4430 | if (W > 0 && w < W) |
| 4427 | − wl = (w * tg->shares) / W; | |
| 4431 | + wl = (w * (long)tg->shares) / W; | |
| 4428 | 4432 | else |
| 4429 | 4433 | wl = tg->shares; |
| 4430 | 4434 | |
| @@ -132,8 +132,8 @@ static int kdb_ftdump(int argc, const char **argv) · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | static __init int kdb_ftrace_register(void) |
| 134 | 134 | { |
| 135 | − kdb_register_repeat("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", | |
| 136 | − "Dump ftrace log", 0, KDB_REPEAT_NONE); | |
| 135 | + kdb_register_flags("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", | |
| 136 | + "Dump ftrace log", 0, KDB_ENABLE_ALWAYS_SAFE); | |
| 137 | 137 | return 0; |
| 138 | 138 | } |
| 139 | 139 | |
| @@ -73,6 +73,31 @@ config KGDB_KDB · 72 unmodified lines | ||
| 73 | 73 | help |
| 74 | 74 | KDB frontend for kernel |
| 75 | 75 | |
| 76 | +config KDB_DEFAULT_ENABLE | |
| 77 | + hex "KDB: Select kdb command functions to be enabled by default" | |
| 78 | + depends on KGDB_KDB | |
| 79 | + default 0x1 | |
| 80 | + help | |
| 81 | + Specifiers which kdb commands are enabled by default. This may | |
| 82 | + be set to 1 or 0 to enable all commands or disable almost all | |
| 83 | + commands. | |
| 84 | + | |
| 85 | + Alternatively the following bitmask applies: | |
| 86 | + | |
| 87 | + 0x0002 - allow arbitrary reads from memory and symbol lookup | |
| 88 | + 0x0004 - allow arbitrary writes to memory | |
| 89 | + 0x0008 - allow current register state to be inspected | |
| 90 | + 0x0010 - allow current register state to be modified | |
| 91 | + 0x0020 - allow passive inspection (backtrace, process list, lsmod) | |
| 92 | + 0x0040 - allow flow control management (breakpoint, single step) | |
| 93 | + 0x0080 - enable signalling of processes | |
| 94 | + 0x0100 - allow machine to be rebooted | |
| 95 | + | |
| 96 | + The config option merely sets the default at boot time. Both | |
| 97 | + issuing 'echo X > /sys/module/kdb/parameters/cmd_enable' or | |
| 98 | + setting with kdb.cmd_enable=X kernel command line option will | |
| 99 | + override the default settings. | |
| 100 | + | |
| 76 | 101 | config KDB_KEYBOARD |
| 77 | 102 | bool "KGDB_KDB: keyboard as input device" |
| 78 | 103 | depends on VT && KGDB_KDB |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | * 2 of the Licence, or (at your option) any later version. |
| 12 | 12 | */ |
| 13 | 13 | //#define DEBUG |
| 14 | +#include <linux/rcupdate.h> | |
| 14 | 15 | #include <linux/slab.h> |
| 15 | 16 | #include <linux/err.h> |
| 16 | 17 | #include <linux/assoc_array_priv.h> |
| @@ -14,7 +14,6 @@ config DEBUG_PAGEALLOC · 13 unmodified lines | ||
| 14 | 14 | depends on !KMEMCHECK |
| 15 | 15 | select PAGE_EXTENSION |
| 16 | 16 | select PAGE_POISONING if !ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 17 | − select PAGE_GUARD if ARCH_SUPPORTS_DEBUG_PAGEALLOC | |
| 18 | 17 | ---help--- |
| 19 | 18 | Unmap pages from the kernel linear mapping after free_pages(). |
| 20 | 19 | This results in a large slowdown, but helps to find certain types |
| @@ -27,13 +26,5 @@ config DEBUG_PAGEALLOC · 6 unmodified lines | ||
| 27 | 26 | that would result in incorrect warnings of memory corruption after |
| 28 | 27 | a resume because free pages are not saved to the suspend image. |
| 29 | 28 | |
| 30 | −config WANT_PAGE_DEBUG_FLAGS | |
| 31 | − bool | |
| 32 | − | |
| 33 | 29 | config PAGE_POISONING |
| 34 | 30 | bool |
| 35 | − select WANT_PAGE_DEBUG_FLAGS | |
| 36 | − | |
| 37 | −config PAGE_GUARD | |
| 38 | − bool | |
| 39 | − select WANT_PAGE_DEBUG_FLAGS | |
| @@ -3043,18 +3043,6 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry, · 3042 unmodified lines | ||
| 3043 | 3043 | if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) { |
| 3044 | 3044 | mem_cgroup_swap_statistics(from, false); |
| 3045 | 3045 | mem_cgroup_swap_statistics(to, true); |
| 3046 | − /* | |
| 3047 | − * This function is only called from task migration context now. | |
| 3048 | − * It postpones page_counter and refcount handling till the end | |
| 3049 | − * of task migration(mem_cgroup_clear_mc()) for performance | |
| 3050 | − * improvement. But we cannot postpone css_get(to) because if | |
| 3051 | − * the process that has been moved to @to does swap-in, the | |
| 3052 | − * refcount of @to might be decreased to 0. | |
| 3053 | − * | |
| 3054 | − * We are in attach() phase, so the cgroup is guaranteed to be | |
| 3055 | − * alive, so we can just call css_get(). | |
| 3056 | − */ | |
| 3057 | − css_get(&to->css); | |
| 3058 | 3046 | return 0; |
| 3059 | 3047 | } |
| 3060 | 3048 | return -EINVAL; |
| @@ -4679,6 +4667,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) · 1618 unmodified lines | ||
| 4679 | 4667 | if (parent_css == NULL) { |
| 4680 | 4668 | root_mem_cgroup = memcg; |
| 4681 | 4669 | page_counter_init(&memcg->memory, NULL); |
| 4670 | + memcg->soft_limit = PAGE_COUNTER_MAX; | |
| 4682 | 4671 | page_counter_init(&memcg->memsw, NULL); |
| 4683 | 4672 | page_counter_init(&memcg->kmem, NULL); |
| 4684 | 4673 | } |
| @@ -4724,6 +4713,7 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) · 39 unmodified lines | ||
| 4724 | 4713 | |
| 4725 | 4714 | if (parent->use_hierarchy) { |
| 4726 | 4715 | page_counter_init(&memcg->memory, &parent->memory); |
| 4716 | + memcg->soft_limit = PAGE_COUNTER_MAX; | |
| 4727 | 4717 | page_counter_init(&memcg->memsw, &parent->memsw); |
| 4728 | 4718 | page_counter_init(&memcg->kmem, &parent->kmem); |
| 4729 | 4719 | |
| @@ -4733,6 +4723,7 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) · 3 unmodified lines | ||
| 4733 | 4723 | */ |
| 4734 | 4724 | } else { |
| 4735 | 4725 | page_counter_init(&memcg->memory, NULL); |
| 4726 | + memcg->soft_limit = PAGE_COUNTER_MAX; | |
| 4736 | 4727 | page_counter_init(&memcg->memsw, NULL); |
| 4737 | 4728 | page_counter_init(&memcg->kmem, NULL); |
| 4738 | 4729 | /* |
| @@ -4807,7 +4798,7 @@ static void mem_cgroup_css_reset(struct cgroup_subsys_state *css) · 68 unmodified lines | ||
| 4807 | 4798 | mem_cgroup_resize_limit(memcg, PAGE_COUNTER_MAX); |
| 4808 | 4799 | mem_cgroup_resize_memsw_limit(memcg, PAGE_COUNTER_MAX); |
| 4809 | 4800 | memcg_update_kmem_limit(memcg, PAGE_COUNTER_MAX); |
| 4810 | − memcg->soft_limit = 0; | |
| 4801 | + memcg->soft_limit = PAGE_COUNTER_MAX; | |
| 4811 | 4802 | } |
| 4812 | 4803 | |
| 4813 | 4804 | #ifdef CONFIG_MMU |
| @@ -2137,17 +2137,24 @@ reuse: · 2136 unmodified lines | ||
| 2137 | 2137 | if (!dirty_page) |
| 2138 | 2138 | return ret; |
| 2139 | 2139 | |
| 2140 | − /* | |
| 2141 | − * Yes, Virginia, this is actually required to prevent a race | |
| 2142 | − * with clear_page_dirty_for_io() from clearing the page dirty | |
| 2143 | − * bit after it clear all dirty ptes, but before a racing | |
| 2144 | − * do_wp_page installs a dirty pte. | |
| 2145 | − * | |
| 2146 | − * do_shared_fault is protected similarly. | |
| 2147 | − */ | |
| 2148 | 2140 | if (!page_mkwrite) { |
| 2149 | − wait_on_page_locked(dirty_page); | |
| 2150 | − set_page_dirty_balance(dirty_page); | |
| 2141 | + struct address_space *mapping; | |
| 2142 | + int dirtied; | |
| 2143 | + | |
| 2144 | + lock_page(dirty_page); | |
| 2145 | + dirtied = set_page_dirty(dirty_page); | |
| 2146 | + VM_BUG_ON_PAGE(PageAnon(dirty_page), dirty_page); | |
| 2147 | + mapping = dirty_page->mapping; | |
| 2148 | + unlock_page(dirty_page); | |
| 2149 | + | |
| 2150 | + if (dirtied && mapping) { | |
| 2151 | + /* | |
| 2152 | + * Some device drivers do not set page.mapping | |
| 2153 | + * but still dirty their pages | |
| 2154 | + */ | |
| 2155 | + balance_dirty_pages_ratelimited(mapping); | |
| 2156 | + } | |
| 2157 | + | |
| 2151 | 2158 | /* file_update_time outside page_lock */ |
| 2152 | 2159 | if (vma->vm_file) |
| 2153 | 2160 | file_update_time(vma->vm_file); |
| @@ -2593,7 +2600,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo · 439 unmodified lines | ||
| 2593 | 2600 | if (prev && prev->vm_end == address) |
| 2594 | 2601 | return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; |
| 2595 | 2602 | |
| 2596 | − expand_downwards(vma, address - PAGE_SIZE); | |
| 2603 | + return expand_downwards(vma, address - PAGE_SIZE); | |
| 2597 | 2604 | } |
| 2598 | 2605 | if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { |
| 2599 | 2606 | struct vm_area_struct *next = vma->vm_next; |
| @@ -2602,7 +2609,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo · 2 unmodified lines | ||
| 2602 | 2609 | if (next && next->vm_start == address + PAGE_SIZE) |
| 2603 | 2610 | return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; |
| 2604 | 2611 | |
| 2605 | − expand_upwards(vma, address + PAGE_SIZE); | |
| 2612 | + return expand_upwards(vma, address + PAGE_SIZE); | |
| 2606 | 2613 | } |
| 2607 | 2614 | return 0; |
| 2608 | 2615 | } |
| @@ -778,10 +778,12 @@ again: remove_next = 1 + (end > next->vm_end); · 777 unmodified lines | ||
| 778 | 778 | if (exporter && exporter->anon_vma && !importer->anon_vma) { |
| 779 | 779 | int error; |
| 780 | 780 | |
| 781 | + importer->anon_vma = exporter->anon_vma; | |
| 781 | 782 | error = anon_vma_clone(importer, exporter); |
| 782 | − if (error) | |
| 783 | + if (error) { | |
| 784 | + importer->anon_vma = NULL; | |
| 783 | 785 | return error; |
| 784 | − importer->anon_vma = exporter->anon_vma; | |
| 786 | + } | |
| 785 | 787 | } |
| 786 | 788 | } |
| 787 | 789 | |
| @@ -2099,14 +2101,17 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns · 1311 unmodified lines | ||
| 2099 | 2101 | { |
| 2100 | 2102 | struct mm_struct *mm = vma->vm_mm; |
| 2101 | 2103 | struct rlimit *rlim = current->signal->rlim; |
| 2102 | − unsigned long new_start; | |
| 2104 | + unsigned long new_start, actual_size; | |
| 2103 | 2105 | |
| 2104 | 2106 | /* address space limit tests */ |
| 2105 | 2107 | if (!may_expand_vm(mm, grow)) |
| 2106 | 2108 | return -ENOMEM; |
| 2107 | 2109 | |
| 2108 | 2110 | /* Stack limit test */ |
| 2109 | − if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) | |
| 2111 | + actual_size = size; | |
| 2112 | + if (size && (vma->vm_flags & (VM_GROWSUP | VM_GROWSDOWN))) | |
| 2113 | + actual_size -= PAGE_SIZE; | |
| 2114 | + if (actual_size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) | |
| 2110 | 2115 | return -ENOMEM; |
| 2111 | 2116 | |
| 2112 | 2117 | /* mlock limit tests */ |
| @@ -1541,16 +1541,6 @@ pause: · 1540 unmodified lines | ||
| 1541 | 1541 | bdi_start_background_writeback(bdi); |
| 1542 | 1542 | } |
| 1543 | 1543 | |
| 1544 | −void set_page_dirty_balance(struct page *page) | |
| 1545 | −{ | |
| 1546 | − if (set_page_dirty(page)) { | |
| 1547 | − struct address_space *mapping = page_mapping(page); | |
| 1548 | − | |
| 1549 | − if (mapping) | |
| 1550 | − balance_dirty_pages_ratelimited(mapping); | |
| 1551 | − } | |
| 1552 | −} | |
| 1553 | − | |
| 1554 | 1544 | static DEFINE_PER_CPU(int, bdp_ratelimits); |
| 1555 | 1545 | |
| 1556 | 1546 | /* |
| @@ -2123,32 +2113,25 @@ EXPORT_SYMBOL(account_page_dirtied); · 566 unmodified lines | ||
| 2123 | 2113 | * page dirty in that case, but not all the buffers. This is a "bottom-up" |
| 2124 | 2114 | * dirtying, whereas __set_page_dirty_buffers() is a "top-down" dirtying. |
| 2125 | 2115 | * |
| 2126 | − * Most callers have locked the page, which pins the address_space in memory. | |
| 2127 | − * But zap_pte_range() does not lock the page, however in that case the | |
| 2128 | − * mapping is pinned by the vma's ->vm_file reference. | |
| 2129 | − * | |
| 2130 | − * We take care to handle the case where the page was truncated from the | |
| 2131 | − * mapping by re-checking page_mapping() inside tree_lock. | |
| 2116 | + * The caller must ensure this doesn't race with truncation. Most will simply | |
| 2117 | + * hold the page lock, but e.g. zap_pte_range() calls with the page mapped and | |
| 2118 | + * the pte lock held, which also locks out truncation. | |
| 2132 | 2119 | */ |
| 2133 | 2120 | int __set_page_dirty_nobuffers(struct page *page) |
| 2134 | 2121 | { |
| 2135 | 2122 | if (!TestSetPageDirty(page)) { |
| 2136 | 2123 | struct address_space *mapping = page_mapping(page); |
| 2137 | − struct address_space *mapping2; | |
| 2138 | 2124 | unsigned long flags; |
| 2139 | 2125 | |
| 2140 | 2126 | if (!mapping) |
| 2141 | 2127 | return 1; |
| 2142 | 2128 | |
| 2143 | 2129 | spin_lock_irqsave(&mapping->tree_lock, flags); |
| 2144 | − mapping2 = page_mapping(page); | |
| 2145 | − if (mapping2) { /* Race with truncate? */ | |
| 2146 | − BUG_ON(mapping2 != mapping); | |
| 2147 | − WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page)); | |
| 2148 | − account_page_dirtied(page, mapping); | |
| 2149 | − radix_tree_tag_set(&mapping->page_tree, | |
| 2150 | − page_index(page), PAGECACHE_TAG_DIRTY); | |
| 2151 | − } | |
| 2130 | + BUG_ON(page_mapping(page) != mapping); | |
| 2131 | + WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page)); | |
| 2132 | + account_page_dirtied(page, mapping); | |
| 2133 | + radix_tree_tag_set(&mapping->page_tree, page_index(page), | |
| 2134 | + PAGECACHE_TAG_DIRTY); | |
| 2152 | 2135 | spin_unlock_irqrestore(&mapping->tree_lock, flags); |
| 2153 | 2136 | if (mapping->host) { |
| 2154 | 2137 | /* !PageAnon && !swapper_space */ |
| @@ -2305,12 +2288,10 @@ int clear_page_dirty_for_io(struct page *page) · 150 unmodified lines | ||
| 2305 | 2288 | /* |
| 2306 | 2289 | * We carefully synchronise fault handlers against |
| 2307 | 2290 | * installing a dirty pte and marking the page dirty |
| 2308 | − * at this point. We do this by having them hold the | |
| 2309 | − * page lock at some point after installing their | |
| 2310 | − * pte, but before marking the page dirty. | |
| 2311 | − * Pages are always locked coming in here, so we get | |
| 2312 | − * the desired exclusion. See mm/memory.c:do_wp_page() | |
| 2313 | − * for more comments. | |
| 2291 | + * at this point. We do this by having them hold the | |
| 2292 | + * page lock while dirtying the page, and pages are | |
| 2293 | + * always locked coming in here, so we get the desired | |
| 2294 | + * exclusion. | |
| 2314 | 2295 | */ |
| 2315 | 2296 | if (TestClearPageDirty(page)) { |
| 2316 | 2297 | dec_zone_page_state(page, NR_FILE_DIRTY); |
| @@ -72,6 +72,8 @@ static inline struct anon_vma *anon_vma_alloc(void) · 71 unmodified lines | ||
| 72 | 72 | anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); |
| 73 | 73 | if (anon_vma) { |
| 74 | 74 | atomic_set(&anon_vma->refcount, 1); |
| 75 | + anon_vma->degree = 1; /* Reference for first vma */ | |
| 76 | + anon_vma->parent = anon_vma; | |
| 75 | 77 | /* |
| 76 | 78 | * Initialise the anon_vma root to point to itself. If called |
| 77 | 79 | * from fork, the root will be reset to the parents anon_vma. |
| @@ -188,6 +190,8 @@ int anon_vma_prepare(struct vm_area_struct *vma) · 110 unmodified lines | ||
| 188 | 190 | if (likely(!vma->anon_vma)) { |
| 189 | 191 | vma->anon_vma = anon_vma; |
| 190 | 192 | anon_vma_chain_link(vma, avc, anon_vma); |
| 193 | + /* vma reference or self-parent link for new root */ | |
| 194 | + anon_vma->degree++; | |
| 191 | 195 | allocated = NULL; |
| 192 | 196 | avc = NULL; |
| 193 | 197 | } |
| @@ -236,6 +240,14 @@ static inline void unlock_anon_vma_root(struct anon_vma *root) · 42 unmodified lines | ||
| 236 | 240 | /* |
| 237 | 241 | * Attach the anon_vmas from src to dst. |
| 238 | 242 | * Returns 0 on success, -ENOMEM on failure. |
| 243 | + * | |
| 244 | + * If dst->anon_vma is NULL this function tries to find and reuse existing | |
| 245 | + * anon_vma which has no vmas and only one child anon_vma. This prevents | |
| 246 | + * degradation of anon_vma hierarchy to endless linear chain in case of | |
| 247 | + * constantly forking task. On the other hand, an anon_vma with more than one | |
| 248 | + * child isn't reused even if there was no alive vma, thus rmap walker has a | |
| 249 | + * good chance of avoiding scanning the whole hierarchy when it searches where | |
| 250 | + * page is mapped. | |
| 239 | 251 | */ |
| 240 | 252 | int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) |
| 241 | 253 | { |
| @@ -256,7 +268,21 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) · 14 unmodified lines | ||
| 256 | 268 | anon_vma = pavc->anon_vma; |
| 257 | 269 | root = lock_anon_vma_root(root, anon_vma); |
| 258 | 270 | anon_vma_chain_link(dst, avc, anon_vma); |
| 271 | + | |
| 272 | + /* | |
| 273 | + * Reuse existing anon_vma if its degree lower than two, | |
| 274 | + * that means it has no vma and only one anon_vma child. | |
| 275 | + * | |
| 276 | + * Do not chose parent anon_vma, otherwise first child | |
| 277 | + * will always reuse it. Root anon_vma is never reused: | |
| 278 | + * it has self-parent reference and at least one child. | |
| 279 | + */ | |
| 280 | + if (!dst->anon_vma && anon_vma != src->anon_vma && | |
| 281 | + anon_vma->degree < 2) | |
| 282 | + dst->anon_vma = anon_vma; | |
| 259 | 283 | } |
| 284 | + if (dst->anon_vma) | |
| 285 | + dst->anon_vma->degree++; | |
| 260 | 286 | unlock_anon_vma_root(root); |
| 261 | 287 | return 0; |
| 262 | 288 | |
| @@ -280,6 +306,9 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) · 17 unmodified lines | ||
| 280 | 306 | if (!pvma->anon_vma) |
| 281 | 307 | return 0; |
| 282 | 308 | |
| 309 | + /* Drop inherited anon_vma, we'll reuse existing or allocate new. */ | |
| 310 | + vma->anon_vma = NULL; | |
| 311 | + | |
| 283 | 312 | /* |
| 284 | 313 | * First, attach the new VMA to the parent VMA's anon_vmas, |
| 285 | 314 | * so rmap can find non-COWed pages in child processes. |
| @@ -288,6 +317,10 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) · 2 unmodified lines | ||
| 288 | 317 | if (error) |
| 289 | 318 | return error; |
| 290 | 319 | |
| 320 | + /* An existing anon_vma has been reused, all done then. */ | |
| 321 | + if (vma->anon_vma) | |
| 322 | + return 0; | |
| 323 | + | |
| 291 | 324 | /* Then add our own anon_vma. */ |
| 292 | 325 | anon_vma = anon_vma_alloc(); |
| 293 | 326 | if (!anon_vma) |
| @@ -301,6 +334,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) · 7 unmodified lines | ||
| 301 | 334 | * lock any of the anon_vmas in this anon_vma tree. |
| 302 | 335 | */ |
| 303 | 336 | anon_vma->root = pvma->anon_vma->root; |
| 337 | + anon_vma->parent = pvma->anon_vma; | |
| 304 | 338 | /* |
| 305 | 339 | * With refcounts, an anon_vma can stay around longer than the |
| 306 | 340 | * process it belongs to. The root anon_vma needs to be pinned until |
| @@ -311,6 +345,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) · 4 unmodified lines | ||
| 311 | 345 | vma->anon_vma = anon_vma; |
| 312 | 346 | anon_vma_lock_write(anon_vma); |
| 313 | 347 | anon_vma_chain_link(vma, avc, anon_vma); |
| 348 | + anon_vma->parent->degree++; | |
| 314 | 349 | anon_vma_unlock_write(anon_vma); |
| 315 | 350 | |
| 316 | 351 | return 0; |
| @@ -341,12 +376,16 @@ void unlink_anon_vmas(struct vm_area_struct *vma) · 24 unmodified lines | ||
| 341 | 376 | * Leave empty anon_vmas on the list - we'll need |
| 342 | 377 | * to free them outside the lock. |
| 343 | 378 | */ |
| 344 | − if (RB_EMPTY_ROOT(&anon_vma->rb_root)) | |
| 379 | + if (RB_EMPTY_ROOT(&anon_vma->rb_root)) { | |
| 380 | + anon_vma->parent->degree--; | |
| 345 | 381 | continue; |
| 382 | + } | |
| 346 | 383 | |
| 347 | 384 | list_del(&avc->same_vma); |
| 348 | 385 | anon_vma_chain_free(avc); |
| 349 | 386 | } |
| 387 | + if (vma->anon_vma) | |
| 388 | + vma->anon_vma->degree--; | |
| 350 | 389 | unlock_anon_vma_root(root); |
| 351 | 390 | |
| 352 | 391 | /* |
| @@ -357,6 +396,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma) · 4 unmodified lines | ||
| 357 | 396 | list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) { |
| 358 | 397 | struct anon_vma *anon_vma = avc->anon_vma; |
| 359 | 398 | |
| 399 | + BUG_ON(anon_vma->degree); | |
| 360 | 400 | put_anon_vma(anon_vma); |
| 361 | 401 | |
| 362 | 402 | list_del(&avc->same_vma); |
| @@ -2921,18 +2921,20 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining, · 2920 unmodified lines | ||
| 2921 | 2921 | return false; |
| 2922 | 2922 | |
| 2923 | 2923 | /* |
| 2924 | − * There is a potential race between when kswapd checks its watermarks | |
| 2925 | − * and a process gets throttled. There is also a potential race if | |
| 2926 | − * processes get throttled, kswapd wakes, a large process exits therby | |
| 2927 | − * balancing the zones that causes kswapd to miss a wakeup. If kswapd | |
| 2928 | − * is going to sleep, no process should be sleeping on pfmemalloc_wait | |
| 2929 | − * so wake them now if necessary. If necessary, processes will wake | |
| 2930 | − * kswapd and get throttled again | |
| 2924 | + * The throttled processes are normally woken up in balance_pgdat() as | |
| 2925 | + * soon as pfmemalloc_watermark_ok() is true. But there is a potential | |
| 2926 | + * race between when kswapd checks the watermarks and a process gets | |
| 2927 | + * throttled. There is also a potential race if processes get | |
| 2928 | + * throttled, kswapd wakes, a large process exits thereby balancing the | |
| 2929 | + * zones, which causes kswapd to exit balance_pgdat() before reaching | |
| 2930 | + * the wake up checks. If kswapd is going to sleep, no process should | |
| 2931 | + * be sleeping on pfmemalloc_wait, so wake them now if necessary. If | |
| 2932 | + * the wake up is premature, processes will wake kswapd and get | |
| 2933 | + * throttled again. The difference from wake ups in balance_pgdat() is | |
| 2934 | + * that here we are under prepare_to_wait(). | |
| 2931 | 2935 | */ |
| 2932 | − if (waitqueue_active(&pgdat->pfmemalloc_wait)) { | |
| 2933 | − wake_up(&pgdat->pfmemalloc_wait); | |
| 2934 | − return false; | |
| 2935 | − } | |
| 2936 | + if (waitqueue_active(&pgdat->pfmemalloc_wait)) | |
| 2937 | + wake_up_all(&pgdat->pfmemalloc_wait); | |
| 2936 | 2938 | |
| 2937 | 2939 | return pgdat_balanced(pgdat, order, classzone_idx); |
| 2938 | 2940 | } |
| @@ -685,11 +685,13 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, · 684 unmodified lines | ||
| 685 | 685 | if (orig_initialized) |
| 686 | 686 | atomic_dec(&bat_priv->mcast.num_disabled); |
| 687 | 687 | orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST; |
| 688 | − /* If mcast support is being switched off increase the disabled | |
| 689 | − * mcast node counter. | |
| 688 | + /* If mcast support is being switched off or if this is an initial | |
| 689 | + * OGM without mcast support then increase the disabled mcast | |
| 690 | + * node counter. | |
| 690 | 691 | */ |
| 691 | 692 | } else if (!orig_mcast_enabled && |
| 692 | − orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) { | |
| 693 | + (orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST || | |
| 694 | + !orig_initialized)) { | |
| 693 | 695 | atomic_inc(&bat_priv->mcast.num_disabled); |
| 694 | 696 | orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST; |
| 695 | 697 | } |
| @@ -738,7 +740,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig) · 42 unmodified lines | ||
| 738 | 740 | { |
| 739 | 741 | struct batadv_priv *bat_priv = orig->bat_priv; |
| 740 | 742 | |
| 741 | − if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) | |
| 743 | + if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) && | |
| 744 | + orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST) | |
| 742 | 745 | atomic_dec(&bat_priv->mcast.num_disabled); |
| 743 | 746 | |
| 744 | 747 | batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); |
| @@ -133,7 +133,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv) · 132 unmodified lines | ||
| 133 | 133 | if (!bat_priv->nc.decoding_hash) |
| 134 | 134 | goto err; |
| 135 | 135 | |
| 136 | − batadv_hash_set_lock_class(bat_priv->nc.coding_hash, | |
| 136 | + batadv_hash_set_lock_class(bat_priv->nc.decoding_hash, | |
| 137 | 137 | &batadv_nc_decoding_hash_lock_class_key); |
| 138 | 138 | |
| 139 | 139 | INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); |
| @@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) · 569 unmodified lines | ||
| 570 | 570 | |
| 571 | 571 | batadv_frag_purge_orig(orig_node, NULL); |
| 572 | 572 | |
| 573 | − batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1, | |
| 574 | − "originator timed out"); | |
| 575 | − | |
| 576 | 573 | if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) |
| 577 | 574 | orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); |
| 578 | 575 | |
| @@ -678,6 +675,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, · 99 unmodified lines | ||
| 678 | 675 | atomic_set(&orig_node->last_ttvn, 0); |
| 679 | 676 | orig_node->tt_buff = NULL; |
| 680 | 677 | orig_node->tt_buff_len = 0; |
| 678 | + orig_node->last_seen = jiffies; | |
| 681 | 679 | reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); |
| 682 | 680 | orig_node->bcast_seqno_reset = reset_time; |
| 683 | 681 | #ifdef CONFIG_BATMAN_ADV_MCAST |
| @@ -977,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv) · 293 unmodified lines | ||
| 977 | 975 | if (batadv_purge_orig_node(bat_priv, orig_node)) { |
| 978 | 976 | batadv_gw_node_delete(bat_priv, orig_node); |
| 979 | 977 | hlist_del_rcu(&orig_node->hash_entry); |
| 978 | + batadv_tt_global_del_orig(orig_node->bat_priv, | |
| 979 | + orig_node, -1, | |
| 980 | + "originator timed out"); | |
| 980 | 981 | batadv_orig_node_free_ref(orig_node); |
| 981 | 982 | continue; |
| 982 | 983 | } |
| @@ -443,11 +443,13 @@ batadv_find_router(struct batadv_priv *bat_priv, · 442 unmodified lines | ||
| 443 | 443 | |
| 444 | 444 | router = batadv_orig_router_get(orig_node, recv_if); |
| 445 | 445 | |
| 446 | + if (!router) | |
| 447 | + return router; | |
| 448 | + | |
| 446 | 449 | /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) |
| 447 | 450 | * and if activated. |
| 448 | 451 | */ |
| 449 | − if (recv_if == BATADV_IF_DEFAULT || !atomic_read(&bat_priv->bonding) || | |
| 450 | − !router) | |
| 452 | + if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding))) | |
| 451 | 453 | return router; |
| 452 | 454 | |
| 453 | 455 | /* bonding: loop through the list of possible routers found |
| @@ -676,7 +676,7 @@ static int calcu_signature(struct ceph_x_authorizer *au, · 675 unmodified lines | ||
| 676 | 676 | int ret; |
| 677 | 677 | char tmp_enc[40]; |
| 678 | 678 | __le32 tmp[5] = { |
| 679 | − 16u, msg->hdr.crc, msg->footer.front_crc, | |
| 679 | + cpu_to_le32(16), msg->hdr.crc, msg->footer.front_crc, | |
| 680 | 680 | msg->footer.middle_crc, msg->footer.data_crc, |
| 681 | 681 | }; |
| 682 | 682 | ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp), |
| @@ -717,7 +717,7 @@ static int get_poolop_reply_buf(const char *src, size_t src_len, · 716 unmodified lines | ||
| 717 | 717 | if (src_len != sizeof(u32) + dst_len) |
| 718 | 718 | return -EINVAL; |
| 719 | 719 | |
| 720 | − buf_len = le32_to_cpu(*(u32 *)src); | |
| 720 | + buf_len = le32_to_cpu(*(__le32 *)src); | |
| 721 | 721 | if (buf_len != dst_len) |
| 722 | 722 | return -EINVAL; |
| 723 | 723 | |
| @@ -2019,7 +2019,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, · 2018 unmodified lines | ||
| 2019 | 2019 | if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) |
| 2020 | 2020 | break; |
| 2021 | 2021 | |
| 2022 | − if (tso_segs == 1) { | |
| 2022 | + if (tso_segs == 1 || !max_segs) { | |
| 2023 | 2023 | if (unlikely(!tcp_nagle_test(tp, skb, mss_now, |
| 2024 | 2024 | (tcp_skb_is_last(sk, skb) ? |
| 2025 | 2025 | nonagle : TCP_NAGLE_PUSH)))) |
| @@ -2032,7 +2032,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, · 6 unmodified lines | ||
| 2032 | 2032 | } |
| 2033 | 2033 | |
| 2034 | 2034 | limit = mss_now; |
| 2035 | − if (tso_segs > 1 && !tcp_urg_mode(tp)) | |
| 2035 | + if (tso_segs > 1 && max_segs && !tcp_urg_mode(tp)) | |
| 2036 | 2036 | limit = tcp_mss_split_point(sk, skb, mss_now, |
| 2037 | 2037 | min_t(unsigned int, |
| 2038 | 2038 | cwnd_quota, |
| @@ -140,7 +140,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) · 139 unmodified lines | ||
| 140 | 140 | if (!ret) { |
| 141 | 141 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 142 | 142 | |
| 143 | − if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | |
| 143 | + if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | |
| 144 | + (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | |
| 145 | + (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | |
| 144 | 146 | sdata->crypto_tx_tailroom_needed_cnt--; |
| 145 | 147 | |
| 146 | 148 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
| @@ -188,7 +190,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) · 41 unmodified lines | ||
| 188 | 190 | sta = key->sta; |
| 189 | 191 | sdata = key->sdata; |
| 190 | 192 | |
| 191 | − if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | |
| 193 | + if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | |
| 194 | + (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | |
| 195 | + (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | |
| 192 | 196 | increment_tailroom_need_count(sdata); |
| 193 | 197 | |
| 194 | 198 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, |
| @@ -884,7 +888,9 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) · 689 unmodified lines | ||
| 884 | 888 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
| 885 | 889 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 886 | 890 | |
| 887 | − if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | |
| 891 | + if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | |
| 892 | + (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | |
| 893 | + (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | |
| 888 | 894 | increment_tailroom_need_count(key->sdata); |
| 889 | 895 | } |
| 890 | 896 | |
| @@ -70,6 +70,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, · 69 unmodified lines | ||
| 70 | 70 | { |
| 71 | 71 | struct flow_stats *stats; |
| 72 | 72 | int node = numa_node_id(); |
| 73 | + int len = skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | |
| 73 | 74 | |
| 74 | 75 | stats = rcu_dereference(flow->stats[node]); |
| 75 | 76 | |
| @@ -105,7 +106,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, · 29 unmodified lines | ||
| 105 | 106 | if (likely(new_stats)) { |
| 106 | 107 | new_stats->used = jiffies; |
| 107 | 108 | new_stats->packet_count = 1; |
| 108 | − new_stats->byte_count = skb->len; | |
| 109 | + new_stats->byte_count = len; | |
| 109 | 110 | new_stats->tcp_flags = tcp_flags; |
| 110 | 111 | spin_lock_init(&new_stats->lock); |
| 111 | 112 | |
| @@ -120,7 +121,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, · 8 unmodified lines | ||
| 120 | 121 | |
| 121 | 122 | stats->used = jiffies; |
| 122 | 123 | stats->packet_count++; |
| 123 | − stats->byte_count += skb->len; | |
| 124 | + stats->byte_count += len; | |
| 124 | 125 | stats->tcp_flags |= tcp_flags; |
| 125 | 126 | unlock: |
| 126 | 127 | spin_unlock(&stats->lock); |
| @@ -480,7 +480,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, · 479 unmodified lines | ||
| 480 | 480 | stats = this_cpu_ptr(vport->percpu_stats); |
| 481 | 481 | u64_stats_update_begin(&stats->syncp); |
| 482 | 482 | stats->rx_packets++; |
| 483 | − stats->rx_bytes += skb->len; | |
| 483 | + stats->rx_bytes += skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | |
| 484 | 484 | u64_stats_update_end(&stats->syncp); |
| 485 | 485 | |
| 486 | 486 | OVS_CB(skb)->input_vport = vport; |
| @@ -606,7 +606,7 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) · 605 unmodified lines | ||
| 606 | 606 | struct kvec *head = buf->head; |
| 607 | 607 | struct kvec *tail = buf->tail; |
| 608 | 608 | int fraglen; |
| 609 | − int new, old; | |
| 609 | + int new; | |
| 610 | 610 | |
| 611 | 611 | if (len > buf->len) { |
| 612 | 612 | WARN_ON_ONCE(1); |
| @@ -629,8 +629,8 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) · 16 unmodified lines | ||
| 629 | 629 | buf->len -= fraglen; |
| 630 | 630 | |
| 631 | 631 | new = buf->page_base + buf->page_len; |
| 632 | − old = new + fraglen; | |
| 633 | − xdr->page_ptr -= (old >> PAGE_SHIFT) - (new >> PAGE_SHIFT); | |
| 632 | + | |
| 633 | + xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT); | |
| 634 | 634 | |
| 635 | 635 | if (buf->page_len) { |
| 636 | 636 | xdr->p = page_address(*xdr->page_ptr); |
| @@ -42,19 +42,19 @@ __clean-files := $(extra-y) $(extra-m) $(extra-) \ · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) |
| 44 | 44 | |
| 45 | −# as clean-files is given relative to the current directory, this adds | |
| 46 | −# a $(obj) prefix, except for absolute paths | |
| 45 | +# clean-files is given relative to the current directory, unless it | |
| 46 | +# starts with $(objtree)/ (which means "./", so do not add "./" unless | |
| 47 | +# you want to delete a file from the toplevel object directory). | |
| 47 | 48 | |
| 48 | 49 | __clean-files := $(wildcard \ |
| 49 | − $(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \ | |
| 50 | − $(filter /%, $(__clean-files))) | |
| 50 | + $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \ | |
| 51 | + $(filter $(objtree)/%, $(__clean-files))) | |
| 51 | 52 | |
| 52 | −# as clean-dirs is given relative to the current directory, this adds | |
| 53 | −# a $(obj) prefix, except for absolute paths | |
| 53 | +# same as clean-files | |
| 54 | 54 | |
| 55 | 55 | __clean-dirs := $(wildcard \ |
| 56 | − $(addprefix $(obj)/, $(filter-out /%, $(clean-dirs))) \ | |
| 57 | − $(filter /%, $(clean-dirs))) | |
| 56 | + $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \ | |
| 57 | + $(filter $(objtree)/%, $(clean-dirs))) | |
| 58 | 58 | |
| 59 | 59 | # ========================================================================== |
| 60 | 60 | |
| @@ -148,12 +148,12 @@ static noinline void key_gc_unused_keys(struct list_head *keys) · 147 unmodified lines | ||
| 148 | 148 | if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) |
| 149 | 149 | atomic_dec(&key->user->nikeys); |
| 150 | 150 | |
| 151 | − key_user_put(key->user); | |
| 152 | − | |
| 153 | 151 | /* now throw away the key memory */ |
| 154 | 152 | if (key->type->destroy) |
| 155 | 153 | key->type->destroy(key); |
| 156 | 154 | |
| 155 | + key_user_put(key->user); | |
| 156 | + | |
| 157 | 157 | kfree(key->description); |
| 158 | 158 | |
| 159 | 159 | #ifdef KEY_DEBUGGING |
| @@ -124,7 +124,7 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode) · 123 unmodified lines | ||
| 124 | 124 | spin_lock_irq(&efw->lock); |
| 125 | 125 | |
| 126 | 126 | t = (struct snd_efw_transaction *)data; |
| 127 | − length = min_t(size_t, t->length * sizeof(t->length), length); | |
| 127 | + length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length); | |
| 128 | 128 | |
| 129 | 129 | if (efw->push_ptr < efw->pull_ptr) |
| 130 | 130 | capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr); |
| @@ -3353,6 +3353,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { · 3352 unmodified lines | ||
| 3353 | 3353 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
| 3354 | 3354 | { .id = 0x10de0070, .name = "GPU 70 HDMI/DP", .patch = patch_nvhdmi }, |
| 3355 | 3355 | { .id = 0x10de0071, .name = "GPU 71 HDMI/DP", .patch = patch_nvhdmi }, |
| 3356 | +{ .id = 0x10de0072, .name = "GPU 72 HDMI/DP", .patch = patch_nvhdmi }, | |
| 3356 | 3357 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
| 3357 | 3358 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
| 3358 | 3359 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, |
| @@ -3413,6 +3414,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0060"); · 54 unmodified lines | ||
| 3413 | 3414 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); |
| 3414 | 3415 | MODULE_ALIAS("snd-hda-codec-id:10de0070"); |
| 3415 | 3416 | MODULE_ALIAS("snd-hda-codec-id:10de0071"); |
| 3417 | +MODULE_ALIAS("snd-hda-codec-id:10de0072"); | |
| 3416 | 3418 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); |
| 3417 | 3419 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); |
| 3418 | 3420 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); |
| @@ -568,9 +568,9 @@ static void stac_store_hints(struct hda_codec *codec) · 567 unmodified lines | ||
| 568 | 568 | spec->gpio_mask; |
| 569 | 569 | } |
| 570 | 570 | if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) |
| 571 | − spec->gpio_mask &= spec->gpio_mask; | |
| 572 | − if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) | |
| 573 | 571 | spec->gpio_dir &= spec->gpio_mask; |
| 572 | + if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) | |
| 573 | + spec->gpio_data &= spec->gpio_mask; | |
| 574 | 574 | if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) |
| 575 | 575 | spec->eapd_mask &= spec->gpio_mask; |
| 576 | 576 | if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) |
| @@ -160,5 +160,7 @@ config SND_BCD2000 · 159 unmodified lines | ||
| 160 | 160 | To compile this driver as a module, choose M here: the module |
| 161 | 161 | will be called snd-bcd2000. |
| 162 | 162 | |
| 163 | +source "sound/usb/line6/Kconfig" | |
| 164 | + | |
| 163 | 165 | endif # SND_USB |
| 164 | 166 | |
| @@ -25,3 +25,4 @@ obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o · 24 unmodified lines | ||
| 25 | 25 | obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o |
| 26 | 26 | |
| 27 | 27 | obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ |
| 28 | +obj-$(CONFIG_LINE6_USB) += line6/ | |
| @@ -816,7 +816,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) · 815 unmodified lines | ||
| 816 | 816 | return -EINVAL; |
| 817 | 817 | } |
| 818 | 818 | |
| 819 | − if (cdev->n_streams < 2) { | |
| 819 | + if (cdev->n_streams < 1) { | |
| 820 | 820 | dev_err(dev, "bogus number of streams: %d\n", cdev->n_streams); |
| 821 | 821 | return -EINVAL; |
| 822 | 822 | } |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -400,6 +400,7 @@ struct snd_pcm_ops snd_line6_capture_ops = { · 399 unmodified lines | ||
| 400 | 400 | |
| 401 | 401 | int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) |
| 402 | 402 | { |
| 403 | + struct usb_line6 *line6 = line6pcm->line6; | |
| 403 | 404 | int i; |
| 404 | 405 | |
| 405 | 406 | /* create audio URBs and fill in constant values: */ |
| @@ -411,14 +412,14 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) · 5 unmodified lines | ||
| 411 | 412 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); |
| 412 | 413 | |
| 413 | 414 | if (urb == NULL) { |
| 414 | − dev_err(line6pcm->line6->ifcdev, "Out of memory\n"); | |
| 415 | + dev_err(line6->ifcdev, "Out of memory\n"); | |
| 415 | 416 | return -ENOMEM; |
| 416 | 417 | } |
| 417 | 418 | |
| 418 | − urb->dev = line6pcm->line6->usbdev; | |
| 419 | + urb->dev = line6->usbdev; | |
| 419 | 420 | urb->pipe = |
| 420 | − usb_rcvisocpipe(line6pcm->line6->usbdev, | |
| 421 | − line6pcm->ep_audio_read & | |
| 421 | + usb_rcvisocpipe(line6->usbdev, | |
| 422 | + line6->properties->ep_audio_r & | |
| 422 | 423 | USB_ENDPOINT_NUMBER_MASK); |
| 423 | 424 | urb->transfer_flags = URB_ISO_ASAP; |
| 424 | 425 | urb->start_frame = -1; |
File renamed without changes.
| @@ -30,61 +30,251 @@ · 29 unmodified lines | ||
| 30 | 30 | #define DRIVER_DESC "Line6 USB Driver" |
| 31 | 31 | #define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION |
| 32 | 32 | |
| 33 | +#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) | |
| 34 | +#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n) | |
| 35 | + | |
| 33 | 36 | /* table of devices that work with this driver */ |
| 34 | 37 | static const struct usb_device_id line6_id_table[] = { |
| 35 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)}, | |
| 36 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)}, | |
| 37 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)}, | |
| 38 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)}, | |
| 39 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)}, | |
| 40 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)}, | |
| 41 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD400)}, | |
| 42 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)}, | |
| 43 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)}, | |
| 44 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)}, | |
| 45 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)}, | |
| 46 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)}, | |
| 47 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)}, | |
| 48 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)}, | |
| 49 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)}, | |
| 50 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)}, | |
| 51 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)}, | |
| 52 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)}, | |
| 53 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)}, | |
| 54 | − {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)}, | |
| 55 | − {}, | |
| 38 | + { LINE6_DEVICE(0x4250), .driver_info = LINE6_BASSPODXT }, | |
| 39 | + { LINE6_DEVICE(0x4642), .driver_info = LINE6_BASSPODXTLIVE }, | |
| 40 | + { LINE6_DEVICE(0x4252), .driver_info = LINE6_BASSPODXTPRO }, | |
| 41 | + { LINE6_DEVICE(0x4750), .driver_info = LINE6_GUITARPORT }, | |
| 42 | + { LINE6_IF_NUM(0x5051, 1), .driver_info = LINE6_POCKETPOD }, | |
| 43 | + { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, | |
| 44 | + { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, | |
| 45 | + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | |
| 46 | + { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | |
| 47 | + { LINE6_DEVICE(0x4153), .driver_info = LINE6_PODSTUDIO_GX }, | |
| 48 | + { LINE6_DEVICE(0x4150), .driver_info = LINE6_PODSTUDIO_UX1 }, | |
| 49 | + { LINE6_IF_NUM(0x4151, 0), .driver_info = LINE6_PODSTUDIO_UX2 }, | |
| 50 | + { LINE6_DEVICE(0x5044), .driver_info = LINE6_PODXT }, | |
| 51 | + { LINE6_IF_NUM(0x4650, 0), .driver_info = LINE6_PODXTLIVE_POD }, | |
| 52 | + { LINE6_IF_NUM(0x4650, 1), .driver_info = LINE6_PODXTLIVE_VARIAX }, | |
| 53 | + { LINE6_DEVICE(0x5050), .driver_info = LINE6_PODXTPRO }, | |
| 54 | + { LINE6_DEVICE(0x4147), .driver_info = LINE6_TONEPORT_GX }, | |
| 55 | + { LINE6_DEVICE(0x4141), .driver_info = LINE6_TONEPORT_UX1 }, | |
| 56 | + { LINE6_IF_NUM(0x4142, 0), .driver_info = LINE6_TONEPORT_UX2 }, | |
| 57 | + { LINE6_DEVICE(0x534d), .driver_info = LINE6_VARIAX }, | |
| 58 | + {} | |
| 56 | 59 | }; |
| 57 | 60 | |
| 58 | 61 | MODULE_DEVICE_TABLE(usb, line6_id_table); |
| 59 | 62 | |
| 60 | −#define L6PROP(dev_bit, dev_id, dev_name, dev_cap)\ | |
| 61 | − {.device_bit = LINE6_BIT_##dev_bit, .id = dev_id,\ | |
| 62 | − .name = dev_name, .capabilities = LINE6_BIT_##dev_cap} | |
| 63 | − | |
| 64 | −/* *INDENT-OFF* */ | |
| 65 | 63 | static const struct line6_properties line6_properties_table[] = { |
| 66 | − L6PROP(BASSPODXT, "BassPODxt", "BassPODxt", CTRL_PCM_HW), | |
| 67 | − L6PROP(BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live", CTRL_PCM_HW), | |
| 68 | − L6PROP(BASSPODXTPRO, "BassPODxtPro", "BassPODxt Pro", CTRL_PCM_HW), | |
| 69 | − L6PROP(GUITARPORT, "GuitarPort", "GuitarPort", PCM), | |
| 70 | − L6PROP(POCKETPOD, "PocketPOD", "Pocket POD", CONTROL), | |
| 71 | − L6PROP(PODHD300, "PODHD300", "POD HD300", CTRL_PCM_HW), | |
| 72 | − L6PROP(PODHD400, "PODHD400", "POD HD400", CTRL_PCM_HW), | |
| 73 | − L6PROP(PODHD500, "PODHD500", "POD HD500", CTRL_PCM_HW), | |
| 74 | − L6PROP(PODSTUDIO_GX, "PODStudioGX", "POD Studio GX", PCM), | |
| 75 | − L6PROP(PODSTUDIO_UX1, "PODStudioUX1", "POD Studio UX1", PCM), | |
| 76 | − L6PROP(PODSTUDIO_UX2, "PODStudioUX2", "POD Studio UX2", PCM), | |
| 77 | − L6PROP(PODX3, "PODX3", "POD X3", PCM), | |
| 78 | − L6PROP(PODX3LIVE, "PODX3Live", "POD X3 Live", PCM), | |
| 79 | − L6PROP(PODXT, "PODxt", "PODxt", CTRL_PCM_HW), | |
| 80 | − L6PROP(PODXTLIVE, "PODxtLive", "PODxt Live", CTRL_PCM_HW), | |
| 81 | − L6PROP(PODXTPRO, "PODxtPro", "PODxt Pro", CTRL_PCM_HW), | |
| 82 | − L6PROP(TONEPORT_GX, "TonePortGX", "TonePort GX", PCM), | |
| 83 | − L6PROP(TONEPORT_UX1, "TonePortUX1", "TonePort UX1", PCM), | |
| 84 | − L6PROP(TONEPORT_UX2, "TonePortUX2", "TonePort UX2", PCM), | |
| 85 | − L6PROP(VARIAX, "Variax", "Variax Workbench", CONTROL), | |
| 64 | + [LINE6_BASSPODXT] = { | |
| 65 | + .id = "BassPODxt", | |
| 66 | + .name = "BassPODxt", | |
| 67 | + .capabilities = LINE6_CAP_CONTROL | |
| 68 | + | LINE6_CAP_PCM | |
| 69 | + | LINE6_CAP_HWMON, | |
| 70 | + .altsetting = 5, | |
| 71 | + .ep_ctrl_r = 0x84, | |
| 72 | + .ep_ctrl_w = 0x03, | |
| 73 | + .ep_audio_r = 0x82, | |
| 74 | + .ep_audio_w = 0x01, | |
| 75 | + }, | |
| 76 | + [LINE6_BASSPODXTLIVE] = { | |
| 77 | + .id = "BassPODxtLive", | |
| 78 | + .name = "BassPODxt Live", | |
| 79 | + .capabilities = LINE6_CAP_CONTROL | |
| 80 | + | LINE6_CAP_PCM | |
| 81 | + | LINE6_CAP_HWMON, | |
| 82 | + .altsetting = 1, | |
| 83 | + .ep_ctrl_r = 0x84, | |
| 84 | + .ep_ctrl_w = 0x03, | |
| 85 | + .ep_audio_r = 0x82, | |
| 86 | + .ep_audio_w = 0x01, | |
| 87 | + }, | |
| 88 | + [LINE6_BASSPODXTPRO] = { | |
| 89 | + .id = "BassPODxtPro", | |
| 90 | + .name = "BassPODxt Pro", | |
| 91 | + .capabilities = LINE6_CAP_CONTROL | |
| 92 | + | LINE6_CAP_PCM | |
| 93 | + | LINE6_CAP_HWMON, | |
| 94 | + .altsetting = 5, | |
| 95 | + .ep_ctrl_r = 0x84, | |
| 96 | + .ep_ctrl_w = 0x03, | |
| 97 | + .ep_audio_r = 0x82, | |
| 98 | + .ep_audio_w = 0x01, | |
| 99 | + }, | |
| 100 | + [LINE6_GUITARPORT] = { | |
| 101 | + .id = "GuitarPort", | |
| 102 | + .name = "GuitarPort", | |
| 103 | + .capabilities = LINE6_CAP_PCM, | |
| 104 | + .altsetting = 2, /* 1..4 seem to be ok */ | |
| 105 | + /* no control channel */ | |
| 106 | + .ep_audio_r = 0x82, | |
| 107 | + .ep_audio_w = 0x01, | |
| 108 | + }, | |
| 109 | + [LINE6_POCKETPOD] = { | |
| 110 | + .id = "PocketPOD", | |
| 111 | + .name = "Pocket POD", | |
| 112 | + .capabilities = LINE6_CAP_CONTROL, | |
| 113 | + .altsetting = 0, | |
| 114 | + .ep_ctrl_r = 0x82, | |
| 115 | + .ep_ctrl_w = 0x02, | |
| 116 | + /* no audio channel */ | |
| 117 | + }, | |
| 118 | + [LINE6_PODHD300] = { | |
| 119 | + .id = "PODHD300", | |
| 120 | + .name = "POD HD300", | |
| 121 | + .capabilities = LINE6_CAP_CONTROL | |
| 122 | + | LINE6_CAP_PCM | |
| 123 | + | LINE6_CAP_HWMON, | |
| 124 | + .altsetting = 5, | |
| 125 | + .ep_ctrl_r = 0x84, | |
| 126 | + .ep_ctrl_w = 0x03, | |
| 127 | + .ep_audio_r = 0x82, | |
| 128 | + .ep_audio_w = 0x01, | |
| 129 | + }, | |
| 130 | + [LINE6_PODHD400] = { | |
| 131 | + .id = "PODHD400", | |
| 132 | + .name = "POD HD400", | |
| 133 | + .capabilities = LINE6_CAP_CONTROL | |
| 134 | + | LINE6_CAP_PCM | |
| 135 | + | LINE6_CAP_HWMON, | |
| 136 | + .altsetting = 5, | |
| 137 | + .ep_ctrl_r = 0x84, | |
| 138 | + .ep_ctrl_w = 0x03, | |
| 139 | + .ep_audio_r = 0x82, | |
| 140 | + .ep_audio_w = 0x01, | |
| 141 | + }, | |
| 142 | + [LINE6_PODHD500_0] = { | |
| 143 | + .id = "PODHD500", | |
| 144 | + .name = "POD HD500", | |
| 145 | + .capabilities = LINE6_CAP_CONTROL | |
| 146 | + | LINE6_CAP_PCM | |
| 147 | + | LINE6_CAP_HWMON, | |
| 148 | + .altsetting = 1, | |
| 149 | + .ep_ctrl_r = 0x81, | |
| 150 | + .ep_ctrl_w = 0x01, | |
| 151 | + .ep_audio_r = 0x86, | |
| 152 | + .ep_audio_w = 0x02, | |
| 153 | + }, | |
| 154 | + [LINE6_PODHD500_1] = { | |
| 155 | + .id = "PODHD500", | |
| 156 | + .name = "POD HD500", | |
| 157 | + .capabilities = LINE6_CAP_CONTROL | |
| 158 | + | LINE6_CAP_PCM | |
| 159 | + | LINE6_CAP_HWMON, | |
| 160 | + .altsetting = 1, | |
| 161 | + .ep_ctrl_r = 0x81, | |
| 162 | + .ep_ctrl_w = 0x01, | |
| 163 | + .ep_audio_r = 0x86, | |
| 164 | + .ep_audio_w = 0x02, | |
| 165 | + }, | |
| 166 | + [LINE6_PODSTUDIO_GX] = { | |
| 167 | + .id = "PODStudioGX", | |
| 168 | + .name = "POD Studio GX", | |
| 169 | + .capabilities = LINE6_CAP_PCM, | |
| 170 | + .altsetting = 2, /* 1..4 seem to be ok */ | |
| 171 | + /* no control channel */ | |
| 172 | + .ep_audio_r = 0x82, | |
| 173 | + .ep_audio_w = 0x01, | |
| 174 | + }, | |
| 175 | + [LINE6_PODSTUDIO_UX1] = { | |
| 176 | + .id = "PODStudioUX1", | |
| 177 | + .name = "POD Studio UX1", | |
| 178 | + .capabilities = LINE6_CAP_PCM, | |
| 179 | + .altsetting = 2, /* 1..4 seem to be ok */ | |
| 180 | + /* no control channel */ | |
| 181 | + .ep_audio_r = 0x82, | |
| 182 | + .ep_audio_w = 0x01, | |
| 183 | + }, | |
| 184 | + [LINE6_PODSTUDIO_UX2] = { | |
| 185 | + .id = "PODStudioUX2", | |
| 186 | + .name = "POD Studio UX2", | |
| 187 | + .capabilities = LINE6_CAP_PCM, | |
| 188 | + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ | |
| 189 | + /* no control channel */ | |
| 190 | + .ep_audio_r = 0x82, | |
| 191 | + .ep_audio_w = 0x01, | |
| 192 | + }, | |
| 193 | + [LINE6_PODXT] = { | |
| 194 | + .id = "PODxt", | |
| 195 | + .name = "PODxt", | |
| 196 | + .capabilities = LINE6_CAP_CONTROL | |
| 197 | + | LINE6_CAP_PCM | |
| 198 | + | LINE6_CAP_HWMON, | |
| 199 | + .altsetting = 5, | |
| 200 | + .ep_ctrl_r = 0x84, | |
| 201 | + .ep_ctrl_w = 0x03, | |
| 202 | + .ep_audio_r = 0x82, | |
| 203 | + .ep_audio_w = 0x01, | |
| 204 | + }, | |
| 205 | + [LINE6_PODXTLIVE_POD] = { | |
| 206 | + .id = "PODxtLive", | |
| 207 | + .name = "PODxt Live", | |
| 208 | + .capabilities = LINE6_CAP_CONTROL | |
| 209 | + | LINE6_CAP_PCM | |
| 210 | + | LINE6_CAP_HWMON, | |
| 211 | + .altsetting = 1, | |
| 212 | + .ep_ctrl_r = 0x84, | |
| 213 | + .ep_ctrl_w = 0x03, | |
| 214 | + .ep_audio_r = 0x82, | |
| 215 | + .ep_audio_w = 0x01, | |
| 216 | + }, | |
| 217 | + [LINE6_PODXTLIVE_VARIAX] = { | |
| 218 | + .id = "PODxtLive", | |
| 219 | + .name = "PODxt Live", | |
| 220 | + .capabilities = LINE6_CAP_CONTROL | |
| 221 | + | LINE6_CAP_PCM | |
| 222 | + | LINE6_CAP_HWMON, | |
| 223 | + .altsetting = 1, | |
| 224 | + .ep_ctrl_r = 0x86, | |
| 225 | + .ep_ctrl_w = 0x05, | |
| 226 | + .ep_audio_r = 0x82, | |
| 227 | + .ep_audio_w = 0x01, | |
| 228 | + }, | |
| 229 | + [LINE6_PODXTPRO] = { | |
| 230 | + .id = "PODxtPro", | |
| 231 | + .name = "PODxt Pro", | |
| 232 | + .capabilities = LINE6_CAP_CONTROL | |
| 233 | + | LINE6_CAP_PCM | |
| 234 | + | LINE6_CAP_HWMON, | |
| 235 | + .altsetting = 5, | |
| 236 | + .ep_ctrl_r = 0x84, | |
| 237 | + .ep_ctrl_w = 0x03, | |
| 238 | + .ep_audio_r = 0x82, | |
| 239 | + .ep_audio_w = 0x01, | |
| 240 | + }, | |
| 241 | + [LINE6_TONEPORT_GX] = { | |
| 242 | + .id = "TonePortGX", | |
| 243 | + .name = "TonePort GX", | |
| 244 | + .capabilities = LINE6_CAP_PCM, | |
| 245 | + .altsetting = 2, /* 1..4 seem to be ok */ | |
| 246 | + /* no control channel */ | |
| 247 | + .ep_audio_r = 0x82, | |
| 248 | + .ep_audio_w = 0x01, | |
| 249 | + }, | |
| 250 | + [LINE6_TONEPORT_UX1] = { | |
| 251 | + .id = "TonePortUX1", | |
| 252 | + .name = "TonePort UX1", | |
| 253 | + .capabilities = LINE6_CAP_PCM, | |
| 254 | + .altsetting = 2, /* 1..4 seem to be ok */ | |
| 255 | + /* no control channel */ | |
| 256 | + .ep_audio_r = 0x82, | |
| 257 | + .ep_audio_w = 0x01, | |
| 258 | + }, | |
| 259 | + [LINE6_TONEPORT_UX2] = { | |
| 260 | + .id = "TonePortUX2", | |
| 261 | + .name = "TonePort UX2", | |
| 262 | + .capabilities = LINE6_CAP_PCM, | |
| 263 | + .altsetting = 2, /* defaults to 44.1kHz, 16-bit */ | |
| 264 | + /* no control channel */ | |
| 265 | + .ep_audio_r = 0x82, | |
| 266 | + .ep_audio_w = 0x01, | |
| 267 | + }, | |
| 268 | + [LINE6_VARIAX] = { | |
| 269 | + .id = "Variax", | |
| 270 | + .name = "Variax Workbench", | |
| 271 | + .capabilities = LINE6_CAP_CONTROL, | |
| 272 | + .altsetting = 1, | |
| 273 | + .ep_ctrl_r = 0x82, | |
| 274 | + .ep_ctrl_w = 0x01, | |
| 275 | + /* no audio channel */ | |
| 276 | + } | |
| 86 | 277 | }; |
| 87 | −/* *INDENT-ON* */ | |
| 88 | 278 | |
| 89 | 279 | /* |
| 90 | 280 | This is Line6's MIDI manufacturer ID. |
| @@ -126,9 +316,9 @@ static int line6_start_listen(struct usb_line6 *line6) · 35 unmodified lines | ||
| 126 | 316 | int err; |
| 127 | 317 | |
| 128 | 318 | usb_fill_int_urb(line6->urb_listen, line6->usbdev, |
| 129 | − usb_rcvintpipe(line6->usbdev, line6->ep_control_read), | |
| 130 | − line6->buffer_listen, LINE6_BUFSIZE_LISTEN, | |
| 131 | − line6_data_received, line6, line6->interval); | |
| 319 | + usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), | |
| 320 | + line6->buffer_listen, LINE6_BUFSIZE_LISTEN, | |
| 321 | + line6_data_received, line6, line6->interval); | |
| 132 | 322 | line6->urb_listen->actual_length = 0; |
| 133 | 323 | err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); |
| 134 | 324 | return err; |
| @@ -158,7 +348,7 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, · 23 unmodified lines | ||
| 158 | 348 | |
| 159 | 349 | retval = usb_interrupt_msg(line6->usbdev, |
| 160 | 350 | usb_sndintpipe(line6->usbdev, |
| 161 | − line6->ep_control_write), | |
| 351 | + line6->properties->ep_ctrl_w), | |
| 162 | 352 | (char *)frag_buf, frag_size, |
| 163 | 353 | &partial, LINE6_TIMEOUT * HZ); |
| 164 | 354 | |
| @@ -200,9 +390,9 @@ static int line6_send_raw_message_async_part(struct message *msg, · 35 unmodified lines | ||
| 200 | 390 | int bytes = min(msg->size - done, line6->max_packet_size); |
| 201 | 391 | |
| 202 | 392 | usb_fill_int_urb(urb, line6->usbdev, |
| 203 | − usb_sndintpipe(line6->usbdev, line6->ep_control_write), | |
| 204 | − (char *)msg->buffer + done, bytes, | |
| 205 | − line6_async_request_sent, msg, line6->interval); | |
| 393 | + usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), | |
| 394 | + (char *)msg->buffer + done, bytes, | |
| 395 | + line6_async_request_sent, msg, line6->interval); | |
| 206 | 396 | |
| 207 | 397 | msg->done += bytes; |
| 208 | 398 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -347,50 +537,8 @@ static void line6_data_received(struct urb *urb) · 138 unmodified lines | ||
| 347 | 537 | line6->message_length = done; |
| 348 | 538 | line6_midi_receive(line6, line6->buffer_message, done); |
| 349 | 539 | |
| 350 | − switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) { | |
| 351 | − case LINE6_DEVID_BASSPODXT: | |
| 352 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 353 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 354 | − case LINE6_DEVID_PODXT: | |
| 355 | − case LINE6_DEVID_PODXTPRO: | |
| 356 | − case LINE6_DEVID_POCKETPOD: | |
| 357 | − line6_pod_process_message((struct usb_line6_pod *) | |
| 358 | − line6); | |
| 359 | − break; | |
| 360 | − | |
| 361 | − case LINE6_DEVID_PODHD300: | |
| 362 | − case LINE6_DEVID_PODHD400: | |
| 363 | − case LINE6_DEVID_PODHD500: | |
| 364 | − break; /* let userspace handle MIDI */ | |
| 365 | − | |
| 366 | − case LINE6_DEVID_PODXTLIVE: | |
| 367 | − switch (line6->interface_number) { | |
| 368 | − case PODXTLIVE_INTERFACE_POD: | |
| 369 | − line6_pod_process_message((struct usb_line6_pod | |
| 370 | − *)line6); | |
| 371 | − break; | |
| 372 | − | |
| 373 | − case PODXTLIVE_INTERFACE_VARIAX: | |
| 374 | − line6_variax_process_message((struct | |
| 375 | − usb_line6_variax | |
| 376 | − *)line6); | |
| 377 | − break; | |
| 378 | − | |
| 379 | − default: | |
| 380 | − dev_err(line6->ifcdev, | |
| 381 | − "PODxt Live interface %d not supported\n", | |
| 382 | − line6->interface_number); | |
| 383 | − } | |
| 384 | − break; | |
| 385 | − | |
| 386 | − case LINE6_DEVID_VARIAX: | |
| 387 | − line6_variax_process_message((struct usb_line6_variax *) | |
| 388 | − line6); | |
| 389 | − break; | |
| 390 | − | |
| 391 | − default: | |
| 392 | − MISSING_CASE; | |
| 393 | − } | |
| 540 | + if (line6->process_message) | |
| 541 | + line6->process_message(line6); | |
| 394 | 542 | } |
| 395 | 543 | |
| 396 | 544 | line6_start_listen(line6); |
| @@ -414,7 +562,7 @@ int line6_send_program(struct usb_line6 *line6, u8 value) · 17 unmodified lines | ||
| 414 | 562 | |
| 415 | 563 | retval = usb_interrupt_msg(line6->usbdev, |
| 416 | 564 | usb_sndintpipe(line6->usbdev, |
| 417 | − line6->ep_control_write), | |
| 565 | + line6->properties->ep_ctrl_w), | |
| 418 | 566 | buffer, 2, &partial, LINE6_TIMEOUT * HZ); |
| 419 | 567 | |
| 420 | 568 | if (retval) |
| @@ -444,7 +592,7 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value) · 23 unmodified lines | ||
| 444 | 592 | |
| 445 | 593 | retval = usb_interrupt_msg(line6->usbdev, |
| 446 | 594 | usb_sndintpipe(line6->usbdev, |
| 447 | − line6->ep_control_write), | |
| 595 | + line6->properties->ep_ctrl_w), | |
| 448 | 596 | buffer, 3, &partial, LINE6_TIMEOUT * HZ); |
| 449 | 597 | |
| 450 | 598 | if (retval) |
| @@ -608,14 +756,12 @@ static void line6_destruct(struct usb_interface *interface) · 157 unmodified lines | ||
| 608 | 756 | static int line6_probe(struct usb_interface *interface, |
| 609 | 757 | const struct usb_device_id *id) |
| 610 | 758 | { |
| 611 | − int devtype; | |
| 759 | + enum line6_device_type devtype; | |
| 612 | 760 | struct usb_device *usbdev; |
| 613 | 761 | struct usb_line6 *line6; |
| 614 | 762 | const struct line6_properties *properties; |
| 615 | − int interface_number, alternate = 0; | |
| 616 | − int product; | |
| 763 | + int interface_number; | |
| 617 | 764 | int size = 0; |
| 618 | − int ep_read = 0, ep_write = 0; | |
| 619 | 765 | int ret; |
| 620 | 766 | |
| 621 | 767 | if (interface == NULL) |
| @@ -630,184 +776,66 @@ static int line6_probe(struct usb_interface *interface, · 8 unmodified lines | ||
| 630 | 776 | goto err_put; |
| 631 | 777 | } |
| 632 | 778 | |
| 633 | − /* check vendor and product id */ | |
| 634 | − for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) { | |
| 635 | − u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor); | |
| 636 | − u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); | |
| 637 | − | |
| 638 | − if (idVendor == line6_id_table[devtype].idVendor && | |
| 639 | − idProduct == line6_id_table[devtype].idProduct) | |
| 640 | − break; | |
| 641 | − } | |
| 642 | − | |
| 643 | − if (devtype < 0) { | |
| 644 | − ret = -ENODEV; | |
| 645 | − goto err_put; | |
| 646 | − } | |
| 779 | + devtype = id->driver_info; | |
| 647 | 780 | |
| 648 | 781 | /* initialize device info: */ |
| 649 | 782 | properties = &line6_properties_table[devtype]; |
| 650 | 783 | dev_info(&interface->dev, "Line6 %s found\n", properties->name); |
| 651 | − product = le16_to_cpu(usbdev->descriptor.idProduct); | |
| 652 | 784 | |
| 653 | 785 | /* query interface number */ |
| 654 | 786 | interface_number = interface->cur_altsetting->desc.bInterfaceNumber; |
| 655 | 787 | |
| 656 | − switch (product) { | |
| 657 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 658 | − case LINE6_DEVID_PODXTLIVE: | |
| 659 | − case LINE6_DEVID_VARIAX: | |
| 660 | − alternate = 1; | |
| 661 | − break; | |
| 662 | − | |
| 663 | − case LINE6_DEVID_POCKETPOD: | |
| 664 | − switch (interface_number) { | |
| 665 | − case 0: | |
| 666 | − return -ENODEV; /* this interface has no endpoints */ | |
| 667 | − case 1: | |
| 668 | − alternate = 0; | |
| 669 | − break; | |
| 670 | − default: | |
| 671 | − MISSING_CASE; | |
| 672 | − } | |
| 673 | − break; | |
| 674 | − | |
| 675 | − case LINE6_DEVID_PODHD500: | |
| 676 | − case LINE6_DEVID_PODX3: | |
| 677 | − case LINE6_DEVID_PODX3LIVE: | |
| 678 | − switch (interface_number) { | |
| 679 | − case 0: | |
| 680 | − alternate = 1; | |
| 681 | − break; | |
| 682 | − case 1: | |
| 683 | − alternate = 0; | |
| 684 | − break; | |
| 685 | − default: | |
| 686 | − MISSING_CASE; | |
| 687 | − } | |
| 688 | − break; | |
| 689 | − | |
| 690 | − case LINE6_DEVID_BASSPODXT: | |
| 691 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 692 | − case LINE6_DEVID_PODXT: | |
| 693 | − case LINE6_DEVID_PODXTPRO: | |
| 694 | − case LINE6_DEVID_PODHD300: | |
| 695 | − case LINE6_DEVID_PODHD400: | |
| 696 | − alternate = 5; | |
| 697 | − break; | |
| 698 | − | |
| 699 | − case LINE6_DEVID_GUITARPORT: | |
| 700 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 701 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 702 | − case LINE6_DEVID_TONEPORT_GX: | |
| 703 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 704 | − alternate = 2; /* 1..4 seem to be ok */ | |
| 705 | − break; | |
| 706 | − | |
| 707 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 708 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 709 | − switch (interface_number) { | |
| 710 | − case 0: | |
| 711 | − /* defaults to 44.1kHz, 16-bit */ | |
| 712 | − alternate = 2; | |
| 713 | − break; | |
| 714 | − case 1: | |
| 715 | − /* don't know yet what this is ... | |
| 716 | − alternate = 1; | |
| 717 | − break; | |
| 718 | − */ | |
| 719 | − return -ENODEV; | |
| 720 | − default: | |
| 721 | − MISSING_CASE; | |
| 722 | − } | |
| 723 | − break; | |
| 724 | − | |
| 725 | − default: | |
| 726 | − MISSING_CASE; | |
| 727 | − ret = -ENODEV; | |
| 728 | − goto err_put; | |
| 729 | − } | |
| 730 | − | |
| 731 | − ret = usb_set_interface(usbdev, interface_number, alternate); | |
| 788 | + ret = usb_set_interface(usbdev, interface_number, | |
| 789 | + properties->altsetting); | |
| 732 | 790 | if (ret < 0) { |
| 733 | 791 | dev_err(&interface->dev, "set_interface failed\n"); |
| 734 | 792 | goto err_put; |
| 735 | 793 | } |
| 736 | 794 | |
| 737 | − /* initialize device data based on product id: */ | |
| 738 | − switch (product) { | |
| 739 | − case LINE6_DEVID_BASSPODXT: | |
| 740 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 741 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 742 | − case LINE6_DEVID_PODXT: | |
| 743 | − case LINE6_DEVID_PODXTPRO: | |
| 795 | + /* initialize device data based on device: */ | |
| 796 | + switch (devtype) { | |
| 797 | + case LINE6_BASSPODXT: | |
| 798 | + case LINE6_BASSPODXTLIVE: | |
| 799 | + case LINE6_BASSPODXTPRO: | |
| 800 | + case LINE6_PODXT: | |
| 801 | + case LINE6_PODXTPRO: | |
| 744 | 802 | size = sizeof(struct usb_line6_pod); |
| 745 | − ep_read = 0x84; | |
| 746 | − ep_write = 0x03; | |
| 747 | 803 | break; |
| 748 | 804 | |
| 749 | − case LINE6_DEVID_PODHD300: | |
| 750 | − case LINE6_DEVID_PODHD400: | |
| 805 | + case LINE6_PODHD300: | |
| 806 | + case LINE6_PODHD400: | |
| 751 | 807 | size = sizeof(struct usb_line6_podhd); |
| 752 | − ep_read = 0x84; | |
| 753 | − ep_write = 0x03; | |
| 754 | 808 | break; |
| 755 | 809 | |
| 756 | − case LINE6_DEVID_PODHD500: | |
| 810 | + case LINE6_PODHD500_0: | |
| 811 | + case LINE6_PODHD500_1: | |
| 757 | 812 | size = sizeof(struct usb_line6_podhd); |
| 758 | − ep_read = 0x81; | |
| 759 | − ep_write = 0x01; | |
| 760 | − break; | |
| 761 | − | |
| 762 | − case LINE6_DEVID_POCKETPOD: | |
| 763 | − size = sizeof(struct usb_line6_pod); | |
| 764 | − ep_read = 0x82; | |
| 765 | − ep_write = 0x02; | |
| 766 | 813 | break; |
| 767 | 814 | |
| 768 | − case LINE6_DEVID_PODX3: | |
| 769 | − case LINE6_DEVID_PODX3LIVE: | |
| 770 | − /* currently unused! */ | |
| 815 | + case LINE6_POCKETPOD: | |
| 771 | 816 | size = sizeof(struct usb_line6_pod); |
| 772 | − ep_read = 0x81; | |
| 773 | − ep_write = 0x01; | |
| 774 | 817 | break; |
| 775 | 818 | |
| 776 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 777 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 778 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 779 | − case LINE6_DEVID_TONEPORT_GX: | |
| 780 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 781 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 782 | − case LINE6_DEVID_GUITARPORT: | |
| 819 | + case LINE6_PODSTUDIO_GX: | |
| 820 | + case LINE6_PODSTUDIO_UX1: | |
| 821 | + case LINE6_PODSTUDIO_UX2: | |
| 822 | + case LINE6_TONEPORT_GX: | |
| 823 | + case LINE6_TONEPORT_UX1: | |
| 824 | + case LINE6_TONEPORT_UX2: | |
| 825 | + case LINE6_GUITARPORT: | |
| 783 | 826 | size = sizeof(struct usb_line6_toneport); |
| 784 | − /* these don't have a control channel */ | |
| 785 | 827 | break; |
| 786 | 828 | |
| 787 | − case LINE6_DEVID_PODXTLIVE: | |
| 788 | − switch (interface_number) { | |
| 789 | − case PODXTLIVE_INTERFACE_POD: | |
| 790 | − size = sizeof(struct usb_line6_pod); | |
| 791 | − ep_read = 0x84; | |
| 792 | − ep_write = 0x03; | |
| 793 | − break; | |
| 794 | − | |
| 795 | − case PODXTLIVE_INTERFACE_VARIAX: | |
| 796 | − size = sizeof(struct usb_line6_variax); | |
| 797 | − ep_read = 0x86; | |
| 798 | − ep_write = 0x05; | |
| 799 | − break; | |
| 829 | + case LINE6_PODXTLIVE_POD: | |
| 830 | + size = sizeof(struct usb_line6_pod); | |
| 831 | + break; | |
| 800 | 832 | |
| 801 | − default: | |
| 802 | − ret = -ENODEV; | |
| 803 | − goto err_put; | |
| 804 | − } | |
| 833 | + case LINE6_PODXTLIVE_VARIAX: | |
| 834 | + size = sizeof(struct usb_line6_variax); | |
| 805 | 835 | break; |
| 806 | 836 | |
| 807 | − case LINE6_DEVID_VARIAX: | |
| 837 | + case LINE6_VARIAX: | |
| 808 | 838 | size = sizeof(struct usb_line6_variax); |
| 809 | − ep_read = 0x82; | |
| 810 | − ep_write = 0x01; | |
| 811 | 839 | break; |
| 812 | 840 | |
| 813 | 841 | default: |
| @@ -830,19 +858,16 @@ static int line6_probe(struct usb_interface *interface, · 16 unmodified lines | ||
| 830 | 858 | } |
| 831 | 859 | |
| 832 | 860 | /* store basic data: */ |
| 833 | − line6->interface_number = interface_number; | |
| 834 | 861 | line6->properties = properties; |
| 835 | 862 | line6->usbdev = usbdev; |
| 836 | 863 | line6->ifcdev = &interface->dev; |
| 837 | − line6->ep_control_read = ep_read; | |
| 838 | − line6->ep_control_write = ep_write; | |
| 839 | − line6->product = product; | |
| 864 | + line6->type = devtype; | |
| 840 | 865 | |
| 841 | 866 | /* get data from endpoint descriptor (see usb_maxpacket): */ |
| 842 | 867 | { |
| 843 | 868 | struct usb_host_endpoint *ep; |
| 844 | − unsigned epnum = | |
| 845 | − usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read)); | |
| 869 | + unsigned pipe = usb_rcvintpipe(usbdev, properties->ep_ctrl_r); | |
| 870 | + unsigned epnum = usb_pipeendpoint(pipe); | |
| 846 | 871 | ep = usbdev->ep_in[epnum]; |
| 847 | 872 | |
| 848 | 873 | if (ep != NULL) { |
| @@ -859,7 +884,7 @@ static int line6_probe(struct usb_interface *interface, · 10 unmodified lines | ||
| 859 | 884 | |
| 860 | 885 | usb_set_intfdata(interface, line6); |
| 861 | 886 | |
| 862 | − if (properties->capabilities & LINE6_BIT_CONTROL) { | |
| 887 | + if (properties->capabilities & LINE6_CAP_CONTROL) { | |
| 863 | 888 | /* initialize USB buffers: */ |
| 864 | 889 | line6->buffer_listen = |
| 865 | 890 | kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); |
| @@ -892,65 +917,44 @@ static int line6_probe(struct usb_interface *interface, · 26 unmodified lines | ||
| 892 | 917 | } |
| 893 | 918 | } |
| 894 | 919 | |
| 895 | − /* initialize device data based on product id: */ | |
| 896 | − switch (product) { | |
| 897 | − case LINE6_DEVID_BASSPODXT: | |
| 898 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 899 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 900 | − case LINE6_DEVID_POCKETPOD: | |
| 901 | − case LINE6_DEVID_PODX3: | |
| 902 | − case LINE6_DEVID_PODX3LIVE: | |
| 903 | − case LINE6_DEVID_PODXT: | |
| 904 | − case LINE6_DEVID_PODXTPRO: | |
| 905 | − ret = line6_pod_init(interface, (struct usb_line6_pod *)line6); | |
| 920 | + /* initialize device data based on device: */ | |
| 921 | + switch (devtype) { | |
| 922 | + case LINE6_BASSPODXT: | |
| 923 | + case LINE6_BASSPODXTLIVE: | |
| 924 | + case LINE6_BASSPODXTPRO: | |
| 925 | + case LINE6_POCKETPOD: | |
| 926 | + case LINE6_PODXT: | |
| 927 | + case LINE6_PODXTPRO: | |
| 928 | + ret = line6_pod_init(interface, line6); | |
| 906 | 929 | break; |
| 907 | 930 | |
| 908 | − case LINE6_DEVID_PODHD300: | |
| 909 | − case LINE6_DEVID_PODHD400: | |
| 910 | − case LINE6_DEVID_PODHD500: | |
| 911 | − ret = line6_podhd_init(interface, | |
| 912 | − (struct usb_line6_podhd *)line6); | |
| 931 | + case LINE6_PODHD300: | |
| 932 | + case LINE6_PODHD400: | |
| 933 | + case LINE6_PODHD500_0: | |
| 934 | + case LINE6_PODHD500_1: | |
| 935 | + ret = line6_podhd_init(interface, line6); | |
| 913 | 936 | break; |
| 914 | 937 | |
| 915 | − case LINE6_DEVID_PODXTLIVE: | |
| 916 | − switch (interface_number) { | |
| 917 | − case PODXTLIVE_INTERFACE_POD: | |
| 918 | − ret = | |
| 919 | − line6_pod_init(interface, | |
| 920 | − (struct usb_line6_pod *)line6); | |
| 921 | − break; | |
| 922 | − | |
| 923 | − case PODXTLIVE_INTERFACE_VARIAX: | |
| 924 | − ret = | |
| 925 | − line6_variax_init(interface, | |
| 926 | − (struct usb_line6_variax *)line6); | |
| 927 | − break; | |
| 928 | − | |
| 929 | − default: | |
| 930 | − dev_err(&interface->dev, | |
| 931 | − "PODxt Live interface %d not supported\n", | |
| 932 | − interface_number); | |
| 933 | − ret = -ENODEV; | |
| 934 | − } | |
| 938 | + case LINE6_PODXTLIVE_POD: | |
| 939 | + ret = line6_pod_init(interface, line6); | |
| 940 | + break; | |
| 935 | 941 | |
| 942 | + case LINE6_PODXTLIVE_VARIAX: | |
| 943 | + ret = line6_variax_init(interface, line6); | |
| 936 | 944 | break; |
| 937 | 945 | |
| 938 | − case LINE6_DEVID_VARIAX: | |
| 939 | − ret = | |
| 940 | − line6_variax_init(interface, | |
| 941 | − (struct usb_line6_variax *)line6); | |
| 946 | + case LINE6_VARIAX: | |
| 947 | + ret = line6_variax_init(interface, line6); | |
| 942 | 948 | break; |
| 943 | 949 | |
| 944 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 945 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 946 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 947 | − case LINE6_DEVID_TONEPORT_GX: | |
| 948 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 949 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 950 | − case LINE6_DEVID_GUITARPORT: | |
| 951 | − ret = | |
| 952 | − line6_toneport_init(interface, | |
| 953 | − (struct usb_line6_toneport *)line6); | |
| 950 | + case LINE6_PODSTUDIO_GX: | |
| 951 | + case LINE6_PODSTUDIO_UX1: | |
| 952 | + case LINE6_PODSTUDIO_UX2: | |
| 953 | + case LINE6_TONEPORT_GX: | |
| 954 | + case LINE6_TONEPORT_UX1: | |
| 955 | + case LINE6_TONEPORT_UX2: | |
| 956 | + case LINE6_GUITARPORT: | |
| 957 | + ret = line6_toneport_init(interface, line6); | |
| 954 | 958 | break; |
| 955 | 959 | |
| 956 | 960 | default: |
| @@ -971,14 +975,6 @@ static int line6_probe(struct usb_interface *interface, · 14 unmodified lines | ||
| 971 | 975 | dev_info(&interface->dev, "Line6 %s now attached\n", |
| 972 | 976 | line6->properties->name); |
| 973 | 977 | |
| 974 | − switch (product) { | |
| 975 | − case LINE6_DEVID_PODX3: | |
| 976 | − case LINE6_DEVID_PODX3LIVE: | |
| 977 | − dev_info(&interface->dev, | |
| 978 | − "NOTE: the Line6 %s is detected, but not yet supported\n", | |
| 979 | − line6->properties->name); | |
| 980 | − } | |
| 981 | − | |
| 982 | 978 | /* increment reference counters: */ |
| 983 | 979 | usb_get_intf(interface); |
| 984 | 980 | usb_get_dev(usbdev); |
| @@ -1021,54 +1017,7 @@ static void line6_disconnect(struct usb_interface *interface) · 36 unmodified lines | ||
| 1021 | 1017 | dev_err(line6->ifcdev, |
| 1022 | 1018 | "driver bug: inconsistent usb device\n"); |
| 1023 | 1019 | |
| 1024 | − switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) { | |
| 1025 | − case LINE6_DEVID_BASSPODXT: | |
| 1026 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 1027 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 1028 | − case LINE6_DEVID_POCKETPOD: | |
| 1029 | − case LINE6_DEVID_PODX3: | |
| 1030 | − case LINE6_DEVID_PODX3LIVE: | |
| 1031 | − case LINE6_DEVID_PODXT: | |
| 1032 | − case LINE6_DEVID_PODXTPRO: | |
| 1033 | − line6_pod_disconnect(interface); | |
| 1034 | − break; | |
| 1035 | − | |
| 1036 | − case LINE6_DEVID_PODHD300: | |
| 1037 | − case LINE6_DEVID_PODHD400: | |
| 1038 | − case LINE6_DEVID_PODHD500: | |
| 1039 | − line6_podhd_disconnect(interface); | |
| 1040 | − break; | |
| 1041 | − | |
| 1042 | − case LINE6_DEVID_PODXTLIVE: | |
| 1043 | − switch (interface_number) { | |
| 1044 | − case PODXTLIVE_INTERFACE_POD: | |
| 1045 | − line6_pod_disconnect(interface); | |
| 1046 | − break; | |
| 1047 | − | |
| 1048 | − case PODXTLIVE_INTERFACE_VARIAX: | |
| 1049 | − line6_variax_disconnect(interface); | |
| 1050 | − break; | |
| 1051 | − } | |
| 1052 | − | |
| 1053 | − break; | |
| 1054 | − | |
| 1055 | − case LINE6_DEVID_VARIAX: | |
| 1056 | − line6_variax_disconnect(interface); | |
| 1057 | − break; | |
| 1058 | − | |
| 1059 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 1060 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 1061 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 1062 | − case LINE6_DEVID_TONEPORT_GX: | |
| 1063 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 1064 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 1065 | − case LINE6_DEVID_GUITARPORT: | |
| 1066 | − line6_toneport_disconnect(interface); | |
| 1067 | − break; | |
| 1068 | − | |
| 1069 | − default: | |
| 1070 | − MISSING_CASE; | |
| 1071 | − } | |
| 1020 | + line6->disconnect(interface); | |
| 1072 | 1021 | |
| 1073 | 1022 | dev_info(&interface->dev, "Line6 %s now disconnected\n", |
| 1074 | 1023 | line6->properties->name); |
| @@ -1093,7 +1042,7 @@ static int line6_suspend(struct usb_interface *interface, pm_message_t message) · 18 unmodified lines | ||
| 1093 | 1042 | |
| 1094 | 1043 | snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot); |
| 1095 | 1044 | |
| 1096 | − if (line6->properties->capabilities & LINE6_BIT_CONTROL) | |
| 1045 | + if (line6->properties->capabilities & LINE6_CAP_CONTROL) | |
| 1097 | 1046 | line6_stop_listen(line6); |
| 1098 | 1047 | |
| 1099 | 1048 | if (line6pcm != NULL) { |
| @@ -1112,7 +1061,7 @@ static int line6_resume(struct usb_interface *interface) · 12 unmodified lines | ||
| 1112 | 1061 | { |
| 1113 | 1062 | struct usb_line6 *line6 = usb_get_intfdata(interface); |
| 1114 | 1063 | |
| 1115 | − if (line6->properties->capabilities & LINE6_BIT_CONTROL) | |
| 1064 | + if (line6->properties->capabilities & LINE6_CAP_CONTROL) | |
| 1116 | 1065 | line6_start_listen(line6); |
| 1117 | 1066 | |
| 1118 | 1067 | snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0); |
| @@ -1126,15 +1075,18 @@ static int line6_reset_resume(struct usb_interface *interface) · 7 unmodified lines | ||
| 1126 | 1075 | { |
| 1127 | 1076 | struct usb_line6 *line6 = usb_get_intfdata(interface); |
| 1128 | 1077 | |
| 1129 | − switch (le16_to_cpu(line6->usbdev->descriptor.idProduct)) { | |
| 1130 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 1131 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 1132 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 1133 | − case LINE6_DEVID_TONEPORT_GX: | |
| 1134 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 1135 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 1136 | − case LINE6_DEVID_GUITARPORT: | |
| 1078 | + switch (line6->type) { | |
| 1079 | + case LINE6_PODSTUDIO_GX: | |
| 1080 | + case LINE6_PODSTUDIO_UX1: | |
| 1081 | + case LINE6_PODSTUDIO_UX2: | |
| 1082 | + case LINE6_TONEPORT_GX: | |
| 1083 | + case LINE6_TONEPORT_UX1: | |
| 1084 | + case LINE6_TONEPORT_UX2: | |
| 1085 | + case LINE6_GUITARPORT: | |
| 1137 | 1086 | line6_toneport_reset_resume((struct usb_line6_toneport *)line6); |
| 1087 | + | |
| 1088 | + default: | |
| 1089 | + break; | |
| 1138 | 1090 | } |
| 1139 | 1091 | |
| 1140 | 1092 | return line6_resume(interface); |
| @@ -20,6 +20,29 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #define DRIVER_NAME "line6usb" |
| 22 | 22 | |
| 23 | +enum line6_device_type { | |
| 24 | + LINE6_BASSPODXT, | |
| 25 | + LINE6_BASSPODXTLIVE, | |
| 26 | + LINE6_BASSPODXTPRO, | |
| 27 | + LINE6_GUITARPORT, | |
| 28 | + LINE6_POCKETPOD, | |
| 29 | + LINE6_PODHD300, | |
| 30 | + LINE6_PODHD400, | |
| 31 | + LINE6_PODHD500_0, | |
| 32 | + LINE6_PODHD500_1, | |
| 33 | + LINE6_PODSTUDIO_GX, | |
| 34 | + LINE6_PODSTUDIO_UX1, | |
| 35 | + LINE6_PODSTUDIO_UX2, | |
| 36 | + LINE6_PODXT, | |
| 37 | + LINE6_PODXTLIVE_POD, | |
| 38 | + LINE6_PODXTLIVE_VARIAX, | |
| 39 | + LINE6_PODXTPRO, | |
| 40 | + LINE6_TONEPORT_GX, | |
| 41 | + LINE6_TONEPORT_UX1, | |
| 42 | + LINE6_TONEPORT_UX2, | |
| 43 | + LINE6_VARIAX | |
| 44 | +}; | |
| 45 | + | |
| 23 | 46 | #define LINE6_TIMEOUT 1 |
| 24 | 47 | #define LINE6_BUFSIZE_LISTEN 32 |
| 25 | 48 | #define LINE6_MESSAGE_MAXLEN 256 |
| @@ -75,11 +98,6 @@ static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; · 49 unmodified lines | ||
| 75 | 98 | Common properties of Line6 devices. |
| 76 | 99 | */ |
| 77 | 100 | struct line6_properties { |
| 78 | − /** | |
| 79 | − Bit identifying this device in the line6usb driver. | |
| 80 | − */ | |
| 81 | − int device_bit; | |
| 82 | − | |
| 83 | 101 | /** |
| 84 | 102 | Card id string (maximum 16 characters). |
| 85 | 103 | This can be used to address the device in ALSA programs as |
| @@ -97,6 +115,13 @@ struct line6_properties { · 11 unmodified lines | ||
| 97 | 115 | line6usb driver. |
| 98 | 116 | */ |
| 99 | 117 | int capabilities; |
| 118 | + | |
| 119 | + int altsetting; | |
| 120 | + | |
| 121 | + unsigned ep_ctrl_r; | |
| 122 | + unsigned ep_ctrl_w; | |
| 123 | + unsigned ep_audio_r; | |
| 124 | + unsigned ep_audio_w; | |
| 100 | 125 | }; |
| 101 | 126 | |
| 102 | 127 | /** |
| @@ -110,20 +135,15 @@ struct usb_line6 { · 7 unmodified lines | ||
| 110 | 135 | struct usb_device *usbdev; |
| 111 | 136 | |
| 112 | 137 | /** |
| 113 | − Product id. | |
| 138 | + Device type. | |
| 114 | 139 | */ |
| 115 | − int product; | |
| 140 | + enum line6_device_type type; | |
| 116 | 141 | |
| 117 | 142 | /** |
| 118 | 143 | Properties. |
| 119 | 144 | */ |
| 120 | 145 | const struct line6_properties *properties; |
| 121 | 146 | |
| 122 | − /** | |
| 123 | − Interface number. | |
| 124 | − */ | |
| 125 | − int interface_number; | |
| 126 | − | |
| 127 | 147 | /** |
| 128 | 148 | Interval (ms). |
| 129 | 149 | */ |
| @@ -155,16 +175,6 @@ struct usb_line6 { · 25 unmodified lines | ||
| 155 | 175 | */ |
| 156 | 176 | struct snd_line6_midi *line6midi; |
| 157 | 177 | |
| 158 | − /** | |
| 159 | − USB endpoint for listening to control commands. | |
| 160 | − */ | |
| 161 | − int ep_control_read; | |
| 162 | − | |
| 163 | − /** | |
| 164 | − USB endpoint for writing control commands. | |
| 165 | − */ | |
| 166 | − int ep_control_write; | |
| 167 | − | |
| 168 | 178 | /** |
| 169 | 179 | URB for listening to PODxt Pro control endpoint. |
| 170 | 180 | */ |
| @@ -184,6 +194,9 @@ struct usb_line6 { · 13 unmodified lines | ||
| 184 | 194 | Length of message to be processed. |
| 185 | 195 | */ |
| 186 | 196 | int message_length; |
| 197 | + | |
| 198 | + void (*process_message)(struct usb_line6 *); | |
| 199 | + void (*disconnect)(struct usb_interface *); | |
| 187 | 200 | }; |
| 188 | 201 | |
| 189 | 202 | extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, |
| @@ -136,7 +136,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, · 135 unmodified lines | ||
| 136 | 136 | |
| 137 | 137 | usb_fill_int_urb(urb, line6->usbdev, |
| 138 | 138 | usb_sndbulkpipe(line6->usbdev, |
| 139 | − line6->ep_control_write), | |
| 139 | + line6->properties->ep_ctrl_w), | |
| 140 | 140 | transfer_buffer, length, midi_sent, line6, |
| 141 | 141 | line6->interval); |
| 142 | 142 | urb->actual_length = 0; |
| @@ -279,7 +279,7 @@ int line6_init_midi(struct usb_line6 *line6) · 136 unmodified lines | ||
| 279 | 279 | int err; |
| 280 | 280 | struct snd_line6_midi *line6midi; |
| 281 | 281 | |
| 282 | − if (!(line6->properties->capabilities & LINE6_BIT_CONTROL)) { | |
| 282 | + if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { | |
| 283 | 283 | /* skip MIDI initialization and report success */ |
| 284 | 284 | return 0; |
| 285 | 285 | } |
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -421,60 +421,13 @@ int line6_init_pcm(struct usb_line6 *line6, · 420 unmodified lines | ||
| 421 | 421 | }; |
| 422 | 422 | |
| 423 | 423 | int err; |
| 424 | − int ep_read = 0, ep_write = 0; | |
| 424 | + unsigned ep_read = line6->properties->ep_audio_r; | |
| 425 | + unsigned ep_write = line6->properties->ep_audio_w; | |
| 425 | 426 | struct snd_line6_pcm *line6pcm; |
| 426 | 427 | |
| 427 | − if (!(line6->properties->capabilities & LINE6_BIT_PCM)) | |
| 428 | + if (!(line6->properties->capabilities & LINE6_CAP_PCM)) | |
| 428 | 429 | return 0; /* skip PCM initialization and report success */ |
| 429 | 430 | |
| 430 | − /* initialize PCM subsystem based on product id: */ | |
| 431 | − switch (line6->product) { | |
| 432 | − case LINE6_DEVID_BASSPODXT: | |
| 433 | − case LINE6_DEVID_BASSPODXTLIVE: | |
| 434 | − case LINE6_DEVID_BASSPODXTPRO: | |
| 435 | − case LINE6_DEVID_PODXT: | |
| 436 | − case LINE6_DEVID_PODXTLIVE: | |
| 437 | − case LINE6_DEVID_PODXTPRO: | |
| 438 | − case LINE6_DEVID_PODHD300: | |
| 439 | − case LINE6_DEVID_PODHD400: | |
| 440 | − ep_read = 0x82; | |
| 441 | − ep_write = 0x01; | |
| 442 | − break; | |
| 443 | − | |
| 444 | − case LINE6_DEVID_PODHD500: | |
| 445 | − case LINE6_DEVID_PODX3: | |
| 446 | − case LINE6_DEVID_PODX3LIVE: | |
| 447 | − ep_read = 0x86; | |
| 448 | − ep_write = 0x02; | |
| 449 | − break; | |
| 450 | − | |
| 451 | − case LINE6_DEVID_POCKETPOD: | |
| 452 | − ep_read = 0x82; | |
| 453 | − ep_write = 0x02; | |
| 454 | − break; | |
| 455 | − | |
| 456 | − case LINE6_DEVID_GUITARPORT: | |
| 457 | − case LINE6_DEVID_PODSTUDIO_GX: | |
| 458 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 459 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 460 | − case LINE6_DEVID_TONEPORT_GX: | |
| 461 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 462 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 463 | − ep_read = 0x82; | |
| 464 | − ep_write = 0x01; | |
| 465 | − break; | |
| 466 | − | |
| 467 | − /* this is for interface_number == 1: | |
| 468 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 469 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 470 | − ep_read = 0x87; | |
| 471 | − ep_write = 0x00; | |
| 472 | − break; */ | |
| 473 | − | |
| 474 | − default: | |
| 475 | − MISSING_CASE; | |
| 476 | − } | |
| 477 | − | |
| 478 | 431 | line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL); |
| 479 | 432 | |
| 480 | 433 | if (line6pcm == NULL) |
| @@ -483,8 +436,6 @@ int line6_init_pcm(struct usb_line6 *line6, · 2 unmodified lines | ||
| 483 | 436 | line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255; |
| 484 | 437 | line6pcm->volume_monitor = 255; |
| 485 | 438 | line6pcm->line6 = line6; |
| 486 | − line6pcm->ep_audio_read = ep_read; | |
| 487 | − line6pcm->ep_audio_write = ep_write; | |
| 488 | 439 | |
| 489 | 440 | /* Read and write buffers are sized identically, so choose minimum */ |
| 490 | 441 | line6pcm->max_packet_size = min( |
| @@ -98,6 +98,8 @@ enum { · 97 unmodified lines | ||
| 98 | 98 | LINE6_INDEX_PAUSE_PLAYBACK, |
| 99 | 99 | LINE6_INDEX_PREPARED, |
| 100 | 100 | |
| 101 | +#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x | |
| 102 | + | |
| 101 | 103 | /* individual bit masks: */ |
| 102 | 104 | LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER), |
| 103 | 105 | LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM), |
| @@ -145,21 +147,21 @@ enum { · 41 unmodified lines | ||
| 145 | 147 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | |
| 146 | 148 | #endif |
| 147 | 149 | LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | |
| 148 | − LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER , | |
| 150 | + LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER, | |
| 149 | 151 | |
| 150 | 152 | LINE6_BITS_PLAYBACK_STREAM = |
| 151 | 153 | #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE |
| 152 | 154 | LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | |
| 153 | 155 | #endif |
| 154 | 156 | LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | |
| 155 | − LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM , | |
| 157 | + LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM, | |
| 156 | 158 | |
| 157 | 159 | LINE6_BITS_CAPTURE_BUFFER = |
| 158 | 160 | #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE |
| 159 | 161 | LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | |
| 160 | 162 | #endif |
| 161 | 163 | LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER | |
| 162 | − LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER , | |
| 164 | + LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER, | |
| 163 | 165 | |
| 164 | 166 | LINE6_BITS_CAPTURE_STREAM = |
| 165 | 167 | #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE |
| @@ -294,16 +296,6 @@ struct snd_line6_pcm { · 128 unmodified lines | ||
| 294 | 296 | */ |
| 295 | 297 | int max_packet_size; |
| 296 | 298 | |
| 297 | − /** | |
| 298 | − USB endpoint for listening to audio data. | |
| 299 | − */ | |
| 300 | − int ep_audio_read; | |
| 301 | − | |
| 302 | − /** | |
| 303 | − USB endpoint for writing audio data. | |
| 304 | − */ | |
| 305 | − int ep_audio_write; | |
| 306 | − | |
| 307 | 299 | /** |
| 308 | 300 | Bit mask of active capture URBs. |
| 309 | 301 | */ |
| @@ -261,7 +261,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) · 260 unmodified lines | ||
| 261 | 261 | #endif |
| 262 | 262 | if (! |
| 263 | 263 | (line6pcm->line6-> |
| 264 | − properties->capabilities & LINE6_BIT_HWMON) | |
| 264 | + properties->capabilities & LINE6_CAP_HWMON) | |
| 265 | 265 | && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) |
| 266 | 266 | && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)) |
| 267 | 267 | add_monitor_signal(urb_out, line6pcm->prev_fbuf, |
| @@ -560,6 +560,7 @@ struct snd_pcm_ops snd_line6_playback_ops = { · 292 unmodified lines | ||
| 560 | 560 | |
| 561 | 561 | int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) |
| 562 | 562 | { |
| 563 | + struct usb_line6 *line6 = line6pcm->line6; | |
| 563 | 564 | int i; |
| 564 | 565 | |
| 565 | 566 | /* create audio URBs and fill in constant values: */ |
| @@ -571,14 +572,14 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) · 5 unmodified lines | ||
| 571 | 572 | usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); |
| 572 | 573 | |
| 573 | 574 | if (urb == NULL) { |
| 574 | − dev_err(line6pcm->line6->ifcdev, "Out of memory\n"); | |
| 575 | + dev_err(line6->ifcdev, "Out of memory\n"); | |
| 575 | 576 | return -ENOMEM; |
| 576 | 577 | } |
| 577 | 578 | |
| 578 | − urb->dev = line6pcm->line6->usbdev; | |
| 579 | + urb->dev = line6->usbdev; | |
| 579 | 580 | urb->pipe = |
| 580 | − usb_sndisocpipe(line6pcm->line6->usbdev, | |
| 581 | − line6pcm->ep_audio_write & | |
| 581 | + usb_sndisocpipe(line6->usbdev, | |
| 582 | + line6->properties->ep_audio_w & | |
| 582 | 583 | USB_ENDPOINT_NUMBER_MASK); |
| 583 | 584 | urb->transfer_flags = URB_ISO_ASAP; |
| 584 | 585 | urb->start_frame = -1; |
File renamed without changes.
| @@ -131,8 +131,9 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, · 130 unmodified lines | ||
| 131 | 131 | /* |
| 132 | 132 | Process a completely received message. |
| 133 | 133 | */ |
| 134 | −void line6_pod_process_message(struct usb_line6_pod *pod) | |
| 134 | +static void line6_pod_process_message(struct usb_line6 *line6) | |
| 135 | 135 | { |
| 136 | + struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; | |
| 136 | 137 | const unsigned char *buf = pod->line6.buffer_message; |
| 137 | 138 | |
| 138 | 139 | if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) { |
| @@ -158,15 +159,6 @@ void line6_pod_process_message(struct usb_line6_pod *pod) · 19 unmodified lines | ||
| 158 | 159 | } |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | −/* | |
| 162 | − Transmit PODxt Pro control parameter. | |
| 163 | −*/ | |
| 164 | −void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, | |
| 165 | − u8 value) | |
| 166 | −{ | |
| 167 | − line6_transmit_parameter(&pod->line6, param, value); | |
| 168 | −} | |
| 169 | − | |
| 170 | 162 | /* |
| 171 | 163 | Send system parameter (from integer). |
| 172 | 164 | */ |
| @@ -345,6 +337,35 @@ static void pod_destruct(struct usb_interface *interface) · 172 unmodified lines | ||
| 345 | 337 | cancel_work_sync(&pod->startup_work); |
| 346 | 338 | } |
| 347 | 339 | |
| 340 | +/* | |
| 341 | + POD device disconnected. | |
| 342 | +*/ | |
| 343 | +static void line6_pod_disconnect(struct usb_interface *interface) | |
| 344 | +{ | |
| 345 | + struct usb_line6_pod *pod; | |
| 346 | + | |
| 347 | + if (interface == NULL) | |
| 348 | + return; | |
| 349 | + pod = usb_get_intfdata(interface); | |
| 350 | + | |
| 351 | + if (pod != NULL) { | |
| 352 | + struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; | |
| 353 | + struct device *dev = &interface->dev; | |
| 354 | + | |
| 355 | + if (line6pcm != NULL) | |
| 356 | + line6_pcm_disconnect(line6pcm); | |
| 357 | + | |
| 358 | + if (dev != NULL) { | |
| 359 | + /* remove sysfs entries: */ | |
| 360 | + device_remove_file(dev, &dev_attr_device_id); | |
| 361 | + device_remove_file(dev, &dev_attr_firmware_version); | |
| 362 | + device_remove_file(dev, &dev_attr_serial_number); | |
| 363 | + } | |
| 364 | + } | |
| 365 | + | |
| 366 | + pod_destruct(interface); | |
| 367 | +} | |
| 368 | + | |
| 348 | 369 | /* |
| 349 | 370 | Create sysfs entries. |
| 350 | 371 | */ |
| @@ -362,10 +383,13 @@ static int pod_create_files2(struct device *dev) · 11 unmodified lines | ||
| 362 | 383 | Try to init POD device. |
| 363 | 384 | */ |
| 364 | 385 | static int pod_try_init(struct usb_interface *interface, |
| 365 | − struct usb_line6_pod *pod) | |
| 386 | + struct usb_line6 *line6) | |
| 366 | 387 | { |
| 367 | 388 | int err; |
| 368 | − struct usb_line6 *line6 = &pod->line6; | |
| 389 | + struct usb_line6_pod *pod = (struct usb_line6_pod *) line6; | |
| 390 | + | |
| 391 | + line6->process_message = line6_pod_process_message; | |
| 392 | + line6->disconnect = line6_pod_disconnect; | |
| 369 | 393 | |
| 370 | 394 | init_timer(&pod->startup_timer); |
| 371 | 395 | INIT_WORK(&pod->startup_work, pod_startup4); |
| @@ -405,7 +429,7 @@ static int pod_try_init(struct usb_interface *interface, · 33 unmodified lines | ||
| 405 | 429 | handler. |
| 406 | 430 | */ |
| 407 | 431 | |
| 408 | − if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) { | |
| 432 | + if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { | |
| 409 | 433 | pod->monitor_level = POD_SYSTEM_INVALID; |
| 410 | 434 | |
| 411 | 435 | /* initiate startup procedure: */ |
| @@ -418,41 +442,12 @@ static int pod_try_init(struct usb_interface *interface, · 6 unmodified lines | ||
| 418 | 442 | /* |
| 419 | 443 | Init POD device (and clean up in case of failure). |
| 420 | 444 | */ |
| 421 | −int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) | |
| 445 | +int line6_pod_init(struct usb_interface *interface, struct usb_line6 *line6) | |
| 422 | 446 | { |
| 423 | − int err = pod_try_init(interface, pod); | |
| 447 | + int err = pod_try_init(interface, line6); | |
| 424 | 448 | |
| 425 | 449 | if (err < 0) |
| 426 | 450 | pod_destruct(interface); |
| 427 | 451 | |
| 428 | 452 | return err; |
| 429 | 453 | } |
| 430 | − | |
| 431 | −/* | |
| 432 | − POD device disconnected. | |
| 433 | −*/ | |
| 434 | −void line6_pod_disconnect(struct usb_interface *interface) | |
| 435 | −{ | |
| 436 | − struct usb_line6_pod *pod; | |
| 437 | − | |
| 438 | − if (interface == NULL) | |
| 439 | − return; | |
| 440 | − pod = usb_get_intfdata(interface); | |
| 441 | − | |
| 442 | − if (pod != NULL) { | |
| 443 | − struct snd_line6_pcm *line6pcm = pod->line6.line6pcm; | |
| 444 | − struct device *dev = &interface->dev; | |
| 445 | − | |
| 446 | − if (line6pcm != NULL) | |
| 447 | − line6_pcm_disconnect(line6pcm); | |
| 448 | − | |
| 449 | − if (dev != NULL) { | |
| 450 | − /* remove sysfs entries: */ | |
| 451 | − device_remove_file(dev, &dev_attr_device_id); | |
| 452 | − device_remove_file(dev, &dev_attr_firmware_version); | |
| 453 | − device_remove_file(dev, &dev_attr_serial_number); | |
| 454 | − } | |
| 455 | − } | |
| 456 | − | |
| 457 | − pod_destruct(interface); | |
| 458 | −} | |
| @@ -20,12 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include "driver.h" |
| 22 | 22 | |
| 23 | −/* | |
| 24 | − PODxt Live interfaces | |
| 25 | −*/ | |
| 26 | −#define PODXTLIVE_INTERFACE_POD 0 | |
| 27 | −#define PODXTLIVE_INTERFACE_VARIAX 1 | |
| 28 | − | |
| 29 | 23 | /* |
| 30 | 24 | Locate name in binary program dump |
| 31 | 25 | */ |
| @@ -92,11 +86,7 @@ struct usb_line6_pod { · 60 unmodified lines | ||
| 92 | 86 | int device_id; |
| 93 | 87 | }; |
| 94 | 88 | |
| 95 | −extern void line6_pod_disconnect(struct usb_interface *interface); | |
| 96 | 89 | extern int line6_pod_init(struct usb_interface *interface, |
| 97 | − struct usb_line6_pod *pod); | |
| 98 | −extern void line6_pod_process_message(struct usb_line6_pod *pod); | |
| 99 | −extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, | |
| 100 | − u8 value); | |
| 90 | + struct usb_line6 *line6); | |
| 101 | 91 | |
| 102 | 92 | #endif |
| @@ -86,6 +86,27 @@ static void podhd_destruct(struct usb_interface *interface) · 85 unmodified lines | ||
| 86 | 86 | line6_cleanup_audio(&podhd->line6); |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | +/* | |
| 90 | + POD HD device disconnected. | |
| 91 | +*/ | |
| 92 | +static void line6_podhd_disconnect(struct usb_interface *interface) | |
| 93 | +{ | |
| 94 | + struct usb_line6_podhd *podhd; | |
| 95 | + | |
| 96 | + if (interface == NULL) | |
| 97 | + return; | |
| 98 | + podhd = usb_get_intfdata(interface); | |
| 99 | + | |
| 100 | + if (podhd != NULL) { | |
| 101 | + struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; | |
| 102 | + | |
| 103 | + if (line6pcm != NULL) | |
| 104 | + line6_pcm_disconnect(line6pcm); | |
| 105 | + } | |
| 106 | + | |
| 107 | + podhd_destruct(interface); | |
| 108 | +} | |
| 109 | + | |
| 89 | 110 | /* |
| 90 | 111 | Try to init POD HD device. |
| 91 | 112 | */ |
| @@ -98,6 +119,8 @@ static int podhd_try_init(struct usb_interface *interface, · 6 unmodified lines | ||
| 98 | 119 | if ((interface == NULL) || (podhd == NULL)) |
| 99 | 120 | return -ENODEV; |
| 100 | 121 | |
| 122 | + line6->disconnect = line6_podhd_disconnect; | |
| 123 | + | |
| 101 | 124 | /* initialize audio system: */ |
| 102 | 125 | err = line6_init_audio(line6); |
| 103 | 126 | if (err < 0) |
| @@ -121,9 +144,9 @@ static int podhd_try_init(struct usb_interface *interface, · 17 unmodified lines | ||
| 121 | 144 | /* |
| 122 | 145 | Init POD HD device (and clean up in case of failure). |
| 123 | 146 | */ |
| 124 | −int line6_podhd_init(struct usb_interface *interface, | |
| 125 | − struct usb_line6_podhd *podhd) | |
| 147 | +int line6_podhd_init(struct usb_interface *interface, struct usb_line6 *line6) | |
| 126 | 148 | { |
| 149 | + struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6; | |
| 127 | 150 | int err = podhd_try_init(interface, podhd); |
| 128 | 151 | |
| 129 | 152 | if (err < 0) |
| @@ -131,24 +154,3 @@ int line6_podhd_init(struct usb_interface *interface, · 1 unmodified line | ||
| 131 | 154 | |
| 132 | 155 | return err; |
| 133 | 156 | } |
| 134 | − | |
| 135 | −/* | |
| 136 | − POD HD device disconnected. | |
| 137 | −*/ | |
| 138 | −void line6_podhd_disconnect(struct usb_interface *interface) | |
| 139 | −{ | |
| 140 | − struct usb_line6_podhd *podhd; | |
| 141 | − | |
| 142 | − if (interface == NULL) | |
| 143 | − return; | |
| 144 | − podhd = usb_get_intfdata(interface); | |
| 145 | − | |
| 146 | − if (podhd != NULL) { | |
| 147 | − struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm; | |
| 148 | − | |
| 149 | − if (line6pcm != NULL) | |
| 150 | − line6_pcm_disconnect(line6pcm); | |
| 151 | − } | |
| 152 | − | |
| 153 | − podhd_destruct(interface); | |
| 154 | −} | |
| @@ -23,8 +23,7 @@ struct usb_line6_podhd { · 22 unmodified lines | ||
| 23 | 23 | struct usb_line6 line6; |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | −extern void line6_podhd_disconnect(struct usb_interface *interface); | |
| 27 | 26 | extern int line6_podhd_init(struct usb_interface *interface, |
| 28 | − struct usb_line6_podhd *podhd); | |
| 27 | + struct usb_line6 *line6); | |
| 29 | 28 | |
| 30 | 29 | #endif /* PODHD_H */ |
File renamed without changes.
| @@ -97,11 +97,11 @@ static const struct { · 96 unmodified lines | ||
| 97 | 97 | {"Inst & Mic", 0x0901} |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | −static bool toneport_has_led(short product) | |
| 100 | +static bool toneport_has_led(enum line6_device_type type) | |
| 101 | 101 | { |
| 102 | 102 | return |
| 103 | − (product == LINE6_DEVID_GUITARPORT) || | |
| 104 | − (product == LINE6_DEVID_TONEPORT_GX); | |
| 103 | + (type == LINE6_GUITARPORT) || | |
| 104 | + (type == LINE6_TONEPORT_GX); | |
| 105 | 105 | /* add your device here if you are missing support for the LEDs */ |
| 106 | 106 | } |
| 107 | 107 | |
| @@ -310,7 +310,6 @@ static void toneport_setup(struct usb_line6_toneport *toneport) · 202 unmodified lines | ||
| 310 | 310 | int ticks; |
| 311 | 311 | struct usb_line6 *line6 = &toneport->line6; |
| 312 | 312 | struct usb_device *usbdev = line6->usbdev; |
| 313 | − u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); | |
| 314 | 313 | |
| 315 | 314 | /* sync time on device with host: */ |
| 316 | 315 | ticks = (int)get_seconds(); |
| @@ -320,34 +319,69 @@ static void toneport_setup(struct usb_line6_toneport *toneport) · 3 unmodified lines | ||
| 320 | 319 | toneport_send_cmd(usbdev, 0x0301, 0x0000); |
| 321 | 320 | |
| 322 | 321 | /* initialize source select: */ |
| 323 | − switch (le16_to_cpu(usbdev->descriptor.idProduct)) { | |
| 324 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 325 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 326 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 327 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 322 | + switch (line6->type) { | |
| 323 | + case LINE6_TONEPORT_UX1: | |
| 324 | + case LINE6_TONEPORT_UX2: | |
| 325 | + case LINE6_PODSTUDIO_UX1: | |
| 326 | + case LINE6_PODSTUDIO_UX2: | |
| 328 | 327 | toneport_send_cmd(usbdev, |
| 329 | 328 | toneport_source_info[toneport->source].code, |
| 330 | 329 | 0x0000); |
| 330 | + default: | |
| 331 | + break; | |
| 331 | 332 | } |
| 332 | 333 | |
| 333 | − if (toneport_has_led(idProduct)) | |
| 334 | + if (toneport_has_led(line6->type)) | |
| 334 | 335 | toneport_update_led(&usbdev->dev); |
| 335 | 336 | } |
| 336 | 337 | |
| 338 | +/* | |
| 339 | + Toneport device disconnected. | |
| 340 | +*/ | |
| 341 | +static void line6_toneport_disconnect(struct usb_interface *interface) | |
| 342 | +{ | |
| 343 | + struct usb_line6_toneport *toneport; | |
| 344 | + u16 idProduct; | |
| 345 | + | |
| 346 | + if (interface == NULL) | |
| 347 | + return; | |
| 348 | + | |
| 349 | + toneport = usb_get_intfdata(interface); | |
| 350 | + del_timer_sync(&toneport->timer); | |
| 351 | + idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct); | |
| 352 | + | |
| 353 | + if (toneport_has_led(idProduct)) { | |
| 354 | + device_remove_file(&interface->dev, &dev_attr_led_red); | |
| 355 | + device_remove_file(&interface->dev, &dev_attr_led_green); | |
| 356 | + } | |
| 357 | + | |
| 358 | + if (toneport != NULL) { | |
| 359 | + struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; | |
| 360 | + | |
| 361 | + if (line6pcm != NULL) { | |
| 362 | + line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); | |
| 363 | + line6_pcm_disconnect(line6pcm); | |
| 364 | + } | |
| 365 | + } | |
| 366 | + | |
| 367 | + toneport_destruct(interface); | |
| 368 | +} | |
| 369 | + | |
| 370 | + | |
| 337 | 371 | /* |
| 338 | 372 | Try to init Toneport device. |
| 339 | 373 | */ |
| 340 | 374 | static int toneport_try_init(struct usb_interface *interface, |
| 341 | − struct usb_line6_toneport *toneport) | |
| 375 | + struct usb_line6 *line6) | |
| 342 | 376 | { |
| 343 | 377 | int err; |
| 344 | − struct usb_line6 *line6 = &toneport->line6; | |
| 345 | − struct usb_device *usbdev = line6->usbdev; | |
| 346 | − u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); | |
| 378 | + struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6; | |
| 347 | 379 | |
| 348 | 380 | if ((interface == NULL) || (toneport == NULL)) |
| 349 | 381 | return -ENODEV; |
| 350 | 382 | |
| 383 | + line6->disconnect = line6_toneport_disconnect; | |
| 384 | + | |
| 351 | 385 | /* initialize audio system: */ |
| 352 | 386 | err = line6_init_audio(line6); |
| 353 | 387 | if (err < 0) |
| @@ -366,17 +400,20 @@ static int toneport_try_init(struct usb_interface *interface, · 12 unmodified lines | ||
| 366 | 400 | return err; |
| 367 | 401 | |
| 368 | 402 | /* register source select control: */ |
| 369 | − switch (le16_to_cpu(usbdev->descriptor.idProduct)) { | |
| 370 | − case LINE6_DEVID_TONEPORT_UX1: | |
| 371 | − case LINE6_DEVID_TONEPORT_UX2: | |
| 372 | − case LINE6_DEVID_PODSTUDIO_UX1: | |
| 373 | − case LINE6_DEVID_PODSTUDIO_UX2: | |
| 403 | + switch (line6->type) { | |
| 404 | + case LINE6_TONEPORT_UX1: | |
| 405 | + case LINE6_TONEPORT_UX2: | |
| 406 | + case LINE6_PODSTUDIO_UX1: | |
| 407 | + case LINE6_PODSTUDIO_UX2: | |
| 374 | 408 | err = |
| 375 | 409 | snd_ctl_add(line6->card, |
| 376 | 410 | snd_ctl_new1(&toneport_control_source, |
| 377 | 411 | line6->line6pcm)); |
| 378 | 412 | if (err < 0) |
| 379 | 413 | return err; |
| 414 | + | |
| 415 | + default: | |
| 416 | + break; | |
| 380 | 417 | } |
| 381 | 418 | |
| 382 | 419 | /* register audio system: */ |
| @@ -387,7 +424,7 @@ static int toneport_try_init(struct usb_interface *interface, · 4 unmodified lines | ||
| 387 | 424 | line6_read_serial_number(line6, &toneport->serial_number); |
| 388 | 425 | line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1); |
| 389 | 426 | |
| 390 | − if (toneport_has_led(idProduct)) { | |
| 427 | + if (toneport_has_led(line6->type)) { | |
| 391 | 428 | CHECK_RETURN(device_create_file |
| 392 | 429 | (&interface->dev, &dev_attr_led_red)); |
| 393 | 430 | CHECK_RETURN(device_create_file |
| @@ -409,9 +446,9 @@ static int toneport_try_init(struct usb_interface *interface, · 15 unmodified lines | ||
| 409 | 446 | Init Toneport device (and clean up in case of failure). |
| 410 | 447 | */ |
| 411 | 448 | int line6_toneport_init(struct usb_interface *interface, |
| 412 | − struct usb_line6_toneport *toneport) | |
| 449 | + struct usb_line6 *line6) | |
| 413 | 450 | { |
| 414 | − int err = toneport_try_init(interface, toneport); | |
| 451 | + int err = toneport_try_init(interface, line6); | |
| 415 | 452 | |
| 416 | 453 | if (err < 0) |
| 417 | 454 | toneport_destruct(interface); |
| @@ -426,35 +463,3 @@ void line6_toneport_reset_resume(struct usb_line6_toneport *toneport) · 8 unmodified lines | ||
| 426 | 463 | { |
| 427 | 464 | toneport_setup(toneport); |
| 428 | 465 | } |
| 429 | − | |
| 430 | −/* | |
| 431 | − Toneport device disconnected. | |
| 432 | −*/ | |
| 433 | −void line6_toneport_disconnect(struct usb_interface *interface) | |
| 434 | −{ | |
| 435 | − struct usb_line6_toneport *toneport; | |
| 436 | − u16 idProduct; | |
| 437 | − | |
| 438 | − if (interface == NULL) | |
| 439 | − return; | |
| 440 | − | |
| 441 | − toneport = usb_get_intfdata(interface); | |
| 442 | − del_timer_sync(&toneport->timer); | |
| 443 | − idProduct = le16_to_cpu(toneport->line6.usbdev->descriptor.idProduct); | |
| 444 | − | |
| 445 | − if (toneport_has_led(idProduct)) { | |
| 446 | − device_remove_file(&interface->dev, &dev_attr_led_red); | |
| 447 | − device_remove_file(&interface->dev, &dev_attr_led_green); | |
| 448 | − } | |
| 449 | − | |
| 450 | − if (toneport != NULL) { | |
| 451 | − struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; | |
| 452 | − | |
| 453 | − if (line6pcm != NULL) { | |
| 454 | − line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); | |
| 455 | − line6_pcm_disconnect(line6pcm); | |
| 456 | − } | |
| 457 | − } | |
| 458 | − | |
| 459 | − toneport_destruct(interface); | |
| 460 | −} | |
| @@ -44,9 +44,8 @@ struct usb_line6_toneport { · 43 unmodified lines | ||
| 44 | 44 | struct timer_list timer; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | −extern void line6_toneport_disconnect(struct usb_interface *interface); | |
| 48 | 47 | extern int line6_toneport_init(struct usb_interface *interface, |
| 49 | − struct usb_line6_toneport *toneport); | |
| 48 | + struct usb_line6 *line6); | |
| 50 | 49 | extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport); |
| 51 | 50 | |
| 52 | 51 | #endif |
| @@ -0,0 +1,27 @@ | ||
| 1 | +/* | |
| 2 | + * Line6 Linux USB driver - 0.9.1beta | |
| 3 | + * | |
| 4 | + * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at) | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or | |
| 7 | + * modify it under the terms of the GNU General Public License as | |
| 8 | + * published by the Free Software Foundation, version 2. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#ifndef USBDEFS_H | |
| 13 | +#define USBDEFS_H | |
| 14 | + | |
| 15 | +#define USB_INTERVALS_PER_SECOND 1000 | |
| 16 | + | |
| 17 | +/* device supports settings parameter via USB */ | |
| 18 | +#define LINE6_CAP_CONTROL (1 << 0) | |
| 19 | +/* device supports PCM input/output via USB */ | |
| 20 | +#define LINE6_CAP_PCM (1 << 1) | |
| 21 | +/* device support hardware monitoring */ | |
| 22 | +#define LINE6_CAP_HWMON (1 << 2) | |
| 23 | + | |
| 24 | +#define LINE6_FALLBACK_INTERVAL 10 | |
| 25 | +#define LINE6_FALLBACK_MAXPACKETSIZE 16 | |
| 26 | + | |
| 27 | +#endif | |
| @@ -130,8 +130,9 @@ static void variax_startup6(struct work_struct *work) · 129 unmodified lines | ||
| 130 | 130 | /* |
| 131 | 131 | Process a completely received message. |
| 132 | 132 | */ |
| 133 | −void line6_variax_process_message(struct usb_line6_variax *variax) | |
| 133 | +static void line6_variax_process_message(struct usb_line6 *line6) | |
| 134 | 134 | { |
| 135 | + struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; | |
| 135 | 136 | const unsigned char *buf = variax->line6.buffer_message; |
| 136 | 137 | |
| 137 | 138 | switch (buf[0]) { |
| @@ -170,14 +171,29 @@ static void variax_destruct(struct usb_interface *interface) · 32 unmodified lines | ||
| 170 | 171 | kfree(variax->buffer_activate); |
| 171 | 172 | } |
| 172 | 173 | |
| 174 | +/* | |
| 175 | + Workbench device disconnected. | |
| 176 | +*/ | |
| 177 | +static void line6_variax_disconnect(struct usb_interface *interface) | |
| 178 | +{ | |
| 179 | + if (interface == NULL) | |
| 180 | + return; | |
| 181 | + | |
| 182 | + variax_destruct(interface); | |
| 183 | +} | |
| 184 | + | |
| 173 | 185 | /* |
| 174 | 186 | Try to init workbench device. |
| 175 | 187 | */ |
| 176 | 188 | static int variax_try_init(struct usb_interface *interface, |
| 177 | − struct usb_line6_variax *variax) | |
| 189 | + struct usb_line6 *line6) | |
| 178 | 190 | { |
| 191 | + struct usb_line6_variax *variax = (struct usb_line6_variax *) line6; | |
| 179 | 192 | int err; |
| 180 | 193 | |
| 194 | + line6->process_message = line6_variax_process_message; | |
| 195 | + line6->disconnect = line6_variax_disconnect; | |
| 196 | + | |
| 181 | 197 | init_timer(&variax->startup_timer1); |
| 182 | 198 | init_timer(&variax->startup_timer2); |
| 183 | 199 | INIT_WORK(&variax->startup_work, variax_startup6); |
| @@ -212,24 +228,12 @@ static int variax_try_init(struct usb_interface *interface, · 28 unmodified lines | ||
| 212 | 228 | /* |
| 213 | 229 | Init workbench device (and clean up in case of failure). |
| 214 | 230 | */ |
| 215 | −int line6_variax_init(struct usb_interface *interface, | |
| 216 | − struct usb_line6_variax *variax) | |
| 231 | +int line6_variax_init(struct usb_interface *interface, struct usb_line6 *line6) | |
| 217 | 232 | { |
| 218 | − int err = variax_try_init(interface, variax); | |
| 233 | + int err = variax_try_init(interface, line6); | |
| 219 | 234 | |
| 220 | 235 | if (err < 0) |
| 221 | 236 | variax_destruct(interface); |
| 222 | 237 | |
| 223 | 238 | return err; |
| 224 | 239 | } |
| 225 | − | |
| 226 | −/* | |
| 227 | − Workbench device disconnected. | |
| 228 | −*/ | |
| 229 | −void line6_variax_disconnect(struct usb_interface *interface) | |
| 230 | −{ | |
| 231 | − if (interface == NULL) | |
| 232 | − return; | |
| 233 | − | |
| 234 | − variax_destruct(interface); | |
| 235 | −} | |
| @@ -64,9 +64,7 @@ struct usb_line6_variax { · 63 unmodified lines | ||
| 64 | 64 | int startup_progress; |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | −extern void line6_variax_disconnect(struct usb_interface *interface); | |
| 68 | 67 | extern int line6_variax_init(struct usb_interface *interface, |
| 69 | − struct usb_line6_variax *variax); | |
| 70 | −extern void line6_variax_process_message(struct usb_line6_variax *variax); | |
| 68 | + struct usb_line6 *line6); | |
| 71 | 69 | |
| 72 | 70 | #endif |
| @@ -317,7 +317,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex) · 316 unmodified lines | ||
| 317 | 317 | * |
| 318 | 318 | * TODO: Hook into free() and add that check there as well. |
| 319 | 319 | */ |
| 320 | − debug_check_no_locks_freed(mutex, mutex + sizeof(*mutex)); | |
| 320 | + debug_check_no_locks_freed(mutex, sizeof(*mutex)); | |
| 321 | 321 | __del_lock(__get_lock(mutex)); |
| 322 | 322 | return ll_pthread_mutex_destroy(mutex); |
| 323 | 323 | } |
| @@ -341,7 +341,7 @@ int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) · 17 unmodified lines | ||
| 341 | 341 | { |
| 342 | 342 | try_init_preload(); |
| 343 | 343 | |
| 344 | − debug_check_no_locks_freed(rwlock, rwlock + sizeof(*rwlock)); | |
| 344 | + debug_check_no_locks_freed(rwlock, sizeof(*rwlock)); | |
| 345 | 345 | __del_lock(__get_lock(rwlock)); |
| 346 | 346 | return ll_pthread_rwlock_destroy(rwlock); |
| 347 | 347 | } |
| @@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann) · 231 unmodified lines | ||
| 232 | 232 | if (nr_samples > 0) { |
| 233 | 233 | total_nr_samples += nr_samples; |
| 234 | 234 | hists__collapse_resort(hists, NULL); |
| 235 | − hists__output_resort(hists); | |
| 235 | + hists__output_resort(hists, NULL); | |
| 236 | 236 | |
| 237 | 237 | if (symbol_conf.event_group && |
| 238 | 238 | !perf_evsel__is_group_leader(pos)) |
| @@ -545,6 +545,42 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right, · 544 unmodified lines | ||
| 545 | 545 | return __hist_entry__cmp_compute(p_left, p_right, c); |
| 546 | 546 | } |
| 547 | 547 | |
| 548 | +static int64_t | |
| 549 | +hist_entry__cmp_nop(struct hist_entry *left __maybe_unused, | |
| 550 | + struct hist_entry *right __maybe_unused) | |
| 551 | +{ | |
| 552 | + return 0; | |
| 553 | +} | |
| 554 | + | |
| 555 | +static int64_t | |
| 556 | +hist_entry__cmp_baseline(struct hist_entry *left, struct hist_entry *right) | |
| 557 | +{ | |
| 558 | + if (sort_compute) | |
| 559 | + return 0; | |
| 560 | + | |
| 561 | + if (left->stat.period == right->stat.period) | |
| 562 | + return 0; | |
| 563 | + return left->stat.period > right->stat.period ? 1 : -1; | |
| 564 | +} | |
| 565 | + | |
| 566 | +static int64_t | |
| 567 | +hist_entry__cmp_delta(struct hist_entry *left, struct hist_entry *right) | |
| 568 | +{ | |
| 569 | + return hist_entry__cmp_compute(right, left, COMPUTE_DELTA); | |
| 570 | +} | |
| 571 | + | |
| 572 | +static int64_t | |
| 573 | +hist_entry__cmp_ratio(struct hist_entry *left, struct hist_entry *right) | |
| 574 | +{ | |
| 575 | + return hist_entry__cmp_compute(right, left, COMPUTE_RATIO); | |
| 576 | +} | |
| 577 | + | |
| 578 | +static int64_t | |
| 579 | +hist_entry__cmp_wdiff(struct hist_entry *left, struct hist_entry *right) | |
| 580 | +{ | |
| 581 | + return hist_entry__cmp_compute(right, left, COMPUTE_WEIGHTED_DIFF); | |
| 582 | +} | |
| 583 | + | |
| 548 | 584 | static void insert_hist_entry_by_compute(struct rb_root *root, |
| 549 | 585 | struct hist_entry *he, |
| 550 | 586 | int c) |
| @@ -605,7 +641,7 @@ static void hists__process(struct hists *hists) · 54 unmodified lines | ||
| 605 | 641 | hists__precompute(hists); |
| 606 | 642 | hists__compute_resort(hists); |
| 607 | 643 | } else { |
| 608 | − hists__output_resort(hists); | |
| 644 | + hists__output_resort(hists, NULL); | |
| 609 | 645 | } |
| 610 | 646 | |
| 611 | 647 | hists__fprintf(hists, true, 0, 0, 0, stdout); |
| @@ -1038,27 +1074,35 @@ static void data__hpp_register(struct data__file *d, int idx) · 426 unmodified lines | ||
| 1038 | 1074 | fmt->header = hpp__header; |
| 1039 | 1075 | fmt->width = hpp__width; |
| 1040 | 1076 | fmt->entry = hpp__entry_global; |
| 1077 | + fmt->cmp = hist_entry__cmp_nop; | |
| 1078 | + fmt->collapse = hist_entry__cmp_nop; | |
| 1041 | 1079 | |
| 1042 | 1080 | /* TODO more colors */ |
| 1043 | 1081 | switch (idx) { |
| 1044 | 1082 | case PERF_HPP_DIFF__BASELINE: |
| 1045 | 1083 | fmt->color = hpp__color_baseline; |
| 1084 | + fmt->sort = hist_entry__cmp_baseline; | |
| 1046 | 1085 | break; |
| 1047 | 1086 | case PERF_HPP_DIFF__DELTA: |
| 1048 | 1087 | fmt->color = hpp__color_delta; |
| 1088 | + fmt->sort = hist_entry__cmp_delta; | |
| 1049 | 1089 | break; |
| 1050 | 1090 | case PERF_HPP_DIFF__RATIO: |
| 1051 | 1091 | fmt->color = hpp__color_ratio; |
| 1092 | + fmt->sort = hist_entry__cmp_ratio; | |
| 1052 | 1093 | break; |
| 1053 | 1094 | case PERF_HPP_DIFF__WEIGHTED_DIFF: |
| 1054 | 1095 | fmt->color = hpp__color_wdiff; |
| 1096 | + fmt->sort = hist_entry__cmp_wdiff; | |
| 1055 | 1097 | break; |
| 1056 | 1098 | default: |
| 1099 | + fmt->sort = hist_entry__cmp_nop; | |
| 1057 | 1100 | break; |
| 1058 | 1101 | } |
| 1059 | 1102 | |
| 1060 | 1103 | init_header(d, dfmt); |
| 1061 | 1104 | perf_hpp__column_register(fmt); |
| 1105 | + perf_hpp__register_sort_field(fmt); | |
| 1062 | 1106 | } |
| 1063 | 1107 | |
| 1064 | 1108 | static void ui_init(void) |
| @@ -19,7 +19,9 @@ · 18 unmodified lines | ||
| 19 | 19 | int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) |
| 20 | 20 | { |
| 21 | 21 | int i; |
| 22 | − const struct option list_options[] = { | |
| 22 | + bool raw_dump = false; | |
| 23 | + struct option list_options[] = { | |
| 24 | + OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), | |
| 23 | 25 | OPT_END() |
| 24 | 26 | }; |
| 25 | 27 | const char * const list_usage[] = { |
| @@ -27,11 +29,18 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) · 1 unmodified line | ||
| 27 | 29 | NULL |
| 28 | 30 | }; |
| 29 | 31 | |
| 32 | + set_option_flag(list_options, 0, "raw-dump", PARSE_OPT_HIDDEN); | |
| 33 | + | |
| 30 | 34 | argc = parse_options(argc, argv, list_options, list_usage, |
| 31 | 35 | PARSE_OPT_STOP_AT_NON_OPTION); |
| 32 | 36 | |
| 33 | 37 | setup_pager(); |
| 34 | 38 | |
| 39 | + if (raw_dump) { | |
| 40 | + print_events(NULL, true); | |
| 41 | + return 0; | |
| 42 | + } | |
| 43 | + | |
| 35 | 44 | if (argc == 0) { |
| 36 | 45 | print_events(NULL, false); |
| 37 | 46 | return 0; |
| @@ -53,8 +62,6 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) · 15 unmodified lines | ||
| 53 | 62 | print_hwcache_events(NULL, false); |
| 54 | 63 | else if (strcmp(argv[i], "pmu") == 0) |
| 55 | 64 | print_pmu_events(NULL, false); |
| 56 | − else if (strcmp(argv[i], "--raw-dump") == 0) | |
| 57 | − print_events(NULL, true); | |
| 58 | 65 | else { |
| 59 | 66 | char *sep = strchr(argv[i], ':'), *s; |
| 60 | 67 | int sep_idx; |
| @@ -457,6 +457,19 @@ static void report__collapse_hists(struct report *rep) · 456 unmodified lines | ||
| 457 | 457 | ui_progress__finish(); |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | +static void report__output_resort(struct report *rep) | |
| 461 | +{ | |
| 462 | + struct ui_progress prog; | |
| 463 | + struct perf_evsel *pos; | |
| 464 | + | |
| 465 | + ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); | |
| 466 | + | |
| 467 | + evlist__for_each(rep->session->evlist, pos) | |
| 468 | + hists__output_resort(evsel__hists(pos), &prog); | |
| 469 | + | |
| 470 | + ui_progress__finish(); | |
| 471 | +} | |
| 472 | + | |
| 460 | 473 | static int __cmd_report(struct report *rep) |
| 461 | 474 | { |
| 462 | 475 | int ret; |
| @@ -505,13 +518,20 @@ static int __cmd_report(struct report *rep) · 42 unmodified lines | ||
| 505 | 518 | if (session_done()) |
| 506 | 519 | return 0; |
| 507 | 520 | |
| 521 | + /* | |
| 522 | + * recalculate number of entries after collapsing since it | |
| 523 | + * might be changed during the collapse phase. | |
| 524 | + */ | |
| 525 | + rep->nr_entries = 0; | |
| 526 | + evlist__for_each(session->evlist, pos) | |
| 527 | + rep->nr_entries += evsel__hists(pos)->nr_entries; | |
| 528 | + | |
| 508 | 529 | if (rep->nr_entries == 0) { |
| 509 | 530 | ui__error("The %s file has no samples!\n", file->path); |
| 510 | 531 | return 0; |
| 511 | 532 | } |
| 512 | 533 | |
| 513 | − evlist__for_each(session->evlist, pos) | |
| 514 | − hists__output_resort(evsel__hists(pos)); | |
| 534 | + report__output_resort(rep); | |
| 515 | 535 | |
| 516 | 536 | return report__browse_hists(rep); |
| 517 | 537 | } |
| @@ -285,7 +285,7 @@ static void perf_top__print_sym_table(struct perf_top *top) · 284 unmodified lines | ||
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | hists__collapse_resort(hists, NULL); |
| 288 | − hists__output_resort(hists); | |
| 288 | + hists__output_resort(hists, NULL); | |
| 289 | 289 | |
| 290 | 290 | hists__output_recalc_col_len(hists, top->print_entries - printed); |
| 291 | 291 | putchar('\n'); |
| @@ -554,7 +554,7 @@ static void perf_top__sort_new_samples(void *arg) · 262 unmodified lines | ||
| 554 | 554 | } |
| 555 | 555 | |
| 556 | 556 | hists__collapse_resort(hists, NULL); |
| 557 | − hists__output_resort(hists); | |
| 557 | + hists__output_resort(hists, NULL); | |
| 558 | 558 | } |
| 559 | 559 | |
| 560 | 560 | static void *display_thread_tui(void *arg) |
| @@ -187,7 +187,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec · 186 unmodified lines | ||
| 187 | 187 | * function since TEST_ASSERT_VAL() returns in case of failure. |
| 188 | 188 | */ |
| 189 | 189 | hists__collapse_resort(hists, NULL); |
| 190 | − hists__output_resort(hists); | |
| 190 | + hists__output_resort(hists, NULL); | |
| 191 | 191 | |
| 192 | 192 | if (verbose > 2) { |
| 193 | 193 | pr_info("use callchain: %d, cumulate callchain: %d\n", |
| @@ -454,12 +454,12 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) · 260 unmodified lines | ||
| 454 | 454 | * 30.00% 10.00% perf perf [.] cmd_record |
| 455 | 455 | * 20.00% 0.00% bash libc [.] malloc |
| 456 | 456 | * 10.00% 10.00% bash [kernel] [k] page_fault |
| 457 | − * 10.00% 10.00% perf [kernel] [k] schedule | |
| 458 | − * 10.00% 0.00% perf [kernel] [k] sys_perf_event_open | |
| 457 | + * 10.00% 10.00% bash bash [.] xmalloc | |
| 459 | 458 | * 10.00% 10.00% perf [kernel] [k] page_fault |
| 460 | − * 10.00% 10.00% perf libc [.] free | |
| 461 | 459 | * 10.00% 10.00% perf libc [.] malloc |
| 462 | − * 10.00% 10.00% bash bash [.] xmalloc | |
| 460 | + * 10.00% 10.00% perf [kernel] [k] schedule | |
| 461 | + * 10.00% 10.00% perf libc [.] free | |
| 462 | + * 10.00% 0.00% perf [kernel] [k] sys_perf_event_open | |
| 463 | 463 | */ |
| 464 | 464 | struct result expected[] = { |
| 465 | 465 | { 7000, 2000, "perf", "perf", "main" }, |
| @@ -468,12 +468,12 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) · 2 unmodified lines | ||
| 468 | 468 | { 3000, 1000, "perf", "perf", "cmd_record" }, |
| 469 | 469 | { 2000, 0, "bash", "libc", "malloc" }, |
| 470 | 470 | { 1000, 1000, "bash", "[kernel]", "page_fault" }, |
| 471 | − { 1000, 1000, "perf", "[kernel]", "schedule" }, | |
| 472 | − { 1000, 0, "perf", "[kernel]", "sys_perf_event_open" }, | |
| 471 | + { 1000, 1000, "bash", "bash", "xmalloc" }, | |
| 473 | 472 | { 1000, 1000, "perf", "[kernel]", "page_fault" }, |
| 473 | + { 1000, 1000, "perf", "[kernel]", "schedule" }, | |
| 474 | 474 | { 1000, 1000, "perf", "libc", "free" }, |
| 475 | 475 | { 1000, 1000, "perf", "libc", "malloc" }, |
| 476 | − { 1000, 1000, "bash", "bash", "xmalloc" }, | |
| 476 | + { 1000, 0, "perf", "[kernel]", "sys_perf_event_open" }, | |
| 477 | 477 | }; |
| 478 | 478 | |
| 479 | 479 | symbol_conf.use_callchain = false; |
| @@ -537,10 +537,13 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 57 unmodified lines | ||
| 537 | 537 | * malloc |
| 538 | 538 | * main |
| 539 | 539 | * |
| 540 | − * 10.00% 10.00% perf [kernel] [k] schedule | |
| 540 | + * 10.00% 10.00% bash bash [.] xmalloc | |
| 541 | 541 | * | |
| 542 | − * --- schedule | |
| 543 | − * run_command | |
| 542 | + * --- xmalloc | |
| 543 | + * malloc | |
| 544 | + * xmalloc <--- NOTE: there's a cycle | |
| 545 | + * malloc | |
| 546 | + * xmalloc | |
| 544 | 547 | * main |
| 545 | 548 | * |
| 546 | 549 | * 10.00% 0.00% perf [kernel] [k] sys_perf_event_open |
| @@ -556,6 +559,12 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 9 unmodified lines | ||
| 556 | 559 | * run_command |
| 557 | 560 | * main |
| 558 | 561 | * |
| 562 | + * 10.00% 10.00% perf [kernel] [k] schedule | |
| 563 | + * | | |
| 564 | + * --- schedule | |
| 565 | + * run_command | |
| 566 | + * main | |
| 567 | + * | |
| 559 | 568 | * 10.00% 10.00% perf libc [.] free |
| 560 | 569 | * | |
| 561 | 570 | * --- free |
| @@ -570,15 +579,6 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 8 unmodified lines | ||
| 570 | 579 | * run_command |
| 571 | 580 | * main |
| 572 | 581 | * |
| 573 | − * 10.00% 10.00% bash bash [.] xmalloc | |
| 574 | − * | | |
| 575 | − * --- xmalloc | |
| 576 | − * malloc | |
| 577 | − * xmalloc <--- NOTE: there's a cycle | |
| 578 | − * malloc | |
| 579 | − * xmalloc | |
| 580 | − * main | |
| 581 | − * | |
| 582 | 582 | */ |
| 583 | 583 | struct result expected[] = { |
| 584 | 584 | { 7000, 2000, "perf", "perf", "main" }, |
| @@ -587,12 +587,12 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 2 unmodified lines | ||
| 587 | 587 | { 3000, 1000, "perf", "perf", "cmd_record" }, |
| 588 | 588 | { 2000, 0, "bash", "libc", "malloc" }, |
| 589 | 589 | { 1000, 1000, "bash", "[kernel]", "page_fault" }, |
| 590 | − { 1000, 1000, "perf", "[kernel]", "schedule" }, | |
| 590 | + { 1000, 1000, "bash", "bash", "xmalloc" }, | |
| 591 | 591 | { 1000, 0, "perf", "[kernel]", "sys_perf_event_open" }, |
| 592 | 592 | { 1000, 1000, "perf", "[kernel]", "page_fault" }, |
| 593 | + { 1000, 1000, "perf", "[kernel]", "schedule" }, | |
| 593 | 594 | { 1000, 1000, "perf", "libc", "free" }, |
| 594 | 595 | { 1000, 1000, "perf", "libc", "malloc" }, |
| 595 | − { 1000, 1000, "bash", "bash", "xmalloc" }, | |
| 596 | 596 | }; |
| 597 | 597 | struct callchain_result expected_callchain[] = { |
| 598 | 598 | { |
| @@ -622,9 +622,12 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 23 unmodified lines | ||
| 622 | 622 | { "bash", "main" }, }, |
| 623 | 623 | }, |
| 624 | 624 | { |
| 625 | − 3, { { "[kernel]", "schedule" }, | |
| 626 | − { "perf", "run_command" }, | |
| 627 | − { "perf", "main" }, }, | |
| 625 | + 6, { { "bash", "xmalloc" }, | |
| 626 | + { "libc", "malloc" }, | |
| 627 | + { "bash", "xmalloc" }, | |
| 628 | + { "libc", "malloc" }, | |
| 629 | + { "bash", "xmalloc" }, | |
| 630 | + { "bash", "main" }, }, | |
| 628 | 631 | }, |
| 629 | 632 | { |
| 630 | 633 | 3, { { "[kernel]", "sys_perf_event_open" }, |
| @@ -637,6 +640,11 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 6 unmodified lines | ||
| 637 | 640 | { "perf", "run_command" }, |
| 638 | 641 | { "perf", "main" }, }, |
| 639 | 642 | }, |
| 643 | + { | |
| 644 | + 3, { { "[kernel]", "schedule" }, | |
| 645 | + { "perf", "run_command" }, | |
| 646 | + { "perf", "main" }, }, | |
| 647 | + }, | |
| 640 | 648 | { |
| 641 | 649 | 4, { { "libc", "free" }, |
| 642 | 650 | { "perf", "cmd_record" }, |
| @@ -649,14 +657,6 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 6 unmodified lines | ||
| 649 | 657 | { "perf", "run_command" }, |
| 650 | 658 | { "perf", "main" }, }, |
| 651 | 659 | }, |
| 652 | − { | |
| 653 | − 6, { { "bash", "xmalloc" }, | |
| 654 | − { "libc", "malloc" }, | |
| 655 | − { "bash", "xmalloc" }, | |
| 656 | − { "libc", "malloc" }, | |
| 657 | − { "bash", "xmalloc" }, | |
| 658 | − { "bash", "main" }, }, | |
| 659 | − }, | |
| 660 | 660 | }; |
| 661 | 661 | |
| 662 | 662 | symbol_conf.use_callchain = true; |
| @@ -138,7 +138,7 @@ int test__hists_filter(void) · 137 unmodified lines | ||
| 138 | 138 | struct hists *hists = evsel__hists(evsel); |
| 139 | 139 | |
| 140 | 140 | hists__collapse_resort(hists, NULL); |
| 141 | − hists__output_resort(hists); | |
| 141 | + hists__output_resort(hists, NULL); | |
| 142 | 142 | |
| 143 | 143 | if (verbose > 2) { |
| 144 | 144 | pr_info("Normal histogram\n"); |
| @@ -152,7 +152,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) · 151 unmodified lines | ||
| 152 | 152 | goto out; |
| 153 | 153 | |
| 154 | 154 | hists__collapse_resort(hists, NULL); |
| 155 | − hists__output_resort(hists); | |
| 155 | + hists__output_resort(hists, NULL); | |
| 156 | 156 | |
| 157 | 157 | if (verbose > 2) { |
| 158 | 158 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -252,7 +252,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) · 93 unmodified lines | ||
| 252 | 252 | goto out; |
| 253 | 253 | |
| 254 | 254 | hists__collapse_resort(hists, NULL); |
| 255 | − hists__output_resort(hists); | |
| 255 | + hists__output_resort(hists, NULL); | |
| 256 | 256 | |
| 257 | 257 | if (verbose > 2) { |
| 258 | 258 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -306,7 +306,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) · 47 unmodified lines | ||
| 306 | 306 | goto out; |
| 307 | 307 | |
| 308 | 308 | hists__collapse_resort(hists, NULL); |
| 309 | − hists__output_resort(hists); | |
| 309 | + hists__output_resort(hists, NULL); | |
| 310 | 310 | |
| 311 | 311 | if (verbose > 2) { |
| 312 | 312 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -384,7 +384,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) · 71 unmodified lines | ||
| 384 | 384 | goto out; |
| 385 | 385 | |
| 386 | 386 | hists__collapse_resort(hists, NULL); |
| 387 | − hists__output_resort(hists); | |
| 387 | + hists__output_resort(hists, NULL); | |
| 388 | 388 | |
| 389 | 389 | if (verbose > 2) { |
| 390 | 390 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -487,7 +487,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) · 96 unmodified lines | ||
| 487 | 487 | goto out; |
| 488 | 488 | |
| 489 | 489 | hists__collapse_resort(hists, NULL); |
| 490 | − hists__output_resort(hists); | |
| 490 | + hists__output_resort(hists, NULL); | |
| 491 | 491 | |
| 492 | 492 | if (verbose > 2) { |
| 493 | 493 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -550,7 +550,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser, · 549 unmodified lines | ||
| 550 | 550 | bool need_percent; |
| 551 | 551 | |
| 552 | 552 | node = rb_first(root); |
| 553 | − need_percent = !!rb_next(node); | |
| 553 | + need_percent = node && rb_next(node); | |
| 554 | 554 | |
| 555 | 555 | while (node) { |
| 556 | 556 | struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); |
| @@ -204,6 +204,9 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b, · 203 unmodified lines | ||
| 204 | 204 | if (ret) |
| 205 | 205 | return ret; |
| 206 | 206 | |
| 207 | + if (a->thread != b->thread || !symbol_conf.use_callchain) | |
| 208 | + return 0; | |
| 209 | + | |
| 207 | 210 | ret = b->callchain->max_depth - a->callchain->max_depth; |
| 208 | 211 | } |
| 209 | 212 | return ret; |
| @@ -1,5 +1,8 @@ | ||
| 1 | 1 | #include <signal.h> |
| 2 | 2 | #include <stdbool.h> |
| 3 | +#ifdef HAVE_BACKTRACE_SUPPORT | |
| 4 | +#include <execinfo.h> | |
| 5 | +#endif | |
| 3 | 6 | |
| 4 | 7 | #include "../../util/cache.h" |
| 5 | 8 | #include "../../util/debug.h" |
| @@ -88,6 +91,25 @@ int ui__getch(int delay_secs) · 82 unmodified lines | ||
| 88 | 91 | return SLkp_getkey(); |
| 89 | 92 | } |
| 90 | 93 | |
| 94 | +#ifdef HAVE_BACKTRACE_SUPPORT | |
| 95 | +static void ui__signal_backtrace(int sig) | |
| 96 | +{ | |
| 97 | + void *stackdump[32]; | |
| 98 | + size_t size; | |
| 99 | + | |
| 100 | + ui__exit(false); | |
| 101 | + psignal(sig, "perf"); | |
| 102 | + | |
| 103 | + printf("-------- backtrace --------\n"); | |
| 104 | + size = backtrace(stackdump, ARRAY_SIZE(stackdump)); | |
| 105 | + backtrace_symbols_fd(stackdump, size, STDOUT_FILENO); | |
| 106 | + | |
| 107 | + exit(0); | |
| 108 | +} | |
| 109 | +#else | |
| 110 | +# define ui__signal_backtrace ui__signal | |
| 111 | +#endif | |
| 112 | + | |
| 91 | 113 | static void ui__signal(int sig) |
| 92 | 114 | { |
| 93 | 115 | ui__exit(false); |
| @@ -122,8 +144,8 @@ int ui__init(void) · 28 unmodified lines | ||
| 122 | 144 | ui_browser__init(); |
| 123 | 145 | tui_progress__init(); |
| 124 | 146 | |
| 125 | − signal(SIGSEGV, ui__signal); | |
| 126 | − signal(SIGFPE, ui__signal); | |
| 147 | + signal(SIGSEGV, ui__signal_backtrace); | |
| 148 | + signal(SIGFPE, ui__signal_backtrace); | |
| 127 | 149 | signal(SIGINT, ui__signal); |
| 128 | 150 | signal(SIGQUIT, ui__signal); |
| 129 | 151 | signal(SIGTERM, ui__signal); |
| @@ -841,3 +841,33 @@ char *callchain_list__sym_name(struct callchain_list *cl, · 840 unmodified lines | ||
| 841 | 841 | |
| 842 | 842 | return bf; |
| 843 | 843 | } |
| 844 | + | |
| 845 | +static void free_callchain_node(struct callchain_node *node) | |
| 846 | +{ | |
| 847 | + struct callchain_list *list, *tmp; | |
| 848 | + struct callchain_node *child; | |
| 849 | + struct rb_node *n; | |
| 850 | + | |
| 851 | + list_for_each_entry_safe(list, tmp, &node->val, list) { | |
| 852 | + list_del(&list->list); | |
| 853 | + free(list); | |
| 854 | + } | |
| 855 | + | |
| 856 | + n = rb_first(&node->rb_root_in); | |
| 857 | + while (n) { | |
| 858 | + child = container_of(n, struct callchain_node, rb_node_in); | |
| 859 | + n = rb_next(n); | |
| 860 | + rb_erase(&child->rb_node_in, &node->rb_root_in); | |
| 861 | + | |
| 862 | + free_callchain_node(child); | |
| 863 | + free(child); | |
| 864 | + } | |
| 865 | +} | |
| 866 | + | |
| 867 | +void free_callchain(struct callchain_root *root) | |
| 868 | +{ | |
| 869 | + if (!symbol_conf.use_callchain) | |
| 870 | + return; | |
| 871 | + | |
| 872 | + free_callchain_node(&root->node); | |
| 873 | +} | |
| @@ -198,4 +198,6 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, · 197 unmodified lines | ||
| 198 | 198 | char *callchain_list__sym_name(struct callchain_list *cl, |
| 199 | 199 | char *bf, size_t bfsize, bool show_dso); |
| 200 | 200 | |
| 201 | +void free_callchain(struct callchain_root *root); | |
| 202 | + | |
| 201 | 203 | #endif /* __PERF_CALLCHAIN_H */ |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "evlist.h" |
| 7 | 7 | #include "evsel.h" |
| 8 | 8 | #include "annotate.h" |
| 9 | +#include "ui/progress.h" | |
| 9 | 10 | #include <math.h> |
| 10 | 11 | |
| 11 | 12 | static bool hists__filter_entry_by_dso(struct hists *hists, |
| @@ -303,7 +304,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template, · 291 unmodified lines | ||
| 303 | 304 | size_t callchain_size = 0; |
| 304 | 305 | struct hist_entry *he; |
| 305 | 306 | |
| 306 | − if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) | |
| 307 | + if (symbol_conf.use_callchain) | |
| 307 | 308 | callchain_size = sizeof(struct callchain_root); |
| 308 | 309 | |
| 309 | 310 | he = zalloc(sizeof(*he) + callchain_size); |
| @@ -736,7 +737,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, · 426 unmodified lines | ||
| 736 | 737 | iter->he = he; |
| 737 | 738 | he_cache[iter->curr++] = he; |
| 738 | 739 | |
| 739 | − callchain_append(he->callchain, &callchain_cursor, sample->period); | |
| 740 | + hist_entry__append_callchain(he, sample); | |
| 740 | 741 | |
| 741 | 742 | /* |
| 742 | 743 | * We need to re-initialize the cursor since callchain_append() |
| @@ -809,7 +810,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, · 66 unmodified lines | ||
| 809 | 810 | iter->he = he; |
| 810 | 811 | he_cache[iter->curr++] = he; |
| 811 | 812 | |
| 812 | − callchain_append(he->callchain, &cursor, sample->period); | |
| 813 | + if (symbol_conf.use_callchain) | |
| 814 | + callchain_append(he->callchain, &cursor, sample->period); | |
| 813 | 815 | return 0; |
| 814 | 816 | } |
| 815 | 817 | |
| @@ -945,6 +947,7 @@ void hist_entry__free(struct hist_entry *he) · 129 unmodified lines | ||
| 945 | 947 | zfree(&he->mem_info); |
| 946 | 948 | zfree(&he->stat_acc); |
| 947 | 949 | free_srcline(he->srcline); |
| 950 | + free_callchain(he->callchain); | |
| 948 | 951 | free(he); |
| 949 | 952 | } |
| 950 | 953 | |
| @@ -987,6 +990,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused, · 36 unmodified lines | ||
| 987 | 990 | else |
| 988 | 991 | p = &(*p)->rb_right; |
| 989 | 992 | } |
| 993 | + hists->nr_entries++; | |
| 990 | 994 | |
| 991 | 995 | rb_link_node(&he->rb_node_in, parent, p); |
| 992 | 996 | rb_insert_color(&he->rb_node_in, root); |
| @@ -1024,7 +1028,10 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) · 31 unmodified lines | ||
| 1024 | 1028 | if (!sort__need_collapse) |
| 1025 | 1029 | return; |
| 1026 | 1030 | |
| 1031 | + hists->nr_entries = 0; | |
| 1032 | + | |
| 1027 | 1033 | root = hists__get_rotate_entries_in(hists); |
| 1034 | + | |
| 1028 | 1035 | next = rb_first(root); |
| 1029 | 1036 | |
| 1030 | 1037 | while (next) { |
| @@ -1119,7 +1126,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, · 88 unmodified lines | ||
| 1119 | 1126 | rb_insert_color(&he->rb_node, entries); |
| 1120 | 1127 | } |
| 1121 | 1128 | |
| 1122 | −void hists__output_resort(struct hists *hists) | |
| 1129 | +void hists__output_resort(struct hists *hists, struct ui_progress *prog) | |
| 1123 | 1130 | { |
| 1124 | 1131 | struct rb_root *root; |
| 1125 | 1132 | struct rb_node *next; |
| @@ -1148,6 +1155,9 @@ void hists__output_resort(struct hists *hists) · 22 unmodified lines | ||
| 1148 | 1155 | |
| 1149 | 1156 | if (!n->filtered) |
| 1150 | 1157 | hists__calc_col_len(hists, n); |
| 1158 | + | |
| 1159 | + if (prog) | |
| 1160 | + ui_progress__update(prog, 1); | |
| 1151 | 1161 | } |
| 1152 | 1162 | } |
| 1153 | 1163 | |
| @@ -121,7 +121,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, · 120 unmodified lines | ||
| 121 | 121 | struct hists *hists); |
| 122 | 122 | void hist_entry__free(struct hist_entry *); |
| 123 | 123 | |
| 124 | −void hists__output_resort(struct hists *hists); | |
| 124 | +void hists__output_resort(struct hists *hists, struct ui_progress *prog); | |
| 125 | 125 | void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); |
| 126 | 126 | |
| 127 | 127 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); |
| @@ -495,9 +495,11 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, · 494 unmodified lines | ||
| 495 | 495 | } |
| 496 | 496 | |
| 497 | 497 | if (ntevs == 0) { /* No error but failed to find probe point. */ |
| 498 | − pr_warning("Probe point '%s' not found.\n", | |
| 498 | + pr_warning("Probe point '%s' not found in debuginfo.\n", | |
| 499 | 499 | synthesize_perf_probe_point(&pev->point)); |
| 500 | − return -ENOENT; | |
| 500 | + if (need_dwarf) | |
| 501 | + return -ENOENT; | |
| 502 | + return 0; | |
| 501 | 503 | } |
| 502 | 504 | /* Error path : ntevs < 0 */ |
| 503 | 505 | pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs); |
| @@ -989,8 +989,24 @@ static int debuginfo__find_probes(struct debuginfo *dbg, · 988 unmodified lines | ||
| 989 | 989 | int ret = 0; |
| 990 | 990 | |
| 991 | 991 | #if _ELFUTILS_PREREQ(0, 142) |
| 992 | + Elf *elf; | |
| 993 | + GElf_Ehdr ehdr; | |
| 994 | + GElf_Shdr shdr; | |
| 995 | + | |
| 992 | 996 | /* Get the call frame information from this dwarf */ |
| 993 | − pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg)); | |
| 997 | + elf = dwarf_getelf(dbg->dbg); | |
| 998 | + if (elf == NULL) | |
| 999 | + return -EINVAL; | |
| 1000 | + | |
| 1001 | + if (gelf_getehdr(elf, &ehdr) == NULL) | |
| 1002 | + return -EINVAL; | |
| 1003 | + | |
| 1004 | + if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && | |
| 1005 | + shdr.sh_type == SHT_PROGBITS) { | |
| 1006 | + pf->cfi = dwarf_getcfi_elf(elf); | |
| 1007 | + } else { | |
| 1008 | + pf->cfi = dwarf_getcfi(dbg->dbg); | |
| 1009 | + } | |
| 994 | 1010 | #endif |
| 995 | 1011 | |
| 996 | 1012 | off = 0; |