diff --git a/[refs] b/[refs] index a968e6eb818c..3b42ffbde282 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fa7952bf1bdacd10b5e8364d3e4faea08890bbff +refs/heads/master: bd6880477a3d73270edead88f4b806504998e5d8 diff --git a/trunk/Documentation/arm64/memory.txt b/trunk/Documentation/arm64/memory.txt index 4110cca96bd6..dbbdcbba75a3 100644 --- a/trunk/Documentation/arm64/memory.txt +++ b/trunk/Documentation/arm64/memory.txt @@ -27,17 +27,17 @@ Start End Size Use ----------------------------------------------------------------------- 0000000000000000 0000007fffffffff 512GB user -ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc +ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc -ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] +ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] -ffffffbc00000000 ffffffbdffffffff 8GB vmemmap +ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space -ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] +ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] -ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap -ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] +ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] ffffffbffc000000 ffffffbfffffffff 64MB modules diff --git a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt deleted file mode 100644 index df70318a617f..000000000000 --- a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt +++ /dev/null @@ -1,19 +0,0 @@ -* EETI eGalax Multiple Touch Controller - -Required properties: -- compatible: must be "eeti,egalax_ts" -- reg: i2c slave address -- interrupt-parent: the phandle for the interrupt controller -- interrupts: touch controller interrupt -- wakeup-gpios: the gpio pin to be used for waking up the controller - as well as uased as irq pin - -Example: - - egalax_ts@04 { - compatible = "eeti,egalax_ts"; - reg = <0x04>; - interrupt-parent = <&gpio1>; - interrupts = <9 2>; - wakeup-gpios = <&gpio1 9 0>; - }; diff --git a/trunk/Documentation/hwmon/fam15h_power b/trunk/Documentation/hwmon/fam15h_power index 80654813d04a..a92918e0bd69 100644 --- a/trunk/Documentation/hwmon/fam15h_power +++ b/trunk/Documentation/hwmon/fam15h_power @@ -10,7 +10,7 @@ Supported chips: BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors (not yet published) -Author: Andreas Herrmann +Author: Andreas Herrmann Description ----------- diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 59203e77ce9e..1fa907441f8f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -503,7 +503,7 @@ F: include/linux/altera_uart.h F: include/linux/altera_jtaguart.h AMD FAM15H PROCESSOR POWER MONITORING DRIVER -M: Andreas Herrmann +M: Andreas Herrmann L: lm-sensors@lm-sensors.org S: Maintained F: Documentation/hwmon/fam15h_power @@ -2507,7 +2507,6 @@ M: Joonyoung Shim M: Seung-Woo Kim M: Kyungmin Park L: dri-devel@lists.freedesktop.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git S: Supported F: drivers/gpu/drm/exynos F: include/drm/exynos* @@ -5648,7 +5647,7 @@ S: Maintained F: drivers/pinctrl/spear/ PKTCDVD DRIVER -M: Jiri Kosina +M: Peter Osterlund S: Maintained F: drivers/block/pktcdvd.c F: include/linux/pktcdvd.h diff --git a/trunk/Makefile b/trunk/Makefile index 6edac73ee1ba..42d0e56818ea 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc3 NAME = Terrified Chipmunk # *DOCUMENTATION* diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index 42f042ee4ada..35c1ed89b936 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Q" (*(volatile u16 __force *)addr) + : "+Qo" (*(volatile u16 __force *)addr) : "r" (val)); } @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile("ldrh %1, %0" - : "+Q" (*(volatile u16 __force *)addr), + : "+Qo" (*(volatile u16 __force *)addr), "=r" (val)); return val; } diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h index e3f757263438..05b8e82ec9f5 100644 --- a/trunk/arch/arm/include/asm/sched_clock.h +++ b/trunk/arch/arm/include/asm/sched_clock.h @@ -10,5 +10,7 @@ extern void sched_clock_postinit(void); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate); #endif diff --git a/trunk/arch/arm/include/asm/vfpmacros.h b/trunk/arch/arm/include/asm/vfpmacros.h index 301c1db3e99b..6a6f1e485f41 100644 --- a/trunk/arch/arm/include/asm/vfpmacros.h +++ b/trunk/arch/arm/include/asm/vfpmacros.h @@ -27,9 +27,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field @@ -51,9 +51,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field diff --git a/trunk/arch/arm/include/uapi/asm/hwcap.h b/trunk/arch/arm/include/uapi/asm/hwcap.h index 3688fd15a32d..f254f6503cce 100644 --- a/trunk/arch/arm/include/uapi/asm/hwcap.h +++ b/trunk/arch/arm/include/uapi/asm/hwcap.h @@ -18,12 +18,11 @@ #define HWCAP_THUMBEE (1 << 11) #define HWCAP_NEON (1 << 12) #define HWCAP_VFPv3 (1 << 13) -#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ +#define HWCAP_VFPv3D16 (1 << 14) #define HWCAP_TLS (1 << 15) #define HWCAP_VFPv4 (1 << 16) #define HWCAP_IDIVA (1 << 17) #define HWCAP_IDIVT (1 << 18) -#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index fc6692e2b603..e21bac20d90d 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -107,6 +107,13 @@ static void sched_clock_poll(unsigned long wrap_ticks) update_sched_clock(); } +void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate) +{ + setup_sched_clock(read, bits, rate); + cd.needs_suspend = true; +} + void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) { unsigned long r, w; @@ -182,15 +189,18 @@ void __init sched_clock_postinit(void) static int sched_clock_suspend(void) { sched_clock_poll(sched_clock_timer.data); - cd.suspended = true; + if (cd.needs_suspend) + cd.suspended = true; return 0; } static void sched_clock_resume(void) { - cd.epoch_cyc = read_sched_clock(); - cd.epoch_cyc_copy = cd.epoch_cyc; - cd.suspended = false; + if (cd.needs_suspend) { + cd.epoch_cyc = read_sched_clock(); + cd.epoch_cyc_copy = cd.epoch_cyc; + cd.suspended = false; + } } static struct syscore_ops sched_clock_ops = { diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index b820edaf3184..023f443784ec 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - union offset_union uninitialized_var(offset); + union offset_union offset; unsigned long instr = 0, instrptr; int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); unsigned int type; diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 3b44e0dd0a93..c834b32af275 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -701,14 +701,11 @@ static int __init vfp_init(void) elf_hwcap |= HWCAP_VFPv3; /* - * Check for VFPv3 D16 and VFPv4 D16. CPUs in - * this configuration only have 16 x 64bit - * registers. + * Check for VFPv3 D16. CPUs in this configuration + * only have 16 x 64bit registers. */ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ - else - elf_hwcap |= HWCAP_VFPD32; + elf_hwcap |= HWCAP_VFPv3D16; } #endif /* diff --git a/trunk/arch/arm/xen/enlighten.c b/trunk/arch/arm/xen/enlighten.c index f57609275449..59bcb96ac369 100644 --- a/trunk/arch/arm/xen/enlighten.c +++ b/trunk/arch/arm/xen/enlighten.c @@ -166,14 +166,3 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) *pages = NULL; } EXPORT_SYMBOL_GPL(free_xenballooned_pages); - -/* In the hypervisor.S file. */ -EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); -EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); -EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); -EXPORT_SYMBOL_GPL(privcmd_call); diff --git a/trunk/arch/arm/xen/hypercall.S b/trunk/arch/arm/xen/hypercall.S index 71f723984cbd..074f5ed101b9 100644 --- a/trunk/arch/arm/xen/hypercall.S +++ b/trunk/arch/arm/xen/hypercall.S @@ -48,16 +48,20 @@ #include #include -#include #include -#define XEN_IMM 0xEA1 +/* HVC 0xEA1 */ +#ifdef CONFIG_THUMB2_KERNEL +#define xen_hvc .word 0xf7e08ea1 +#else +#define xen_hvc .word 0xe140ea71 +#endif #define HYPERCALL_SIMPLE(hypercall) \ ENTRY(HYPERVISOR_##hypercall) \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc; \ mov pc, lr; \ ENDPROC(HYPERVISOR_##hypercall) @@ -72,7 +76,7 @@ ENTRY(HYPERVISOR_##hypercall) \ stmdb sp!, {r4} \ ldr r4, [sp, #4] \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc \ ldm sp!, {r4} \ mov pc, lr \ ENDPROC(HYPERVISOR_##hypercall) @@ -96,7 +100,7 @@ ENTRY(privcmd_call) mov r2, r3 ldr r3, [sp, #8] ldr r4, [sp, #4] - __HVC(XEN_IMM) + xen_hvc ldm sp!, {r4} mov pc, lr ENDPROC(privcmd_call); diff --git a/trunk/arch/arm64/Kconfig b/trunk/arch/arm64/Kconfig index 15ac18a56c93..ef54a59a9e89 100644 --- a/trunk/arch/arm64/Kconfig +++ b/trunk/arch/arm64/Kconfig @@ -1,7 +1,6 @@ config ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE - select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select GENERIC_CLOCKEVENTS select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IOMAP diff --git a/trunk/arch/arm64/include/asm/elf.h b/trunk/arch/arm64/include/asm/elf.h index 07fea290d7c1..cf284649dfcb 100644 --- a/trunk/arch/arm64/include/asm/elf.h +++ b/trunk/arch/arm64/include/asm/elf.h @@ -25,10 +25,12 @@ #include typedef unsigned long elf_greg_t; +typedef unsigned long elf_freg_t[3]; #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef struct user_fpsimd_state elf_fpregset_t; + +typedef struct user_fp elf_fpregset_t; #define EM_AARCH64 183 @@ -85,6 +87,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define R_AARCH64_MOVW_PREL_G2_NC 292 #define R_AARCH64_MOVW_PREL_G3 293 + /* * These are used to set parameters in the core dumps. */ diff --git a/trunk/arch/arm64/include/asm/fpsimd.h b/trunk/arch/arm64/include/asm/fpsimd.h index c43b4ac13008..b42fab9f62a9 100644 --- a/trunk/arch/arm64/include/asm/fpsimd.h +++ b/trunk/arch/arm64/include/asm/fpsimd.h @@ -25,8 +25,9 @@ * - FPSR and FPCR * - 32 128-bit data registers * - * Note that user_fpsimd forms a prefix of this structure, which is - * relied upon in the ptrace FP/SIMD accessors. + * Note that user_fp forms a prefix of this structure, which is relied + * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must + * form a prefix of struct fpsimd_state. */ struct fpsimd_state { union { diff --git a/trunk/arch/arm64/include/asm/io.h b/trunk/arch/arm64/include/asm/io.h index 54f6116697f7..74a2a7d304a9 100644 --- a/trunk/arch/arm64/include/asm/io.h +++ b/trunk/arch/arm64/include/asm/io.h @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * I/O port access primitives. */ #define IO_SPACE_LIMIT 0xffff -#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) +#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) static inline u8 inb(unsigned long addr) { @@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr); #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) -#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) +#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) #define iounmap __iounmap #define ARCH_HAS_IOREMAP_WC diff --git a/trunk/arch/arm64/include/asm/processor.h b/trunk/arch/arm64/include/asm/processor.h index 77f696c14339..5d810044feda 100644 --- a/trunk/arch/arm64/include/asm/processor.h +++ b/trunk/arch/arm64/include/asm/processor.h @@ -43,8 +43,6 @@ #else #define STACK_TOP STACK_TOP_MAX #endif /* CONFIG_COMPAT */ - -#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK #endif /* __KERNEL__ */ struct debug_info { diff --git a/trunk/arch/arm64/include/asm/unistd.h b/trunk/arch/arm64/include/asm/unistd.h index 68aff2816e86..63f853f8b718 100644 --- a/trunk/arch/arm64/include/asm/unistd.h +++ b/trunk/arch/arm64/include/asm/unistd.h @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #ifdef CONFIG_COMPAT +#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE diff --git a/trunk/arch/arm64/kernel/perf_event.c b/trunk/arch/arm64/kernel/perf_event.c index c76c7241125b..ecbf2d81ec5c 100644 --- a/trunk/arch/arm64/kernel/perf_event.c +++ b/trunk/arch/arm64/kernel/perf_event.c @@ -613,11 +613,17 @@ enum armv8_pmuv3_perf_types { ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, + + /* + * This isn't an architected event. + * We detect this event number and use the cycle counter instead. + */ + ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, }; /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, @@ -1100,7 +1106,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; /* Always place a cycle counter into the cycle counter. */ - if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { + if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) return -EAGAIN; diff --git a/trunk/arch/arm64/kernel/process.c b/trunk/arch/arm64/kernel/process.c index e04cebdbb47f..f22965ea1cfc 100644 --- a/trunk/arch/arm64/kernel/process.c +++ b/trunk/arch/arm64/kernel/process.c @@ -309,6 +309,24 @@ struct task_struct *__switch_to(struct task_struct *prev, return last; } +/* + * Fill in the task's elfregs structure for a core dump. + */ +int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) +{ + elf_core_copy_regs(elfregs, task_pt_regs(t)); + return 1; +} + +/* + * fill in the fpe structure for a core dump... + */ +int dump_fpu (struct pt_regs *regs, struct user_fp *fp) +{ + return 0; +} +EXPORT_SYMBOL(dump_fpu); + /* * Shuffle the argument into the correct register before calling the * thread function. x1 is the thread argument, x2 is the pointer to diff --git a/trunk/arch/arm64/kernel/smp.c b/trunk/arch/arm64/kernel/smp.c index 538300f2273d..226b6bf6e9c2 100644 --- a/trunk/arch/arm64/kernel/smp.c +++ b/trunk/arch/arm64/kernel/smp.c @@ -211,7 +211,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); - complete(&cpu_running); + while (!cpu_active(cpu)) + cpu_relax(); /* * OK, it's off to the idle thread for us diff --git a/trunk/arch/arm64/mm/init.c b/trunk/arch/arm64/mm/init.c index 4cd28931dba9..efbf7df05d3f 100644 --- a/trunk/arch/arm64/mm/init.c +++ b/trunk/arch/arm64/mm/init.c @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) #ifdef CONFIG_ZONE_DMA32 /* 4GB maximum for 32-bit only capable devices */ max_dma32 = min(max, MAX_DMA32_PFN); - zone_size[ZONE_DMA32] = max(min, max_dma32) - min; + zone_size[ZONE_DMA32] = max_dma32 - min; #endif zone_size[ZONE_NORMAL] = max - max_dma32; diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index df2eb4bd9fa2..b7412504f08a 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -13,7 +13,6 @@ config FRV select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE config ZONE_DMA bool diff --git a/trunk/arch/frv/boot/Makefile b/trunk/arch/frv/boot/Makefile index 636d5bbcd53f..6ae3254da019 100644 --- a/trunk/arch/frv/boot/Makefile +++ b/trunk/arch/frv/boot/Makefile @@ -17,8 +17,6 @@ PARAMS_PHYS = 0x0207c000 INITRD_PHYS = 0x02180000 INITRD_VIRT = 0x02180000 -OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment - # # If you don't define ZRELADDR above, # then it defaults to ZTEXTADDR @@ -34,18 +32,18 @@ Image: $(obj)/Image targets: $(obj)/Image $(obj)/Image: vmlinux FORCE - $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@ + $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@ #$(obj)/Image: $(CONFIGURE) $(SYSTEM) -# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@ +# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/$(LINUX) - $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@ + $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@ bootpImage: bootp/bootp - $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@ + $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ compressed/$(LINUX): $(LINUX) dep @$(MAKE) -C compressed $(LINUX) diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 2358634cacca..266a5b25a0c1 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -30,6 +30,7 @@ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index dfcd263c0517..ee0beb354e4d 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -869,6 +869,11 @@ ret_from_kernel_thread: call schedule_tail calll.p @(gr21,gr0) or gr20,gr20,gr8 + bra sys_exit + + .globl ret_from_kernel_execve +ret_from_kernel_execve: + ori gr28,0,sp bra __syscall_exit ################################################################################################### @@ -1075,10 +1080,27 @@ __entry_return_from_kernel_interrupt: subicc gr5,#0,gr0,icc0 beq icc0,#0,__entry_return_direct - subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ - call preempt_schedule_irq -#endif +__entry_preempt_need_resched: + ldi @(gr15,#TI_FLAGS),gr4 + andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 + beq icc0,#1,__entry_return_direct + + setlos #PREEMPT_ACTIVE,gr5 + sti gr5,@(gr15,#TI_FLAGS) + + andi gr23,#~PSR_PIL,gr23 + movgs gr23,psr + + call schedule + sti gr0,@(gr15,#TI_PRE_COUNT) + + movsg psr,gr23 + ori gr23,#PSR_PIL_14,gr23 + movgs gr23,psr + bra __entry_preempt_need_resched +#else bra __entry_return_direct +#endif ############################################################################### diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 7e33215f1d8f..e1e3aa196aa4 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -181,9 +181,6 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); - /* set up the userspace frame (the only place that the USP is stored) */ - *childregs = *__kernel_frame0_ptr; - p->set_child_tid = p->clear_child_tid = NULL; p->thread.frame = childregs; @@ -194,8 +191,10 @@ int copy_thread(unsigned long clone_flags, p->thread.frame0 = childregs; if (unlikely(!regs)) { + memset(childregs, 0, sizeof(struct pt_regs)); childregs->gr9 = usp; /* function */ childregs->gr8 = arg; + childregs->psr = PSR_S; p->thread.pc = (unsigned long) ret_from_kernel_thread; save_user_regs(p->thread.user); return 0; diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index b99c2a7cc7a4..e47857f889b6 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/h8300/include/asm/cache.h b/trunk/arch/h8300/include/asm/cache.h index 05887a1d80e5..c6350283649d 100644 --- a/trunk/arch/h8300/include/asm/cache.h +++ b/trunk/arch/h8300/include/asm/cache.h @@ -2,8 +2,7 @@ #define __ARCH_H8300_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_SHIFT 2 -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define L1_CACHE_BYTES 4 /* m68k-elf-gcc 2.95.2 doesn't like these */ diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index ad2b924167d7..55bde6035216 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -9,8 +9,6 @@ #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 -#define __MAX_SUBCHANNEL 65535 -#define __MAX_SSID 3 #include diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 2d3b7cb26005..dd647c919a66 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -506,15 +506,12 @@ static inline int pud_bad(pud_t pud) static inline int pmd_present(pmd_t pmd) { - unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; - return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || - !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); + return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; } static inline int pmd_none(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && - !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; } static inline int pmd_large(pmd_t pmd) @@ -1226,11 +1223,6 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE - -#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) -#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) -#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) - #define __HAVE_ARCH_PGTABLE_DEPOSIT extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); @@ -1250,15 +1242,16 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) { - /* - * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) - * Convert to segment table entry format. - */ - if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) - return pgprot_val(SEGMENT_NONE); - if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) - return pgprot_val(SEGMENT_RO); - return pgprot_val(SEGMENT_RW); + unsigned long pgprot_pmd = 0; + + if (pgprot_val(pgprot) & _PAGE_INVALID) { + if (pgprot_val(pgprot) & _PAGE_SWT) + pgprot_pmd |= _HPAGE_TYPE_NONE; + pgprot_pmd |= _SEGMENT_ENTRY_INV; + } + if (pgprot_val(pgprot) & _PAGE_RO) + pgprot_pmd |= _SEGMENT_ENTRY_RO; + return pgprot_pmd; } static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) @@ -1276,9 +1269,7 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd) { - /* Do not clobber _HPAGE_TYPE_NONE pages! */ - if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) - pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; return pmd; } diff --git a/trunk/arch/s390/kernel/sclp.S b/trunk/arch/s390/kernel/sclp.S index b6506ee32a36..bf053898630d 100644 --- a/trunk/arch/s390/kernel/sclp.S +++ b/trunk/arch/s390/kernel/sclp.S @@ -44,12 +44,6 @@ _sclp_wait_int: #endif mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) mvc 0(16,%r8),0(%r9) -#ifdef CONFIG_64BIT - epsw %r6,%r7 # set current addressing mode - nill %r6,0x1 # in new psw (31 or 64 bit mode) - nilh %r7,0x8000 - stm %r6,%r7,0(%r8) -#endif lhi %r6,0x0200 # cr mask for ext int (cr0.54) ltr %r2,%r2 jz .LsetctS1 @@ -93,7 +87,7 @@ _sclp_wait_int: .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int #ifdef CONFIG_64BIT .LextpswS1_64: - .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit + .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit #endif .LwaitpswS1: .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 9017a63dda3d..2d37bb861faf 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) return -0x10UL; - if (pmd_large(*pmd)) { + if (pmd_huge(*pmd)) { if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) return -0x04UL; return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); diff --git a/trunk/arch/s390/mm/gup.c b/trunk/arch/s390/mm/gup.c index 8b8285310b5a..60acb93a4680 100644 --- a/trunk/arch/s390/mm/gup.c +++ b/trunk/arch/s390/mm/gup.c @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, */ if (pmd_none(pmd) || pmd_trans_splitting(pmd)) return 0; - if (unlikely(pmd_large(pmd))) { + if (unlikely(pmd_huge(pmd))) { if (!gup_huge_pmd(pmdp, pmd, addr, next, write, pages, nr)) return 0; diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 9f2edb5c5551..b6b442b0d793 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -20,7 +20,6 @@ config SPARC select HAVE_ARCH_TRACEHOOK select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK diff --git a/trunk/arch/sparc/crypto/Makefile b/trunk/arch/sparc/crypto/Makefile index 5d469d81761f..6ae1ad5e502b 100644 --- a/trunk/arch/sparc/crypto/Makefile +++ b/trunk/arch/sparc/crypto/Makefile @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o -sha1-sparc64-y := sha1_asm.o sha1_glue.o -sha256-sparc64-y := sha256_asm.o sha256_glue.o -sha512-sparc64-y := sha512_asm.o sha512_glue.o -md5-sparc64-y := md5_asm.o md5_glue.o +sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o +sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o +sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o +md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o -aes-sparc64-y := aes_asm.o aes_glue.o -des-sparc64-y := des_asm.o des_glue.o -camellia-sparc64-y := camellia_asm.o camellia_glue.o +aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o +des-sparc64-y := des_asm.o des_glue.o crop_devid.o +camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o -crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o diff --git a/trunk/arch/sparc/crypto/aes_glue.c b/trunk/arch/sparc/crypto/aes_glue.c index 3965d1d36dfa..8f1c9980f637 100644 --- a/trunk/arch/sparc/crypto/aes_glue.c +++ b/trunk/arch/sparc/crypto/aes_glue.c @@ -475,5 +475,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/camellia_glue.c b/trunk/arch/sparc/crypto/camellia_glue.c index 62c89af3fd3f..42905c084299 100644 --- a/trunk/arch/sparc/crypto/camellia_glue.c +++ b/trunk/arch/sparc/crypto/camellia_glue.c @@ -320,5 +320,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/crc32c_glue.c b/trunk/arch/sparc/crypto/crc32c_glue.c index 5162fad912ce..0bd89cea8d8e 100644 --- a/trunk/arch/sparc/crypto/crc32c_glue.c +++ b/trunk/arch/sparc/crypto/crc32c_glue.c @@ -177,5 +177,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); MODULE_ALIAS("crc32c"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/des_glue.c b/trunk/arch/sparc/crypto/des_glue.c index 41524cebcc49..c4940c2d3073 100644 --- a/trunk/arch/sparc/crypto/des_glue.c +++ b/trunk/arch/sparc/crypto/des_glue.c @@ -527,5 +527,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); MODULE_ALIAS("des"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/md5_glue.c b/trunk/arch/sparc/crypto/md5_glue.c index 09a9ea1dfb69..603d723038ce 100644 --- a/trunk/arch/sparc/crypto/md5_glue.c +++ b/trunk/arch/sparc/crypto/md5_glue.c @@ -186,5 +186,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); MODULE_ALIAS("md5"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha1_glue.c b/trunk/arch/sparc/crypto/sha1_glue.c index 6cd5f29e1e0d..2bbb20bee9f1 100644 --- a/trunk/arch/sparc/crypto/sha1_glue.c +++ b/trunk/arch/sparc/crypto/sha1_glue.c @@ -181,5 +181,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); MODULE_ALIAS("sha1"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha256_glue.c b/trunk/arch/sparc/crypto/sha256_glue.c index 04f555ab2680..591e656bd891 100644 --- a/trunk/arch/sparc/crypto/sha256_glue.c +++ b/trunk/arch/sparc/crypto/sha256_glue.c @@ -239,5 +239,3 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op MODULE_ALIAS("sha224"); MODULE_ALIAS("sha256"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha512_glue.c b/trunk/arch/sparc/crypto/sha512_glue.c index f04d1994d19a..486f0a2b7001 100644 --- a/trunk/arch/sparc/crypto/sha512_glue.c +++ b/trunk/arch/sparc/crypto/sha512_glue.c @@ -224,5 +224,3 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op MODULE_ALIAS("sha384"); MODULE_ALIAS("sha512"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h index be56a244c9cf..ce35a1cf1a20 100644 --- a/trunk/arch/sparc/include/asm/atomic_64.h +++ b/trunk/arch/sparc/include/asm/atomic_64.h @@ -1,7 +1,7 @@ /* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * - * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) */ #ifndef __ARCH_SPARC64_ATOMIC__ @@ -106,8 +106,6 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -extern long atomic64_dec_if_positive(atomic64_t *v); - /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier() diff --git a/trunk/arch/sparc/include/asm/backoff.h b/trunk/arch/sparc/include/asm/backoff.h index 4e02086b839c..db3af0d30fb1 100644 --- a/trunk/arch/sparc/include/asm/backoff.h +++ b/trunk/arch/sparc/include/asm/backoff.h @@ -1,46 +1,6 @@ #ifndef _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H -/* The macros in this file implement an exponential backoff facility - * for atomic operations. - * - * When multiple threads compete on an atomic operation, it is - * possible for one thread to be continually denied a successful - * completion of the compare-and-swap instruction. Heavily - * threaded cpu implementations like Niagara can compound this - * problem even further. - * - * When an atomic operation fails and needs to be retried, we spin a - * certain number of times. At each subsequent failure of the same - * operation we double the spin count, realizing an exponential - * backoff. - * - * When we spin, we try to use an operation that will cause the - * current cpu strand to block, and therefore make the core fully - * available to any other other runnable strands. There are two - * options, based upon cpu capabilities. - * - * On all cpus prior to SPARC-T4 we do three dummy reads of the - * condition code register. Each read blocks the strand for something - * between 40 and 50 cpu cycles. - * - * For SPARC-T4 and later we have a special "pause" instruction - * available. This is implemented using writes to register %asr27. - * The cpu will block the number of cycles written into the register, - * unless a disrupting trap happens first. SPARC-T4 specifically - * implements pause with a granularity of 8 cycles. Each strand has - * an internal pause counter which decrements every 8 cycles. So the - * chip shifts the %asr27 value down by 3 bits, and writes the result - * into the pause counter. If a value smaller than 8 is written, the - * chip blocks for 1 cycle. - * - * To achieve the same amount of backoff as the three %ccr reads give - * on earlier chips, we shift the backoff value up by 7 bits. (Three - * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the - * whole amount we want to block into the pause register, rather than - * loop writing 128 each time. - */ - #define BACKOFF_LIMIT (4 * 1024) #ifdef CONFIG_SMP @@ -51,25 +11,16 @@ #define BACKOFF_LABEL(spin_label, continue_label) \ spin_label -#define BACKOFF_SPIN(reg, tmp, label) \ - mov reg, tmp; \ -88: rd %ccr, %g0; \ - rd %ccr, %g0; \ - rd %ccr, %g0; \ - .section .pause_3insn_patch,"ax";\ - .word 88b; \ - sllx tmp, 7, tmp; \ - wr tmp, 0, %asr27; \ - clr tmp; \ - .previous; \ - brnz,pt tmp, 88b; \ - sub tmp, 1, tmp; \ - set BACKOFF_LIMIT, tmp; \ - cmp reg, tmp; \ - bg,pn %xcc, label; \ - nop; \ - ba,pt %xcc, label; \ - sllx reg, 1, reg; +#define BACKOFF_SPIN(reg, tmp, label) \ + mov reg, tmp; \ +88: brnz,pt tmp, 88b; \ + sub tmp, 1, tmp; \ + set BACKOFF_LIMIT, tmp; \ + cmp reg, tmp; \ + bg,pn %xcc, label; \ + nop; \ + ba,pt %xcc, label; \ + sllx reg, 1, reg; #else diff --git a/trunk/arch/sparc/include/asm/compat.h b/trunk/arch/sparc/include/asm/compat.h index 830502fe62b4..cef99fbc0a21 100644 --- a/trunk/arch/sparc/include/asm/compat.h +++ b/trunk/arch/sparc/include/asm/compat.h @@ -232,10 +232,9 @@ static inline void __user *arch_compat_alloc_user_space(long len) struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; - if (test_thread_64bit_stack(usp)) + if (!(test_thread_flag(TIF_32BIT))) usp += STACK_BIAS; - - if (test_thread_flag(TIF_32BIT)) + else usp &= 0xffffffffUL; usp -= len; diff --git a/trunk/arch/sparc/include/asm/processor_64.h b/trunk/arch/sparc/include/asm/processor_64.h index 721e25f0e2ea..4e5a483122a0 100644 --- a/trunk/arch/sparc/include/asm/processor_64.h +++ b/trunk/arch/sparc/include/asm/processor_64.h @@ -196,22 +196,7 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) -/* Please see the commentary in asm/backoff.h for a description of - * what these instructions are doing and how they have been choosen. - * To make a long story short, we are trying to yield the current cpu - * strand during busy loops. - */ -#define cpu_relax() asm volatile("\n99:\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - ".section .pause_3insn_patch,\"ax\"\n\t"\ - ".word 99b\n\t" \ - "wr %%g0, 128, %%asr27\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".previous" \ - ::: "memory") +#define cpu_relax() barrier() /* Prefetch support. This is tuned for UltraSPARC-III and later. * UltraSPARC-I will treat these as nops, and UltraSPARC-II has diff --git a/trunk/arch/sparc/include/asm/prom.h b/trunk/arch/sparc/include/asm/prom.h index f93003123bce..c28765110706 100644 --- a/trunk/arch/sparc/include/asm/prom.h +++ b/trunk/arch/sparc/include/asm/prom.h @@ -63,10 +63,5 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has a local implementation */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); -#define of_address_to_resource of_address_to_resource - #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/trunk/arch/sparc/include/asm/thread_info_64.h b/trunk/arch/sparc/include/asm/thread_info_64.h index a3fe4dcc0aa6..4e2276631081 100644 --- a/trunk/arch/sparc/include/asm/thread_info_64.h +++ b/trunk/arch/sparc/include/asm/thread_info_64.h @@ -259,11 +259,6 @@ static inline bool test_and_clear_restore_sigmask(void) #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) -#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) -#define test_thread_64bit_stack(__SP) \ - ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ - false : true) - #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/sparc/include/asm/ttable.h b/trunk/arch/sparc/include/asm/ttable.h index 71b5a67522ab..48f2807d3265 100644 --- a/trunk/arch/sparc/include/asm/ttable.h +++ b/trunk/arch/sparc/include/asm/ttable.h @@ -372,9 +372,7 @@ etrap_spill_fixup_64bit: \ /* Normal 32bit spill */ #define SPILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + %g0] ASI; \ mov 0x04, %g3; \ stwa %l1, [%sp + %g3] ASI; \ @@ -400,16 +398,14 @@ etrap_spill_fixup_64bit: \ stwa %i6, [%g1 + %g0] ASI; \ stwa %i7, [%g1 + %g3] ASI; \ saved; \ - retry; \ + retry; nop; nop; \ b,a,pt %xcc, spill_fixup_dax; \ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; #define SPILL_2_GENERIC_ETRAP \ etrap_user_spill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, etrap_user_spill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + 0x00] %asi; \ stwa %l1, [%sp + 0x04] %asi; \ stwa %l2, [%sp + 0x08] %asi; \ @@ -431,7 +427,7 @@ etrap_user_spill_32bit: \ ba,pt %xcc, etrap_save; \ wrpr %g1, %cwp; \ nop; nop; nop; nop; \ - nop; nop; \ + nop; nop; nop; nop; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; @@ -596,9 +592,7 @@ user_rtt_fill_64bit: \ /* Normal 32bit fill */ #define FILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + %g0] ASI, %l0; \ mov 0x04, %g2; \ mov 0x08, %g3; \ @@ -622,16 +616,14 @@ user_rtt_fill_64bit: \ lduwa [%g1 + %g3] ASI, %i6; \ lduwa [%g1 + %g5] ASI, %i7; \ restored; \ - retry; nop; nop; \ + retry; nop; nop; nop; nop; \ b,a,pt %xcc, fill_fixup_dax; \ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; #define FILL_2_GENERIC_RTRAP \ user_rtt_fill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, user_rtt_fill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + 0x00] %asi, %l0; \ lduwa [%sp + 0x04] %asi, %l1; \ lduwa [%sp + 0x08] %asi, %l2; \ @@ -651,7 +643,7 @@ user_rtt_fill_32bit: \ ba,pt %xcc, user_rtt_pre_restore; \ restored; \ nop; nop; nop; nop; nop; \ - nop; nop; nop; \ + nop; nop; nop; nop; nop; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; diff --git a/trunk/arch/sparc/include/uapi/asm/unistd.h b/trunk/arch/sparc/include/uapi/asm/unistd.h index cac719d1bc5c..8974ef7ae920 100644 --- a/trunk/arch/sparc/include/uapi/asm/unistd.h +++ b/trunk/arch/sparc/include/uapi/asm/unistd.h @@ -405,13 +405,8 @@ #define __NR_setns 337 #define __NR_process_vm_readv 338 #define __NR_process_vm_writev 339 -#define __NR_kern_features 340 -#define __NR_kcmp 341 -#define NR_syscalls 342 - -/* Bitmask values returned from kern_features system call. */ -#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 +#define NR_syscalls 340 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/trunk/arch/sparc/kernel/entry.h b/trunk/arch/sparc/kernel/entry.h index cc3c5cb47cda..0c218e4c0881 100644 --- a/trunk/arch/sparc/kernel/entry.h +++ b/trunk/arch/sparc/kernel/entry.h @@ -59,13 +59,6 @@ struct popc_6insn_patch_entry { extern struct popc_6insn_patch_entry __popc_6insn_patch, __popc_6insn_patch_end; -struct pause_patch_entry { - unsigned int addr; - unsigned int insns[3]; -}; -extern struct pause_patch_entry __pause_3insn_patch, - __pause_3insn_patch_end; - extern void __init per_cpu_patch(void); extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, struct sun4v_1insn_patch_entry *); diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index 87f60ee65433..f8b6eee40bde 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -56,13 +56,11 @@ static inline unsigned int leon_eirq_get(int cpu) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) { unsigned int eirq; - struct irq_bucket *p; int cpu = sparc_leon3_cpuid(); eirq = leon_eirq_get(cpu); - p = irq_map[eirq]; - if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ - generic_handle_irq(p->irq); + if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ + generic_handle_irq(irq_map[eirq]->irq); } /* The extended IRQ controller has been found, this function registers it */ diff --git a/trunk/arch/sparc/kernel/perf_event.c b/trunk/arch/sparc/kernel/perf_event.c index b5c38faa4ead..885a8af74064 100644 --- a/trunk/arch/sparc/kernel/perf_event.c +++ b/trunk/arch/sparc/kernel/perf_event.c @@ -1762,25 +1762,15 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { + struct sparc_stackf32 *usf, sf; unsigned long pc; - if (thread32_stack_is_64bit(ufp)) { - struct sparc_stackf *usf, sf; + usf = (struct sparc_stackf32 *) ufp; + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) + break; - ufp += STACK_BIAS; - usf = (struct sparc_stackf *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc & 0xffffffff; - ufp = ((unsigned long) sf.fp) & 0xffffffff; - } else { - struct sparc_stackf32 *usf, sf; - usf = (struct sparc_stackf32 *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc; - ufp = (unsigned long)sf.fp; - } + pc = sf.callers_pc; + ufp = (unsigned long)sf.fp; perf_callchain_store(entry, pc); } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index c6e0c2910043..d778248ef3f8 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -452,16 +452,13 @@ void flush_thread(void) /* It's a bit more tricky when 64-bit tasks are involved... */ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) { - bool stack_64bit = test_thread_64bit_stack(psp); unsigned long fp, distance, rval; - if (stack_64bit) { + if (!(test_thread_flag(TIF_32BIT))) { csp += STACK_BIAS; psp += STACK_BIAS; __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); fp += STACK_BIAS; - if (test_thread_flag(TIF_32BIT)) - fp &= 0xffffffff; } else __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); @@ -475,7 +472,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) rval = (csp - distance); if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) rval = 0; - else if (!stack_64bit) { + else if (test_thread_flag(TIF_32BIT)) { if (put_user(((u32)csp), &(((struct reg_window32 __user *)rval)->ins[6]))) rval = 0; @@ -510,18 +507,18 @@ void synchronize_user_stack(void) flush_user_windows(); if ((window = get_thread_wsaved()) != 0) { + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; + window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (!copy_to_user((char __user *)sp, rwin, winsize)) { shift_window_buffer(window, get_thread_wsaved() - 1, t); @@ -547,6 +544,13 @@ void fault_in_user_windows(void) { struct thread_info *t = current_thread_info(); unsigned long window; + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; flush_user_windows(); window = get_thread_wsaved(); @@ -554,16 +558,8 @@ void fault_in_user_windows(void) if (likely(window != 0)) { window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (unlikely(sp & 0x7UL)) stack_unaligned(sp); diff --git a/trunk/arch/sparc/kernel/ptrace_64.c b/trunk/arch/sparc/kernel/ptrace_64.c index 7ff45e4ba681..484dabac7045 100644 --- a/trunk/arch/sparc/kernel/ptrace_64.c +++ b/trunk/arch/sparc/kernel/ptrace_64.c @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; diff --git a/trunk/arch/sparc/kernel/setup_64.c b/trunk/arch/sparc/kernel/setup_64.c index 0eaf0059aaef..0800e71d8a88 100644 --- a/trunk/arch/sparc/kernel/setup_64.c +++ b/trunk/arch/sparc/kernel/setup_64.c @@ -316,25 +316,6 @@ static void __init popc_patch(void) } } -static void __init pause_patch(void) -{ - struct pause_patch_entry *p; - - p = &__pause_3insn_patch; - while (p < &__pause_3insn_patch_end) { - unsigned long i, addr = p->addr; - - for (i = 0; i < 3; i++) { - *(unsigned int *) (addr + (i * 4)) = p->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p++; - } -} - #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -547,8 +528,6 @@ static void __init init_sparc64_elf_hwcap(void) if (sparc64_elf_hwcap & AV_SPARC_POPC) popc_patch(); - if (sparc64_elf_hwcap & AV_SPARC_PAUSE) - pause_patch(); } void __init setup_arch(char **cmdline_p) diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 878ef3d5fec5..11c6c9603e71 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -751,8 +751,3 @@ int kernel_execve(const char *filename, : "cc"); return __res; } - -asmlinkage long sys_kern_features(void) -{ - return KERN_FEATURE_MIXED_MODE_STACK; -} diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 5147f574f125..63402f9e9f51 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,3 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 1c9af9fa38e9..3a58e0d66f51 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,6 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -164,4 +163,3 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp diff --git a/trunk/arch/sparc/kernel/unaligned_64.c b/trunk/arch/sparc/kernel/unaligned_64.c index 8201c25e7669..f81d038f7340 100644 --- a/trunk/arch/sparc/kernel/unaligned_64.c +++ b/trunk/arch/sparc/kernel/unaligned_64.c @@ -113,24 +113,21 @@ static inline long sign_extend_imm13(long imm) static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -138,24 +135,19 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { - unsigned long fp; - if (reg < 16) return ®s->u_regs[reg]; - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; - win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long *)&win32->locals[reg - 16]; } else { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -400,15 +392,13 @@ int handle_popc(u32 insn, struct pt_regs *regs) if (rd) regs->u_regs[rd] = ret; } else { - unsigned long fp = regs->u_regs[UREG_FP]; - - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); put_user(ret, &win32->locals[rd - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); put_user(ret, &win->locals[rd - 16]); } } @@ -564,7 +554,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) reg[0] = 0; if ((insn & 0x780000) == 0x180000) reg[1] = 0; - } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + } else if (test_thread_flag(TIF_32BIT)) { put_user(0, (int __user *) reg); if ((insn & 0x780000) == 0x180000) put_user(0, ((int __user *) reg) + 1); diff --git a/trunk/arch/sparc/kernel/visemul.c b/trunk/arch/sparc/kernel/visemul.c index c096c624ac4d..08e074b7eb6a 100644 --- a/trunk/arch/sparc/kernel/visemul.c +++ b/trunk/arch/sparc/kernel/visemul.c @@ -149,24 +149,21 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -175,18 +172,16 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, struct pt_regs *regs) { - unsigned long fp = regs->u_regs[UREG_FP]; - BUG_ON(reg < 16); BUG_ON(regs->tstate & TSTATE_PRIV); - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long __user *)&win32->locals[reg - 16]; } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -209,7 +204,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) } else { unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); - if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) + if (test_thread_flag(TIF_32BIT)) __put_user((u32)val, (u32 __user *)rd_user); else __put_user(val, rd_user); diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 0bacceb19150..89c2c29f154b 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -132,11 +132,6 @@ SECTIONS *(.popc_6insn_patch) __popc_6insn_patch_end = .; } - .pause_3insn_patch : { - __pause_3insn_patch = .; - *(.pause_3insn_patch) - __pause_3insn_patch_end = .; - } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/sparc/kernel/winfixup.S b/trunk/arch/sparc/kernel/winfixup.S index 1e67ce958369..a6b0863c27df 100644 --- a/trunk/arch/sparc/kernel/winfixup.S +++ b/trunk/arch/sparc/kernel/winfixup.S @@ -43,8 +43,6 @@ spill_fixup_mna: spill_fixup_dax: TRAP_LOAD_THREAD_REG(%g6, %g1) ldx [%g6 + TI_FLAGS], %g1 - andcc %sp, 0x1, %g0 - movne %icc, 0, %g1 andcc %g1, _TIF_32BIT, %g0 ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 diff --git a/trunk/arch/sparc/lib/atomic_64.S b/trunk/arch/sparc/lib/atomic_64.S index 85c233d0a340..4d502da3de78 100644 --- a/trunk/arch/sparc/lib/atomic_64.S +++ b/trunk/arch/sparc/lib/atomic_64.S @@ -1,6 +1,6 @@ /* atomic.S: These things are too big to do inline. * - * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -117,17 +117,3 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) ENDPROC(atomic64_sub_ret) - -ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o0], %g1 - brlez,pn %g1, 3f - sub %g1, 1, %g7 - casx [%o0], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop -3: retl - sub %g1, 1, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_dec_if_positive) diff --git a/trunk/arch/sparc/lib/ksyms.c b/trunk/arch/sparc/lib/ksyms.c index 0c4e35e522fa..ee31b884c61b 100644 --- a/trunk/arch/sparc/lib/ksyms.c +++ b/trunk/arch/sparc/lib/ksyms.c @@ -116,7 +116,6 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); -EXPORT_SYMBOL(atomic64_dec_if_positive); /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); diff --git a/trunk/arch/sparc/math-emu/math_64.c b/trunk/arch/sparc/math-emu/math_64.c index 034aadbff036..1704068da928 100644 --- a/trunk/arch/sparc/math-emu/math_64.c +++ b/trunk/arch/sparc/math-emu/math_64.c @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) XR = 0; else if (freg < 16) XR = regs->u_regs[freg]; - else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; flushw_user (); win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); diff --git a/trunk/arch/x86/include/asm/xen/hypercall.h b/trunk/arch/x86/include/asm/xen/hypercall.h index c20d1ce62dc6..59c226d120cd 100644 --- a/trunk/arch/x86/include/asm/xen/hypercall.h +++ b/trunk/arch/x86/include/asm/xen/hypercall.h @@ -359,14 +359,18 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, return _hypercall4(int, update_va_mapping, va, new_val.pte, new_val.pte >> 32, flags); } -extern int __must_check xen_event_channel_op_compat(int, void *); static inline int HYPERVISOR_event_channel_op(int cmd, void *arg) { int rc = _hypercall2(int, event_channel_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = xen_event_channel_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct evtchn_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } @@ -382,14 +386,17 @@ HYPERVISOR_console_io(int cmd, int count, char *str) return _hypercall3(int, console_io, cmd, count, str); } -extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); - static inline int HYPERVISOR_physdev_op(int cmd, void *arg) { int rc = _hypercall2(int, physdev_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = HYPERVISOR_physdev_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct physdev_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } diff --git a/trunk/arch/x86/include/asm/xen/hypervisor.h b/trunk/arch/x86/include/asm/xen/hypervisor.h index 125f344f06a9..66d0fff1ee84 100644 --- a/trunk/arch/x86/include/asm/xen/hypervisor.h +++ b/trunk/arch/x86/include/asm/xen/hypervisor.h @@ -33,6 +33,7 @@ #ifndef _ASM_X86_XEN_HYPERVISOR_H #define _ASM_X86_XEN_HYPERVISOR_H +/* arch/i386/kernel/setup.c */ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 224a7e78cb6c..1eefebe5d727 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, { struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; - memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); + memcpy(vcpu->run->mmio.data, frag->data, frag->len); return X86EMUL_CONTINUE; } @@ -3832,11 +3832,18 @@ static int emulator_read_write_onepage(unsigned long addr, void *val, bytes -= handled; val += handled; - WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); - frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; - frag->gpa = gpa; - frag->data = val; - frag->len = bytes; + while (bytes) { + unsigned now = min(bytes, 8U); + + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; + frag->gpa = gpa; + frag->data = val; + frag->len = now; + + gpa += now; + val += now; + bytes -= now; + } return X86EMUL_CONTINUE; } @@ -3883,7 +3890,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, vcpu->mmio_needed = 1; vcpu->mmio_cur_fragment = 0; - vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); + vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = gpa; @@ -5515,44 +5522,28 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * read: * for each fragment - * for each mmio piece in the fragment - * write gpa, len - * exit - * copy data + * write gpa, len + * exit + * copy data * execute insn * * write: * for each fragment - * for each mmio piece in the fragment - * write gpa, len - * copy data - * exit + * write gpa, len + * copy data + * exit */ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; - unsigned len; BUG_ON(!vcpu->mmio_needed); /* Complete previous fragment */ - frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; - len = min(8u, frag->len); + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; if (!vcpu->mmio_is_write) - memcpy(frag->data, run->mmio.data, len); - - if (frag->len <= 8) { - /* Switch to the next fragment. */ - frag++; - vcpu->mmio_cur_fragment++; - } else { - /* Go forward to the next mmio piece. */ - frag->data += len; - frag->gpa += len; - frag->len -= len; - } - + memcpy(frag->data, run->mmio.data, frag->len); if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; if (vcpu->mmio_is_write) @@ -5560,12 +5551,13 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) vcpu->mmio_read_completed = 1; return complete_emulated_io(vcpu); } - + /* Initiate next fragment */ + ++frag; run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = frag->gpa; if (vcpu->mmio_is_write) - memcpy(run->mmio.data, frag->data, min(8u, frag->len)); - run->mmio.len = min(8u, frag->len); + memcpy(run->mmio.data, frag->data, frag->len); + run->mmio.len = frag->len; run->mmio.is_write = vcpu->mmio_is_write; vcpu->arch.complete_userspace_io = complete_emulated_mmio; return 0; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index dcf5f2dd91ec..6226c99729b9 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1288,25 +1288,6 @@ unsigned long xen_read_cr2_direct(void) return this_cpu_read(xen_vcpu_info.arch.cr2); } -void xen_flush_tlb_all(void) -{ - struct mmuext_op *op; - struct multicall_space mcs; - - trace_xen_mmu_flush_tlb_all(0); - - preempt_disable(); - - mcs = xen_mc_entry(sizeof(*op)); - - op = mcs.args; - op->cmd = MMUEXT_TLB_FLUSH_ALL; - MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); - - xen_mc_issue(PARAVIRT_LAZY_MMU); - - preempt_enable(); -} static void xen_flush_tlb(void) { struct mmuext_op *op; @@ -2537,7 +2518,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, err = 0; out: - xen_flush_tlb_all(); + flush_tlb_all(); return err; } diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 0d1f36a22c98..cdcb48adee4c 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -13,8 +13,6 @@ config XTENSA select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA select GENERIC_PCI_IOMAP - select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB help Xtensa processors are 32-bit RISC machines designed by Tensilica diff --git a/trunk/arch/xtensa/include/asm/io.h b/trunk/arch/xtensa/include/asm/io.h index 700c2e6f2d25..e6be5b9091c2 100644 --- a/trunk/arch/xtensa/include/asm/io.h +++ b/trunk/arch/xtensa/include/asm/io.h @@ -62,10 +62,6 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { } - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - #endif /* CONFIG_MMU */ /* diff --git a/trunk/arch/xtensa/include/asm/processor.h b/trunk/arch/xtensa/include/asm/processor.h index 2d630e7399ca..5c371d8d4528 100644 --- a/trunk/arch/xtensa/include/asm/processor.h +++ b/trunk/arch/xtensa/include/asm/processor.h @@ -152,7 +152,6 @@ struct thread_struct { /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ - memset(regs, 0, sizeof(*regs)); \ regs->pc = new_pc; \ regs->ps = USER_PS_VALUE; \ regs->areg[1] = new_sp; \ @@ -169,6 +168,9 @@ struct mm_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) +/* Create a kernel thread without removing it from tasklists */ +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) diff --git a/trunk/arch/xtensa/include/asm/syscall.h b/trunk/arch/xtensa/include/asm/syscall.h index 124aeee0d381..c1dacca312f3 100644 --- a/trunk/arch/xtensa/include/asm/syscall.h +++ b/trunk/arch/xtensa/include/asm/syscall.h @@ -10,7 +10,7 @@ struct pt_regs; struct sigaction; -asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); +asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); asmlinkage long xtensa_ptrace(long, long, long, long); asmlinkage long xtensa_sigreturn(struct pt_regs*); diff --git a/trunk/arch/xtensa/include/asm/unistd.h b/trunk/arch/xtensa/include/asm/unistd.h index f4e6eaa40d1c..9ef1c31d2c83 100644 --- a/trunk/arch/xtensa/include/asm/unistd.h +++ b/trunk/arch/xtensa/include/asm/unistd.h @@ -1,9 +1,16 @@ -#ifndef _XTENSA_UNISTD_H -#define _XTENSA_UNISTD_H +/* + * include/asm-xtensa/unistd.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + */ -#define __ARCH_WANT_SYS_EXECVE #include + /* * "Conditional" syscalls * @@ -30,5 +37,3 @@ #define __IGNORE_mmap /* use mmap2 */ #define __IGNORE_vfork /* use clone */ #define __IGNORE_fadvise64 /* use fadvise64_64 */ - -#endif /* _XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/include/uapi/asm/unistd.h b/trunk/arch/xtensa/include/uapi/asm/unistd.h index 9f36d0e3e0ac..479abaea5aae 100644 --- a/trunk/arch/xtensa/include/uapi/asm/unistd.h +++ b/trunk/arch/xtensa/include/uapi/asm/unistd.h @@ -1,4 +1,14 @@ -#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) +/* + * include/asm-xtensa/unistd.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2012 Tensilica Inc. + */ + +#ifndef _UAPI_XTENSA_UNISTD_H #define _UAPI_XTENSA_UNISTD_H #ifndef __SYSCALL @@ -262,7 +272,7 @@ __SYSCALL(115, sys_sendmmsg, 4) #define __NR_clone 116 __SYSCALL(116, xtensa_clone, 5) #define __NR_execve 117 -__SYSCALL(117, sys_execve, 3) +__SYSCALL(117, xtensa_execve, 3) #define __NR_exit 118 __SYSCALL(118, sys_exit, 1) #define __NR_exit_group 119 @@ -749,6 +759,4 @@ __SYSCALL(331, sys_kcmp, 5) #define SYS_XTENSA_COUNT 5 /* count */ -#undef __SYSCALL - #endif /* _UAPI_XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/kernel/entry.S b/trunk/arch/xtensa/kernel/entry.S index 90bfc1dbc13d..18453067c258 100644 --- a/trunk/arch/xtensa/kernel/entry.S +++ b/trunk/arch/xtensa/kernel/entry.S @@ -1832,6 +1832,50 @@ ENTRY(system_call) retw +/* + * Create a kernel thread + * + * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_thread) + entry a1, 16 + + mov a5, a2 # preserve fn over syscall + mov a7, a3 # preserve args over syscall + + movi a3, _CLONE_VM | _CLONE_UNTRACED + movi a2, __NR_clone + or a6, a4, a3 # arg0: flags + mov a3, a1 # arg1: sp + syscall + + beq a3, a1, 1f # branch if parent + mov a6, a7 # args + callx4 a5 # fn(args) + + movi a2, __NR_exit + syscall # return value of fn(args) still in a6 + +1: retw + +/* + * Do a system call from kernel instead of calling sys_execve, so we end up + * with proper pt_regs. + * + * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_execve) + entry a1, 16 + mov a6, a2 # arg0 is in a6 + movi a2, __NR_execve + syscall + + retw + /* * Task switch. * @@ -1914,16 +1958,3 @@ ENTRY(ret_from_fork) j common_exception_return -/* - * Kernel thread creation helper - * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg - * left from _switch_to: a6 = prev - */ -ENTRY(ret_from_kernel_thread) - - call4 schedule_tail - mov a6, a3 - callx4 a2 - j common_exception_return - -ENDPROC(ret_from_kernel_thread) diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 09ae7bfab9a7..1908f6642d31 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -45,7 +45,6 @@ #include extern void ret_from_fork(void); -extern void ret_from_kernel_thread(void); struct task_struct *current_set[NR_CPUS] = {&init_task, }; @@ -159,30 +158,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy thread. * - * There are two modes in which this function is called: - * 1) Userspace thread creation, - * regs != NULL, usp_thread_fn is userspace stack pointer. - * It is expected to copy parent regs (in case CLONE_VM is not set - * in the clone_flags) and set up passed usp in the childregs. - * 2) Kernel thread creation, - * regs == NULL, usp_thread_fn is the function to run in the new thread - * and thread_fn_arg is its parameter. - * childregs are not used for the kernel threads. - * * The stack layout for the new thread looks like this: * - * +------------------------+ + * +------------------------+ <- sp in childregs (= tos) * | childregs | * +------------------------+ <- thread.sp = sp in dummy-frame * | dummy-frame | (saved in dummy-frame spill-area) * +------------------------+ * - * We create a dummy frame to return to either ret_from_fork or - * ret_from_kernel_thread: - * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) + * We create a dummy frame to return to ret_from_fork: + * a0 points to ret_from_fork (simulating a call4) * sp points to itself (thread.sp) - * a2, a3 are unused for userspace threads, - * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. + * a2, a3 are unused. * * Note: This is a pristine frame, so we don't need any spill region on top of * childregs. @@ -198,63 +185,43 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) * involved. Much simpler to just not copy those live frames across. */ -int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, - unsigned long thread_fn_arg, - struct task_struct *p, struct pt_regs *unused) +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct * p, struct pt_regs * regs) { - struct pt_regs *childregs = task_pt_regs(p); + struct pt_regs *childregs; + unsigned long tos; + int user_mode = user_mode(regs); #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) struct thread_info *ti; #endif + /* Set up new TSS. */ + tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; + if (user_mode) + childregs = (struct pt_regs*)(tos - PT_USER_SIZE); + else + childregs = (struct pt_regs*)tos - 1; + + /* This does not copy all the regs. In a bout of brilliance or madness, + ARs beyond a0-a15 exist past the end of the struct. */ + *childregs = *regs; + /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ *((int*)childregs - 3) = (unsigned long)childregs; *((int*)childregs - 4) = 0; + childregs->areg[2] = 0; + p->set_child_tid = p->clear_child_tid = NULL; + p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); p->thread.sp = (unsigned long)childregs; - if (!(p->flags & PF_KTHREAD)) { - struct pt_regs *regs = current_pt_regs(); - unsigned long usp = usp_thread_fn ? - usp_thread_fn : regs->areg[1]; + if (user_mode(regs)) { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_fork, 0x1); - - /* This does not copy all the regs. - * In a bout of brilliance or madness, - * ARs beyond a0-a15 exist past the end of the struct. - */ - *childregs = *regs; childregs->areg[1] = usp; - childregs->areg[2] = 0; - - /* When sharing memory with the parent thread, the child - usually starts on a pristine stack, so we have to reset - windowbase, windowstart and wmask. - (Note that such a new thread is required to always create - an initial call4 frame) - The exception is vfork, where the new thread continues to - run on the parent's stack until it calls execve. This could - be a call8 or call12, which requires a legal stack frame - of the previous caller for the overflow handlers to work. - (Note that it's always legal to overflow live registers). - In this case, ensure to spill at least the stack pointer - of that frame. */ - if (clone_flags & CLONE_VM) { - /* check that caller window is live and same stack */ - int len = childregs->wmask & ~0xf; - if (regs->areg[1] == usp && len != 0) { - int callinc = (regs->areg[0] >> 30) & 3; - int caller_ars = XCHAL_NUM_AREGS - callinc * 4; - put_user(regs->areg[caller_ars+1], - (unsigned __user*)(usp - 12)); - } - childregs->wmask = 1; - childregs->windowstart = 1; - childregs->windowbase = 0; + childregs->wmask = 1; /* can't share live windows */ } else { int len = childregs->wmask & ~0xf; memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], @@ -263,19 +230,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, // FIXME: we need to set THREADPTR in thread_info... if (clone_flags & CLONE_SETTLS) childregs->areg[2] = childregs->areg[6]; + } else { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_kernel_thread, 1); - - /* pass parameters to ret_from_kernel_thread: - * a2 = thread_fn, a3 = thread_fn arg - */ - *((int *)childregs - 1) = thread_fn_arg; - *((int *)childregs - 2) = usp_thread_fn; - - /* Childregs are only used when we're going to userspace - * in which case start_thread will set them up. - */ + /* In kernel space, we start a new thread with a new stack. */ + childregs->wmask = 1; + childregs->areg[1] = tos; } #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) @@ -371,5 +330,32 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, void __user *child_tid, long a5, struct pt_regs *regs) { + if (!newsp) + newsp = regs->areg[1]; return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } + +/* + * xtensa_execve() executes a new program. + */ + +asmlinkage +long xtensa_execve(const char __user *name, + const char __user *const __user *argv, + const char __user *const __user *envp, + long a3, long a4, long a5, + struct pt_regs *regs) +{ + long error; + struct filename *filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename->name, argv, envp, regs); + putname(filename); +out: + return error; +} + diff --git a/trunk/arch/xtensa/kernel/syscall.c b/trunk/arch/xtensa/kernel/syscall.c index 5702065f472a..a5c01e74d5d5 100644 --- a/trunk/arch/xtensa/kernel/syscall.c +++ b/trunk/arch/xtensa/kernel/syscall.c @@ -32,8 +32,10 @@ typedef void (*syscall_t)(void); syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, +#undef __SYSCALL #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, -#include +#undef __KERNEL_SYSCALLS__ +#include }; asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) @@ -47,8 +49,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) return (long)ret; } -asmlinkage long xtensa_fadvise64_64(int fd, int advice, - unsigned long long offset, unsigned long long len) +asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) { return sys_fadvise64_64(fd, offset, len, advice); } diff --git a/trunk/arch/xtensa/kernel/xtensa_ksyms.c b/trunk/arch/xtensa/kernel/xtensa_ksyms.c index afe058b24e6e..a8b9f1fd1e17 100644 --- a/trunk/arch/xtensa/kernel/xtensa_ksyms.c +++ b/trunk/arch/xtensa/kernel/xtensa_ksyms.c @@ -43,6 +43,7 @@ EXPORT_SYMBOL(__strncpy_user); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index a7e40a7c8214..09acf1b39905 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -89,7 +89,7 @@ config BLK_DEV_INTEGRITY config BLK_DEV_THROTTLING bool "Block layer bio throttling support" - depends on BLK_CGROUP=y + depends on BLK_CGROUP=y && EXPERIMENTAL default n ---help--- Block layer bio throttling support. It can be used to limit diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index d0b770391ad4..cafcd7431189 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -285,13 +285,6 @@ static void blkg_destroy_all(struct request_queue *q) blkg_destroy(blkg); spin_unlock(&blkcg->lock); } - - /* - * root blkg is destroyed. Just clear the pointer since - * root_rl does not take reference on root blkg. - */ - q->root_blkg = NULL; - q->root_rl.blkg = NULL; } static void blkg_rcu_free(struct rcu_head *rcu_head) @@ -333,9 +326,6 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl, */ if (rl == &q->root_rl) { ent = &q->blkg_list; - /* There are no more block groups, hence no request lists */ - if (list_empty(ent)) - return NULL; } else { blkg = container_of(rl, struct blkcg_gq, rl); ent = &blkg->q_node; diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 3c95c4d6e31a..a33870b1847b 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -2868,8 +2868,7 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b) struct request *rqa = container_of(a, struct request, queuelist); struct request *rqb = container_of(b, struct request, queuelist); - return !(rqa->q < rqb->q || - (rqa->q == rqb->q && blk_rq_pos(rqa) < blk_rq_pos(rqb))); + return !(rqa->q <= rqb->q); } /* diff --git a/trunk/crypto/cryptd.c b/trunk/crypto/cryptd.c index 7bdd61b867c8..671d4d6d14df 100644 --- a/trunk/crypto/cryptd.c +++ b/trunk/crypto/cryptd.c @@ -137,18 +137,13 @@ static void cryptd_queue_worker(struct work_struct *work) struct crypto_async_request *req, *backlog; cpu_queue = container_of(work, struct cryptd_cpu_queue, work); - /* - * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. - */ - local_bh_disable(); + /* Only handle one request at a time to avoid hogging crypto + * workqueue. preempt_disable/enable is used to prevent + * being preempted by cryptd_enqueue_request() */ preempt_disable(); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); preempt_enable(); - local_bh_enable(); if (!req) return; diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 0230cb6cbb3a..f94d4c818fc7 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -1345,15 +1345,12 @@ static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { - int status = 0; + int status; struct acpi_device *dev; - /* - * There are systems where video module known to work fine regardless - * of broken _DOD and ignoring returned value here doesn't cause - * any issues later. - */ - acpi_video_device_enumerate(video); + status = acpi_video_device_enumerate(video); + if (status) + return status; list_for_each_entry(dev, &device->children, node) { diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 72c776f2a1f5..8727e9c5eea4 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -83,16 +83,9 @@ EXPORT_SYMBOL_GPL(platform_get_resource); */ int platform_get_irq(struct platform_device *dev, unsigned int num) { -#ifdef CONFIG_SPARC - /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ - if (!dev || num >= dev->archdata.num_irqs) - return -ENXIO; - return dev->archdata.irqs[num]; -#else struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); return r ? r->start : -ENXIO; -#endif } EXPORT_SYMBOL_GPL(platform_get_irq); diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 824e09c4d0d7..f529407db93f 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -131,7 +131,6 @@ config BLK_CPQ_DA config BLK_CPQ_CISS_DA tristate "Compaq Smart Array 5xxx support" depends on PCI - select CHECK_SIGNATURE help This is the driver for Compaq Smart Array 5xxx controllers. Everyone using these boards should say Y here. @@ -167,8 +166,8 @@ config BLK_DEV_DAC960 module will be called DAC960. config BLK_DEV_UMEM - tristate "Micro Memory MM5415 Battery Backed RAM support" - depends on PCI + tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL ---help--- Saying Y here will include support for the MM5415 family of battery backed (Non-volatile) RAM cards. @@ -431,8 +430,8 @@ config CDROM_PKTCDVD_BUFFERS a disc is opened for writing. config CDROM_PKTCDVD_WCACHE - bool "Enable write caching" - depends on CDROM_PKTCDVD + bool "Enable write caching (EXPERIMENTAL)" + depends on CDROM_PKTCDVD && EXPERIMENTAL help If enabled, write caching will be set for the CD-R/W device. For now this option is dangerous unless the CD-RW media is known good, as we @@ -509,8 +508,8 @@ config XEN_BLKDEV_BACKEND config VIRTIO_BLK - tristate "Virtio block driver" - depends on VIRTIO + tristate "Virtio block driver (EXPERIMENTAL)" + depends on EXPERIMENTAL && VIRTIO ---help--- This is the virtual block driver for virtio. It can be used with lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. @@ -529,7 +528,7 @@ config BLK_DEV_HD config BLK_DEV_RBD tristate "Rados block device (RBD)" - depends on INET && BLOCK + depends on INET && EXPERIMENTAL && BLOCK select CEPH_LIB select LIBCRC32C select CRYPTO_AES diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index ca83f96756ad..b0f553b26d0f 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -5205,6 +5205,7 @@ static void cciss_shutdown(struct pci_dev *pdev) return; } /* write all data in the battery backed cache to disk */ + memset(flush_buf, 0, 4); return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, 4, 0, CTLR_LUNID, TYPE_CMD); kfree(flush_buf); diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 1c49d7173966..17c675c52295 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4109,19 +4109,12 @@ static struct platform_driver floppy_driver = { static struct platform_device floppy_device[N_DRIVE]; -static bool floppy_available(int drive) -{ - if (!(allowed_drive_mask & (1 << drive))) - return false; - if (fdc_state[FDC(drive)].version == FDC_NONE) - return false; - return true; -} - static struct kobject *floppy_find(dev_t dev, int *part, void *data) { int drive = (*part & 3) | ((*part & 0x80) >> 5); - if (drive >= N_DRIVE || !floppy_available(drive)) + if (drive >= N_DRIVE || + !(allowed_drive_mask & (1 << drive)) || + fdc_state[FDC(drive)].version == FDC_NONE) return NULL; if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) return NULL; @@ -4131,7 +4124,8 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) static int __init do_floppy_init(void) { - int i, unit, drive, err; + int i, unit, drive; + int err, dr; set_debugt(); interruptjiffies = resultjiffies = jiffies; @@ -4143,32 +4137,34 @@ static int __init do_floppy_init(void) raw_cmd = NULL; - floppy_wq = alloc_ordered_workqueue("floppy", 0); - if (!floppy_wq) - return -ENOMEM; - - for (drive = 0; drive < N_DRIVE; drive++) { - disks[drive] = alloc_disk(1); - if (!disks[drive]) { + for (dr = 0; dr < N_DRIVE; dr++) { + disks[dr] = alloc_disk(1); + if (!disks[dr]) { err = -ENOMEM; goto out_put_disk; } - disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock); - if (!disks[drive]->queue) { + floppy_wq = alloc_ordered_workqueue("floppy", 0); + if (!floppy_wq) { err = -ENOMEM; goto out_put_disk; } - blk_queue_max_hw_sectors(disks[drive]->queue, 64); - disks[drive]->major = FLOPPY_MAJOR; - disks[drive]->first_minor = TOMINOR(drive); - disks[drive]->fops = &floppy_fops; - sprintf(disks[drive]->disk_name, "fd%d", drive); + disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); + if (!disks[dr]->queue) { + err = -ENOMEM; + goto out_destroy_workq; + } + + blk_queue_max_hw_sectors(disks[dr]->queue, 64); + disks[dr]->major = FLOPPY_MAJOR; + disks[dr]->first_minor = TOMINOR(dr); + disks[dr]->fops = &floppy_fops; + sprintf(disks[dr]->disk_name, "fd%d", dr); - init_timer(&motor_off_timer[drive]); - motor_off_timer[drive].data = drive; - motor_off_timer[drive].function = motor_off_callback; + init_timer(&motor_off_timer[dr]); + motor_off_timer[dr].data = dr; + motor_off_timer[dr].function = motor_off_callback; } err = register_blkdev(FLOPPY_MAJOR, "fd"); @@ -4286,7 +4282,9 @@ static int __init do_floppy_init(void) } for (drive = 0; drive < N_DRIVE; drive++) { - if (!floppy_available(drive)) + if (!(allowed_drive_mask & (1 << drive))) + continue; + if (fdc_state[FDC(drive)].version == FDC_NONE) continue; floppy_device[drive].name = floppy_device_name; @@ -4295,7 +4293,7 @@ static int __init do_floppy_init(void) err = platform_device_register(&floppy_device[drive]); if (err) - goto out_remove_drives; + goto out_release_dma; err = device_create_file(&floppy_device[drive].dev, &dev_attr_cmos); @@ -4313,34 +4311,29 @@ static int __init do_floppy_init(void) out_unreg_platform_dev: platform_device_unregister(&floppy_device[drive]); -out_remove_drives: - while (drive--) { - if (floppy_available(drive)) { - del_gendisk(disks[drive]); - device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); - platform_device_unregister(&floppy_device[drive]); - } - } out_release_dma: if (atomic_read(&usage_count)) floppy_release_irq_and_dma(); out_unreg_region: blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); platform_driver_unregister(&floppy_driver); +out_destroy_workq: + destroy_workqueue(floppy_wq); out_unreg_blkdev: unregister_blkdev(FLOPPY_MAJOR, "fd"); out_put_disk: - for (drive = 0; drive < N_DRIVE; drive++) { - if (!disks[drive]) - break; - if (disks[drive]->queue) { - del_timer_sync(&motor_off_timer[drive]); - blk_cleanup_queue(disks[drive]->queue); - disks[drive]->queue = NULL; + while (dr--) { + del_timer_sync(&motor_off_timer[dr]); + if (disks[dr]->queue) { + blk_cleanup_queue(disks[dr]->queue); + /* + * put_disk() is not paired with add_disk() and + * will put queue reference one extra time. fix it. + */ + disks[dr]->queue = NULL; } - put_disk(disks[drive]); + put_disk(disks[dr]); } - destroy_workqueue(floppy_wq); return err; } @@ -4558,7 +4551,8 @@ static void __exit floppy_module_exit(void) for (drive = 0; drive < N_DRIVE; drive++) { del_timer_sync(&motor_off_timer[drive]); - if (floppy_available(drive)) { + if ((allowed_drive_mask & (1 << drive)) && + fdc_state[FDC(drive)].version != FDC_NONE) { del_gendisk(disks[drive]); device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); platform_device_unregister(&floppy_device[drive]); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 54046e51160a..e9d594fd12cb 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -976,21 +976,8 @@ static int loop_clr_fd(struct loop_device *lo) if (lo->lo_state != Lo_bound) return -ENXIO; - /* - * If we've explicitly asked to tear down the loop device, - * and it has an elevated reference count, set it for auto-teardown when - * the last reference goes away. This stops $!~#$@ udev from - * preventing teardown because it decided that it needs to run blkid on - * the loopback device whenever they appear. xfstests is notorious for - * failing tests because blkid via udev races with a losetup - * /do something like mkfs/losetup -d causing the losetup -d - * command to fail with EBUSY. - */ - if (lo->lo_refcnt > 1) { - lo->lo_flags |= LO_FLAGS_AUTOCLEAR; - mutex_unlock(&lo->lo_ctl_mutex); - return 0; - } + if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ + return -EBUSY; if (filp == NULL) return -EINVAL; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index adc6f36564cf..f946d31d6917 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -2035,9 +2035,8 @@ static unsigned int implicit_sector(unsigned char command, } return rv; } -static void mtip_set_timeout(struct driver_data *dd, - struct host_to_dev_fis *fis, - unsigned int *timeout, u8 erasemode) + +static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) { switch (fis->command) { case ATA_CMD_DOWNLOAD_MICRO: @@ -2045,10 +2044,7 @@ static void mtip_set_timeout(struct driver_data *dd, break; case ATA_CMD_SEC_ERASE_UNIT: case 0xFC: - if (erasemode) - *timeout = ((*(dd->port->identify + 90) * 2) * 60000); - else - *timeout = ((*(dd->port->identify + 89) * 2) * 60000); + *timeout = 240000; /* 4 minutes */ break; case ATA_CMD_STANDBYNOW1: *timeout = 120000; /* 2 minutes */ @@ -2091,7 +2087,6 @@ static int exec_drive_taskfile(struct driver_data *dd, unsigned int transfer_size; unsigned long task_file_data; int intotal = outtotal + req_task->out_size; - int erasemode = 0; taskout = req_task->out_size; taskin = req_task->in_size; @@ -2217,13 +2212,7 @@ static int exec_drive_taskfile(struct driver_data *dd, fis.lba_hi, fis.device); - /* check for erase mode support during secure erase.*/ - if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) - && (outbuf[0] & MTIP_SEC_ERASE_MODE)) { - erasemode = 1; - } - - mtip_set_timeout(dd, &fis, &timeout, erasemode); + mtip_set_timeout(&fis, &timeout); /* Determine the correct transfer size.*/ if (force_single_sector) diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index 5f4a917bd8bb..18627a1d04c5 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -33,9 +33,6 @@ /* offset of Device Control register in PCIe extended capabilites space */ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 -/* check for erase mode support during secure erase */ -#define MTIP_SEC_ERASE_MODE 0x3 - /* # of times to retry timed out/failed IOs */ #define MTIP_MAX_RETRIES 2 diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 9a54623e52d7..9ad3b5ec1dc1 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -158,8 +158,8 @@ struct xen_vbd { struct block_device *bdev; /* Cached size parameter. */ sector_t size; - unsigned int flush_support:1; - unsigned int discard_secure:1; + bool flush_support; + bool discard_secure; }; struct backend_info; diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index f58434c2617c..4f66171c6683 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -105,10 +105,11 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) { struct xen_blkif *blkif; - blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); + blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL); if (!blkif) return ERR_PTR(-ENOMEM); + memset(blkif, 0, sizeof(*blkif)); blkif->domid = domid; spin_lock_init(&blkif->blk_ring_lock); atomic_set(&blkif->refcnt, 1); @@ -195,7 +196,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) } } -static void xen_blkif_free(struct xen_blkif *blkif) +void xen_blkif_free(struct xen_blkif *blkif) { if (!atomic_dec_and_test(&blkif->refcnt)) BUG(); @@ -256,7 +257,7 @@ static struct attribute_group xen_vbdstat_group = { VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); VBD_SHOW(mode, "%s\n", be->mode); -static int xenvbd_sysfs_addif(struct xenbus_device *dev) +int xenvbd_sysfs_addif(struct xenbus_device *dev) { int error; @@ -280,7 +281,7 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); return error; } -static void xenvbd_sysfs_delif(struct xenbus_device *dev) +void xenvbd_sysfs_delif(struct xenbus_device *dev) { sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); device_remove_file(&dev->dev, &dev_attr_mode); diff --git a/trunk/drivers/cpufreq/powernow-k8.c b/trunk/drivers/cpufreq/powernow-k8.c index e3ebb4fa2c3e..c16a3a593ba4 100644 --- a/trunk/drivers/cpufreq/powernow-k8.c +++ b/trunk/drivers/cpufreq/powernow-k8.c @@ -5,7 +5,7 @@ * http://www.gnu.org/licenses/gpl.html * * Maintainer: - * Andreas Herrmann + * Andreas Herrmann * * Based on the powernow-k7.c module written by Dave Jones. * (C) 2003 Dave Jones on behalf of SuSE Labs diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index f11d8e3b4041..d055cee36942 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -47,7 +47,7 @@ if GPIOLIB config OF_GPIO def_bool y - depends on OF + depends on OF && !SPARC config DEBUG_GPIO bool "Debug GPIO calls" diff --git a/trunk/drivers/gpio/gpio-74x164.c b/trunk/drivers/gpio/gpio-74x164.c index f05e54258ffb..ed3e55161bdc 100644 --- a/trunk/drivers/gpio/gpio-74x164.c +++ b/trunk/drivers/gpio/gpio-74x164.c @@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) } chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; - chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); + chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); if (!chip->buffer) { ret = -ENOMEM; goto exit_destroy; diff --git a/trunk/drivers/gpio/gpio-mvebu.c b/trunk/drivers/gpio/gpio-mvebu.c index cf7afb9eb61a..7a874129e5d8 100644 --- a/trunk/drivers/gpio/gpio-mvebu.c +++ b/trunk/drivers/gpio/gpio-mvebu.c @@ -244,8 +244,6 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, if (ret) return ret; - mvebu_gpio_set(chip, pin, value); - spin_lock_irqsave(&mvchip->lock, flags); u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); u &= ~(1 << pin); @@ -646,7 +644,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) ct->handler = handle_edge_irq; ct->chip.name = mvchip->chip.label; - irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, + irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); /* Setup irq domain on top of the generic chip. */ diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index d335af1d4d85..94cbc842fbc3 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -251,40 +251,6 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, } } -/** - * _clear_gpio_debounce - clear debounce settings for a gpio - * @bank: the gpio bank we're acting upon - * @gpio: the gpio number on this @gpio - * - * If a gpio is using debounce, then clear the debounce enable bit and if - * this is the only gpio in this bank using debounce, then clear the debounce - * time too. The debounce clock will also be disabled when calling this function - * if this is the only gpio in the bank using debounce. - */ -static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) -{ - u32 gpio_bit = GPIO_BIT(bank, gpio); - - if (!bank->dbck_flag) - return; - - if (!(bank->dbck_enable_mask & gpio_bit)) - return; - - bank->dbck_enable_mask &= ~gpio_bit; - bank->context.debounce_en &= ~gpio_bit; - __raw_writel(bank->context.debounce_en, - bank->base + bank->regs->debounce_en); - - if (!bank->dbck_enable_mask) { - bank->context.debounce = 0; - __raw_writel(bank->context.debounce, bank->base + - bank->regs->debounce); - clk_disable(bank->dbck); - bank->dbck_enabled = false; - } -} - static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, unsigned trigger) { @@ -573,7 +539,6 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) _set_gpio_irqenable(bank, gpio, 0); _clear_gpio_irqstatus(bank, gpio); _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); - _clear_gpio_debounce(bank, gpio); } /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ diff --git a/trunk/drivers/gpio/gpio-timberdale.c b/trunk/drivers/gpio/gpio-timberdale.c index 1a3e2b9b4772..031c6adf5b65 100644 --- a/trunk/drivers/gpio/gpio-timberdale.c +++ b/trunk/drivers/gpio/gpio-timberdale.c @@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) unsigned long flags; spin_lock_irqsave(&tgpio->lock, flags); - tgpio->last_ier &= ~(1UL << offset); + tgpio->last_ier &= ~(1 << offset); iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); spin_unlock_irqrestore(&tgpio->lock, flags); } @@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) unsigned long flags; spin_lock_irqsave(&tgpio->lock, flags); - tgpio->last_ier |= 1UL << offset; + tgpio->last_ier |= 1 << offset; iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); spin_unlock_irqrestore(&tgpio->lock, flags); } diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 1c8d9e3380e1..5d6c71edc739 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -623,11 +623,9 @@ static ssize_t export_store(struct class *class, */ status = gpio_request(gpio, "sysfs"); - if (status < 0) { - if (status == -EPROBE_DEFER) - status = -ENODEV; + if (status < 0) goto done; - } + status = gpio_export(gpio, true); if (status < 0) gpio_free(gpio); @@ -1193,10 +1191,8 @@ int gpio_request(unsigned gpio, const char *label) spin_lock_irqsave(&gpio_lock, flags); - if (!gpio_is_valid(gpio)) { - status = -EINVAL; + if (!gpio_is_valid(gpio)) goto done; - } desc = &gpio_desc[gpio]; chip = desc->chip; if (chip == NULL) diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 133b4132983e..7ef1b673e1be 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -121,8 +121,6 @@ int drm_open(struct inode *inode, struct file *filp) int minor_id = iminor(inode); struct drm_minor *minor; int retcode = 0; - int need_setup = 0; - struct address_space *old_mapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -134,37 +132,23 @@ int drm_open(struct inode *inode, struct file *filp) if (drm_device_is_unplugged(dev)) return -ENODEV; - if (!dev->open_count++) - need_setup = 1; - mutex_lock(&dev->struct_mutex); - old_mapping = dev->dev_mapping; - if (old_mapping == NULL) - dev->dev_mapping = &inode->i_data; - /* ihold ensures nobody can remove inode with our i_data */ - ihold(container_of(dev->dev_mapping, struct inode, i_data)); - inode->i_mapping = dev->dev_mapping; - filp->f_mapping = dev->dev_mapping; - mutex_unlock(&dev->struct_mutex); - retcode = drm_open_helper(inode, filp, dev); - if (retcode) - goto err_undo; - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - if (need_setup) { - retcode = drm_setup(dev); - if (retcode) - goto err_undo; + if (!retcode) { + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); + if (!dev->open_count++) + retcode = drm_setup(dev); + } + if (!retcode) { + mutex_lock(&dev->struct_mutex); + if (dev->dev_mapping == NULL) + dev->dev_mapping = &inode->i_data; + /* ihold ensures nobody can remove inode with our i_data */ + ihold(container_of(dev->dev_mapping, struct inode, i_data)); + inode->i_mapping = dev->dev_mapping; + filp->f_mapping = dev->dev_mapping; + mutex_unlock(&dev->struct_mutex); } - return 0; -err_undo: - mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_mapping; - inode->i_mapping = old_mapping; - iput(container_of(dev->dev_mapping, struct inode, i_data)); - dev->dev_mapping = old_mapping; - mutex_unlock(&dev->struct_mutex); - dev->open_count--; return retcode; } EXPORT_SYMBOL(drm_open); diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index fc345d4ebb03..59a26e577b57 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -1,6 +1,6 @@ config DRM_EXYNOS tristate "DRM Support for Samsung SoC EXYNOS Series" - depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) + depends on DRM && PLAT_SAMSUNG select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c index 0f68a2872673..18c271862ca8 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -374,7 +374,6 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, exynos_connector->encoder_id = encoder->base.id; exynos_connector->manager = manager; exynos_connector->dpms = DRM_MODE_DPMS_OFF; - connector->dpms = DRM_MODE_DPMS_OFF; connector->encoder = encoder; err = drm_mode_connector_attach_encoder(connector, encoder); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 241ad1eeec64..e51503fbaf2b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -43,14 +43,12 @@ * @manager: specific encoder has its own manager to control a hardware * appropriately and we can access a hardware drawing on this manager. * @dpms: store the encoder dpms value. - * @updated: indicate whether overlay data updating is needed or not. */ struct exynos_drm_encoder { struct drm_crtc *old_crtc; struct drm_encoder drm_encoder; struct exynos_drm_manager *manager; - int dpms; - bool updated; + int dpms; }; static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) @@ -87,9 +85,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: if (manager_ops && manager_ops->apply) - if (!exynos_encoder->updated) - manager_ops->apply(manager->dev); - + manager_ops->apply(manager->dev); exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; break; @@ -98,7 +94,6 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_OFF: exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; - exynos_encoder->updated = false; break; default: DRM_ERROR("unspecified mode %d\n", mode); @@ -210,22 +205,13 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) static void exynos_drm_encoder_commit(struct drm_encoder *encoder) { - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_manager *manager = exynos_encoder->manager; + struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); struct exynos_drm_manager_ops *manager_ops = manager->ops; DRM_DEBUG_KMS("%s\n", __FILE__); if (manager_ops && manager_ops->commit) manager_ops->commit(manager->dev); - - /* - * this will avoid one issue that overlay data is updated to - * real hardware two times. - * And this variable will be used to check if the data was - * already updated or not by exynos_drm_encoder_dpms function. - */ - exynos_encoder->updated = true; } static void exynos_drm_encoder_disable(struct drm_encoder *encoder) @@ -414,6 +400,19 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) if (manager_ops && manager_ops->dpms) manager_ops->dpms(manager->dev, mode); + /* + * set current mode to new one so that data aren't updated into + * registers by drm_helper_connector_dpms two times. + * + * in case that drm_crtc_helper_set_mode() is called, + * overlay_ops->commit() and manager_ops->commit() callbacks + * can be called two times, first at drm_crtc_helper_set_mode() + * and second at drm_helper_connector_dpms(). + * so with this setting, when drm_helper_connector_dpms() is called + * encoder->funcs->dpms() will be ignored. + */ + exynos_encoder->dpms = mode; + /* * if this condition is ok then it means that the crtc is already * detached from encoder and last function for detaching is properly diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e7fbb823fd8e..614b2e9ac462 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) const struct of_device_id *match; match = of_match_node(of_match_ptr(mixer_match_types), pdev->dev.of_node); - drv = (struct mixer_drv_data *)match->data; + drv = match->data; } else { drv = (struct mixer_drv_data *) platform_get_device_id(pdev)->driver_data; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 61ae104dca8c..c9bfd83dde64 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1505,8 +1505,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_gmch; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kick_out_firmware_fb(dev_priv); + i915_kick_out_firmware_fb(dev_priv); pci_set_master(dev->pdev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index b726b478a4f5..f78061af7045 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) crt->base.type = INTEL_OUTPUT_ANALOG; crt->base.cloneable = true; - if (IS_HASWELL(dev) || IS_I830(dev)) + if (IS_HASWELL(dev)) crt->base.crtc_mask = (1 << 0); else crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); diff --git a/trunk/drivers/gpu/drm/i915/intel_overlay.c b/trunk/drivers/gpu/drm/i915/intel_overlay.c index d7bc817f51a0..495625914e4a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_overlay.c +++ b/trunk/drivers/gpu/drm/i915/intel_overlay.c @@ -341,17 +341,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) intel_ring_emit(ring, flip_addr); intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); /* turn overlay off */ - if (IS_I830(dev)) { - /* Workaround: Don't disable the overlay fully, since otherwise - * it dies on the next OVERLAY_ON cmd. */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - } else { - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - intel_ring_emit(ring, flip_addr); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - } + intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); + intel_ring_emit(ring, flip_addr); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); intel_ring_advance(ring); return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index e2aacd329545..e019b2369861 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) props.type = BACKLIGHT_RAW; props.max_brightness = _intel_panel_get_max_backlight(dev); if (props.max_brightness == 0) { - DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); + DRM_ERROR("Failed to get maximum backlight value\n"); return -ENODEV; } dev_priv->backlight = diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 79d308da29ff..c01d97db0061 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -894,45 +894,6 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) } #endif -static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, - unsigned if_index, uint8_t tx_rate, - uint8_t *data, unsigned length) -{ - uint8_t set_buf_index[2] = { if_index, 0 }; - uint8_t hbuf_size, tmp[8]; - int i; - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, - &hbuf_size, 1)) - return false; - - /* Buffer size is 0 based, hooray! */ - hbuf_size++; - - DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", - if_index, length, hbuf_size); - - for (i = 0; i < hbuf_size; i += 8) { - memset(tmp, 0, 8); - if (i < length) - memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - tmp, 8)) - return false; - } - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -} - static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) { struct dip_infoframe avi_if = { @@ -940,7 +901,11 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, }; + uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; + uint8_t set_buf_index[2] = { 1, 0 }; uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; + uint64_t *data = (uint64_t *)sdvo_data; + unsigned i; intel_dip_infoframe_csum(&avi_if); @@ -950,9 +915,22 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) sdvo_data[3] = avi_if.checksum; memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); - return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, - SDVO_HBUF_TX_VSYNC, - sdvo_data, sizeof(sdvo_data)); + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2)) + return false; + + for (i = 0; i < sizeof(sdvo_data); i += 8) { + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_DATA, + data, 8)) + return false; + data++; + } + + return intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_TXRATE, + &tx_rate, 1); } static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h index 770bdd6ecd9f..9d030142ee43 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -708,8 +708,6 @@ struct intel_sdvo_enhancements_arg { #define SDVO_CMD_SET_AUDIO_STAT 0x91 #define SDVO_CMD_GET_AUDIO_STAT 0x92 #define SDVO_CMD_SET_HBUF_INDEX 0x93 - #define SDVO_HBUF_INDEX_ELD 0 - #define SDVO_HBUF_INDEX_AVI_IF 1 #define SDVO_CMD_GET_HBUF_INDEX 0x94 #define SDVO_CMD_GET_HBUF_INFO 0x95 #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 diff --git a/trunk/drivers/gpu/drm/nouveau/core/core/mm.c b/trunk/drivers/gpu/drm/nouveau/core/core/mm.c index a6d3cd6490f7..4d6206448670 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/core/mm.c +++ b/trunk/drivers/gpu/drm/nouveau/core/core/mm.c @@ -218,16 +218,13 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) return -ENOMEM; - - if (length) { - node->offset = roundup(offset, mm->block_size); - node->length = rounddown(offset + length, mm->block_size); - node->length -= node->offset; - } + node->offset = roundup(offset, mm->block_size); + node->length = rounddown(offset + length, mm->block_size) - node->offset; list_add_tail(&node->nl_entry, &mm->nodes); list_add_tail(&node->fl_entry, &mm->free); mm->heap_nodes++; + mm->heap_size += length; return 0; } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 05a909a17cee..16a9afb1060b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -22,8 +22,6 @@ * Authors: Ben Skeggs */ -#include - #include #include @@ -39,7 +37,6 @@ nv50_disp_sclass[] = { static void nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) { - struct nouveau_bar *bar = nouveau_bar(priv); struct nouveau_disp *disp = &priv->base; struct nouveau_software_chan *chan, *temp; unsigned long flags; @@ -49,19 +46,18 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) if (chan->vblank.crtc != crtc) continue; + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); nv_wr32(priv, 0x001570, chan->vblank.offset); nv_wr32(priv, 0x001574, chan->vblank.value); } else { - nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); - bar->flush(bar); - nv_wr32(priv, 0x06000c, - upper_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060010, - lower_32_bits(chan->vblank.offset)); + if (nv_device(priv)->chipset >= 0xc0) { + nv_wr32(priv, 0x06000c, + upper_32_bits(chan->vblank.offset)); + } + nv_wr32(priv, 0x060010, chan->vblank.offset); nv_wr32(priv, 0x060014, chan->vblank.value); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 425001204a89..8d0021049ec0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, static int nv40_graph_context_fini(struct nouveau_object *object, bool suspend) { - struct nv40_graph_priv *priv = (void *)object->engine; - struct nv40_graph_chan *chan = (void *)object; + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; int ret = 0; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index f7c581ad1991..12418574efea 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { }; struct nv40_mpeg_chan { - struct nouveau_mpeg_chan base; + struct nouveau_mpeg base; }; /******************************************************************************* diff --git a/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h b/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h index 975137ba34a6..9ee9bf4028ca 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h +++ b/trunk/drivers/gpu/drm/nouveau/core/include/core/mm.h @@ -19,6 +19,7 @@ struct nouveau_mm { u32 block_size; int heap_nodes; + u32 heap_size; }; int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 5f570806143a..27fb1af7a779 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -219,11 +219,13 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ((priv->base.ram.size & 0x000000ff) << 32); tags = nv_rd32(priv, 0x100320); - ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); - if (ret) - return ret; + if (tags) { + ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); + if (ret) + return ret; - nv_debug(priv, "%d compression tags\n", tags); + nv_debug(priv, "%d compression tags\n", tags); + } size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; switch (device->chipset) { diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index dbfc2abf0cfe..3d2c88310f98 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, case DCB_I2C_NVIO_BIT: port->drive = info.drive & 0x0f; if (device->card_type < NV_D0) { - if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) + if (info.drive >= ARRAY_SIZE(nv50_i2c_port)) break; port->drive = nv50_i2c_port[port->drive]; port->sense = port->drive; diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 9474cfca6e4c..49050d991e75 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) static void nv41_vm_flush(struct nouveau_vm *vm) { - struct nv04_vmmgr_priv *priv = (void *)vm->vmm; + struct nv04_vm_priv *priv = (void *)vm->vmm; mutex_lock(&nv_subdev(priv)->mutex); nv_wr32(priv, 0x100810, 0x00000022); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index d3595b23434a..9a6e2cb282dc 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) * valid - it's not (rh#613284) */ if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { - if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { + if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { status = connector_status_connected; goto out; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 86124b131f4f..d2f8ffeed742 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -290,7 +290,6 @@ nouveau_display_create(struct drm_device *dev) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); struct nouveau_display *disp; - u32 pclass = dev->pdev->class >> 8; int ret, gen; disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); @@ -361,27 +360,23 @@ nouveau_display_create(struct drm_device *dev) drm_kms_helper_poll_init(dev); drm_kms_helper_poll_disable(dev); - if (nouveau_modeset == 1 || - (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) { - if (nv_device(drm->device)->card_type < NV_50) - ret = nv04_display_create(dev); - else - if (nv_device(drm->device)->card_type < NV_D0) - ret = nv50_display_create(dev); - else - ret = nvd0_display_create(dev); - if (ret) - goto disp_create_err; - - if (dev->mode_config.num_crtc) { - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret) - goto vblank_err; - } + if (nv_device(drm->device)->card_type < NV_50) + ret = nv04_display_create(dev); + else + if (nv_device(drm->device)->card_type < NV_D0) + ret = nv50_display_create(dev); + else + ret = nvd0_display_create(dev); + if (ret) + goto disp_create_err; - nouveau_backlight_init(dev); + if (dev->mode_config.num_crtc) { + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret) + goto vblank_err; } + nouveau_backlight_init(dev); return 0; vblank_err: @@ -400,8 +395,7 @@ nouveau_display_destroy(struct drm_device *dev) nouveau_backlight_exit(dev); drm_vblank_cleanup(dev); - if (disp->dtor) - disp->dtor(dev); + disp->dtor(dev); drm_kms_helper_poll_fini(dev); drm_mode_config_cleanup(dev); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 0910125cbbc3..ccae8c26ae2b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -63,9 +63,8 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration"); static int nouveau_noaccel = 0; module_param_named(noaccel, nouveau_noaccel, int, 0400); -MODULE_PARM_DESC(modeset, "enable driver (default: auto, " - "0 = disabled, 1 = enabled, 2 = headless)"); -int nouveau_modeset = -1; +MODULE_PARM_DESC(modeset, "enable driver"); +static int nouveau_modeset = -1; module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; @@ -364,8 +363,7 @@ nouveau_drm_unload(struct drm_device *dev) nouveau_pm_fini(dev); - if (dev->mode_config.num_crtc) - nouveau_display_fini(dev); + nouveau_display_fini(dev); nouveau_display_destroy(dev); nouveau_irq_fini(dev); @@ -405,15 +403,13 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) pm_state.event == PM_EVENT_PRETHAW) return 0; - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "suspending fbcon...\n"); - nouveau_fbcon_set_suspend(dev, 1); + NV_INFO(drm, "suspending fbcon...\n"); + nouveau_fbcon_set_suspend(dev, 1); - NV_INFO(drm, "suspending display...\n"); - ret = nouveau_display_suspend(dev); - if (ret) - return ret; - } + NV_INFO(drm, "suspending display...\n"); + ret = nouveau_display_suspend(dev); + if (ret) + return ret; NV_INFO(drm, "evicting buffers...\n"); ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); @@ -449,10 +445,8 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) nouveau_client_init(&cli->base); } - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); - nouveau_display_resume(dev); - } + NV_INFO(drm, "resuming display...\n"); + nouveau_display_resume(dev); return ret; } @@ -492,10 +486,8 @@ nouveau_drm_resume(struct pci_dev *pdev) nouveau_irq_postinstall(dev); nouveau_pm_resume(dev); - if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); - nouveau_display_resume(dev); - } + NV_INFO(drm, "resuming display...\n"); + nouveau_display_resume(dev); return 0; } @@ -670,7 +662,9 @@ nouveau_drm_init(void) #ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) nouveau_modeset = 0; + else #endif + nouveau_modeset = 1; } if (!nouveau_modeset) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h index a10169927086..819471217546 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -141,6 +141,4 @@ int nouveau_drm_resume(struct pci_dev *); nv_info((cli), fmt, ##args); \ } while (0) -extern int nouveau_modeset; - #endif diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c index 1d8cb506a28a..9ca8afdb5549 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -61,15 +61,13 @@ nouveau_irq_handler(DRM_IRQ_ARGS) nv_subdev(pmc)->intr(nv_subdev(pmc)); - if (dev->mode_config.num_crtc) { - if (device->card_type >= NV_D0) { - if (nv_rd32(device, 0x000100) & 0x04000000) - nvd0_display_intr(dev); - } else - if (device->card_type >= NV_50) { - if (nv_rd32(device, 0x000100) & 0x04000000) - nv50_display_intr(dev); - } + if (device->card_type >= NV_D0) { + if (nv_rd32(device, 0x000100) & 0x04000000) + nvd0_display_intr(dev); + } else + if (device->card_type >= NV_50) { + if (nv_rd32(device, 0x000100) & 0x04000000) + nv50_display_intr(dev); } return IRQ_HANDLED; diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dac.c b/trunk/drivers/gpu/drm/nouveau/nv04_dac.c index 64f7020fb605..347a3bd78d04 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dac.c @@ -220,7 +220,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); if (blue == 0x18) { - NV_DEBUG(drm, "Load detected on head A\n"); + NV_INFO(drm, "Load detected on head A\n"); return connector_status_connected; } @@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) if (nv17_dac_sample_load(encoder) & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { - NV_DEBUG(drm, "Load detected on output %c\n", - '@' + ffs(dcb->or)); + NV_INFO(drm, "Load detected on output %c\n", + '@' + ffs(dcb->or)); return connector_status_connected; } else { return connector_status_disconnected; @@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) @@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n", + mode, nv_encoder->dcb->index); nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); } diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index 184cdf806761..da55d7642c8c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) @@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", + mode, nv_encoder->dcb->index); if (was_powersaving && is_powersaving_dpms(mode)) return; @@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) return; nv_encoder->last_dpms = mode; - NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", + mode, nv_encoder->dcb->index); nv04_dfp_update_backlight(encoder, mode); nv04_dfp_update_fp_control(encoder, mode); diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_tv.c b/trunk/drivers/gpu/drm/nouveau/nv04_tv.c index 62e826a139b3..099fbeda6e2e 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_tv.c @@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; uint8_t crtc1A; - NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", - mode, nv_encoder->dcb->index); + NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n", + mode, nv_encoder->dcb->index); state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); @@ -167,8 +167,9 @@ static void nv04_tv_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); - NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, + '@' + ffs(nv_encoder->dcb->or)); } static void nv04_tv_destroy(struct drm_encoder *encoder) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 3bce0299f64a..2e566e123e9e 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1696,43 +1696,35 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) return ATOM_PPLL2; DRM_ERROR("unable to allocate a PPLL\n"); return ATOM_PPLL_INVALID; - } else if (ASIC_IS_AVIVO(rdev)) { - /* in DP mode, the DP ref clock can come from either PPLL - * depending on the asic: - * DCE3: PPLL1 or PPLL2 - */ - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { - /* use the same PPLL for all DP monitors */ - pll = radeon_get_shared_dp_ppll(crtc); - if (pll != ATOM_PPLL_INVALID) - return pll; - } else { - /* use the same PPLL for all monitors with the same clock */ - pll = radeon_get_shared_nondp_ppll(crtc); - if (pll != ATOM_PPLL_INVALID) - return pll; - } - /* all other cases */ - pll_in_use = radeon_get_pll_use_mask(crtc); - /* the order shouldn't matter here, but we probably - * need this until we have atomic modeset - */ - if (rdev->flags & RADEON_IS_IGP) { + } else { + if (ASIC_IS_AVIVO(rdev)) { + /* in DP mode, the DP ref clock can come from either PPLL + * depending on the asic: + * DCE3: PPLL1 or PPLL2 + */ + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { + /* use the same PPLL for all DP monitors */ + pll = radeon_get_shared_dp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } else { + /* use the same PPLL for all monitors with the same clock */ + pll = radeon_get_shared_nondp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } + /* all other cases */ + pll_in_use = radeon_get_pll_use_mask(crtc); if (!(pll_in_use & (1 << ATOM_PPLL1))) return ATOM_PPLL1; if (!(pll_in_use & (1 << ATOM_PPLL2))) return ATOM_PPLL2; + DRM_ERROR("unable to allocate a PPLL\n"); + return ATOM_PPLL_INVALID; } else { - if (!(pll_in_use & (1 << ATOM_PPLL2))) - return ATOM_PPLL2; - if (!(pll_in_use & (1 << ATOM_PPLL1))) - return ATOM_PPLL1; + /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ + return radeon_crtc->crtc_id; } - DRM_ERROR("unable to allocate a PPLL\n"); - return ATOM_PPLL_INVALID; - } else { - /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ - return radeon_crtc->crtc_id; } } diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index af31f829f4a8..14313ad43b76 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1372,7 +1372,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); for (i = 0; i < rdev->num_crtc; i++) { - if (save->crtc_enabled[i]) { + if (save->crtc_enabled) { if (ASIC_IS_DCE6(rdev)) { tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index c042e497e450..30271b641913 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - mtileb = (palign / 8) * (halign / 8) * tileb; + mtileb = (palign / 8) * (halign / 8) * tileb;; mtile_pr = surf->nbx / palign; mtile_ps = (mtile_pr * surf->nby) / halign; surf->layer_size = mtile_ps * mtileb * slice_pt; @@ -2725,9 +2725,6 @@ static bool evergreen_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: - case CP_COHER_CNTL: - case CP_COHER_SIZE: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_GS_VERTEX_REUSE: diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 2bc0f6a1b428..df542f1a5dfb 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -91,10 +91,6 @@ #define FB_READ_EN (1 << 0) #define FB_WRITE_EN (1 << 1) -#define CP_STRMOUT_CNTL 0x84FC - -#define CP_COHER_CNTL 0x85F0 -#define CP_COHER_SIZE 0x85F4 #define CP_COHER_BASE 0x85F8 #define CP_STALLED_STAT1 0x8674 #define CP_STALLED_STAT2 0x8678 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 15f5ded65e0c..37f6a907aea4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) } /** - * radeon_atpx_power_state - power down/up the requested GPU + * radeon_atpx_switchto - switch to the requested GPU * - * @id: GPU to power down/up + * @id: GPU to switch to * @state: requested power state (0 = off, 1 = on) * * Execute the necessary ATPX function to power down/up the discrete GPU diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index b884c362a8c2..67cfc1795ecd 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct drm_mode_object *obj; int i; enum drm_connector_status ret = connector_status_disconnected; - bool dret = false, broken_edid = false; + bool dret = false; if (!force && radeon_check_hpd_status_unchanged(connector)) return connector->status; @@ -965,9 +965,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); radeon_connector->ddc_bus = NULL; - } else { - ret = connector_status_connected; - broken_edid = true; /* defer use_digital to later */ } } else { radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); @@ -1050,24 +1047,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder_funcs = encoder->helper_private; if (encoder_funcs->detect) { - if (!broken_edid) { - if (ret != connector_status_connected) { - /* deal with analog monitors without DDC */ - ret = encoder_funcs->detect(encoder, connector); - if (ret == connector_status_connected) { - radeon_connector->use_digital = false; - } - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; - } - } else { - enum drm_connector_status lret; - /* assume digital unless load detected otherwise */ - radeon_connector->use_digital = true; - lret = encoder_funcs->detect(encoder, connector); - DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); - if (lret == connector_status_connected) + if (ret != connector_status_connected) { + ret = encoder_funcs->detect(encoder, connector); + if (ret == connector_status_connected) { radeon_connector->use_digital = false; + } + if (ret != connector_status_disconnected) + radeon_connector->detected_by_load = true; } break; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 6857cb4efb76..5677a424b585 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -295,7 +295,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc_ext_cntl = 0; uint32_t mask; if (radeon_crtc->crtc_id) @@ -308,16 +307,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS); - /* - * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. - * Therefore it is set in the DAC DMPS function. - * This is different for GPU's with a single CRTC but a primary and a - * TV DAC: here it controls the single CRTC no matter where it is - * routed. Therefore we set it here. - */ - if (rdev->flags & RADEON_SINGLE_CRTC) - crtc_ext_cntl = RADEON_CRTC_CRT_ON; - switch (mode) { case DRM_MODE_DPMS_ON: radeon_crtc->enabled = true; @@ -328,7 +317,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); } drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); @@ -342,7 +331,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); } radeon_crtc->enabled = false; /* adjust pm to dpms changes AFTER disabling crtcs */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index f5ba2241dacc..0063df9d166d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -537,9 +537,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode break; } - /* handled in radeon_crtc_dpms() */ - if (!(rdev->flags & RADEON_SINGLE_CRTC)) - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); WREG32(RADEON_DAC_CNTL, dac_cntl); WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); @@ -664,8 +662,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc if (ASIC_IS_R300(rdev)) tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); - else if (ASIC_IS_RV100(rdev)) - tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); else tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); @@ -675,7 +671,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; WREG32(RADEON_DAC_CNTL, tmp); - tmp = dac_macro_cntl; tmp &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); @@ -1097,8 +1092,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) } else { if (is_tv) WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - /* handled in radeon_crtc_dpms() */ - else if (!(rdev->flags & RADEON_SINGLE_CRTC)) + else WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); } @@ -1422,104 +1416,13 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, return found; } -static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; - uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; - uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; - uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; - uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; - bool found = false; - int i; - - /* save the regs we need */ - gpio_monid = RREG32(RADEON_GPIO_MONID); - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); - disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); - disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); - disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); - disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); - disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); - crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); - crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); - crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); - crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); - - tmp = RREG32(RADEON_GPIO_MONID); - tmp &= ~RADEON_GPIO_A_0; - WREG32(RADEON_GPIO_MONID, tmp); - - WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | - RADEON_FP2_PANEL_FORMAT | - R200_FP2_SOURCE_SEL_TRANS_UNIT | - RADEON_FP2_DVO_EN | - R200_FP2_DVO_RATE_SEL_SDR)); - - WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | - RADEON_DISP_TRANS_MATRIX_GRAPHICS)); - - WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | - RADEON_CRTC2_DISP_REQ_EN_B)); - - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); - - WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); - - for (i = 0; i < 200; i++) { - tmp = RREG32(RADEON_GPIO_MONID); - if (tmp & RADEON_GPIO_Y_0) - found = true; - - if (found) - break; - - if (!drm_can_sleep()) - mdelay(1); - else - msleep(1); - } - - /* restore the regs we used */ - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); - WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - WREG32(RADEON_GPIO_MONID, gpio_monid); - - return found; -} - static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t gpiopad_a = 0, pixclks_cntl, tmp; - uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; + uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; + uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; enum drm_connector_status found = connector_status_disconnected; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; @@ -1556,27 +1459,12 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder return connector_status_disconnected; } - /* R200 uses an external DAC for secondary DAC */ - if (rdev->family == CHIP_R200) { - if (radeon_legacy_ext_dac_detect(encoder, connector)) - found = connector_status_connected; - return found; - } - /* save the regs we need */ pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - - if (rdev->flags & RADEON_SINGLE_CRTC) { - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - } else { - if (ASIC_IS_R300(rdev)) { - gpiopad_a = RREG32(RADEON_GPIOPAD_A); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - } else { - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - } - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - } + gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; + disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; + disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); dac_cntl2 = RREG32(RADEON_DAC_CNTL2); @@ -1585,24 +1473,22 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | RADEON_PIX2CLK_DAC_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; - WREG32(RADEON_CRTC_EXT_CNTL, tmp); - } else { - tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; - tmp |= RADEON_CRTC2_CRT2_ON | - (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + if (ASIC_IS_R300(rdev)) + WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - if (ASIC_IS_R300(rdev)) { - WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; - tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); - } else { - tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; - WREG32(RADEON_DISP_HW_DEBUG, tmp); - } + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; + tmp |= RADEON_CRTC2_CRT2_ON | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); + + WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + + if (ASIC_IS_R300(rdev)) { + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; + WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); + } else { + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; + WREG32(RADEON_DISP_HW_DEBUG, tmp); } tmp = RADEON_TV_DAC_NBLANK | @@ -1644,19 +1530,14 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder WREG32(RADEON_DAC_CNTL2, dac_cntl2); WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (rdev->flags & RADEON_SINGLE_CRTC) { - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + if (ASIC_IS_R300(rdev)) { + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); + WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); } else { - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (ASIC_IS_R300(rdev)) { - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - } else { - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - } + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); } - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); return found; diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 4422d630b33b..b0db712060fb 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2474,7 +2474,6 @@ static bool si_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_ESGS_RING_SIZE: diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index a8871afc5b4e..7d2a20e56577 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -424,7 +424,6 @@ # define RDERR_INT_ENABLE (1 << 0) # define GUI_IDLE_INT_ENABLE (1 << 19) -#define CP_STRMOUT_CNTL 0x84FC #define SCRATCH_REG0 0x8500 #define SCRATCH_REG1 0x8504 #define SCRATCH_REG2 0x8508 diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.h b/trunk/drivers/gpu/drm/udl/udl_drv.h index 87aa5f5d3c88..fccd361f7b50 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.h +++ b/trunk/drivers/gpu/drm/udl/udl_drv.h @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr); int udl_dumb_create(struct drm_file *file_priv, diff --git a/trunk/drivers/gpu/drm/udl/udl_fb.c b/trunk/drivers/gpu/drm/udl/udl_fb.c index d4ab3beaada0..69a2b16f42a6 100644 --- a/trunk/drivers/gpu/drm/udl/udl_fb.c +++ b/trunk/drivers/gpu/drm/udl/udl_fb.c @@ -114,10 +114,9 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, list_for_each_entry(cur, &fbdefio->pagelist, lru) { if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), - &urb, (char *) info->fix.smem_start, - &cmd, cur->index << PAGE_SHIFT, - cur->index << PAGE_SHIFT, - PAGE_SIZE, &bytes_identical, &bytes_sent)) + &urb, (char *) info->fix.smem_start, + &cmd, cur->index << PAGE_SHIFT, + PAGE_SIZE, &bytes_identical, &bytes_sent)) goto error; bytes_rendered += PAGE_SIZE; } @@ -188,11 +187,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, for (i = y; i < y + height ; i++) { const int line_offset = fb->base.pitches[0] * i; const int byte_offset = line_offset + (x * bpp); - const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); + if (udl_render_hline(dev, bpp, &urb, (char *) fb->obj->vmapping, - &cmd, byte_offset, dev_byte_offset, - width * bpp, + &cmd, byte_offset, width * bpp, &bytes_identical, &bytes_sent)) goto error; } diff --git a/trunk/drivers/gpu/drm/udl/udl_transfer.c b/trunk/drivers/gpu/drm/udl/udl_transfer.c index 142fee5f983f..dc095526ffb7 100644 --- a/trunk/drivers/gpu/drm/udl/udl_transfer.c +++ b/trunk/drivers/gpu/drm/udl/udl_transfer.c @@ -213,12 +213,11 @@ static void udl_compress_hline16( */ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, - u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr) { const u8 *line_start, *line_end, *next_pixel; - u32 base16 = 0 + (device_byte_offset / bpp) * 2; + u32 base16 = 0 + (byte_offset / bpp) * 2; struct urb *urb = *urb_ptr; u8 *cmd = *urb_buf_ptr; u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c index d1498bfd7873..3ce68a2e312d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) BUG_ON(!atomic_read(&bo->reserved)); BUG_ON(old_mem_type != TTM_PL_VRAM && - old_mem_type != VMW_PL_GMR); + old_mem_type != VMW_PL_FLAG_GMR); pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; if (pin) diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 2dd185e42f21..ed3c1e7ddde9 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1098,11 +1098,6 @@ static void vmw_pm_complete(struct device *kdev) struct drm_device *dev = pci_get_drvdata(pdev); struct vmw_private *dev_priv = vmw_priv(dev); - mutex_lock(&dev_priv->hw_mutex); - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); - mutex_unlock(&dev_priv->hw_mutex); - /** * Reclaim 3d reference held by fbdev and potentially * start fifo. diff --git a/trunk/drivers/hid/hid-apple.c b/trunk/drivers/hid/hid-apple.c index fd7722aecf77..06ebdbb6ea02 100644 --- a/trunk/drivers/hid/hid-apple.c +++ b/trunk/drivers/hid/hid-apple.c @@ -522,12 +522,6 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), - .driver_data = APPLE_HAS_FN }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), - .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), - .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index f4109fd657ff..bd3971bf31bf 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1532,9 +1532,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -2142,9 +2139,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 9d7a42857ea1..269b50912a4a 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -118,9 +118,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b diff --git a/trunk/drivers/hid/hid-microsoft.c b/trunk/drivers/hid/hid-microsoft.c index f676c01bb471..3acdcfcc17df 100644 --- a/trunk/drivers/hid/hid-microsoft.c +++ b/trunk/drivers/hid/hid-microsoft.c @@ -28,30 +28,22 @@ #define MS_RDESC 0x08 #define MS_NOGET 0x10 #define MS_DUPLICATE_USAGES 0x20 -#define MS_RDESC_3K 0x40 +/* + * Microsoft Wireless Desktop Receiver (Model 1028) has + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' + */ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - /* - * Microsoft Wireless Desktop Receiver (Model 1028) has - * 'Usage Min/Max' where it ought to have 'Physical Min/Max' - */ if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && rdesc[559] == 0x29) { hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); rdesc[557] = 0x35; rdesc[559] = 0x45; } - /* the same as above (s/usage/physical/) */ - if ((quirks & MS_RDESC_3K) && *rsize == 106 && - !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, - &rdesc[94], 4)) { - rdesc[94] = 0x35; - rdesc[96] = 0x45; - } return rdesc; } @@ -200,7 +192,7 @@ static const struct hid_device_id ms_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), .driver_data = MS_PRESENTER }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), - .driver_data = MS_ERGONOMY | MS_RDESC_3K }, + .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), .driver_data = MS_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), diff --git a/trunk/drivers/hid/hid-multitouch.c b/trunk/drivers/hid/hid-multitouch.c index 7867d69f0efe..3eb02b94fc87 100644 --- a/trunk/drivers/hid/hid-multitouch.c +++ b/trunk/drivers/hid/hid-multitouch.c @@ -210,7 +210,8 @@ static struct mt_class mt_classes[] = { }, { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | - MT_QUIRK_SLOT_IS_CONTACTNUMBER + MT_QUIRK_SLOT_IS_CONTACTNUMBER, + .maxcontacts = 10 }, { .name = MT_CLS_FLATFROG, @@ -420,11 +421,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, * contact max are global to the report */ td->last_field_index = field->index; return -1; + } case HID_DG_TOUCH: /* Legacy devices use TIPSWITCH and not TOUCH. * Let's just ignore this field. */ return -1; - } /* let hid-input decide for the others */ return 0; diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 7c47fc3f7b2b..17d15bb610d1 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -42,6 +42,7 @@ static struct cdev hidraw_cdev; static struct class *hidraw_class; static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; static DEFINE_MUTEX(minors_lock); +static void drop_ref(struct hidraw *hid, int exists_bit); static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { @@ -113,7 +114,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, __u8 *buf; int ret = 0; - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { ret = -ENODEV; goto out; } @@ -261,7 +262,7 @@ static int hidraw_open(struct inode *inode, struct file *file) } mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { err = -ENODEV; goto out_unlock; } @@ -298,36 +299,12 @@ static int hidraw_open(struct inode *inode, struct file *file) static int hidraw_release(struct inode * inode, struct file * file) { unsigned int minor = iminor(inode); - struct hidraw *dev; struct hidraw_list *list = file->private_data; - int ret; - int i; - - mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { - ret = -ENODEV; - goto unlock; - } + drop_ref(hidraw_table[minor], 0); list_del(&list->node); - dev = hidraw_table[minor]; - if (!--dev->open) { - if (list->hidraw->exist) { - hid_hw_power(dev->hid, PM_HINT_NORMAL); - hid_hw_close(dev->hid); - } else { - kfree(list->hidraw); - } - } - - for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) - kfree(list->buffer[i].value); kfree(list); - ret = 0; -unlock: - mutex_unlock(&minors_lock); - - return ret; + return 0; } static long hidraw_ioctl(struct file *file, unsigned int cmd, @@ -529,21 +506,7 @@ EXPORT_SYMBOL_GPL(hidraw_connect); void hidraw_disconnect(struct hid_device *hid) { struct hidraw *hidraw = hid->hidraw; - - mutex_lock(&minors_lock); - hidraw->exist = 0; - - device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); - - hidraw_table[hidraw->minor] = NULL; - - if (hidraw->open) { - hid_hw_close(hid); - wake_up_interruptible(&hidraw->wait); - } else { - kfree(hidraw); - } - mutex_unlock(&minors_lock); + drop_ref(hidraw, 1); } EXPORT_SYMBOL_GPL(hidraw_disconnect); @@ -592,3 +555,23 @@ void hidraw_exit(void) unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); } + +static void drop_ref(struct hidraw *hidraw, int exists_bit) +{ + mutex_lock(&minors_lock); + if (exists_bit) { + hid_hw_close(hidraw->hid); + hidraw->exist = 0; + if (hidraw->open) + wake_up_interruptible(&hidraw->wait); + } else { + --hidraw->open; + } + + if (!hidraw->open && !hidraw->exist) { + device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); + hidraw_table[hidraw->minor] = NULL; + kfree(hidraw); + } + mutex_unlock(&minors_lock); +} diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index 520e5bf4f76d..a227be47149f 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -32,7 +32,7 @@ * ASB100-A supports pwm1, while plain ASB100 does not. There is no known * way for the driver to tell which one is there. * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * asb100 7 3 1 4 0x31 0x0694 yes no */ diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index 4f4110407387..68ad7d255512 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -2,7 +2,7 @@ * fam15h_power.c - AMD Family 15h processor power monitoring * * Copyright (c) 2011 Advanced Micro Devices, Inc. - * Author: Andreas Herrmann + * Author: Andreas Herrmann * * * This driver is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); -MODULE_AUTHOR("Andreas Herrmann "); +MODULE_AUTHOR("Andreas Herrmann "); MODULE_LICENSE("GPL"); /* D18F3 */ diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index 1381a2e3bbd4..36509ae32083 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -630,9 +630,7 @@ static struct platform_driver gpio_fan_driver = { .driver = { .name = "gpio-fan", .pm = GPIO_FAN_PM, -#ifdef CONFIG_OF_GPIO .of_match_table = of_match_ptr(of_gpio_fan_match), -#endif }, }; diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index de3c7e04c3b5..1821b7423d5b 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -2083,7 +2083,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) mutex_init(&data->lock); mutex_init(&data->update_lock); data->name = w83627ehf_device_names[sio_data->kind]; - data->bank = 0xff; /* Force initial bank selection */ platform_set_drvdata(pdev, data); /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index af1589908709..5b1a6a666441 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -25,7 +25,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index 20f11d31da40..5a5046d94c3e 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -24,7 +24,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * as99127f 7 3 0 3 0x31 0x12c3 yes no * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index ed397c645198..39ab7bcc616e 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -22,7 +22,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83791d 10 5 5 3 0x71 0x5ca3 yes no * * The w83791d chip appears to be part way between the 83781d and the diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index 301942d08453..053645279f38 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -31,7 +31,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83792d 9 7 7 3 0x7a 0x5ca3 yes no */ diff --git a/trunk/drivers/hwmon/w83l786ng.c b/trunk/drivers/hwmon/w83l786ng.c index 79710bcac2f7..f0e8286c3c70 100644 --- a/trunk/drivers/hwmon/w83l786ng.c +++ b/trunk/drivers/hwmon/w83l786ng.c @@ -20,7 +20,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no */ diff --git a/trunk/drivers/i2c/Makefile b/trunk/drivers/i2c/Makefile index 1722f50f2473..beee6b2d361d 100644 --- a/trunk/drivers/i2c/Makefile +++ b/trunk/drivers/i2c/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_MUX) += i2c-mux.o obj-y += algos/ busses/ muxes/ -obj-$(CONFIG_I2C_STUB) += i2c-stub.o ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG CFLAGS_i2c-core.o := -Wno-deprecated-declarations diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index e9df4612b7eb..65dd599a0262 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -81,6 +81,7 @@ config I2C_I801 tristate "Intel 82801 (ICH/PCH)" depends on PCI select CHECK_SIGNATURE if X86 && DMI + select GPIOLIB if I2C_MUX help If you say yes to this option, support will be included for the Intel 801 family of mainboard I2C interfaces. Specifically, the following diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index 395b516ffa08..2d33d62952c1 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o +obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 6abc00d59881..37793156bd93 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -82,8 +82,7 @@ #include #include -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE #include #include #include @@ -193,8 +192,7 @@ struct i801_priv { int len; u8 *data; -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE const struct i801_mux_config *mux_drvdata; struct platform_device *mux_pdev; #endif @@ -923,8 +921,7 @@ static void __init input_apanel_init(void) {} static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} #endif /* CONFIG_X86 && CONFIG_DMI */ -#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ - defined CONFIG_DMI +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE static struct i801_mux_config i801_mux_config_asus_z8_d12 = { .gpio_chip = "gpio_ich", .values = { 0x02, 0x03 }, @@ -1062,7 +1059,7 @@ static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv) id = dmi_first_match(mux_dmi_table); if (id) { - /* Remove branch classes from trunk */ + /* Remove from branch classes from trunk */ mux_config = id->driver_data; for (i = 0; i < mux_config->n_values; i++) class &= ~mux_config->classes[i]; diff --git a/trunk/drivers/i2c/busses/i2c-mxs.c b/trunk/drivers/i2c/busses/i2c-mxs.c index 286ca1917820..1f58197062cf 100644 --- a/trunk/drivers/i2c/busses/i2c-mxs.c +++ b/trunk/drivers/i2c/busses/i2c-mxs.c @@ -1,7 +1,7 @@ /* * Freescale MXS I2C bus driver * - * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. + * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. * * based on a (non-working) driver which was: * @@ -35,6 +35,10 @@ #define DRIVER_NAME "mxs-i2c" +static bool use_pioqueue; +module_param(use_pioqueue, bool, 0); +MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); + #define MXS_I2C_CTRL0 (0x00) #define MXS_I2C_CTRL0_SET (0x04) @@ -71,6 +75,23 @@ MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ MXS_I2C_CTRL1_SLAVE_IRQ) +#define MXS_I2C_QUEUECTRL (0x60) +#define MXS_I2C_QUEUECTRL_SET (0x64) +#define MXS_I2C_QUEUECTRL_CLR (0x68) + +#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 +#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 + +#define MXS_I2C_QUEUESTAT (0x70) +#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 +#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F + +#define MXS_I2C_QUEUECMD (0x80) + +#define MXS_I2C_QUEUEDATA (0x90) + +#define MXS_I2C_DATA (0xa0) + #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ MXS_I2C_CTRL0_PRE_SEND_START | \ @@ -132,6 +153,7 @@ struct mxs_i2c_dev { const struct mxs_i2c_speed_config *speed; /* DMA support components */ + bool dma_mode; int dma_channel; struct dma_chan *dmach; struct mxs_dma_data dma_data; @@ -150,6 +172,99 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); + if (i2c->dma_mode) + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); + else + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_SET); +} + +static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, + int flags) +{ + u32 data; + + writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); + + data = (addr << 1) | I2C_SMBUS_READ; + writel(data, i2c->regs + MXS_I2C_DATA); + + data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); +} + +static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, + u8 addr, u8 *buf, int len, int flags) +{ + u32 data; + int i, shifts_left; + + data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); + + /* + * We have to copy the slave address (u8) and buffer (arbitrary number + * of u8) into the data register (u32). To achieve that, the u8 are put + * into the MSBs of 'data' which is then shifted for the next u8. When + * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 + * looks like this: + * + * 3 2 1 0 + * 10987654|32109876|54321098|76543210 + * --------+--------+--------+-------- + * buffer+2|buffer+1|buffer+0|slave_addr + */ + + data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; + + for (i = 0; i < len; i++) { + data >>= 8; + data |= buf[i] << 24; + if ((i & 3) == 2) + writel(data, i2c->regs + MXS_I2C_DATA); + } + + /* Write out the remaining bytes if any */ + shifts_left = 24 - (i & 3) * 8; + if (shifts_left) + writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); +} + +/* + * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the + * rd_threshold to 1). Couldn't get this to work, though. + */ +static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + while (readl(i2c->regs + MXS_I2C_QUEUESTAT) + & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + cond_resched(); + } + + return 0; +} + +static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) +{ + u32 uninitialized_var(data); + int i; + + for (i = 0; i < len; i++) { + if ((i & 3) == 0) { + if (mxs_i2c_wait_for_data(i2c)) + return -ETIMEDOUT; + data = readl(i2c->regs + MXS_I2C_QUEUEDATA); + } + buf[i] = data & 0xff; + data >>= 8; + } + + return 0; } static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) @@ -317,17 +432,39 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, init_completion(&i2c->cmd_complete); i2c->cmd_err = 0; - ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); - if (ret) - return ret; + if (i2c->dma_mode) { + ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); + if (ret) + return ret; + } else { + if (msg->flags & I2C_M_RD) { + mxs_i2c_pioq_setup_read(i2c, msg->addr, + msg->len, flags); + } else { + mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, + msg->len, flags); + } + + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_SET); + } ret = wait_for_completion_timeout(&i2c->cmd_complete, msecs_to_jiffies(1000)); if (ret == 0) goto timeout; + if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { + ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); + if (ret) + goto timeout; + } + if (i2c->cmd_err == -ENXIO) mxs_i2c_reset(i2c); + else + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -335,7 +472,8 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, timeout: dev_dbg(i2c->dev, "Timeout!\n"); - mxs_i2c_dma_finish(i2c); + if (i2c->dma_mode) + mxs_i2c_dma_finish(i2c); mxs_i2c_reset(i2c); return -ETIMEDOUT; } @@ -364,6 +502,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) { struct mxs_i2c_dev *i2c = dev_id; u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; + bool is_last_cmd; if (!stat) return IRQ_NONE; @@ -376,6 +515,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ i2c->cmd_err = -EIO; + if (!i2c->dma_mode) { + is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & + MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; + + if (is_last_cmd || i2c->cmd_err) + complete(&i2c->cmd_complete); + } + writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); return IRQ_HANDLED; @@ -408,6 +555,15 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) struct device_node *node = dev->of_node; int ret; + /* + * The MXS I2C DMA mode is prefered and enabled by default. + * The PIO mode is still supported, but should be used only + * for debuging purposes etc. + */ + i2c->dma_mode = !use_pioqueue; + if (!i2c->dma_mode) + dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); + /* * TODO: This is a temporary solution and should be changed * to use generic DMA binding later when the helpers get in. @@ -415,8 +571,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) ret = of_property_read_u32(node, "fsl,i2c-dma-channel", &i2c->dma_channel); if (ret) { - dev_err(dev, "Failed to get DMA channel!\n"); - return -ENODEV; + dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); + i2c->dma_mode = 0; } ret = of_property_read_u32(node, "clock-frequency", &speed); @@ -478,13 +634,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) } /* Setup the DMA */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - i2c->dma_data.chan_irq = dmairq; - i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); - if (!i2c->dmach) { - dev_err(dev, "Failed to request dma\n"); - return -ENODEV; + if (i2c->dma_mode) { + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + i2c->dma_data.chan_irq = dmairq; + i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); + if (!i2c->dmach) { + dev_err(dev, "Failed to request dma\n"); + return -ENODEV; + } } platform_set_drvdata(pdev, i2c); diff --git a/trunk/drivers/i2c/busses/i2c-nomadik.c b/trunk/drivers/i2c/busses/i2c-nomadik.c index 02c3115a2dfa..698d7acb0f08 100644 --- a/trunk/drivers/i2c/busses/i2c-nomadik.c +++ b/trunk/drivers/i2c/busses/i2c-nomadik.c @@ -644,11 +644,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, pm_runtime_get_sync(&dev->adev->dev); - status = clk_prepare_enable(dev->clk); - if (status) { - dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); - goto out_clk; - } + clk_enable(dev->clk); status = init_hw(dev); if (status) @@ -675,8 +671,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, } out: - clk_disable_unprepare(dev->clk); -out_clk: + clk_disable(dev->clk); pm_runtime_put_sync(&dev->adev->dev); dev->busy = false; diff --git a/trunk/drivers/i2c/i2c-stub.c b/trunk/drivers/i2c/busses/i2c-stub.c similarity index 75% rename from trunk/drivers/i2c/i2c-stub.c rename to trunk/drivers/i2c/busses/i2c-stub.c index d0a9c590c3cd..b1b3447942c9 100644 --- a/trunk/drivers/i2c/i2c-stub.c +++ b/trunk/drivers/i2c/busses/i2c-stub.c @@ -2,7 +2,7 @@ i2c-stub.c - I2C/SMBus chip emulator Copyright (c) 2004 Mark M. Hoffman - Copyright (C) 2007, 2012 Jean Delvare + Copyright (C) 2007 Jean Delvare This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,8 +51,8 @@ struct stub_chip { static struct stub_chip *stub_chips; /* Return negative errno on error. */ -static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, - char read_write, u8 command, int size, union i2c_smbus_data *data) +static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, + char read_write, u8 command, int size, union i2c_smbus_data * data) { s32 ret; int i, len; @@ -78,14 +78,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) { chip->pointer = command; - dev_dbg(&adap->dev, - "smbus byte - addr 0x%02x, wrote 0x%02x.\n", - addr, command); + dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " + "wrote 0x%02x.\n", + addr, command); } else { data->byte = chip->words[chip->pointer++] & 0xff; - dev_dbg(&adap->dev, - "smbus byte - addr 0x%02x, read 0x%02x.\n", - addr, data->byte); + dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " + "read 0x%02x.\n", + addr, data->byte); } ret = 0; @@ -95,14 +95,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, if (read_write == I2C_SMBUS_WRITE) { chip->words[command] &= 0xff00; chip->words[command] |= data->byte; - dev_dbg(&adap->dev, - "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", - addr, data->byte, command); + dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " + "wrote 0x%02x at 0x%02x.\n", + addr, data->byte, command); } else { data->byte = chip->words[command] & 0xff; - dev_dbg(&adap->dev, - "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", - addr, data->byte, command); + dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " + "read 0x%02x at 0x%02x.\n", + addr, data->byte, command); } chip->pointer = command + 1; @@ -112,14 +112,14 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, case I2C_SMBUS_WORD_DATA: if (read_write == I2C_SMBUS_WRITE) { chip->words[command] = data->word; - dev_dbg(&adap->dev, - "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", - addr, data->word, command); + dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " + "wrote 0x%04x at 0x%02x.\n", + addr, data->word, command); } else { data->word = chip->words[command]; - dev_dbg(&adap->dev, - "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", - addr, data->word, command); + dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " + "read 0x%04x at 0x%02x.\n", + addr, data->word, command); } ret = 0; @@ -132,17 +132,17 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, chip->words[command + i] &= 0xff00; chip->words[command + i] |= data->block[1 + i]; } - dev_dbg(&adap->dev, - "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", - addr, len, command); + dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " + "wrote %d bytes at 0x%02x.\n", + addr, len, command); } else { for (i = 0; i < len; i++) { data->block[1 + i] = chip->words[command + i] & 0xff; } - dev_dbg(&adap->dev, - "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", - addr, len, command); + dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " + "read %d bytes at 0x%02x.\n", + addr, len, command); } ret = 0; @@ -179,24 +179,25 @@ static int __init i2c_stub_init(void) int i, ret; if (!chip_addr[0]) { - pr_err("i2c-stub: Please specify a chip address\n"); + printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); return -ENODEV; } for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { - pr_err("i2c-stub: Invalid chip address 0x%02x\n", - chip_addr[i]); + printk(KERN_ERR "i2c-stub: Invalid chip address " + "0x%02x\n", chip_addr[i]); return -EINVAL; } - pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]); + printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", + chip_addr[i]); } /* Allocate memory for all chips at once */ stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); if (!stub_chips) { - pr_err("i2c-stub: Out of memory\n"); + printk(KERN_ERR "i2c-stub: Out of memory\n"); return -ENOMEM; } @@ -218,3 +219,4 @@ MODULE_LICENSE("GPL"); module_init(i2c_stub_init); module_exit(i2c_stub_exit); + diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index dcea77bf6f50..f981ac4e6783 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) } ret = devm_request_irq(&pdev->dev, i2c_dev->irq, - tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); + tegra_i2c_isr, 0, pdev->name, i2c_dev); if (ret) { dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); return ret; diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index de0874054e9f..b4b65af8612a 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -335,7 +335,6 @@ config KEYBOARD_LOCOMO config KEYBOARD_LPC32XX tristate "LPC32XX matrix key scanner support" depends on ARCH_LPC32XX && OF - select INPUT_MATRIXKMAP help Say Y here if you want to use NXP LPC32XX SoC key scanner interface, connected to a key matrix. diff --git a/trunk/drivers/input/keyboard/pxa27x_keypad.c b/trunk/drivers/input/keyboard/pxa27x_keypad.c index cad9d5dd5973..803ff6fe021e 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keypad.c +++ b/trunk/drivers/input/keyboard/pxa27x_keypad.c @@ -368,9 +368,6 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) unsigned int mask = 0, direct_key_num = 0; unsigned long kpc = 0; - /* clear pending interrupt bit */ - keypad_readl(KPC); - /* enable matrix keys with automatic scan */ if (pdata->matrix_key_rows && pdata->matrix_key_cols) { kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; diff --git a/trunk/drivers/input/misc/xen-kbdfront.c b/trunk/drivers/input/misc/xen-kbdfront.c index 6f7d99013031..02ca8680ea5b 100644 --- a/trunk/drivers/input/misc/xen-kbdfront.c +++ b/trunk/drivers/input/misc/xen-kbdfront.c @@ -311,6 +311,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -349,10 +350,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/input/mouse/bcm5974.c b/trunk/drivers/input/mouse/bcm5974.c index 2baff1b79a55..3a78f235fa3e 100644 --- a/trunk/drivers/input/mouse/bcm5974.c +++ b/trunk/drivers/input/mouse/bcm5974.c @@ -84,10 +84,6 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 -/* MacbookPro10,2 (unibody, October 2012) */ -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a -#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -141,10 +137,6 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), - /* MacbookPro10,2 */ - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), - BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), /* Terminating entry */ {} }; @@ -387,19 +379,6 @@ static const struct bcm5974_config bcm5974_config_table[] = { { SN_COORD, -150, 6730 }, { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, - { - USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, - USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, - USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, - HAS_INTEGRATED_BUTTON, - 0x84, sizeof(struct bt_data), - 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { SN_PRESSURE, 0, 300 }, - { SN_WIDTH, 0, 2048 }, - { SN_COORD, -4750, 5280 }, - { SN_COORD, -150, 6730 }, - { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } - }, {} }; diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index 858ad446de91..2c1e12bf2ab4 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf, features->pktlen = WACOM_PKGLEN_TPC2FG; } - if (features->type == MTSCREEN || features->type == WACOM_24HDT) + if (features->type == MTSCREEN || WACOM_24HDT) features->pktlen = WACOM_PKGLEN_MTOUCH; if (features->type == BAMBOO_PT) { diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 0a67031ffc13..aa6010131179 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -1518,9 +1518,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - wacom_setup_cintiq(wacom_wac); break; diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index f7668b24c378..1ba232cbc09d 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI config TOUCHSCREEN_EGALAX tristate "EETI eGalax multi-touch panel support" - depends on I2C && OF + depends on I2C help Say Y here to enable support for I2C connected EETI eGalax multi-touch panels. diff --git a/trunk/drivers/input/touchscreen/egalax_ts.c b/trunk/drivers/input/touchscreen/egalax_ts.c index 13fa62fdfb0b..c1e3460f1195 100644 --- a/trunk/drivers/input/touchscreen/egalax_ts.c +++ b/trunk/drivers/input/touchscreen/egalax_ts.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * Mouse Mode: some panel may configure the controller to mouse mode, @@ -123,17 +122,9 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) /* wake up controller by an falling edge of interrupt gpio. */ static int egalax_wake_up_device(struct i2c_client *client) { - struct device_node *np = client->dev.of_node; - int gpio; + int gpio = irq_to_gpio(client->irq); int ret; - if (!np) - return -ENODEV; - - gpio = of_get_named_gpio(np, "wakeup-gpios", 0); - if (!gpio_is_valid(gpio)) - return -ENODEV; - ret = gpio_request(gpio, "egalax_irq"); if (ret < 0) { dev_err(&client->dev, @@ -190,11 +181,7 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, ts->input_dev = input_dev; /* controller may be in sleep, wake it up. */ - error = egalax_wake_up_device(client); - if (error) { - dev_err(&client->dev, "Failed to wake up the controller\n"); - goto err_free_dev; - } + egalax_wake_up_device(client); ret = egalax_firmware_version(client); if (ret < 0) { @@ -287,17 +274,11 @@ static int egalax_ts_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); -static struct of_device_id egalax_ts_dt_ids[] = { - { .compatible = "eeti,egalax_ts" }, - { /* sentinel */ } -}; - static struct i2c_driver egalax_ts_driver = { .driver = { .name = "egalax_ts", .owner = THIS_MODULE, .pm = &egalax_ts_pm_ops, - .of_match_table = of_match_ptr(egalax_ts_dt_ids), }, .id_table = egalax_ts_id, .probe = egalax_ts_probe, diff --git a/trunk/drivers/input/touchscreen/tsc40.c b/trunk/drivers/input/touchscreen/tsc40.c index eb96f168fb9d..63209aaa55f0 100644 --- a/trunk/drivers/input/touchscreen/tsc40.c +++ b/trunk/drivers/input/touchscreen/tsc40.c @@ -107,6 +107,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) __set_bit(BTN_TOUCH, input_dev->keybit); input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); + input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); serio_set_drvdata(serio, ptsc); diff --git a/trunk/drivers/isdn/Kconfig b/trunk/drivers/isdn/Kconfig index 86cd75a0e84d..a233ed53913a 100644 --- a/trunk/drivers/isdn/Kconfig +++ b/trunk/drivers/isdn/Kconfig @@ -4,7 +4,7 @@ menuconfig ISDN bool "ISDN support" - depends on NET && NETDEVICES + depends on NET depends on !S390 && !UML ---help--- ISDN ("Integrated Services Digital Network", called RNIS in France) diff --git a/trunk/drivers/isdn/i4l/Kconfig b/trunk/drivers/isdn/i4l/Kconfig index 9c6650ea848e..2302fbe70ac6 100644 --- a/trunk/drivers/isdn/i4l/Kconfig +++ b/trunk/drivers/isdn/i4l/Kconfig @@ -6,7 +6,7 @@ if ISDN_I4L config ISDN_PPP bool "Support synchronous PPP" - depends on INET + depends on INET && NETDEVICES select SLHC help Over digital connections such as ISDN, there is no need to diff --git a/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index e2a945ee9f05..8c610fa6782b 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/drivers/isdn/i4l/isdn_common.c @@ -1312,6 +1312,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) } else return -EINVAL; break; +#ifdef CONFIG_NETDEVICES case IIOCNETGPN: /* Get peer phone number of a connected * isdn network interface */ @@ -1321,6 +1322,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return isdn_net_getpeer(&phone, argp); } else return -EINVAL; +#endif default: return -EINVAL; } @@ -1350,6 +1352,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) case IIOCNETLCR: printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); return -ENODEV; +#ifdef CONFIG_NETDEVICES case IIOCNETAIF: /* Add a network-interface */ if (arg) { @@ -1488,6 +1491,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return -EFAULT; return isdn_net_force_hangup(name); break; +#endif /* CONFIG_NETDEVICES */ case IIOCSETVER: dev->net_verbose = arg; printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); diff --git a/trunk/drivers/md/faulty.c b/trunk/drivers/md/faulty.c index 5e7dc772f5de..45135f69509c 100644 --- a/trunk/drivers/md/faulty.c +++ b/trunk/drivers/md/faulty.c @@ -315,11 +315,8 @@ static int run(struct mddev *mddev) } conf->nfaults = 0; - rdev_for_each(rdev, mddev) { + rdev_for_each(rdev, mddev) conf->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); - } md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); mddev->private = conf; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 636bae0405e8..8034fbd6190c 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -2710,7 +2710,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) || disk_idx < 0) continue; if (test_bit(Replacement, &rdev->flags)) - disk = conf->mirrors + mddev->raid_disks + disk_idx; + disk = conf->mirrors + conf->raid_disks + disk_idx; else disk = conf->mirrors + disk_idx; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index d1295aff4173..906ccbd0f7dc 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1783,7 +1783,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) clear_bit(Unmerged, &rdev->flags); } md_integrity_add_rdev(rdev, mddev); - if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) + if (blk_queue_discard(bdev_get_queue(rdev->bdev))) queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); print_conf(conf); @@ -3613,14 +3613,11 @@ static int run(struct mddev *mddev) discard_supported = true; } - if (mddev->queue) { - if (discard_supported) - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, - mddev->queue); - else - queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, - mddev->queue); - } + if (discard_supported) + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + else + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + /* need to check that every block has at least one working mirror */ if (!enough(conf, -1)) { printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", diff --git a/trunk/drivers/mmc/host/dw_mmc-exynos.c b/trunk/drivers/mmc/host/dw_mmc-exynos.c index 4d50da618166..660bbc528862 100644 --- a/trunk/drivers/mmc/host/dw_mmc-exynos.c +++ b/trunk/drivers/mmc/host/dw_mmc-exynos.c @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { MMC_CAP_CMD23, }; -static const struct dw_mci_drv_data exynos5250_drv_data = { +static struct dw_mci_drv_data exynos5250_drv_data = { .caps = exynos5250_dwmmc_caps, .init = dw_mci_exynos_priv_init, .setup_clock = dw_mci_exynos_setup_clock, @@ -220,14 +220,14 @@ static const struct dw_mci_drv_data exynos5250_drv_data = { static const struct of_device_id dw_mci_exynos_match[] = { { .compatible = "samsung,exynos5250-dw-mshc", - .data = &exynos5250_drv_data, }, + .data = (void *)&exynos5250_drv_data, }, {}, }; -MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); +MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); int dw_mci_exynos_probe(struct platform_device *pdev) { - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; const struct of_device_id *match; match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.c b/trunk/drivers/mmc/host/dw_mmc-pltfm.c index 917936bee5d5..c960ca7ffbe6 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.c +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.c @@ -24,7 +24,7 @@ #include "dw_mmc.h" int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data) + struct dw_mci_drv_data *drv_data) { struct dw_mci *host; struct resource *regs; @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, if (!host->regs) return -ENOMEM; - if (drv_data && drv_data->init) { - ret = drv_data->init(host); + if (host->drv_data->init) { + ret = host->drv_data->init(host); if (ret) return ret; } diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.h b/trunk/drivers/mmc/host/dw_mmc-pltfm.h index 2ac37b81de4d..301f24541fc2 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.h +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.h @@ -13,7 +13,7 @@ #define _DW_MMC_PLTFM_H_ extern int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data); + struct dw_mci_drv_data *drv_data); extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); extern const struct dev_pm_ops dw_mci_pltfm_pmops; diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index c0667c8af2bd..c2828f35c3b8 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -232,7 +232,6 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) { struct mmc_data *data; struct dw_mci_slot *slot = mmc_priv(mmc); - struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 cmdr; cmd->error = -EINPROGRESS; @@ -262,8 +261,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) cmdr |= SDMMC_CMD_DAT_WR; } - if (drv_data && drv_data->prepare_command) - drv_data->prepare_command(slot->host, &cmdr); + if (slot->host->drv_data->prepare_command) + slot->host->drv_data->prepare_command(slot->host, &cmdr); return cmdr; } @@ -435,7 +434,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) return 0; } -static const struct dw_mci_dma_ops dw_mci_idmac_ops = { +static struct dw_mci_dma_ops dw_mci_idmac_ops = { .init = dw_mci_idmac_init, .start = dw_mci_idmac_start_dma, .stop = dw_mci_idmac_stop_dma, @@ -773,7 +772,6 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct dw_mci_slot *slot = mmc_priv(mmc); - struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 regs; /* set default 1 bit mode */ @@ -809,8 +807,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) slot->clock = ios->clock; } - if (drv_data && drv_data->set_ios) - drv_data->set_ios(slot->host, ios); + if (slot->host->drv_data->set_ios) + slot->host->drv_data->set_ios(slot->host, ios); switch (ios->power_mode) { case MMC_POWER_UP: @@ -1817,7 +1815,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; struct dw_mci_slot *slot; - struct dw_mci_drv_data *drv_data = host->drv_data; int ctrl_id, ret; u8 bus_width; @@ -1857,8 +1854,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else { ctrl_id = to_platform_device(host->dev)->id; } - if (drv_data && drv_data->caps) - mmc->caps |= drv_data->caps[ctrl_id]; + if (host->drv_data && host->drv_data->caps) + mmc->caps |= host->drv_data->caps[ctrl_id]; if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; @@ -1870,10 +1867,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) else bus_width = 1; - if (drv_data && drv_data->setup_bus) { + if (host->drv_data->setup_bus) { struct device_node *slot_np; slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); - ret = drv_data->setup_bus(host, slot_np, bus_width); + ret = host->drv_data->setup_bus(host, slot_np, bus_width); if (ret) goto err_setup_bus; } @@ -1971,7 +1968,7 @@ static void dw_mci_init_dma(struct dw_mci *host) /* Determine which DMA interface to use */ #ifdef CONFIG_MMC_DW_IDMAC host->dma_ops = &dw_mci_idmac_ops; - dev_info(host->dev, "Using internal DMA controller.\n"); + dev_info(&host->dev, "Using internal DMA controller.\n"); #endif if (!host->dma_ops) @@ -2038,7 +2035,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) struct dw_mci_board *pdata; struct device *dev = host->dev; struct device_node *np = dev->of_node; - struct dw_mci_drv_data *drv_data = host->drv_data; int idx, ret; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); @@ -2066,8 +2062,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); - if (drv_data && drv_data->parse_dt) { - ret = drv_data->parse_dt(host); + if (host->drv_data->parse_dt) { + ret = host->drv_data->parse_dt(host); if (ret) return ERR_PTR(ret); } @@ -2084,7 +2080,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) int dw_mci_probe(struct dw_mci *host) { - struct dw_mci_drv_data *drv_data = host->drv_data; int width, i, ret = 0; u32 fifo_size; int init_slots = 0; @@ -2132,8 +2127,8 @@ int dw_mci_probe(struct dw_mci *host) else host->bus_hz = clk_get_rate(host->ciu_clk); - if (drv_data && drv_data->setup_clock) { - ret = drv_data->setup_clock(host); + if (host->drv_data->setup_clock) { + ret = host->drv_data->setup_clock(host); if (ret) { dev_err(host->dev, "implementation specific clock setup failed\n"); @@ -2233,21 +2228,6 @@ int dw_mci_probe(struct dw_mci *host) else host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; - /* - * Enable interrupts for command done, data over, data empty, card det, - * receive ready and error such as transmit, receive timeout, crc error - */ - mci_writel(host, RINTSTS, 0xFFFFFFFF); - mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | - SDMMC_INT_TXDR | SDMMC_INT_RXDR | - DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); - mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ - - dev_info(host->dev, "DW MMC controller at irq %d, " - "%d bit host data width, " - "%u deep fifo\n", - host->irq, width, fifo_size); - /* We need at least one slot to succeed */ for (i = 0; i < host->num_slots; i++) { ret = dw_mci_init_slot(host, i); @@ -2277,6 +2257,20 @@ int dw_mci_probe(struct dw_mci *host) else host->data_offset = DATA_240A_OFFSET; + /* + * Enable interrupts for command done, data over, data empty, card det, + * receive ready and error such as transmit, receive timeout, crc error + */ + mci_writel(host, RINTSTS, 0xFFFFFFFF); + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | + SDMMC_INT_TXDR | SDMMC_INT_RXDR | + DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); + mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ + + dev_info(host->dev, "DW MMC controller at irq %d, " + "%d bit host data width, " + "%u deep fifo\n", + host->irq, width, fifo_size); if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); diff --git a/trunk/drivers/mmc/host/mxcmmc.c b/trunk/drivers/mmc/host/mxcmmc.c index 6290b7f1ccfe..565c2e4fac75 100644 --- a/trunk/drivers/mmc/host/mxcmmc.c +++ b/trunk/drivers/mmc/host/mxcmmc.c @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mxc-mmc"); +MODULE_ALIAS("platform:imx-mmc"); diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index fedd258cc4ea..54bfd0cc106b 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -178,8 +178,7 @@ struct omap_hsmmc_host { static int omap_hsmmc_card_detect(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -187,8 +186,7 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) static int omap_hsmmc_get_wp(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); @@ -196,8 +194,7 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) static int omap_hsmmc_get_cover_state(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -207,8 +204,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; disable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -216,8 +212,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; enable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -2014,9 +2009,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) clk_put(host->dbclk); } - omap_hsmmc_gpio_free(host->pdata); - iounmap(host->base); mmc_free_host(host->mmc); + iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) diff --git a/trunk/drivers/mmc/host/sdhci-dove.c b/trunk/drivers/mmc/host/sdhci-dove.c index 8fd50a211037..90140eb03e36 100644 --- a/trunk/drivers/mmc/host/sdhci-dove.c +++ b/trunk/drivers/mmc/host/sdhci-dove.c @@ -19,7 +19,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -85,32 +84,30 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); + if (ret) + goto sdhci_dove_register_fail; + priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "unable to allocate private data"); - return -ENOMEM; + ret = -ENOMEM; + goto sdhci_dove_allocate_fail; } - priv->clk = clk_get(&pdev->dev, NULL); - if (!IS_ERR(priv->clk)) - clk_prepare_enable(priv->clk); - - ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); - if (ret) - goto sdhci_dove_register_fail; - host = platform_get_drvdata(pdev); pltfm_host = sdhci_priv(host); pltfm_host->priv = priv; + priv->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(priv->clk)) + clk_prepare_enable(priv->clk); return 0; +sdhci_dove_allocate_fail: + sdhci_pltfm_unregister(pdev); sdhci_dove_register_fail: - if (!IS_ERR(priv->clk)) { - clk_disable_unprepare(priv->clk); - clk_put(priv->clk); - } return ret; } @@ -120,13 +117,14 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_dove_priv *priv = pltfm_host->priv; - sdhci_pltfm_unregister(pdev); - - if (!IS_ERR(priv->clk)) { - clk_disable_unprepare(priv->clk); - clk_put(priv->clk); + if (priv->clk) { + if (!IS_ERR(priv->clk)) { + clk_disable_unprepare(priv->clk); + clk_put(priv->clk); + } + devm_kfree(&pdev->dev, priv->clk); } - return 0; + return sdhci_pltfm_unregister(pdev); } static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { diff --git a/trunk/drivers/mmc/host/sdhci-of-esdhc.c b/trunk/drivers/mmc/host/sdhci-of-esdhc.c index 63d219f57cae..ae5fcbfa1eef 100644 --- a/trunk/drivers/mmc/host/sdhci-of-esdhc.c +++ b/trunk/drivers/mmc/host/sdhci-of-esdhc.c @@ -169,16 +169,6 @@ static void esdhc_of_resume(struct sdhci_host *host) } #endif -static void esdhc_of_platform_init(struct sdhci_host *host) -{ - u32 vvn; - - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - if (vvn == VENDOR_V_22) - host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; -} - static struct sdhci_ops sdhci_esdhc_ops = { .read_l = esdhc_readl, .read_w = esdhc_readw, @@ -190,7 +180,6 @@ static struct sdhci_ops sdhci_esdhc_ops = { .enable_dma = esdhc_of_enable_dma, .get_max_clock = esdhc_of_get_max_clock, .get_min_clock = esdhc_of_get_min_clock, - .platform_init = esdhc_of_platform_init, #ifdef CONFIG_PM .platform_suspend = esdhc_of_suspend, .platform_resume = esdhc_of_resume, diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 04936f353ced..4bb74b042a06 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( return ERR_PTR(-ENODEV); } - if (pci_resource_len(pdev, bar) < 0x100) { + if (pci_resource_len(pdev, bar) != 0x100) { dev_err(&pdev->dev, "Invalid iomem size. You may " "experience problems.\n"); } diff --git a/trunk/drivers/mmc/host/sdhci-pltfm.c b/trunk/drivers/mmc/host/sdhci-pltfm.c index 27164457f861..65551a9709cc 100644 --- a/trunk/drivers/mmc/host/sdhci-pltfm.c +++ b/trunk/drivers/mmc/host/sdhci-pltfm.c @@ -150,13 +150,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, goto err_remap; } - /* - * Some platforms need to probe the controller to be able to - * determine which caps should be used. - */ - if (host->ops && host->ops->platform_init) - host->ops->platform_init(host); - platform_set_drvdata(pdev, host); return host; diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index a54dd5d7a5f9..2903949594c6 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) if (ourhost->cur_clk != best_src) { struct clk *clk = ourhost->clk_bus[best_src]; - clk_prepare_enable(clk); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(clk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); /* turn clock off to card before changing clock source */ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); @@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } /* enable the local io clock and keep it running for the moment. */ - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { struct clk *clk; @@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } #ifndef CONFIG_PM_RUNTIME - clk_prepare_enable(sc->clk_bus[sc->cur_clk]); + clk_enable(sc->clk_bus[sc->cur_clk]); #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -747,14 +747,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) sdhci_s3c_setup_card_detect_gpio(sc); #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); #endif return 0; err_req_regs: #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { @@ -763,7 +762,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } err_no_busclks: - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); err_io_clk: @@ -795,8 +794,7 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) gpio_free(sc->ext_cd_gpio); #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); #endif sdhci_remove_host(host, 1); @@ -804,14 +802,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { clk_put(sc->clk_bus[ptr]); } } - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); if (pdev->dev.of_node) { @@ -851,8 +849,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) ret = sdhci_runtime_suspend_host(host); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); - clk_disable_unprepare(busclk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); + clk_disable(busclk); return ret; } @@ -863,8 +861,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) struct clk *busclk = ourhost->clk_io; int ret; - clk_prepare_enable(busclk); - clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(busclk); + clk_enable(ourhost->clk_bus[ourhost->cur_clk]); ret = sdhci_runtime_resume_host(host); return ret; } diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index c7851c0aabce..7922adb42386 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -1315,19 +1315,16 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) */ if ((host->flags & SDHCI_NEEDS_RETUNING) && !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { - if (mmc->card) { - /* eMMC uses cmd21 but sd and sdio use cmd19 */ - tuning_opcode = - mmc->card->type == MMC_TYPE_MMC ? - MMC_SEND_TUNING_BLOCK_HS200 : - MMC_SEND_TUNING_BLOCK; - spin_unlock_irqrestore(&host->lock, flags); - sdhci_execute_tuning(mmc, tuning_opcode); - spin_lock_irqsave(&host->lock, flags); - - /* Restore original mmc_request structure */ - host->mrq = mrq; - } + /* eMMC uses cmd21 while sd and sdio use cmd19 */ + tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? + MMC_SEND_TUNING_BLOCK_HS200 : + MMC_SEND_TUNING_BLOCK; + spin_unlock_irqrestore(&host->lock, flags); + sdhci_execute_tuning(mmc, tuning_opcode); + spin_lock_irqsave(&host->lock, flags); + + /* Restore original mmc_request structure */ + host->mrq = mrq; } if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) @@ -2840,9 +2837,6 @@ int sdhci_add_host(struct sdhci_host *host) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) - mmc->caps &= ~MMC_CAP_CMD23; - if (caps[0] & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; @@ -2852,12 +2846,9 @@ int sdhci_add_host(struct sdhci_host *host) /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); - if (IS_ERR_OR_NULL(host->vqmmc)) { - if (PTR_ERR(host->vqmmc) < 0) { - pr_info("%s: no vqmmc regulator found\n", - mmc_hostname(mmc)); - host->vqmmc = NULL; - } + if (IS_ERR(host->vqmmc)) { + pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); + host->vqmmc = NULL; } else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) regulator_enable(host->vqmmc); @@ -2913,12 +2904,9 @@ int sdhci_add_host(struct sdhci_host *host) ocr_avail = 0; host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); - if (IS_ERR_OR_NULL(host->vmmc)) { - if (PTR_ERR(host->vmmc) < 0) { - pr_info("%s: no vmmc regulator found\n", - mmc_hostname(mmc)); - host->vmmc = NULL; - } + if (IS_ERR(host->vmmc)) { + pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); + host->vmmc = NULL; } else regulator_enable(host->vmmc); diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index 71a4a7ed46c5..97653ea8942b 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -278,7 +278,6 @@ struct sdhci_ops { void (*hw_reset)(struct sdhci_host *host); void (*platform_suspend)(struct sdhci_host *host); void (*platform_resume)(struct sdhci_host *host); - void (*platform_init)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS diff --git a/trunk/drivers/mmc/host/sh_mmcif.c b/trunk/drivers/mmc/host/sh_mmcif.c index d25bc97dc5c6..11d2bc3b51d5 100644 --- a/trunk/drivers/mmc/host/sh_mmcif.c +++ b/trunk/drivers/mmc/host/sh_mmcif.c @@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - clk_disable(host->hclk); mmc_free_host(host->mmc); pm_runtime_put_sync(&pdev->dev); + clk_disable(host->hclk); pm_runtime_disable(&pdev->dev); return 0; diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index ef8d2a080d17..dc15d248443f 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -1060,7 +1060,7 @@ static ssize_t bonding_store_primary(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing primary */ if (!strlen(ifname) || buf[0] == '\n') { @@ -1237,7 +1237,7 @@ static ssize_t bonding_store_active_slave(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing active */ if (!strlen(ifname) || buf[0] == '\n') { diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 6e5bdd1a31d9..c65295dded39 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) SHMEM_EEE_ADV_STATUS_SHIFT); if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { DP(BNX2X_MSG_ETHTOOL, - "Direct manipulation of EEE advertisement is not supported\n"); + "Direct manipulation of EEE advertisment is not supported\n"); return -EINVAL; } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f6cfdc6cf20f..e2e45ee5df33 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -137,16 +137,7 @@ #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD -#define LINK_UPDATE_MASK \ - (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \ - LINK_STATUS_LINK_UP | \ - LINK_STATUS_PHYSICAL_LINK_FLAG | \ - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \ - LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \ - LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \ - LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) + #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 @@ -3304,21 +3295,6 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) DEFAULT_PHY_DEV_ADDR); } -static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy, - struct link_params *params, - u32 action) -{ - struct bnx2x *bp = params->bp; - switch (action) { - case PHY_INIT: - /* Set correct devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, - phy->def_md_devad); - break; - } -} - static void bnx2x_xgxs_deassert(struct link_params *params) { struct bnx2x *bp = params->bp; @@ -3333,8 +3309,10 @@ static void bnx2x_xgxs_deassert(struct link_params *params) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - bnx2x_xgxs_specific_func(¶ms->phy[INT_PHY], params, - PHY_INIT); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); } static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, @@ -3567,11 +3545,14 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 lane, i, cl72_ctrl, an_adv = 0; - u16 ucode_ver; + u16 val16 = 0, lane, i; struct bnx2x *bp = params->bp; static struct bnx2x_reg_set reg_set[] = { {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, @@ -3584,19 +3565,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); - cl72_ctrl &= 0xf8ff; - cl72_ctrl |= 0x3800; - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); - /* Check adding advertisement for 1G KX */ if (((vars->line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || (vars->line_speed == SPEED_1000)) { u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; - an_adv |= (1<<5); + val16 |= (1<<5); /* Enable CL37 1G Parallel Detect */ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); @@ -3606,14 +3580,11 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || (vars->line_speed == SPEED_10000)) { /* Check adding advertisement for 10G KR */ - an_adv |= (1<<7); + val16 |= (1<<7); /* Enable 10G Parallel Detect */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 1); - bnx2x_set_aer_mmd(params, phy); + DP(NETIF_MSG_LINK, "Advertize 10G\n"); } @@ -3633,7 +3604,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Advertised speeds */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv); + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); /* Advertised and set FEC (Forward Error Correction) */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, @@ -3657,10 +3628,9 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 */ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); - if (ucode_ver < 0xd108) { - DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", - ucode_ver); + MDIO_WC_REG_UC_INFO_B1_VERSION, &val16); + if (val16 < 0xd108) { + DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; } bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, @@ -3681,16 +3651,21 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val16, i, lane; + u16 i; static struct bnx2x_reg_set reg_set[] = { /* Disable Autoneg */ {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00}, {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, + /* Disable CL36 PCS Tx */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, + /* Double Wide Single Data Rate @ pll rate */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, /* Leave cl72 training enable, needed for KR */ {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, @@ -3701,24 +3676,11 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Global registers */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 &= ~(0x0011 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); + /* Leave CL72 enabled */ + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x3800); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 |= (0x0303 << (lane << 1)); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); /* Set speed via PMA/PMD register */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); @@ -4341,7 +4303,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u16 val16, lane; + u16 val16; bnx2x_sfp_e3_set_transmitter(params, phy, 0); bnx2x_set_mdio_clk(bp, params->chip_id, params->port); bnx2x_set_aer_mmd(params, phy); @@ -4378,30 +4340,6 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, MDIO_WC_REG_XGXSBLK1_LANECTRL2, val16 & 0xff00); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 |= (0x11 << lane); - if (phy->flags & FLAGS_WC_DUAL_MODE) - val16 |= (0x22 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); - - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 &= ~(0x0303 << (lane << 1)); - val16 |= (0x0101 << (lane << 1)); - if (phy->flags & FLAGS_WC_DUAL_MODE) { - val16 &= ~(0x0c0c << (lane << 1)); - val16 |= (0x0404 << (lane << 1)); - } - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); - } static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, @@ -6358,7 +6296,15 @@ static int bnx2x_update_link_down(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; /* Update shared memory */ - vars->link_status &= ~LINK_UPDATE_MASK; + vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | + LINK_STATUS_LINK_UP | + LINK_STATUS_PHYSICAL_LINK_FLAG | + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | + LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | + LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | + LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE); vars->line_speed = 0; bnx2x_update_mng(params, vars->link_status); @@ -6506,7 +6452,6 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; - vars->link_status &= ~LINK_UPDATE_MASK; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { phy_vars[phy_index].flow_ctrl = 0; @@ -7634,7 +7579,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params, static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, - u8 *o_buf, u8 is_init) + u8 *o_buf) { int rc = 0; u8 i, j = 0, cnt = 0; @@ -7651,10 +7596,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { - if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) { + if (cnt == I2C_WA_PWR_ITER) { bnx2x_warpcore_power_module(params, phy, 0); /* Note that 100us are not enough here */ - usleep_range(1000, 2000); + usleep_range(1000,1000); bnx2x_warpcore_power_module(params, phy, 1); } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, @@ -7774,7 +7719,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf, 0); + byte_cnt, o_buf); break; } return rc; @@ -7978,7 +7923,6 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, { u8 val; - int rc; struct bnx2x *bp = params->bp; u16 timeout; /* Initialization time after hot-plug may take up to 300ms for @@ -7986,14 +7930,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, */ for (timeout = 0; timeout < 60; timeout++) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, - params, 1, - 1, &val, 1); - else - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, - &val); - if (rc == 0) { + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) + == 0) { DP(NETIF_MSG_LINK, "SFP+ module initialization took %d ms\n", timeout * 5); @@ -8001,8 +7939,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, } usleep_range(5000, 10000); } - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val); - return rc; + return -EINVAL; } static void bnx2x_8727_power_module(struct bnx2x *bp, @@ -9941,7 +9878,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, else rc = bnx2x_8483x_disable_eee(phy, params, vars); if (rc) { - DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); + DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); return rc; } } else { @@ -11056,7 +10993,7 @@ static struct bnx2x_phy phy_xgxs = { .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, .set_link_led = (set_link_led_t)NULL, - .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_warpcore = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, @@ -11528,11 +11465,6 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_BASE_T; break; case PORT_HW_CFG_NET_SERDES_IF_XFI: - phy->supported &= (SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); phy->media_type = ETH_PHY_XFP_FIBER; break; case PORT_HW_CFG_NET_SERDES_IF_SFI: @@ -12987,7 +12919,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); break; default: - DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); + DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); } DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, old_status, status); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bd1fd3d87c24..d5648fc666bd 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -6794,9 +6794,8 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, BLOCK_DORQ, init_phase); - bnx2x_init_block(bp, BLOCK_BRB1, init_phase); - if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); if (IS_MF(bp)) low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); @@ -11903,15 +11902,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* disable FCOE L2 queue for E1x */ if (CHIP_IS_E1x(bp)) bp->flags |= NO_FCOE_FLAG; - /* disable FCOE for 57840 device, until FW supports it */ - switch (ent->driver_data) { - case BCM57840_O: - case BCM57840_4_10: - case BCM57840_2_20: - case BCM57840_MFO: - case BCM57840_MF: - bp->flags |= NO_FCOE_FLAG; - } + #endif diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 0df1284df497..c1cde11b0c6d 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3415,6 +3415,16 @@ static int adap_init0_config(struct adapter *adapter, int reset) "mismatch: [fini] csum=%#x, computed csum=%#x\n", finicsum, cfcsum); + /* + * If we're a pure NIC driver then disable all offloading facilities. + * This will allow the firmware to optimize aspects of the hardware + * configuration which will result in improved performance. + */ + caps_cmd.ofldcaps = 0; + caps_cmd.iscsicaps = 0; + caps_cmd.rdmacaps = 0; + caps_cmd.fcoecaps = 0; + /* * And now tell the firmware to use the configuration we just loaded. */ diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 730ae2cfa49e..32eec15fe4c2 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2519,7 +2519,6 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) { struct fw_bye_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, BYE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2536,7 +2535,6 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) { struct fw_initialize_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, INITIALIZE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2553,7 +2551,6 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) { struct fw_reset_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, RESET, WRITE); c.val = htonl(reset); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); @@ -2831,7 +2828,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, HOSTPAGESIZEPF7(sge_hps)); t4_set_reg_field(adap, SGE_CONTROL, - INGPADBOUNDARY_MASK | + INGPADBOUNDARY(INGPADBOUNDARY_MASK) | EGRSTATUSPAGESIZE_MASK, INGPADBOUNDARY(fl_align_log - 5) | EGRSTATUSPAGESIZE(stat_len != 64)); @@ -3281,7 +3278,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, { struct fw_vi_enable_cmd c; - memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index 19ac096cb07b..1d03dcdd5e56 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1353,11 +1353,8 @@ static int gfar_restore(struct device *dev) struct gfar_private *priv = dev_get_drvdata(dev); struct net_device *ndev = priv->ndev; - if (!netif_running(ndev)) { - netif_device_attach(ndev); - + if (!netif_running(ndev)) return 0; - } gfar_init_bds(ndev); init_registers(ndev); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 116f0e901bee..56b20d17d0e4 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2673,9 +2673,6 @@ static int ixgbe_get_ts_info(struct net_device *dev, case ixgbe_mac_X540: case ixgbe_mac_82599EB: info->so_timestamping = - SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; diff --git a/trunk/drivers/net/ethernet/jme.c b/trunk/drivers/net/ethernet/jme.c index 92317e9c0f73..f8064df10cc4 100644 --- a/trunk/drivers/net/ethernet/jme.c +++ b/trunk/drivers/net/ethernet/jme.c @@ -1948,10 +1948,10 @@ jme_close(struct net_device *netdev) JME_NAPI_DISABLE(jme); - tasklet_kill(&jme->linkch_task); - tasklet_kill(&jme->txclean_task); - tasklet_kill(&jme->rxclean_task); - tasklet_kill(&jme->rxempty_task); + tasklet_disable(&jme->linkch_task); + tasklet_disable(&jme->txclean_task); + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); diff --git a/trunk/drivers/net/ethernet/marvell/skge.c b/trunk/drivers/net/ethernet/marvell/skge.c index d19a143aa5a8..9b9c2ac5c4c2 100644 --- a/trunk/drivers/net/ethernet/marvell/skge.c +++ b/trunk/drivers/net/ethernet/marvell/skge.c @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) dev0 = hw->dev[0]; unregister_netdev(dev0); - tasklet_kill(&hw->phy_task); + tasklet_disable(&hw->phy_task); spin_lock_irq(&hw->hw_lock); hw->intr_mask = 0; diff --git a/trunk/drivers/net/ethernet/micrel/ksz884x.c b/trunk/drivers/net/ethernet/micrel/ksz884x.c index e558edd1cb6c..318fee91c79d 100644 --- a/trunk/drivers/net/ethernet/micrel/ksz884x.c +++ b/trunk/drivers/net/ethernet/micrel/ksz884x.c @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) /* Delay for receive task to stop scheduling itself. */ msleep(2000 / HZ); - tasklet_kill(&hw_priv->rx_tasklet); - tasklet_kill(&hw_priv->tx_tasklet); + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); free_irq(dev->irq, hw_priv->dev); transmit_cleanup(hw_priv, 0); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index af8b4142088c..53743f7a2ca9 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -1524,7 +1524,6 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) pldat->dma_buff_base_p); free_irq(ndev->irq, ndev); iounmap(pldat->net_base); - mdiobus_unregister(pldat->mii_bus); mdiobus_free(pldat->mii_bus); clk_disable(pldat->clk); clk_put(pldat->clk); diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 927aa33d4349..e7ff886e8047 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3827,8 +3827,6 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_25: - case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_32: @@ -4521,9 +4519,6 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = swab32(data); } - if (tp->mac_version == RTL_GIGA_MAC_VER_35) - mc_filter[1] = mc_filter[0] = 0xffffffff; - RTL_W32(MAR0 + 4, mc_filter[1]); RTL_W32(MAR0 + 0, mc_filter[0]); diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1d04754a6637..0793299bd39e 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -990,7 +990,7 @@ static int axienet_stop(struct net_device *ndev) axienet_setoptions(ndev, lp->options & ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); - tasklet_kill(&lp->dma_err_tasklet); + tasklet_disable(&lp->dma_err_tasklet); free_irq(lp->tx_irq, ndev); free_irq(lp->rx_irq, ndev); diff --git a/trunk/drivers/net/phy/mdio-bitbang.c b/trunk/drivers/net/phy/mdio-bitbang.c index 6428fcbbdd4b..daec9b05d168 100644 --- a/trunk/drivers/net/phy/mdio-bitbang.c +++ b/trunk/drivers/net/phy/mdio-bitbang.c @@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus) struct mdiobb_ctrl *ctrl = bus->priv; module_put(ctrl->ops->owner); - mdiobus_unregister(bus); mdiobus_free(bus); } EXPORT_SYMBOL(free_mdio_bitbang); diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index 08d55b6bf272..c81e278629ff 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -31,7 +31,6 @@ #include #include #include -#include /* @@ -93,7 +92,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) /* no jumbogram (16K) support for now */ - dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; + dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 3286166415b4..7479a5761d0d 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1344,7 +1344,6 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, } else { u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); skb_push(skb, 4); - cpu_to_le32s(&csum_preamble); memcpy(skb->data, &csum_preamble, 4); } } diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index edb81ed06950..cb04f900cc46 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -359,12 +359,10 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, void usbnet_defer_kevent (struct usbnet *dev, int work) { set_bit (work, &dev->flags); - if (!schedule_work (&dev->kevent)) { - if (net_ratelimit()) - netdev_err(dev->net, "kevent %d may have been dropped\n", work); - } else { + if (!schedule_work (&dev->kevent)) + netdev_err(dev->net, "kevent %d may have been dropped\n", work); + else netdev_dbg(dev->net, "kevent %d scheduled\n", work); - } } EXPORT_SYMBOL_GPL(usbnet_defer_kevent); diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index 0ae1bcc6da73..ce9d4f2c9776 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -744,43 +744,28 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - u32 buf_size; - - buf_offset = 0; - len = skb_frag_size(frag); - while (len) { - tbi = tq->buf_info + tq->tx_ring.next2fill; - if (len < VMXNET3_MAX_TX_BUF_SIZE) { - buf_size = len; - dw2 |= len; - } else { - buf_size = VMXNET3_MAX_TX_BUF_SIZE; - /* spec says that for TxDesc.len, 0 == 2^14 */ - } - tbi->map_type = VMXNET3_MAP_PAGE; - tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, - buf_offset, buf_size, - DMA_TO_DEVICE); - tbi->len = buf_size; + tbi = tq->buf_info + tq->tx_ring.next2fill; + tbi->map_type = VMXNET3_MAP_PAGE; + tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, + 0, skb_frag_size(frag), + DMA_TO_DEVICE); - gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; - BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); + tbi->len = skb_frag_size(frag); - gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); - gdesc->dword[2] = cpu_to_le32(dw2); - gdesc->dword[3] = 0; + gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; + BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); - dev_dbg(&adapter->netdev->dev, - "txd[%u]: 0x%llu %u %u\n", - tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), - le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); - vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); - dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; + gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); + gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); + gdesc->dword[3] = 0; - len -= buf_size; - buf_offset += buf_size; - } + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%llu %u %u\n", + tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), + le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); + vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); + dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; } ctx->eop_txd = gdesc; @@ -901,18 +886,6 @@ vmxnet3_prepare_tso(struct sk_buff *skb, } } -static int txd_estimate(const struct sk_buff *skb) -{ - int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1; - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - - count += VMXNET3_TXD_NEEDED(skb_frag_size(frag)); - } - return count; -} /* * Transmits a pkt thru a given tq @@ -941,7 +914,9 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, union Vmxnet3_GenericDesc tempTxDesc; #endif - count = txd_estimate(skb); + /* conservatively estimate # of descriptors to use */ + count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + + skb_shinfo(skb)->nr_frags + 1; ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); diff --git a/trunk/drivers/net/vxlan.c b/trunk/drivers/net/vxlan.c index 7b4adde93c01..607976c00162 100644 --- a/trunk/drivers/net/vxlan.c +++ b/trunk/drivers/net/vxlan.c @@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long arg) = container_of(p, struct vxlan_fdb, hlist); unsigned long timeout; - if (f->state & NUD_PERMANENT) + if (f->state == NUD_PERMANENT) continue; timeout = f->used + vxlan->age_interval * HZ; diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 741918a2027b..378bd70256b2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); - bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -394,7 +393,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; - bool rc_update = true, isba; + bool rc_update = true; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; @@ -438,17 +437,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; - isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted - * - * Only BlockAcks have a TID and therefore normal Acks cannot be - * checked */ - if (isba && tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1779,7 +1774,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; - bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); diff --git a/trunk/drivers/net/wireless/b43legacy/pio.c b/trunk/drivers/net/wireless/b43legacy/pio.c index 282eedec675e..192251adf986 100644 --- a/trunk/drivers/net/wireless/b43legacy/pio.c +++ b/trunk/drivers/net/wireless/b43legacy/pio.c @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) { struct b43legacy_pio_txpacket *packet, *tmp_packet; - tasklet_kill(&queue->txtask); + tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) free_txpacket(packet, 0); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 59474ae0aec0..01dc8891070c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index a543746fb354..6241fd05bd41 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -320,7 +320,10 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), } else next = dev->bus_list.next; + /* Run device routines with the device locked */ + device_lock(&dev->dev); retval = cb(dev, userdata); + device_unlock(&dev->dev); if (retval) break; } diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 6c94fc9489e7..94c6e2aa03d6 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -398,8 +398,6 @@ static void pci_device_shutdown(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; - pm_runtime_resume(dev); - if (drv && drv->shutdown) drv->shutdown(pci_dev); pci_msi_shutdown(pci_dev); @@ -410,6 +408,16 @@ static void pci_device_shutdown(struct device *dev) * continue to do DMA */ pci_disable_device(pci_dev); + + /* + * Devices may be enabled to wake up by runtime PM, but they need not + * be supposed to wake up the system from its "power off" state (e.g. + * ACPI S5). Therefore disable wakeup for all devices that aren't + * supposed to wake up the system at this point. The state argument + * will be ignored by pci_enable_wake(). + */ + if (!device_may_wakeup(dev)) + pci_enable_wake(pci_dev, PCI_UNKNOWN, false); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index f39378d9da15..02d107b15281 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) } struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static void +pci_config_pm_runtime_get(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + if (parent) + pm_runtime_get_sync(parent); + pm_runtime_get_noresume(dev); + /* + * pdev->current_state is set to PCI_D3cold during suspending, + * so wait until suspending completes + */ + pm_runtime_barrier(dev); + /* + * Only need to resume devices in D3cold, because config + * registers are still accessible for devices suspended but + * not in D3cold. + */ + if (pdev->current_state == PCI_D3cold) + pm_runtime_resume(dev); +} + +static void +pci_config_pm_runtime_put(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + pm_runtime_put(dev); + if (parent) + pm_runtime_put_sync(parent); +} + static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index aabf64798bda..54858838f098 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -1858,38 +1858,6 @@ bool pci_dev_run_wake(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_dev_run_wake); -void pci_config_pm_runtime_get(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - if (parent) - pm_runtime_get_sync(parent); - pm_runtime_get_noresume(dev); - /* - * pdev->current_state is set to PCI_D3cold during suspending, - * so wait until suspending completes - */ - pm_runtime_barrier(dev); - /* - * Only need to resume devices in D3cold, because config - * registers are still accessible for devices suspended but - * not in D3cold. - */ - if (pdev->current_state == PCI_D3cold) - pm_runtime_resume(dev); -} - -void pci_config_pm_runtime_put(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - pm_runtime_put(dev); - if (parent) - pm_runtime_put_sync(parent); -} - /** * pci_pm_init - Initialize PM functions of given PCI device * @dev: PCI device to handle. diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index fd92aab9904b..bacbcba69cf3 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -72,8 +72,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); extern int pci_finish_runtime_suspend(struct pci_dev *dev); extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); extern void pci_wakeup_bus(struct pci_bus *bus); -extern void pci_config_pm_runtime_get(struct pci_dev *dev); -extern void pci_config_pm_runtime_put(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index af4e31cd3a3b..06bad96af415 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -213,7 +213,6 @@ static int report_error_detected(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); dev->error_state = result_data->state; if (!dev->driver || @@ -232,14 +231,12 @@ static int report_error_detected(struct pci_dev *dev, void *data) dev->driver ? "no AER-aware driver" : "no driver"); } - goto out; + return 0; } err_handler = dev->driver->err_handler; vote = err_handler->error_detected(dev, result_data->state); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -250,17 +247,14 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->mmio_enabled) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->mmio_enabled(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -271,17 +265,14 @@ static int report_slot_reset(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->slot_reset) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->slot_reset(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -289,18 +280,15 @@ static int report_resume(struct pci_dev *dev, void *data) { const struct pci_error_handlers *err_handler; - device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->resume) - goto out; + return 0; err_handler = dev->driver->err_handler; err_handler->resume(dev); -out: - device_unlock(&dev->dev); return 0; } diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index ed129b414624..d03a7a39b2d8 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -272,8 +272,7 @@ static int get_port_device_capability(struct pci_dev *dev) } /* Hot-Plug Capable */ - if ((cap_mask & PCIE_PORT_SERVICE_HP) && - dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { + if (cap_mask & PCIE_PORT_SERVICE_HP) { pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) { services |= PCIE_PORT_SERVICE_HP; diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 9b8505ccc56d..eb907a8faf2a 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/drivers/pci/proc.c @@ -76,8 +76,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (!access_ok(VERIFY_WRITE, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); @@ -123,8 +121,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; return nbytes; } @@ -150,8 +146,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (!access_ok(VERIFY_READ, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; __get_user(val, buf); @@ -197,8 +191,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; i_size_write(ino, dp->size); return nbytes; diff --git a/trunk/drivers/pinctrl/Kconfig b/trunk/drivers/pinctrl/Kconfig index d96caefd914a..7bf914df6e91 100644 --- a/trunk/drivers/pinctrl/Kconfig +++ b/trunk/drivers/pinctrl/Kconfig @@ -179,13 +179,11 @@ config PINCTRL_COH901 config PINCTRL_SAMSUNG bool "Samsung pinctrl driver" - depends on OF && GPIOLIB select PINMUX select PINCONF config PINCTRL_EXYNOS4 bool "Pinctrl driver data for Exynos4 SoC" - depends on OF && GPIOLIB select PINCTRL_SAMSUNG config PINCTRL_MVEBU diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.c b/trunk/drivers/pinctrl/spear/pinctrl-spear.c index b1fd6ee33c6c..5d4f44f462f0 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.c @@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, else temp = ~muxreg->val; - val |= muxreg->mask & temp; + val |= temp; pmx_writel(pmx, val, muxreg->reg); } } diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c index 0436fc7895d6..d6cca8c81b92 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { }; /* registers */ -#define PERIP_CFG 0x3B0 - #define MCIF_SEL_SHIFT 5 +#define PERIP_CFG 0x32C + #define MCIF_SEL_SHIFT 3 #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) @@ -164,10 +164,6 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { #define PMX_SSP0_CS0_MASK (1 << 29) #define PMX_SSP0_CS1_2_MASK (1 << 30) -#define PAD_DIRECTION_SEL_0 0x65C -#define PAD_DIRECTION_SEL_1 0x660 -#define PAD_DIRECTION_SEL_2 0x664 - /* combined macros */ #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ @@ -241,10 +237,6 @@ static struct spear_muxreg i2c0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = PMX_I2C0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -277,10 +269,6 @@ static struct spear_muxreg ssp0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SSP0_MASK, .val = PMX_SSP0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SSP0_MASK, - .val = PMX_SSP0_MASK, }, }; @@ -306,10 +294,6 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS0_MASK, .val = PMX_SSP0_CS0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS0_MASK, - .val = PMX_SSP0_CS0_MASK, }, }; @@ -335,10 +319,6 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS1_2_MASK, .val = PMX_SSP0_CS1_2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS1_2_MASK, - .val = PMX_SSP0_CS1_2_MASK, }, }; @@ -372,10 +352,6 @@ static struct spear_muxreg i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = PMX_I2S0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -408,10 +384,6 @@ static struct spear_muxreg i2s1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK, .val = PMX_I2S1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK, - .val = PMX_I2S1_MASK, }, }; @@ -446,10 +418,6 @@ static struct spear_muxreg clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = PMX_CLCD1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -475,10 +443,6 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_CLCD2_MASK, .val = PMX_CLCD2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_CLCD2_MASK, - .val = PMX_CLCD2_MASK, }, }; @@ -497,7 +461,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), }; -static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; +static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -515,14 +479,6 @@ static struct spear_muxreg arm_gpio_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_EGPIO_1_GRP_MASK, .val = PMX_EGPIO_1_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_EGPIO_0_GRP_MASK, - .val = PMX_EGPIO_0_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_EGPIO_1_GRP_MASK, - .val = PMX_EGPIO_1_GRP_MASK, }, }; @@ -555,10 +511,6 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -587,14 +539,6 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, }, }; @@ -629,10 +573,6 @@ static struct spear_muxreg gmii_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_GMII_MASK, .val = PMX_GMII_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_GMII_MASK, - .val = PMX_GMII_MASK, }, }; @@ -675,18 +615,6 @@ static struct spear_muxreg rgmii_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_RGMII_REG2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_RGMII_REG0_MASK, - .val = PMX_RGMII_REG0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_RGMII_REG1_MASK, - .val = PMX_RGMII_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_RGMII_REG2_MASK, - .val = PMX_RGMII_REG2_MASK, }, }; @@ -721,10 +649,6 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMII_0_1_2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMII_0_1_2_MASK, - .val = PMX_SMII_0_1_2_MASK, }, }; @@ -757,10 +681,6 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFCE2_MASK, - .val = PMX_NFCE2_MASK, }, }; @@ -801,14 +721,6 @@ static struct spear_muxreg nand_8bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND8BIT_1_MASK, .val = PMX_NAND8BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NAND8BIT_0_MASK, - .val = PMX_NAND8BIT_0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND8BIT_1_MASK, - .val = PMX_NAND8BIT_1_MASK, }, }; @@ -835,10 +747,6 @@ static struct spear_muxreg nand_16bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND16BIT_1_MASK, .val = PMX_NAND16BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND16BIT_1_MASK, - .val = PMX_NAND16BIT_1_MASK, }, }; @@ -864,10 +772,6 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND_4CHIPS_MASK, .val = PMX_NAND_4CHIPS_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND_4CHIPS_MASK, - .val = PMX_NAND_4CHIPS_MASK, }, }; @@ -929,10 +833,6 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL68_MASK, .val = PMX_KBD_ROWCOL68_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL68_MASK, - .val = PMX_KBD_ROWCOL68_MASK, }, }; @@ -966,10 +866,6 @@ static struct spear_muxreg uart0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_UART0_MASK, .val = PMX_UART0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_UART0_MASK, - .val = PMX_UART0_MASK, }, }; @@ -995,10 +891,6 @@ static struct spear_muxreg uart0_modem_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_UART0_MODEM_MASK, .val = PMX_UART0_MODEM_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_UART0_MODEM_MASK, - .val = PMX_UART0_MODEM_MASK, }, }; @@ -1031,10 +923,6 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR0_MASK, .val = PMX_GPT0_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR0_MASK, - .val = PMX_GPT0_TMR0_MASK, }, }; @@ -1060,10 +948,6 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR1_MASK, .val = PMX_GPT0_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR1_MASK, - .val = PMX_GPT0_TMR1_MASK, }, }; @@ -1096,10 +980,6 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR0_MASK, .val = PMX_GPT1_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR0_MASK, - .val = PMX_GPT1_TMR0_MASK, }, }; @@ -1125,10 +1005,6 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR1_MASK, .val = PMX_GPT1_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR1_MASK, - .val = PMX_GPT1_TMR1_MASK, }, }; @@ -1173,20 +1049,6 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, .reg = PAD_FUNCTION_EN_2, \ .mask = PMX_MCIFALL_2_MASK, \ .val = PMX_MCIFALL_2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_0, \ - .mask = PMX_MCI_DATA8_15_MASK, \ - .val = PMX_MCI_DATA8_15_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_1, \ - .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_2, \ - .mask = PMX_MCIFALL_2_MASK, \ - .val = PMX_MCIFALL_2_MASK, \ } /* sdhci device */ @@ -1292,10 +1154,6 @@ static struct spear_muxreg touch_xy_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_TOUCH_XY_MASK, .val = PMX_TOUCH_XY_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_TOUCH_XY_MASK, - .val = PMX_TOUCH_XY_MASK, }, }; @@ -1329,10 +1187,6 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -1359,12 +1213,6 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { .mask = PMX_MCIDATA1_MASK | PMX_MCIDATA2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, - .val = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, }, }; @@ -1398,10 +1246,6 @@ static struct spear_muxreg uart2_3_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -1434,10 +1278,6 @@ static struct spear_muxreg uart4_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, - .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, }, }; @@ -1470,10 +1310,6 @@ static struct spear_muxreg uart5_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1508,10 +1344,6 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1544,10 +1376,6 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1581,10 +1409,6 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, - .val = PMX_CLCD1_MASK | PMX_SMI_MASK, }, }; @@ -1611,10 +1435,6 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, - .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, }, }; @@ -1649,10 +1469,6 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -1683,14 +1499,6 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCIDATA5_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA4_MASK, - .val = PMX_MCIDATA4_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA5_MASK, - .val = PMX_MCIDATA5_MASK, }, }; @@ -1718,12 +1526,6 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { .mask = PMX_MCIDATA6_MASK | PMX_MCIDATA7_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, - .val = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, }, }; @@ -1758,10 +1560,6 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1789,12 +1587,6 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { .mask = PMX_MCIIORDRE_MASK | PMX_MCIIOWRWE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, - .val = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, }, }; @@ -1821,12 +1613,6 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { .mask = PMX_MCIRESETCF_MASK | PMX_MCICS0CE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, - .val = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, }, }; @@ -1865,14 +1651,6 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFRSTPWDWN3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NFRSTPWDWN2_MASK, - .val = PMX_NFRSTPWDWN2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFRSTPWDWN3_MASK, - .val = PMX_NFRSTPWDWN3_MASK, }, }; @@ -1899,10 +1677,6 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, - .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, }, }; @@ -1937,10 +1711,6 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, - .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, }, }; @@ -1967,10 +1737,6 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1997,64 +1763,29 @@ static struct spear_function can1_function = { .ngroups = ARRAY_SIZE(can1_grps), }; -/* Pad multiplexing for (ras-ip) pci device */ -static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, +/* Pad multiplexing for pci device */ +static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; +#define PCI_SATA_MUXREG \ + { \ + .reg = PAD_FUNCTION_EN_0, \ + .mask = PMX_MCI_DATA8_15_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_1, \ + .mask = PMX_PCI_REG1_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_2, \ + .mask = PMX_PCI_REG2_MASK, \ + .val = 0, \ + } -static struct spear_muxreg pci_muxreg[] = { - { - .reg = PAD_FUNCTION_EN_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_1, - .mask = PMX_PCI_REG1_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_2, - .mask = PMX_PCI_REG2_MASK, - .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = PMX_MCI_DATA8_15_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_PCI_REG1_MASK, - .val = PMX_PCI_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_PCI_REG2_MASK, - .val = PMX_PCI_REG2_MASK, - }, -}; - -static struct spear_modemux pci_modemux[] = { - { - .muxregs = pci_muxreg, - .nmuxregs = ARRAY_SIZE(pci_muxreg), - }, -}; - -static struct spear_pingroup pci_pingroup = { - .name = "pci_grp", - .pins = pci_pins, - .npins = ARRAY_SIZE(pci_pins), - .modemuxs = pci_modemux, - .nmodemuxs = ARRAY_SIZE(pci_modemux), -}; - -static const char *const pci_grps[] = { "pci_grp" }; -static struct spear_function pci_function = { - .name = "pci", - .groups = pci_grps, - .ngroups = ARRAY_SIZE(pci_grps), -}; - -/* pad multiplexing for (fix-part) pcie0 device */ +/* pad multiplexing for pcie0 device */ static struct spear_muxreg pcie0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(0), @@ -2071,12 +1802,15 @@ static struct spear_modemux pcie0_modemux[] = { static struct spear_pingroup pcie0_pingroup = { .name = "pcie0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie0_modemux, .nmodemuxs = ARRAY_SIZE(pcie0_modemux), }; -/* pad multiplexing for (fix-part) pcie1 device */ +/* pad multiplexing for pcie1 device */ static struct spear_muxreg pcie1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(1), @@ -2093,12 +1827,15 @@ static struct spear_modemux pcie1_modemux[] = { static struct spear_pingroup pcie1_pingroup = { .name = "pcie1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie1_modemux, .nmodemuxs = ARRAY_SIZE(pcie1_modemux), }; -/* pad multiplexing for (fix-part) pcie2 device */ +/* pad multiplexing for pcie2 device */ static struct spear_muxreg pcie2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(2), @@ -2115,20 +1852,22 @@ static struct spear_modemux pcie2_modemux[] = { static struct spear_pingroup pcie2_pingroup = { .name = "pcie2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie2_modemux, .nmodemuxs = ARRAY_SIZE(pcie2_modemux), }; -static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" -}; -static struct spear_function pcie_function = { - .name = "pci_express", - .groups = pcie_grps, - .ngroups = ARRAY_SIZE(pcie_grps), +static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; +static struct spear_function pci_function = { + .name = "pci", + .groups = pci_grps, + .ngroups = ARRAY_SIZE(pci_grps), }; /* pad multiplexing for sata0 device */ static struct spear_muxreg sata0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(0), @@ -2145,12 +1884,15 @@ static struct spear_modemux sata0_modemux[] = { static struct spear_pingroup sata0_pingroup = { .name = "sata0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata0_modemux, .nmodemuxs = ARRAY_SIZE(sata0_modemux), }; /* pad multiplexing for sata1 device */ static struct spear_muxreg sata1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(1), @@ -2167,12 +1909,15 @@ static struct spear_modemux sata1_modemux[] = { static struct spear_pingroup sata1_pingroup = { .name = "sata1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata1_modemux, .nmodemuxs = ARRAY_SIZE(sata1_modemux), }; /* pad multiplexing for sata2 device */ static struct spear_muxreg sata2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(2), @@ -2189,6 +1934,8 @@ static struct spear_modemux sata2_modemux[] = { static struct spear_pingroup sata2_pingroup = { .name = "sata2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata2_modemux, .nmodemuxs = ARRAY_SIZE(sata2_modemux), }; @@ -2210,14 +1957,6 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, - .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, }, }; @@ -2244,12 +1983,6 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, - .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, }, }; @@ -2284,12 +2017,6 @@ static struct spear_muxreg gpt64_muxreg[] = { .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | PMX_MCILEDS_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, - .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, }, }; @@ -2366,7 +2093,6 @@ static struct spear_pingroup *spear1310_pingroups[] = { &can0_dis_sd_pingroup, &can1_dis_sd_pingroup, &can1_dis_kbd_pingroup, - &pci_pingroup, &pcie0_pingroup, &pcie1_pingroup, &pcie2_pingroup, @@ -2412,7 +2138,6 @@ static struct spear_function *spear1310_functions[] = { &can0_function, &can1_function, &pci_function, - &pcie_function, &sata_function, &ssp1_function, &gpt64_function, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c index 0606b8cf3f2c..a0eb057e55bd 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { * Pad multiplexing for making all pads as gpio's. This is done to override the * values passed from bootloader and start from scratch. */ -static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; +static const unsigned pads_as_gpio_pins[] = { 251 }; static struct spear_muxreg pads_as_gpio_muxreg[] = { { .reg = PAD_FUNCTION_EN_1, @@ -1692,43 +1692,7 @@ static struct spear_pingroup clcd_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_modemux), }; -/* Disable cld runtime to save panel damage */ -static struct spear_muxreg clcd_sleep_muxreg[] = { - { - .reg = PAD_SHARED_IP_EN_1, - .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_5, - .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_6, - .mask = CLCD_AND_ARM_TRACE_REG5_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_7, - .mask = CLCD_AND_ARM_TRACE_REG6_MASK, - .val = 0x0, - }, -}; - -static struct spear_modemux clcd_sleep_modemux[] = { - { - .muxregs = clcd_sleep_muxreg, - .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), - }, -}; - -static struct spear_pingroup clcd_sleep_pingroup = { - .name = "clcd_sleep_grp", - .pins = clcd_pins, - .npins = ARRAY_SIZE(clcd_pins), - .modemuxs = clcd_sleep_modemux, - .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), -}; - -static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; +static const char *const clcd_grps[] = { "clcd_grp" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -1929,7 +1893,6 @@ static struct spear_pingroup *spear1340_pingroups[] = { &sdhci_pingroup, &cf_pingroup, &xd_pingroup, - &clcd_sleep_pingroup, &clcd_pingroup, &arm_trace_pingroup, &miphy_dbg_pingroup, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c index ca47b0e50780..020b1e0bdb3e 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2239,10 +2239,6 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { .reg = PMX_CONFIG_REG, .mask = PMX_SSP_CS_MASK, .val = 0, - }, { - .reg = MODE_CONFIG_REG, - .mask = PMX_PWM_MASK, - .val = PMX_PWM_MASK, }, { .reg = IP_SEL_PAD_30_39_REG, .mask = PMX_PL_34_MASK, @@ -2960,9 +2956,9 @@ static struct spear_function mii2_function = { }; /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ -static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, +static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; -static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; +static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; static struct spear_muxreg mii0_1_muxreg[] = { { .reg = PMX_CONFIG_REG, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h index 7860b36053c4..31f44347f17c 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -15,7 +15,6 @@ #include "pinctrl-spear.h" /* pad mux declarations */ -#define PMX_PWM_MASK (1 << 16) #define PMX_FIRDA_MASK (1 << 14) #define PMX_I2C_MASK (1 << 13) #define PMX_SSP_CS_MASK (1 << 12) diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index 4af3dfe70ef5..33bb4d891e16 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -112,6 +112,9 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); +#define __MAX_SUBCHANNEL 65535 +#define __MAX_SSID 3 + struct channel_subsystem { u8 cssid; int valid; diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index fd3143c291c6..fc916f5d7314 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) } if (device_is_disconnected(cdev)) return IO_SCH_REPROBE; - if (cdev->online && !cdev->private->flags.resuming) + if (cdev->online) return IO_SCH_VERIFY; if (cdev->private->state == DEV_STATE_NOT_OPER) return IO_SCH_UNREG_ATTACH; @@ -1469,6 +1469,12 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) rc = 0; goto out_unlock; case IO_SCH_VERIFY: + if (cdev->private->flags.resuming == 1) { + if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { + ccw_device_set_notoper(cdev); + break; + } + } /* Trigger path verification. */ io_subchannel_verify(sch); rc = 0; diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index 65d13e38803f..199bc6791177 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -125,7 +125,8 @@ int idset_is_empty(struct idset *set) void idset_add_set(struct idset *to, struct idset *from) { - int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); + int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), + __BITOPS_WORDS(from->num_ssid * from->num_id)); bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); } diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 20fd974f903a..bd4708a422cd 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -149,7 +149,6 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) int qla24xx_disable_vp(scsi_qla_host_t *vha) { - unsigned long flags; int ret; ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); @@ -157,9 +156,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); /* Remove port id from vp target map */ - spin_lock_irqsave(&vha->hw->vport_slock, flags); qlt_update_vp_map(vha, RESET_AL_PA); - spin_unlock_irqrestore(&vha->hw->vport_slock, flags); qla2x00_mark_vp_devices_dead(vha); atomic_set(&vha->vp_state, VP_FAILED); diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.c b/trunk/drivers/scsi/qla2xxx/qla_target.c index 62aa5584f644..0e09d8f433d1 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.c +++ b/trunk/drivers/scsi/qla2xxx/qla_target.c @@ -557,7 +557,6 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, int pmap_len; fc_port_t *fcport; int global_resets; - unsigned long flags; retry: global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); @@ -626,10 +625,10 @@ static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); - spin_lock_irqsave(&ha->hardware_lock, flags); - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); - spin_unlock_irqrestore(&ha->hardware_lock, flags); + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); res = true; @@ -741,9 +740,10 @@ static struct qla_tgt_sess *qlt_create_sess( qlt_undelete_sess(sess); kref_get(&sess->se_sess->sess_kref); - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); - + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); if (sess->local && !local) sess->local = 0; spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -796,7 +796,8 @@ static struct qla_tgt_sess *qlt_create_sess( */ kref_get(&sess->se_sess->sess_kref); - sess->conf_compl_supported = (fcport->flags & FCF_CONF_COMP_SUPPORTED); + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); @@ -868,8 +869,10 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, "Reappeared sess %p\n", sess); } - ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, - (fcport->flags & FCF_CONF_COMP_SUPPORTED)); + sess->s_id = fcport->d_id; + sess->loop_id = fcport->loop_id; + sess->conf_compl_supported = !!(fcport->flags & + FCF_CONF_COMP_SUPPORTED); } if (sess && sess->local) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.h b/trunk/drivers/scsi/qla2xxx/qla_target.h index bad749561ec2..170af1571214 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_target.h +++ b/trunk/drivers/scsi/qla2xxx/qla_target.h @@ -648,7 +648,6 @@ struct qla_tgt_func_tmpl { int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, void *, uint8_t *, uint16_t); - void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool); struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, const uint16_t); struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3d74f2f39ae1..2358c16c4c8e 100644 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -237,7 +237,7 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) struct tcm_qla2xxx_tpg, se_tpg); struct tcm_qla2xxx_lport *lport = tpg->lport; - return lport->lport_naa_name; + return &lport->lport_name[0]; } static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) @@ -1457,78 +1457,6 @@ static int tcm_qla2xxx_check_initiator_node_acl( return 0; } -static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, - uint16_t loop_id, bool conf_compl_supported) -{ - struct qla_tgt *tgt = sess->tgt; - struct qla_hw_data *ha = tgt->ha; - struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; - struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; - struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, - struct tcm_qla2xxx_nacl, se_node_acl); - u32 key; - - - if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24) - pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n", - sess, - sess->port_name[0], sess->port_name[1], - sess->port_name[2], sess->port_name[3], - sess->port_name[4], sess->port_name[5], - sess->port_name[6], sess->port_name[7], - sess->loop_id, loop_id, - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa, - s_id.b.domain, s_id.b.area, s_id.b.al_pa); - - if (sess->loop_id != loop_id) { - /* - * Because we can shuffle loop IDs around and we - * update different sessions non-atomically, we might - * have overwritten this session's old loop ID - * already, and we might end up overwriting some other - * session that will be updated later. So we have to - * be extra careful and we can't warn about those things... - */ - if (lport->lport_loopid_map[sess->loop_id].se_nacl == se_nacl) - lport->lport_loopid_map[sess->loop_id].se_nacl = NULL; - - lport->lport_loopid_map[loop_id].se_nacl = se_nacl; - - sess->loop_id = loop_id; - } - - if (sess->s_id.b24 != s_id.b24) { - key = (((u32) sess->s_id.b.domain << 16) | - ((u32) sess->s_id.b.area << 8) | - ((u32) sess->s_id.b.al_pa)); - - if (btree_lookup32(&lport->lport_fcport_map, key)) - WARN(btree_remove32(&lport->lport_fcport_map, key) != se_nacl, - "Found wrong se_nacl when updating s_id %x:%x:%x\n", - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); - else - WARN(1, "No lport_fcport_map entry for s_id %x:%x:%x\n", - sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa); - - key = (((u32) s_id.b.domain << 16) | - ((u32) s_id.b.area << 8) | - ((u32) s_id.b.al_pa)); - - if (btree_lookup32(&lport->lport_fcport_map, key)) { - WARN(1, "Already have lport_fcport_map entry for s_id %x:%x:%x\n", - s_id.b.domain, s_id.b.area, s_id.b.al_pa); - btree_update32(&lport->lport_fcport_map, key, se_nacl); - } else { - btree_insert32(&lport->lport_fcport_map, key, se_nacl, GFP_ATOMIC); - } - - sess->s_id = s_id; - nacl->nport_id = key; - } - - sess->conf_compl_supported = conf_compl_supported; -} - /* * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. */ @@ -1539,7 +1467,6 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { .free_cmd = tcm_qla2xxx_free_cmd, .free_mcmd = tcm_qla2xxx_free_mcmd, .free_session = tcm_qla2xxx_free_session, - .update_sess = tcm_qla2xxx_update_sess, .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, @@ -1607,7 +1534,6 @@ static struct se_wwn *tcm_qla2xxx_make_lport( lport->lport_wwpn = wwpn; tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, wwpn); - sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) wwpn); ret = tcm_qla2xxx_init_lport(lport); if (ret != 0) @@ -1675,7 +1601,6 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( lport->lport_npiv_wwnn = npiv_wwnn; tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); - sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); /* FIXME: tcm_qla2xxx_npiv_make_lport */ ret = -ENOSYS; diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 9ba075fe9781..825498103352 100644 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h @@ -61,8 +61,6 @@ struct tcm_qla2xxx_lport { u64 lport_npiv_wwnn; /* ASCII formatted WWPN for FC Target Lport */ char lport_name[TCM_QLA2XXX_NAMELEN]; - /* ASCII formatted naa WWPN for VPD page 83 etc */ - char lport_naa_name[TCM_QLA2XXX_NAMELEN]; /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; /* map for fc_port pointers in 24-bit FC Port ID space */ diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 71fddbc60f18..b191dd549207 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1294,19 +1294,26 @@ static struct scsi_host_template qpti_template = { static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; + struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; const char *fcode; + match = of_match_device(qpti_match, &op->dev); + if (!match) + return -EINVAL; + tpnt = match->data; + /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ if (op->archdata.irqs[0] == 0) return -ENODEV; - host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); + host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); if (!host) return -ENOMEM; @@ -1438,15 +1445,19 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) static const struct of_device_id qpti_match[] = { { .name = "ptisp", + .data = &qpti_template, }, { .name = "PTI,ptisp", + .data = &qpti_template, }, { .name = "QLGC,isp", + .data = &qpti_template, }, { .name = "SUNW,isp", + .data = &qpti_template, }, {}, }; diff --git a/trunk/drivers/staging/comedi/comedidev.h b/trunk/drivers/staging/comedi/comedidev.h index 5af3579337eb..4ac2de43cdbb 100644 --- a/trunk/drivers/staging/comedi/comedidev.h +++ b/trunk/drivers/staging/comedi/comedidev.h @@ -247,7 +247,7 @@ struct comedi_device { void (*close) (struct comedi_device *dev); }; -static inline const void *comedi_board(const struct comedi_device *dev) +static inline const void *comedi_board(struct comedi_device *dev) { return dev->board_ptr; } diff --git a/trunk/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/trunk/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c new file mode 100644 index 000000000000..30a44aea0c2f --- /dev/null +++ b/trunk/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -0,0 +1,313 @@ +/** +@verbatim + +Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + + ADDI-DATA GmbH + Dieselstrasse 3 + D-77833 Ottersweier + Tel: +19(0)7223/9493-0 + Fax: +49(0)7223/9493-92 + http://www.addi-data.com + info@addi-data.com + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +You should also find the complete GPL in the COPYING file accompanying this source code. + +@endverbatim +*/ +/* + + +-----------------------------------------------------------------------+ + | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | + +-----------------------------------------------------------------------+ + | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | + | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | + +-------------------------------+---------------------------------------+ + | Project : APCI-1032 | Compiler : GCC | + | Module name : hwdrv_apci1032.c| Version : 2.96 | + +-------------------------------+---------------------------------------+ + | Project manager: Eric Stolz | Date : 02/12/2002 | + +-------------------------------+---------------------------------------+ + | Description : Hardware Layer Access For APCI-1032 | + +-----------------------------------------------------------------------+ + | UPDATES | + +----------+-----------+------------------------------------------------+ + | Date | Author | Description of updates | + +----------+-----------+------------------------------------------------+ + | | | | + | | | | + | | | | + +----------+-----------+------------------------------------------------+ +*/ + +/********* Definitions for APCI-1032 card *****/ + +#define APCI1032_ADDRESS_RANGE 20 +/* DIGITAL INPUT DEFINE */ + +#define APCI1032_DIGITAL_IP 0 +#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4 +#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8 +#define APCI1032_DIGITAL_IP_IRQ 16 + +/* Digital Input IRQ Function Selection */ +#define ADDIDATA_OR 0 +#define ADDIDATA_AND 1 + +/* Digital Input Interrupt Status */ +#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12 + +/* Digital Input Interrupt Enable Disable. */ +#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 +#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb + +static unsigned int ui_InterruptStatus; + +/* ++----------------------------------------------------------------------------+ +| Function Name : int i_APCI1032_ConfigDigitalInput | +| (struct comedi_device *dev,struct comedi_subdevice *s, | +| struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Configures the digital input Subdevice | ++----------------------------------------------------------------------------+ +| Input Parameters : struct comedi_device *dev : Driver handle | +| unsigned int *data : Data Pointer contains | +| configuration parameters as below | +| | +| data[0] : 1 Enable Digital Input Interrupt | +| 0 Disable Digital Input Interrupt | +| data[1] : 0 ADDIDATA Interrupt OR LOGIC | +| : 1 ADDIDATA Interrupt AND LOGIC | +| data[2] : Interrupt mask for the mode 1 | +| data[3] : Interrupt mask for the mode 2 | +| | ++----------------------------------------------------------------------------+ +| Output Parameters : -- | ++----------------------------------------------------------------------------+ +| Return Value : TRUE : No error occur | +| : FALSE : Error occur. Return the error | +| | ++----------------------------------------------------------------------------+ +*/ + +static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_TmpValue; + unsigned int ul_Command1 = 0; + unsigned int ul_Command2 = 0; + + devpriv->tsk_Current = current; + + /*******************************/ + /* Set the digital input logic */ + /*******************************/ + if (data[0] == ADDIDATA_ENABLE) { + ul_Command1 = ul_Command1 | data[2]; + ul_Command2 = ul_Command2 | data[3]; + outl(ul_Command1, + devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); + outl(ul_Command2, + devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + if (data[1] == ADDIDATA_OR) { + outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + ui_TmpValue = + inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + } /* if (data[1] == ADDIDATA_OR) */ + else + outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + /* else if(data[1] == ADDIDATA_OR) */ + } /* if( data[0] == ADDIDATA_ENABLE) */ + else { + ul_Command1 = ul_Command1 & 0xFFFF0000; + ul_Command2 = ul_Command2 & 0xFFFF0000; + outl(ul_Command1, + devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); + outl(ul_Command2, + devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + } /* else if ( data[0] == ADDIDATA_ENABLE) */ + + return insn->n; +} + +/* ++----------------------------------------------------------------------------+ +| Function Name : int i_APCI1032_Read1DigitalInput | +| (struct comedi_device *dev,struct comedi_subdevice *s, | +| struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Return the status of the digital input | ++----------------------------------------------------------------------------+ +| Input Parameters : struct comedi_device *dev : Driver handle | +| unsigned int ui_Channel : Channel number to read | +| unsigned int *data : Data Pointer to read status | ++----------------------------------------------------------------------------+ +| Output Parameters : -- | ++----------------------------------------------------------------------------+ +| Return Value : TRUE : No error occur | +| : FALSE : Error occur. Return the error | +| | ++----------------------------------------------------------------------------+ +*/ +static int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_TmpValue = 0; + unsigned int ui_Channel; + ui_Channel = CR_CHAN(insn->chanspec); + + if (ui_Channel <= 31) { + ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); +/* +* since only 1 channel reqd to bring it to last bit it is rotated 8 +* +(chan - 1) times then ANDed with 1 for last bit. +*/ + *data = (ui_TmpValue >> ui_Channel) & 0x1; + } /* if(ui_Channel >= 0 && ui_Channel <=31) */ + else { + /* comedi_error(dev," \n chan spec wrong\n"); */ + return -EINVAL; /* "sorry channel spec wrong " */ + } /* else if(ui_Channel >= 0 && ui_Channel <=31) */ + return insn->n; +} + +/* ++----------------------------------------------------------------------------+ +| Function Name : int i_APCI1032_ReadMoreDigitalInput | +| (struct comedi_device *dev,struct comedi_subdevice *s, | +| struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Return the status of the Requested digital inputs | ++----------------------------------------------------------------------------+ +| Input Parameters : struct comedi_device *dev : Driver handle | +| unsigned int ui_NoOfChannels : No Of Channels To be Read | +| unsigned int *data : Data Pointer to read status | ++----------------------------------------------------------------------------+ +| Output Parameters : -- | ++----------------------------------------------------------------------------+ +| Return Value : TRUE : No error occur | +| : FALSE : Error occur. Return the error | +| | ++----------------------------------------------------------------------------+ +*/ + +static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_PortValue = data[0]; + unsigned int ui_Mask = 0; + unsigned int ui_NoOfChannels; + + ui_NoOfChannels = CR_CHAN(insn->chanspec); + if (data[1] == 0) { + *data = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); + switch (ui_NoOfChannels) { + case 2: + ui_Mask = 3; + *data = (*data >> (2 * ui_PortValue)) & ui_Mask; + break; + case 4: + ui_Mask = 15; + *data = (*data >> (4 * ui_PortValue)) & ui_Mask; + break; + case 8: + ui_Mask = 255; + *data = (*data >> (8 * ui_PortValue)) & ui_Mask; + break; + case 16: + ui_Mask = 65535; + *data = (*data >> (16 * ui_PortValue)) & ui_Mask; + break; + case 31: + break; + default: + /* comedi_error(dev," \nchan spec wrong\n"); */ + return -EINVAL; /* "sorry channel spec wrong " */ + break; + } /* switch(ui_NoOfChannels) */ + } /* if(data[1]==0) */ + else { + if (data[1] == 1) + *data = ui_InterruptStatus; + /* if(data[1]==1) */ + } /* else if(data[1]==0) */ + return insn->n; +} + +/* ++----------------------------------------------------------------------------+ +| Function Name : static void v_APCI1032_Interrupt | +| (int irq , void *d) | ++----------------------------------------------------------------------------+ +| Task : Interrupt handler for the interruptible digital inputs | ++----------------------------------------------------------------------------+ +| Input Parameters : int irq : irq number | +| void *d : void pointer | ++----------------------------------------------------------------------------+ +| Output Parameters : -- | ++----------------------------------------------------------------------------+ +| Return Value : TRUE : No error occur | +| : FALSE : Error occur. Return the error | +| | ++----------------------------------------------------------------------------+ +*/ +static void v_APCI1032_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; + unsigned int ui_Temp; + + /* disable the interrupt */ + ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE, + devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + ui_InterruptStatus = + inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); + ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; + send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ + outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */ + return; +} + +/* ++----------------------------------------------------------------------------+ +| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | | ++----------------------------------------------------------------------------+ +| Task :resets all the registers | ++----------------------------------------------------------------------------+ +| Input Parameters : struct comedi_device *dev ++----------------------------------------------------------------------------+ +| Output Parameters : -- | ++----------------------------------------------------------------------------+ +| Return Value : | +| | ++----------------------------------------------------------------------------+ +*/ + +static int i_APCI1032_Reset(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + + outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */ + inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ + outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ + outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + return 0; +} diff --git a/trunk/drivers/staging/comedi/drivers/addi_apci_1032.c b/trunk/drivers/staging/comedi/drivers/addi_apci_1032.c index 2f23a1730641..1db3e15ed4ba 100644 --- a/trunk/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/trunk/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,332 +1,39 @@ -/* - * addi_apci_1032.c - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * Project manager: Eric Stolz - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - * You should also find the complete GPL in the COPYING file accompanying this - * source code. - */ - #include "../comedidev.h" #include "comedi_fc.h" - -/* - * I/O Register Map - */ -#define APCI1032_DI_REG 0x00 -#define APCI1032_MODE1_REG 0x04 -#define APCI1032_MODE2_REG 0x08 -#define APCI1032_STATUS_REG 0x0c -#define APCI1032_CTRL_REG 0x10 -#define APCI1032_CTRL_INT_OR (0 << 1) -#define APCI1032_CTRL_INT_AND (1 << 1) -#define APCI1032_CTRL_INT_ENA (1 << 2) - -struct apci1032_private { - unsigned int mode1; /* rising-edge/high level channels */ - unsigned int mode2; /* falling-edge/low level channels */ - unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ +#include "amcc_s5933.h" + +#include "addi-data/addi_common.h" + +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1032.c" +#include "addi-data/addi_common.c" + +static const struct addi_board apci1032_boardtypes[] = { + { + .pc_DriverName = "apci1032", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1003, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .interrupt = v_APCI1032_Interrupt, + .reset = i_APCI1032_Reset, + .di_config = i_APCI1032_ConfigDigitalInput, + .di_read = i_APCI1032_Read1DigitalInput, + .di_bits = i_APCI1032_ReadMoreDigitalInput, + }, }; -static int apci1032_reset(struct comedi_device *dev) -{ - /* disable the interrupts */ - outl(0x0, dev->iobase + APCI1032_CTRL_REG); - /* Reset the interrupt status register */ - inl(dev->iobase + APCI1032_STATUS_REG); - /* Disable the and/or interrupt */ - outl(0x0, dev->iobase + APCI1032_MODE1_REG); - outl(0x0, dev->iobase + APCI1032_MODE2_REG); - - return 0; -} - -/* - * Change-Of-State (COS) interrupt configuration - * - * Channels 0 to 15 are interruptible. These channels can be configured - * to generate interrupts based on AND/OR logic for the desired channels. - * - * OR logic - * - reacts to rising or falling edges - * - interrupt is generated when any enabled channel - * meet the desired interrupt condition - * - * AND logic - * - reacts to changes in level of the selected inputs - * - interrupt is generated when all enabled channels - * meet the desired interrupt condition - * - after an interrupt, a change in level must occur on - * the selected inputs to release the IRQ logic - * - * The COS interrupt must be configured before it can be enabled. - * - * data[0] : INSN_CONFIG_DIGITAL_TRIG - * data[1] : 0 = OR (edge) interrupts - * 1 = AND (level) interrupts - * data[2] : rising-edge/high level channels - * data[3] : falling-edge/low level channels - */ -static int apci1032_cos_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1032_private *devpriv = dev->private; - - switch (data[0]) { - case INSN_CONFIG_DIGITAL_TRIG: - devpriv->mode1 = data[2]; - devpriv->mode2 = data[3]; - - if (devpriv->mode1 || devpriv->mode2) { - devpriv->ctrl = APCI1032_CTRL_INT_ENA; - if (data[1] == 1) - devpriv->ctrl = APCI1032_CTRL_INT_AND; - else - devpriv->ctrl = APCI1032_CTRL_INT_OR; - } else { - devpriv->ctrl = 0; - apci1032_reset(dev); - } - break; - default: - return -EINVAL; - } - - return insn->n; -} - -static int apci1032_cos_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = s->state; - - return 0; -} - -static int apci1032_cos_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - /* Step 2b : and mutually compatible */ - - if (err) - return 2; - - /* step 3: */ - - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - - if (err) - return 3; - - /* step 4: ignored */ - - if (err) - return 4; - - return 0; -} - -/* - * Change-Of-State (COS) 'do_cmd' operation - * - * Enable the COS interrupt as configured by apci1032_cos_insn_config(). - */ -static int apci1032_cos_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct apci1032_private *devpriv = dev->private; - - if (!devpriv->ctrl) { - dev_warn(dev->class_dev, - "Interrupts disabled due to mode configuration!\n"); - return -EINVAL; - } - - outl(devpriv->mode1, dev->iobase + APCI1032_MODE1_REG); - outl(devpriv->mode2, dev->iobase + APCI1032_MODE2_REG); - outl(devpriv->ctrl, dev->iobase + APCI1032_CTRL_REG); - - return 0; -} - -static int apci1032_cos_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - return apci1032_reset(dev); -} - -static irqreturn_t apci1032_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct comedi_subdevice *s = dev->read_subdev; - unsigned int ctrl; - - /* disable the interrupt */ - ctrl = inl(dev->iobase + APCI1032_CTRL_REG); - outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); - - s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; - comedi_buf_put(s->async, s->state); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); - - /* enable the interrupt */ - outl(ctrl, dev->iobase + APCI1032_CTRL_REG); - - return IRQ_HANDLED; -} - -static int apci1032_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inl(dev->iobase + APCI1032_DI_REG); - - return insn->n; -} - -static int apci1032_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - struct apci1032_private *devpriv; - struct comedi_subdevice *s; - int ret; - - dev->board_name = dev->driver->driver_name; - - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - ret = comedi_pci_enable(pcidev, dev->board_name); - if (ret) - return ret; - - dev->iobase = pci_resource_start(pcidev, 2); - - if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret == 0) - dev->irq = pcidev->irq; - } - - ret = comedi_alloc_subdevices(dev, 2); - if (ret) - return ret; - - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 32; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = apci1032_di_insn_bits; - - /* Change-Of-State (COS) interrupt subdevice */ - s = &dev->subdevices[1]; - if (dev->irq) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_DI | SDF_CMD_READ; - s->subdev_flags = SDF_READABLE; - s->n_chan = 1; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = apci1032_cos_insn_config; - s->insn_bits = apci1032_cos_insn_bits; - s->do_cmdtest = apci1032_cos_cmdtest; - s->do_cmd = apci1032_cos_cmd; - s->cancel = apci1032_cos_cancel; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - apci1032_reset(dev); - return 0; -} - -static void apci1032_detach(struct comedi_device *dev) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - - if (dev->iobase) - apci1032_reset(dev); - if (dev->irq) - free_irq(dev->irq, dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static struct comedi_driver apci1032_driver = { .driver_name = "addi_apci_1032", .module = THIS_MODULE, - .attach_pci = apci1032_attach_pci, - .detach = apci1032_detach, + .attach_pci = addi_attach_pci, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1032_boardtypes), + .board_name = &apci1032_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), }; static int __devinit apci1032_pci_probe(struct pci_dev *dev, diff --git a/trunk/drivers/staging/comedi/drivers/cb_pcidas64.c b/trunk/drivers/staging/comedi/drivers/cb_pcidas64.c index 68a128903224..0ae7ef5856c6 100644 --- a/trunk/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/trunk/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -36,57 +36,53 @@ ************************************************************************/ /* - * Driver: cb_pcidas64 - * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series - * with the PLX 9080 PCI controller - * Author: Frank Mori Hess - * Status: works - * Updated: Fri, 02 Nov 2012 18:58:55 +0000 - * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64), - * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16, - * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR, - * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14, - * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014, - * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030, - * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034, - * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052, - * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12 - * - * Configuration options: - * None. - * - * Manual attachment of PCI cards with the comedi_config utility is not - * supported by this driver; they are attached automatically. - * - * These boards may be autocalibrated with the comedi_calibrate utility. - * - * To select the bnc trigger input on the 4020 (instead of the dio input), - * specify a nonzero channel in the chanspec. If you wish to use an external - * master clock on the 4020, you may do so by setting the scan_begin_src - * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn - * to configure the divisor to use for the external clock. - * - * Some devices are not identified because the PCI device IDs are not yet - * known. If you have such a board, please let the maintainers know. - */ + +Driver: cb_pcidas64 +Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller +Author: Frank Mori Hess +Status: works +Updated: 2002-10-09 +Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64), + PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16, + PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR, + PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14, + PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014, + PCI-DAS6023, PCI-DAS6025, PCI-DAS6030, + PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034, + PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052, + PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12 + +Configuration options: + [0] - PCI bus of device (optional) + [1] - PCI slot of device (optional) + +These boards may be autocalibrated with the comedi_calibrate utility. + +To select the bnc trigger input on the 4020 (instead of the dio input), +specify a nonzero channel in the chanspec. If you wish to use an external +master clock on the 4020, you may do so by setting the scan_begin_src +to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn +to configure the divisor to use for the external clock. + +Some devices are not identified because the PCI device IDs are not yet +known. If you have such a board, please file a bug report at +https://bugs.comedi.org. + +*/ /* TODO: make it return error if user attempts an ai command that uses the - external queue, and an ao command simultaneously user counter subdevice + external queue, and an ao command simultaneously + user counter subdevice there are a number of boards this driver will support when they are - fully released, but does not yet since the pci device id numbers - are not yet available. - - support prescaled 100khz clock for slow pacing (not available on 6000 - series?) - + fully released, but does not yet since the pci device id numbers + are not yet available. + support prescaled 100khz clock for slow pacing (not available on 6000 series?) make ao fifo size adjustable like ai fifo */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../comedidev.h" #include #include @@ -100,15 +96,13 @@ /* #define PCIDAS64_DEBUG enable debugging code */ #ifdef PCIDAS64_DEBUG -#define DEBUG_PRINT(format, args...) pr_debug(format, ## args) +#define DEBUG_PRINT(format, args...) printk(format , ## args) #else -#define DEBUG_PRINT(format, args...) no_printk(format, ## args) +#define DEBUG_PRINT(format, args...) #endif #define TIMER_BASE 25 /* 40MHz master clock */ -/* 100kHz 'prescaled' clock for slow acquisition, - * maybe I'll support this someday */ -#define PRESCALED_TIMER_BASE 10000 +#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */ #define DMA_BUFFER_SIZE 0x1000 /* maximum value that can be loaded into board's 24-bit counters*/ @@ -132,36 +126,26 @@ enum write_only_registers { ADC_CONTROL0_REG = 0x10, /* adc control register 0 */ ADC_CONTROL1_REG = 0x12, /* adc control register 1 */ CALIBRATION_REG = 0x14, - /* lower 16 bits of adc sample interval counter */ - ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, - /* upper 8 bits of adc sample interval counter */ - ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, - /* lower 16 bits of delay interval counter */ - ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, - /* upper 8 bits of delay interval counter */ - ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, - /* lower 16 bits of hardware conversion/scan counter */ - ADC_COUNT_LOWER_REG = 0x1e, - /* upper 8 bits of hardware conversion/scan counter */ - ADC_COUNT_UPPER_REG = 0x20, + ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, /* lower 16 bits of adc sample interval counter */ + ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, /* upper 8 bits of adc sample interval counter */ + ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, /* lower 16 bits of delay interval counter */ + ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, /* upper 8 bits of delay interval counter */ + ADC_COUNT_LOWER_REG = 0x1e, /* lower 16 bits of hardware conversion/scan counter */ + ADC_COUNT_UPPER_REG = 0x20, /* upper 8 bits of hardware conversion/scan counter */ ADC_START_REG = 0x22, /* software trigger to start acquisition */ ADC_CONVERT_REG = 0x24, /* initiates single conversion */ ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */ ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */ ADC_BUFFER_CLEAR_REG = 0x2a, - /* high channel for internal queue, use adc_chan_bits() inline above */ - ADC_QUEUE_HIGH_REG = 0x2c, + ADC_QUEUE_HIGH_REG = 0x2c, /* high channel for internal queue, use adc_chan_bits() inline above */ DAC_CONTROL0_REG = 0x50, /* dac control register 0 */ DAC_CONTROL1_REG = 0x52, /* dac control register 0 */ - /* lower 16 bits of dac sample interval counter */ - DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, - /* upper 8 bits of dac sample interval counter */ - DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, + DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, /* lower 16 bits of dac sample interval counter */ + DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, /* upper 8 bits of dac sample interval counter */ DAC_SELECT_REG = 0x60, DAC_START_REG = 0x64, DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */ }; - static inline unsigned int dac_convert_reg(unsigned int channel) { return 0x70 + (2 * (channel & 0x1)); @@ -178,9 +162,7 @@ static inline unsigned int dac_msb_4020_reg(unsigned int channel) } enum read_only_registers { - /* hardware status register, - * reading this apparently clears pending interrupts as well */ - HW_STATUS_REG = 0x0, + HW_STATUS_REG = 0x0, /* hardware status register, reading this apparently clears pending interrupts as well */ PIPE1_READ_REG = 0x4, ADC_READ_PNTR_REG = 0x8, LOWER_XFER_REG = 0x10, @@ -190,11 +172,9 @@ enum read_only_registers { enum read_write_registers { I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */ - /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */ - ADC_QUEUE_FIFO_REG = 0x100, + ADC_QUEUE_FIFO_REG = 0x100, /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */ ADC_FIFO_REG = 0x200, /* adc data fifo */ - /* dac data fifo, has weird interactions with external channel queue */ - DAC_FIFO_REG = 0x300, + DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */ }; /* devpriv->dio_counter_iobase registers */ @@ -209,13 +189,13 @@ enum dio_counter_registers { /* bit definitions for write-only registers */ enum intr_enable_contents { - ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */ - ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */ + ADC_INTR_SRC_MASK = 0x3, /* bits that set adc interrupt source */ + ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quater full */ ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */ ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */ - ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */ + ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence (probably wont use this it's pretty fancy) */ EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */ - EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */ + EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done interrupt */ DAC_INTR_SRC_MASK = 0x30, DAC_INTR_QEMPTY_BITS = 0x0, DAC_INTR_HIGH_CHAN_BITS = 0x10, @@ -229,33 +209,25 @@ enum intr_enable_contents { }; enum hw_config_contents { - MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */ - INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */ + MASTER_CLOCK_4020_MASK = 0x3, /* bits that specify master clock source for 4020 */ + INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock for 4020 */ BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */ EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */ - EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */ - /* use 225 nanosec strobe when loading dac instead of 50 nanosec */ - SLOW_DAC_BIT = 0x400, - /* bit with unknown function yet given as default value in pci-das64 - * manual */ - HW_CONFIG_DUMMY_BITS = 0x2000, - /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */ - DMA_CH_SELECT_BIT = 0x8000, - FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */ + EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue (more versatile than internal queue) */ + SLOW_DAC_BIT = 0x400, /* use 225 nanosec strobe when loading dac instead of 50 nanosec */ + HW_CONFIG_DUMMY_BITS = 0x2000, /* bit with unknown function yet given as default value in pci-das64 manual */ + DMA_CH_SELECT_BIT = 0x8000, /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */ + FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */ DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */ - DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */ + DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */ }; #define DAC_FIFO_SIZE 0x2000 enum daq_atrig_low_4020_contents { - /* use trig/ext clk bnc input for analog gate signal */ - EXT_AGATE_BNC_BIT = 0x8000, - /* use trig/ext clk bnc input for external stop trigger signal */ - EXT_STOP_TRIG_BNC_BIT = 0x4000, - /* use trig/ext clk bnc input for external start trigger signal */ - EXT_START_TRIG_BNC_BIT = 0x2000, + EXT_AGATE_BNC_BIT = 0x8000, /* use trig/ext clk bnc input for analog gate signal */ + EXT_STOP_TRIG_BNC_BIT = 0x4000, /* use trig/ext clk bnc input for external stop trigger signal */ + EXT_START_TRIG_BNC_BIT = 0x2000, /* use trig/ext clk bnc input for external start trigger signal */ }; - static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold) { return threshold & 0xfff; @@ -273,17 +245,14 @@ enum adc_control0_contents { ADC_START_TRIG_ANALOG_BITS = 0x30, ADC_START_TRIG_MASK = 0x30, ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */ - /* external pacing uses falling edge */ - ADC_EXT_CONV_FALLING_BIT = 0x800, - /* enable hardware scan counter */ - ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, + ADC_EXT_CONV_FALLING_BIT = 0x800, /* external pacing uses falling edge */ + ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, /* enable hardware scan counter */ ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */ ADC_ENABLE_BIT = 0x8000, /* master adc enable */ }; enum adc_control1_contents { - /* should be set for boards with > 16 channels */ - ADC_QUEUE_CONFIG_BIT = 0x1, + ADC_QUEUE_CONFIG_BIT = 0x1, /* should be set for boards with > 16 channels */ CONVERT_POLARITY_BIT = 0x10, EOC_POLARITY_BIT = 0x20, ADC_SW_GATE_BIT = 0x40, /* software gate of adc */ @@ -292,11 +261,10 @@ enum adc_control1_contents { ADC_LO_CHANNEL_4020_MASK = 0x300, ADC_HI_CHANNEL_4020_MASK = 0xc00, TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */ - FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */ + FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */ CHANNEL_MODE_4020_MASK = 0x3000, ADC_MODE_MASK = 0xf000, }; - static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 8; @@ -319,10 +287,9 @@ enum calibration_contents { CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */ SERIAL_DATA_IN_BIT = 0x80, SERIAL_CLOCK_BIT = 0x100, - CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */ + CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */ CAL_GAIN_BIT = 0x800, }; - /* calibration sources for 6025 are: * 0 : ground * 1 : 10V @@ -333,7 +300,6 @@ enum calibration_contents { * 6 : dac channel 0 * 7 : dac channel 1 */ - static inline uint16_t adc_src_bits(unsigned int source) { return (source & 0xf) << 3; @@ -347,12 +313,10 @@ static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel) enum adc_queue_load_contents { UNIP_BIT = 0x800, /* unipolar/bipolar bit */ ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */ - /* non-referenced single-ended (common-mode input) */ - ADC_COMMON_BIT = 0x2000, + ADC_COMMON_BIT = 0x2000, /* non-referenced single-ended (common-mode input) */ QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */ QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */ }; - static inline uint16_t adc_chan_bits(unsigned int channel) { return channel & 0x3f; @@ -399,7 +363,6 @@ enum hw_status_contents { EXT_INTR_PENDING_BIT = 0x100, ADC_STOP_BIT = 0x200, }; - static inline uint16_t pipe_full_bits(uint16_t hw_status_bits) { return (hw_status_bits >> 10) & 0x3; @@ -428,12 +391,9 @@ enum i2c_addresses { }; enum range_cal_i2c_contents { - /* bits that set what source the adc converter measures */ - ADC_SRC_4020_MASK = 0x70, - /* make bnc trig/ext clock threshold 0V instead of 2.5V */ - BNC_TRIG_THRESHOLD_0V_BIT = 0x80, + ADC_SRC_4020_MASK = 0x70, /* bits that set what source the adc converter measures */ + BNC_TRIG_THRESHOLD_0V_BIT = 0x80, /* make bnc trig/ext clock threshold 0V instead of 2.5V */ }; - static inline uint8_t adc_src_4020_bits(unsigned int source) { return (source << 4) & ADC_SRC_4020_MASK; @@ -600,12 +560,11 @@ struct pcidas64_board { const struct comedi_lrange *ai_range_table; int ao_nchan; /* number of analog out channels */ int ao_bits; /* analog output resolution */ - int ao_scan_speed; /* analog output scan speed */ + int ao_scan_speed; /* analog output speed (for a scan, not conversion) */ const struct comedi_lrange *ao_range_table; const int *ao_range_code; const struct hw_fifo_info *const ai_fifo; - /* different board families have slightly different registers */ - enum register_layout layout; + enum register_layout layout; /* different board families have slightly different registers */ unsigned has_8255:1; }; @@ -635,7 +594,7 @@ static const struct hw_fifo_info ai_fifo_60xx = { #define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE) #define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) #define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) -static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board) +static inline unsigned int ai_dma_ring_count(struct pcidas64_board *board) { if (board->layout == LAYOUT_4020) return MAX_AI_DMA_RING_COUNT; @@ -1064,23 +1023,24 @@ static const struct pcidas64_board pcidas64_boards[] = { #endif }; +static inline struct pcidas64_board *board(const struct comedi_device *dev) +{ + return (struct pcidas64_board *)dev->board_ptr; +} + static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev, int use_differential) { - const struct pcidas64_board *thisboard = comedi_board(dev); - - if ((thisboard->layout == LAYOUT_64XX && !use_differential) || - (thisboard->layout == LAYOUT_60XX && use_differential)) + if ((board(dev)->layout == LAYOUT_64XX && !use_differential) || + (board(dev)->layout == LAYOUT_60XX && use_differential)) return ADC_SE_DIFF_BIT; else return 0; }; struct ext_clock_info { - /* master clock divisor to use for scans with external master clock */ - unsigned int divisor; - /* chanspec for master clock input when used as scan begin src */ - unsigned int chanspec; + unsigned int divisor; /* master clock divisor to use for scans with external master clock */ + unsigned int chanspec; /* chanspec for master clock input when used as scan begin src */ }; /* this structure is for data unique to this hardware driver. */ @@ -1096,52 +1056,30 @@ struct pcidas64_private { /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; - /* number of analog input samples remaining */ - volatile unsigned int ai_count; - /* dma buffers for analog input */ - uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; - /* physical addresses of ai dma buffers */ - dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; - /* array of ai dma descriptors read by plx9080, - * allocated to get proper alignment */ - struct plx_dma_desc *ai_dma_desc; - /* physical address of ai dma descriptor array */ - dma_addr_t ai_dma_desc_bus_addr; - /* index of the ai dma descriptor/buffer - * that is currently being used */ - volatile unsigned int ai_dma_index; - /* dma buffers for analog output */ - uint16_t *ao_buffer[AO_DMA_RING_COUNT]; - /* physical addresses of ao dma buffers */ - dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; + volatile unsigned int ai_count; /* number of analog input samples remaining */ + uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* dma buffers for analog input */ + dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ + struct plx_dma_desc *ai_dma_desc; /* array of ai dma descriptors read by plx9080, allocated to get proper alignment */ + dma_addr_t ai_dma_desc_bus_addr; /* physical address of ai dma descriptor array */ + volatile unsigned int ai_dma_index; /* index of the ai dma descriptor/buffer that is currently being used */ + uint16_t *ao_buffer[AO_DMA_RING_COUNT]; /* dma buffers for analog output */ + dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; /* physical addresses of ao dma buffers */ struct plx_dma_desc *ao_dma_desc; dma_addr_t ao_dma_desc_bus_addr; - /* keeps track of buffer where the next ao sample should go */ - volatile unsigned int ao_dma_index; - /* number of analog output samples remaining */ - volatile unsigned long ao_count; - /* remember what the analog outputs are set to, to allow readback */ - volatile unsigned int ao_value[2]; + volatile unsigned int ao_dma_index; /* keeps track of buffer where the next ao sample should go */ + volatile unsigned long ao_count; /* number of analog output samples remaining */ + volatile unsigned int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ unsigned int hw_revision; /* stc chip hardware revision number */ - /* last bits sent to INTR_ENABLE_REG register */ - volatile unsigned int intr_enable_bits; - /* last bits sent to ADC_CONTROL1_REG register */ - volatile uint16_t adc_control1_bits; - /* last bits sent to FIFO_SIZE_REG register */ - volatile uint16_t fifo_size_bits; - /* last bits sent to HW_CONFIG_REG register */ - volatile uint16_t hw_config_bits; + volatile unsigned int intr_enable_bits; /* last bits sent to INTR_ENABLE_REG register */ + volatile uint16_t adc_control1_bits; /* last bits sent to ADC_CONTROL1_REG register */ + volatile uint16_t fifo_size_bits; /* last bits sent to FIFO_SIZE_REG register */ + volatile uint16_t hw_config_bits; /* last bits sent to HW_CONFIG_REG register */ volatile uint16_t dac_control1_bits; - /* last bits written to plx9080 control register */ - volatile uint32_t plx_control_bits; - /* last bits written to plx interrupt control and status register */ - volatile uint32_t plx_intcsr_bits; - /* index of calibration source readable through ai ch0 */ - volatile int calibration_source; - /* bits written to i2c calibration/range register */ - volatile uint8_t i2c_cal_range_bits; - /* configure digital triggers to trigger on falling edge */ - volatile unsigned int ext_trig_falling; + volatile uint32_t plx_control_bits; /* last bits written to plx9080 control register */ + volatile uint32_t plx_intcsr_bits; /* last bits written to plx interrupt control and status register */ + volatile int calibration_source; /* index of calibration source readable through ai ch0 */ + volatile uint8_t i2c_cal_range_bits; /* bits written to i2c calibration/range register */ + volatile unsigned int ext_trig_falling; /* configure digital triggers to trigger on falling edge */ /* states of various devices stored to enable read-back */ unsigned int ad8402_state[2]; unsigned int caldac_state[8]; @@ -1151,12 +1089,85 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; +static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int ao_readback_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); +static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_cmd *cmd); +static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s); +static int ao_inttrig(struct comedi_device *dev, + struct comedi_subdevice *subdev, unsigned int trig_num); +static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_cmd *cmd); +static irqreturn_t handle_interrupt(int irq, void *d); +static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); +static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); +static int dio_callback(int dir, int port, int data, unsigned long arg); +static int dio_callback_4020(int dir, int port, int data, unsigned long arg); +static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int dio_60xx_config_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int calib_read_insn(struct comedi_device *dev, + struct comedi_subdevice *s, struct comedi_insn *insn, + unsigned int *data); +static int calib_write_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int ad8402_read_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static void ad8402_write(struct comedi_device *dev, unsigned int channel, + unsigned int value); +static int ad8402_write_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static int eeprom_read_insn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); +static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); +static unsigned int get_divisor(unsigned int ns, unsigned int flags); +static void i2c_write(struct comedi_device *dev, unsigned int address, + const uint8_t *data, unsigned int length); +static void caldac_write(struct comedi_device *dev, unsigned int channel, + unsigned int value); +static int caldac_8800_write(struct comedi_device *dev, unsigned int address, + uint8_t value); +/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b); */ +static int caldac_i2c_write(struct comedi_device *dev, + unsigned int caldac_channel, unsigned int value); +static void abort_dma(struct comedi_device *dev, unsigned int channel); +static void disable_plx_interrupts(struct comedi_device *dev); +static int set_ai_fifo_size(struct comedi_device *dev, + unsigned int num_samples); +static unsigned int ai_fifo_size(struct comedi_device *dev); +static int set_ai_fifo_segment_length(struct comedi_device *dev, + unsigned int num_entries); +static void disable_ai_pacing(struct comedi_device *dev); +static void disable_ai_interrupts(struct comedi_device *dev); +static void enable_ai_interrupts(struct comedi_device *dev, + const struct comedi_cmd *cmd); +static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags); +static void load_ao_dma(struct comedi_device *dev, + const struct comedi_cmd *cmd); + static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { - const struct pcidas64_board *thisboard = comedi_board(dev); const struct comedi_krange *range = - &thisboard->ai_range_table->range[range_index]; + &board(dev)->ai_range_table->range[range_index]; unsigned int bits = 0; switch (range->max) { @@ -1199,9 +1210,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, static unsigned int hw_revision(const struct comedi_device *dev, uint16_t hw_status_bits) { - const struct pcidas64_board *thisboard = comedi_board(dev); - - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) return (hw_status_bits >> 13) & 0x7; return (hw_status_bits >> 12) & 0xf; @@ -1211,8 +1220,7 @@ static void set_dac_range_bits(struct comedi_device *dev, volatile uint16_t *bits, unsigned int channel, unsigned int range) { - const struct pcidas64_board *thisboard = comedi_board(dev); - unsigned int code = thisboard->ao_range_code[range]; + unsigned int code = board(dev)->ao_range_code[range]; if (channel > 1) comedi_error(dev, "bug! bad channel?"); @@ -1228,80 +1236,15 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board) return board->ao_nchan && board->layout != LAYOUT_4020; } -static void abort_dma(struct comedi_device *dev, unsigned int channel) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - /* spinlock for plx dma control/status reg */ - spin_lock_irqsave(&dev->spinlock, flags); - - plx9080_abort_dma(devpriv->plx9080_iobase, channel); - - spin_unlock_irqrestore(&dev->spinlock, flags); -} - -static void disable_plx_interrupts(struct comedi_device *dev) -{ - struct pcidas64_private *devpriv = dev->private; - - devpriv->plx_intcsr_bits = 0; - writel(devpriv->plx_intcsr_bits, - devpriv->plx9080_iobase + PLX_INTRCS_REG); -} - -static void disable_ai_interrupts(struct comedi_device *dev) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->intr_enable_bits &= - ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & - ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & - ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; - writew(devpriv->intr_enable_bits, - devpriv->main_iobase + INTR_ENABLE_REG); - spin_unlock_irqrestore(&dev->spinlock, flags); - - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); -} - -static void enable_ai_interrupts(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - uint32_t bits; - unsigned long flags; - - bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | - EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; - /* Use pio transfer and interrupt on end of conversion - * if TRIG_WAKE_EOS flag is set. */ - if (cmd->flags & TRIG_WAKE_EOS) { - /* 4020 doesn't support pio transfers except for fifo dregs */ - if (thisboard->layout != LAYOUT_4020) - bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; - } - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->intr_enable_bits |= bits; - writew(devpriv->intr_enable_bits, - devpriv->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); - spin_unlock_irqrestore(&dev->spinlock, flags); -} - /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint32_t bits; void __iomem *plx_iobase = devpriv->plx9080_iobase; devpriv->plx_control_bits = - readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", @@ -1355,11 +1298,9 @@ static void init_plx9080(struct comedi_device *dev) bits |= PLX_EN_BTERM_BIT; /* enable dma chaining */ bits |= PLX_EN_CHAIN_BIT; - /* enable interrupt on dma done - * (probably don't need this, since chain never finishes) */ + /* enable interrupt on dma done (probably don't need this, since chain never finishes) */ bits |= PLX_EN_DMA_DONE_INTR_BIT; - /* don't increment local address during transfers - * (we are transferring from a fixed fifo register) */ + /* don't increment local address during transfers (we are transferring from a fixed fifo register) */ bits |= PLX_LOCAL_ADDR_CONST_BIT; /* route dma interrupt to pci bus */ bits |= PLX_DMA_INTR_PCI_BIT; @@ -1368,12 +1309,13 @@ static void init_plx9080(struct comedi_device *dev) /* enable local burst mode */ bits |= PLX_DMA_LOCAL_BURST_EN_BIT; /* 4020 uses 32 bit dma */ - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) { bits |= PLX_LOCAL_BUS_32_WIDE_BITS; - else /* localspace0 bus is 16 bits wide */ + } else { /* localspace0 bus is 16 bits wide */ bits |= PLX_LOCAL_BUS_16_WIDE_BITS; + } writel(bits, plx_iobase + PLX_DMA1_MODE_REG); - if (ao_cmd_is_supported(thisboard)) + if (ao_cmd_is_supported(board(dev))) writel(bits, plx_iobase + PLX_DMA0_MODE_REG); /* enable interrupts on plx 9080 */ @@ -1384,101 +1326,190 @@ static void init_plx9080(struct comedi_device *dev) devpriv->plx9080_iobase + PLX_INTRCS_REG); } -static void disable_ai_pacing(struct comedi_device *dev) +/* Allocate and initialize the subdevice structures. + */ +static int setup_subdevices(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - disable_ai_interrupts(dev); + struct comedi_subdevice *s; + void __iomem *dio_8255_iobase; + int i; + int ret; - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT; - writew(devpriv->adc_control1_bits, - devpriv->main_iobase + ADC_CONTROL1_REG); - spin_unlock_irqrestore(&dev->spinlock, flags); + ret = comedi_alloc_subdevices(dev, 10); + if (ret) + return ret; - /* disable pacing, triggering, etc */ - writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, - devpriv->main_iobase + ADC_CONTROL0_REG); -} + s = &dev->subdevices[0]; + /* analog input subdevice */ + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; + if (board(dev)->layout == LAYOUT_60XX) + s->subdev_flags |= SDF_COMMON | SDF_DIFF; + else if (board(dev)->layout == LAYOUT_64XX) + s->subdev_flags |= SDF_DIFF; + /* XXX Number of inputs in differential mode is ignored */ + s->n_chan = board(dev)->ai_se_chans; + s->len_chanlist = 0x2000; + s->maxdata = (1 << board(dev)->ai_bits) - 1; + s->range_table = board(dev)->ai_range_table; + s->insn_read = ai_rinsn; + s->insn_config = ai_config_insn; + s->do_cmd = ai_cmd; + s->do_cmdtest = ai_cmdtest; + s->cancel = ai_cancel; + if (board(dev)->layout == LAYOUT_4020) { + uint8_t data; + /* set adc to read from inputs (not internal calibration sources) */ + devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); + /* set channels to +-5 volt input ranges */ + for (i = 0; i < s->n_chan; i++) + devpriv->i2c_cal_range_bits |= attenuate_bit(i); + data = devpriv->i2c_cal_range_bits; + i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); + } -static int set_ai_fifo_segment_length(struct comedi_device *dev, - unsigned int num_entries) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - static const int increment_size = 0x100; - const struct hw_fifo_info *const fifo = thisboard->ai_fifo; - unsigned int num_increments; - uint16_t bits; + /* analog output subdevice */ + s = &dev->subdevices[1]; + if (board(dev)->ao_nchan) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; + s->n_chan = board(dev)->ao_nchan; + s->maxdata = (1 << board(dev)->ao_bits) - 1; + s->range_table = board(dev)->ao_range_table; + s->insn_read = ao_readback_insn; + s->insn_write = ao_winsn; + if (ao_cmd_is_supported(board(dev))) { + dev->write_subdev = s; + s->do_cmdtest = ao_cmdtest; + s->do_cmd = ao_cmd; + s->len_chanlist = board(dev)->ao_nchan; + s->cancel = ao_cancel; + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } - if (num_entries < increment_size) - num_entries = increment_size; - if (num_entries > fifo->max_segment_length) - num_entries = fifo->max_segment_length; + /* digital input */ + s = &dev->subdevices[2]; + if (board(dev)->layout == LAYOUT_64XX) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = di_rbits; + } else + s->type = COMEDI_SUBD_UNUSED; - /* 1 == 256 entries, 2 == 512 entries, etc */ - num_increments = (num_entries + increment_size / 2) / increment_size; + /* digital output */ + if (board(dev)->layout == LAYOUT_64XX) { + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = do_wbits; + } else + s->type = COMEDI_SUBD_UNUSED; - bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; - devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask; - devpriv->fifo_size_bits |= bits; - writew(devpriv->fifo_size_bits, - devpriv->main_iobase + FIFO_SIZE_REG); + /* 8255 */ + s = &dev->subdevices[4]; + if (board(dev)->has_8255) { + if (board(dev)->layout == LAYOUT_4020) { + dio_8255_iobase = + devpriv->main_iobase + I8255_4020_REG; + subdev_8255_init(dev, s, dio_callback_4020, + (unsigned long)dio_8255_iobase); + } else { + dio_8255_iobase = + devpriv->dio_counter_iobase + DIO_8255_OFFSET; + subdev_8255_init(dev, s, dio_callback, + (unsigned long)dio_8255_iobase); + } + } else + s->type = COMEDI_SUBD_UNUSED; - devpriv->ai_fifo_segment_length = num_increments * increment_size; + /* 8 channel dio for 60xx */ + s = &dev->subdevices[5]; + if (board(dev)->layout == LAYOUT_60XX) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = dio_60xx_config_insn; + s->insn_bits = dio_60xx_wbits; + } else + s->type = COMEDI_SUBD_UNUSED; - DEBUG_PRINT("set hardware fifo segment length to %i\n", - devpriv->ai_fifo_segment_length); + /* caldac */ + s = &dev->subdevices[6]; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 8; + if (board(dev)->layout == LAYOUT_4020) + s->maxdata = 0xfff; + else + s->maxdata = 0xff; + s->insn_read = calib_read_insn; + s->insn_write = calib_write_insn; + for (i = 0; i < s->n_chan; i++) + caldac_write(dev, i, s->maxdata / 2); - return devpriv->ai_fifo_segment_length; -} + /* 2 channel ad8402 potentiometer */ + s = &dev->subdevices[7]; + if (board(dev)->layout == LAYOUT_64XX) { + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 2; + s->insn_read = ad8402_read_insn; + s->insn_write = ad8402_write_insn; + s->maxdata = 0xff; + for (i = 0; i < s->n_chan; i++) + ad8402_write(dev, i, s->maxdata / 2); + } else + s->type = COMEDI_SUBD_UNUSED; -/* adjusts the size of hardware fifo (which determines block size for dma xfers) */ -static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - unsigned int num_fifo_entries; - int retval; - const struct hw_fifo_info *const fifo = thisboard->ai_fifo; - - num_fifo_entries = num_samples / fifo->sample_packing_ratio; - - retval = set_ai_fifo_segment_length(dev, - num_fifo_entries / - fifo->num_segments); - if (retval < 0) - return retval; - - num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; + /* serial EEPROM, if present */ + s = &dev->subdevices[8]; + if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 128; + s->maxdata = 0xffff; + s->insn_read = eeprom_read_insn; + } else + s->type = COMEDI_SUBD_UNUSED; - DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); + /* user counter subd XXX */ + s = &dev->subdevices[9]; + s->type = COMEDI_SUBD_UNUSED; - return num_samples; + return 0; } -/* query length of fifo */ -static unsigned int ai_fifo_size(struct comedi_device *dev) +static void disable_plx_interrupts(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; - return devpriv->ai_fifo_segment_length * - thisboard->ai_fifo->num_segments * - thisboard->ai_fifo->sample_packing_ratio; + devpriv->plx_intcsr_bits = 0; + writel(devpriv->plx_intcsr_bits, + devpriv->plx9080_iobase + PLX_INTRCS_REG); } static void init_stc_registers(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint16_t bits; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); - /* bit should be set for 6025, - * although docs say boards with <= 16 chans should be cleared XXX */ + /* bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX */ if (1) devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; writew(devpriv->adc_control1_bits, @@ -1488,7 +1519,7 @@ static void init_stc_registers(struct comedi_device *dev) writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT; - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) bits |= INTERNAL_CLOCK_4020_BITS; devpriv->hw_config_bits |= bits; writew(devpriv->hw_config_bits, @@ -1502,12 +1533,11 @@ static void init_stc_registers(struct comedi_device *dev) /* set fifos to maximum size */ devpriv->fifo_size_bits |= DAC_FIFO_BITS; set_ai_fifo_segment_length(dev, - thisboard->ai_fifo->max_segment_length); + board(dev)->ai_fifo->max_segment_length); devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; - devpriv->intr_enable_bits = - /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ - EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; + devpriv->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ + EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); @@ -1516,26 +1546,26 @@ static void init_stc_registers(struct comedi_device *dev) static int alloc_and_init_dma_members(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pcidas64_private *devpriv = dev->private; int i; /* alocate pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { devpriv->ai_buffer[i] = - pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &devpriv->ai_buffer_bus_addr[i]); + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv->ai_buffer_bus_addr[i]); if (devpriv->ai_buffer[i] == NULL) return -ENOMEM; } for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (ao_cmd_is_supported(thisboard)) { + if (ao_cmd_is_supported(board(dev))) { devpriv->ao_buffer[i] = - pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &devpriv-> - ao_buffer_bus_addr[i]); + pci_alloc_consistent(pcidev, + DMA_BUFFER_SIZE, + &devpriv-> + ao_buffer_bus_addr[i]); if (devpriv->ao_buffer[i] == NULL) return -ENOMEM; @@ -1543,60 +1573,65 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) } /* allocate dma descriptors */ devpriv->ai_dma_desc = - pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * - ai_dma_ring_count(thisboard), - &devpriv->ai_dma_desc_bus_addr); + pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + ai_dma_ring_count(board(dev)), + &devpriv->ai_dma_desc_bus_addr); if (devpriv->ai_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ai_dma_desc_bus_addr); - if (ao_cmd_is_supported(thisboard)) { + DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n", + devpriv->ai_dma_desc_bus_addr); + if (ao_cmd_is_supported(board(dev))) { devpriv->ao_dma_desc = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - AO_DMA_RING_COUNT, - &devpriv->ao_dma_desc_bus_addr); + pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + &devpriv->ao_dma_desc_bus_addr); if (devpriv->ao_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ao_dma_desc_bus_addr); + DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n", + devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ - for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { devpriv->ai_dma_desc[i].pci_start_addr = - cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); - if (thisboard->layout == LAYOUT_4020) + cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); + if (board(dev)->layout == LAYOUT_4020) devpriv->ai_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local1_iobase + - ADC_FIFO_REG); + cpu_to_le32(devpriv->local1_iobase + + ADC_FIFO_REG); else devpriv->ai_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local0_iobase + - ADC_FIFO_REG); + cpu_to_le32(devpriv->local0_iobase + + ADC_FIFO_REG); devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0); devpriv->ai_dma_desc[i].next = - cpu_to_le32((devpriv->ai_dma_desc_bus_addr + - ((i + 1) % ai_dma_ring_count(thisboard)) * - sizeof(devpriv->ai_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | - PLX_XFER_LOCAL_TO_PCI); + cpu_to_le32((devpriv->ai_dma_desc_bus_addr + ((i + + 1) % + ai_dma_ring_count + (board + (dev))) * + sizeof(devpriv->ai_dma_desc[0])) | + PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | + PLX_XFER_LOCAL_TO_PCI); } - if (ao_cmd_is_supported(thisboard)) { + if (ao_cmd_is_supported(board(dev))) { for (i = 0; i < AO_DMA_RING_COUNT; i++) { devpriv->ao_dma_desc[i].pci_start_addr = - cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); + cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); devpriv->ao_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local0_iobase + - DAC_FIFO_REG); - devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0); + cpu_to_le32(devpriv->local0_iobase + + DAC_FIFO_REG); + devpriv->ao_dma_desc[i].transfer_size = + cpu_to_le32(0); devpriv->ao_dma_desc[i].next = - cpu_to_le32((devpriv->ao_dma_desc_bus_addr + - ((i + 1) % (AO_DMA_RING_COUNT)) * - sizeof(devpriv->ao_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | - PLX_INTR_TERM_COUNT); + cpu_to_le32((devpriv->ao_dma_desc_bus_addr + + ((i + 1) % (AO_DMA_RING_COUNT)) * + sizeof(devpriv->ao_dma_desc[0])) | + PLX_DESC_IN_PCI_BIT | + PLX_INTR_TERM_COUNT); } } return 0; @@ -1610,139 +1645,207 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); } -/* Their i2c requires a huge delay on setting clock or data high for some reason */ -static const int i2c_high_udelay = 1000; -static const int i2c_low_udelay = 10; - -/* set i2c data line high or low */ -static void i2c_set_sda(struct comedi_device *dev, int state) +static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev, + struct comedi_devconfig *it) { - struct pcidas64_private *devpriv = dev->private; - static const int data_bit = CTL_EE_W; - void __iomem *plx_control_addr = devpriv->plx9080_iobase + - PLX_CONTROL_REG; - - if (state) { - /* set data line high */ - devpriv->plx_control_bits &= ~data_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set data line low */ + struct pci_dev *pcidev = NULL; + int bus = it->options[0]; + int slot = it->options[1]; + int i; - devpriv->plx_control_bits |= data_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); + for_each_pci_dev(pcidev) { + if (bus || slot) { + if (bus != pcidev->bus->number || + slot != PCI_SLOT(pcidev->devfn)) + continue; + } + if (pcidev->vendor != PCI_VENDOR_ID_CB) + continue; + + for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) { + if (pcidas64_boards[i].device_id != pcidev->device) + continue; + dev->board_ptr = pcidas64_boards + i; + return pcidev; + } } + dev_err(dev->class_dev, + "No supported board found! (req. bus %d, slot %d)\n", + bus, slot); + return NULL; } -/* set i2c clock line high or low */ -static void i2c_set_scl(struct comedi_device *dev, int state) +/* + * Attach is called by the Comedi core to configure the driver + * for a particular board. + */ +static int attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct pcidas64_private *devpriv = dev->private; - static const int clock_bit = CTL_USERO; - void __iomem *plx_control_addr = devpriv->plx9080_iobase + - PLX_CONTROL_REG; + struct pcidas64_private *devpriv; + struct pci_dev *pcidev; + uint32_t local_range, local_decode; + int retval; - if (state) { - /* set clock line high */ - devpriv->plx_control_bits &= ~clock_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set clock line low */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - devpriv->plx_control_bits |= clock_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); + pcidev = cb_pcidas64_find_pci_dev(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); + + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { + dev_warn(dev->class_dev, + "failed to enable PCI device and request regions\n"); + return -EIO; } -} + pci_set_master(pcidev); -static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) -{ - uint8_t bit; - unsigned int num_bits = 8; + /* Initialize dev->board_name */ + dev->board_name = board(dev)->name; - DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); + dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); - for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { - i2c_set_scl(dev, 0); - if ((byte & bit)) - i2c_set_sda(dev, 1); - else - i2c_set_sda(dev, 0); - i2c_set_scl(dev, 1); + devpriv->plx9080_phys_iobase = + pci_resource_start(pcidev, PLX9080_BADDRINDEX); + devpriv->main_phys_iobase = dev->iobase; + devpriv->dio_counter_phys_iobase = + pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); + + /* remap, won't work with 2.0 kernels but who cares */ + devpriv->plx9080_iobase = ioremap(devpriv->plx9080_phys_iobase, + pci_resource_len(pcidev, + PLX9080_BADDRINDEX)); + devpriv->main_iobase = + ioremap(devpriv->main_phys_iobase, + pci_resource_len(pcidev, MAIN_BADDRINDEX)); + devpriv->dio_counter_iobase = + ioremap(devpriv->dio_counter_phys_iobase, + pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); + + if (!devpriv->plx9080_iobase || !devpriv->main_iobase + || !devpriv->dio_counter_iobase) { + dev_warn(dev->class_dev, "failed to remap io memory\n"); + return -ENOMEM; } -} -/* we can't really read the lines, so fake it */ -static int i2c_read_ack(struct comedi_device *dev) -{ - i2c_set_scl(dev, 0); - i2c_set_sda(dev, 1); - i2c_set_scl(dev, 1); + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); + DEBUG_PRINT(" diocounter remapped to 0x%p\n", + devpriv->dio_counter_iobase); - return 0; /* return fake acknowledge bit */ -} + /* figure out what local addresses are */ + local_range = + readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; + local_decode = + readl(devpriv->plx9080_iobase + + PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK; + devpriv->local0_iobase = + ((uint32_t) devpriv->main_phys_iobase & ~local_range) | + local_decode; + local_range = + readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK; + local_decode = + readl(devpriv->plx9080_iobase + + PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK; + devpriv->local1_iobase = + ((uint32_t) devpriv->dio_counter_phys_iobase & ~local_range) | + local_decode; -/* send start bit */ -static void i2c_start(struct comedi_device *dev) -{ - i2c_set_scl(dev, 1); - i2c_set_sda(dev, 1); - i2c_set_sda(dev, 0); -} + DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); + DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); -/* send stop bit */ -static void i2c_stop(struct comedi_device *dev) -{ - i2c_set_scl(dev, 0); - i2c_set_sda(dev, 0); - i2c_set_scl(dev, 1); - i2c_set_sda(dev, 1); -} + retval = alloc_and_init_dma_members(dev); + if (retval < 0) + return retval; -static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int i; - uint8_t bitstream; - static const int read_bit = 0x1; + devpriv->hw_revision = + hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); + dev_dbg(dev->class_dev, "stc hardware revision %i\n", + devpriv->hw_revision); + init_plx9080(dev); + init_stc_registers(dev); + /* get irq */ + if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, + "cb_pcidas64", dev)) { + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", + pcidev->irq); + return -EINVAL; + } + dev->irq = pcidev->irq; + dev_dbg(dev->class_dev, "irq %u\n", dev->irq); - /* XXX need mutex to prevent simultaneous attempts to access - * eeprom and i2c bus */ + retval = setup_subdevices(dev); + if (retval < 0) + return retval; - /* make sure we dont send anything to eeprom */ - devpriv->plx_control_bits &= ~CTL_EE_CS; - i2c_stop(dev); - i2c_start(dev); + return 0; +} - /* send address and write bit */ - bitstream = (address << 1) & ~read_bit; - i2c_write_byte(dev, bitstream); +static void detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; + unsigned int i; - /* get acknowledge */ - if (i2c_read_ack(dev) != 0) { - comedi_error(dev, "i2c write failed: no acknowledge"); - i2c_stop(dev); - return; - } - /* write data bytes */ - for (i = 0; i < length; i++) { - i2c_write_byte(dev, data[i]); - if (i2c_read_ack(dev) != 0) { - comedi_error(dev, "i2c write failed: no acknowledge"); - i2c_stop(dev); - return; + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (pcidev) { + if (devpriv->plx9080_iobase) { + disable_plx_interrupts(dev); + iounmap(devpriv->plx9080_iobase); + } + if (devpriv->main_iobase) + iounmap(devpriv->main_iobase); + if (devpriv->dio_counter_iobase) + iounmap(devpriv->dio_counter_iobase); + /* free pci dma buffers */ + for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { + if (devpriv->ai_buffer[i]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->ai_buffer[i], + devpriv->ai_buffer_bus_addr[i]); + } + for (i = 0; i < AO_DMA_RING_COUNT; i++) { + if (devpriv->ao_buffer[i]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->ao_buffer[i], + devpriv->ao_buffer_bus_addr[i]); + } + /* free dma descriptors */ + if (devpriv->ai_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + ai_dma_ring_count(board(dev)), + devpriv->ai_dma_desc, + devpriv->ai_dma_desc_bus_addr); + if (devpriv->ao_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + devpriv->ao_dma_desc, + devpriv->ao_dma_desc_bus_addr); } } - i2c_stop(dev); + if (dev->subdevices) + subdev_8255_cleanup(dev, &dev->subdevices[4]); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + + pci_dev_put(pcidev); + } } static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int bits = 0, n, i; unsigned int channel, range, aref; @@ -1767,7 +1870,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->main_iobase + ADC_CONTROL1_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - if (thisboard->layout != LAYOUT_4020) { + if (board(dev)->layout != LAYOUT_4020) { /* use internal queue */ devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; writew(devpriv->hw_config_bits, @@ -1778,18 +1881,16 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int cal_en_bit; DEBUG_PRINT("reading calibration source\n"); - if (thisboard->layout == LAYOUT_60XX) + if (board(dev)->layout == LAYOUT_60XX) cal_en_bit = CAL_EN_60XX_BIT; else cal_en_bit = CAL_EN_64XX_BIT; - /* select internal reference source to connect - * to channel 0 */ + /* select internal reference source to connect to channel 0 */ writew(cal_en_bit | adc_src_bits(devpriv->calibration_source), devpriv->main_iobase + CALIBRATION_REG); } else { - /* make sure internal calibration source - * is turned off */ + /* make sure internal calibration source is turned off */ writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* load internal queue */ @@ -1813,7 +1914,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (insn->chanspec & CR_ALT_SOURCE) { DEBUG_PRINT("reading calibration source\n"); devpriv->i2c_cal_range_bits |= - adc_src_4020_bits(devpriv->calibration_source); + adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4); } @@ -1821,21 +1922,21 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (range == 0) devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else - devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); - /* update calibration/range i2c register only if necessary, - * as it is very slow */ + devpriv->i2c_cal_range_bits &= + ~attenuate_bit(channel); + /* update calibration/range i2c register only if necessary, as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } - /* 4020 manual asks that sample interval register to be set - * before writing to convert register. - * Using somewhat arbitrary setting of 4 master clock ticks - * = 0.1 usec */ - writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); - writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + /* 4020 manual asks that sample interval register to be set before writing to convert register. + * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */ + writew(0, + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + writew(2, + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); } for (n = 0; n < insn->n; n++) { @@ -1851,7 +1952,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, for (i = 0; i < timeout; i++) { bits = readw(devpriv->main_iobase + HW_STATUS_REG); DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) break; @@ -1864,14 +1965,16 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, DEBUG_PRINT(" looped %i times waiting for data\n", i); if (i == timeout) { comedi_error(dev, " analog input read insn timed out"); - dev_info(dev->class_dev, "status 0x%x\n", bits); + printk(" status 0x%x\n", bits); return -ETIME; } - if (thisboard->layout == LAYOUT_4020) - data[n] = readl(devpriv->dio_counter_iobase + - ADC_FIFO_REG) & 0xffff; + if (board(dev)->layout == LAYOUT_4020) + data[n] = + readl(devpriv->dio_counter_iobase + + ADC_FIFO_REG) & 0xffff; else - data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG); + data[n] = + readw(devpriv->main_iobase + PIPE1_READ_REG); } return n; @@ -1880,12 +1983,11 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int source = data[1]; int num_calibration_sources; - if (thisboard->layout == LAYOUT_60XX) + if (board(dev)->layout == LAYOUT_60XX) num_calibration_sources = 16; else num_calibration_sources = 8; @@ -1903,17 +2005,16 @@ static int ai_config_calibration_source(struct comedi_device *dev, static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) { - const struct pcidas64_board *thisboard = comedi_board(dev); int fifo_size; - const struct hw_fifo_info *const fifo = thisboard->ai_fifo; + const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; unsigned int block_size, requested_block_size; int retval; requested_block_size = data[1]; if (requested_block_size) { - fifo_size = requested_block_size * fifo->num_segments / - bytes_in_sample; + fifo_size = + requested_block_size * fifo->num_segments / bytes_in_sample; retval = set_ai_fifo_size(dev, fifo_size); if (retval < 0) @@ -1958,9 +2059,8 @@ static int ai_config_master_clock_4020(struct comedi_device *dev, /* XXX could add support for 60xx series */ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data) { - const struct pcidas64_board *thisboard = comedi_board(dev); - switch (thisboard->layout) { + switch (board(dev)->layout) { case LAYOUT_4020: return ai_config_master_clock_4020(dev, data); break; @@ -1994,84 +2094,9 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, return -EINVAL; } -/* Gets nearest achievable timing given master clock speed, does not - * take into account possible minimum/maximum divisor values. Used - * by other timing checking functions. */ -static unsigned int get_divisor(unsigned int ns, unsigned int flags) -{ - unsigned int divisor; - - switch (flags & TRIG_ROUND_MASK) { - case TRIG_ROUND_UP: - divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; - break; - case TRIG_ROUND_DOWN: - divisor = ns / TIMER_BASE; - break; - case TRIG_ROUND_NEAREST: - default: - divisor = (ns + TIMER_BASE / 2) / TIMER_BASE; - break; - } - return divisor; -} - -/* utility function that rounds desired timing to an achievable time, and - * sets cmd members appropriately. - * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number - */ -static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - unsigned int convert_divisor = 0, scan_divisor; - static const int min_convert_divisor = 3; - static const int max_convert_divisor = - max_counter_value + min_convert_divisor; - static const int min_scan_divisor_4020 = 2; - unsigned long long max_scan_divisor, min_scan_divisor; - - if (cmd->convert_src == TRIG_TIMER) { - if (thisboard->layout == LAYOUT_4020) { - cmd->convert_arg = 0; - } else { - convert_divisor = get_divisor(cmd->convert_arg, - cmd->flags); - if (convert_divisor > max_convert_divisor) - convert_divisor = max_convert_divisor; - if (convert_divisor < min_convert_divisor) - convert_divisor = min_convert_divisor; - cmd->convert_arg = convert_divisor * TIMER_BASE; - } - } else if (cmd->convert_src == TRIG_NOW) { - cmd->convert_arg = 0; - } - - if (cmd->scan_begin_src == TRIG_TIMER) { - scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); - if (cmd->convert_src == TRIG_TIMER) { - /* XXX check for integer overflows */ - min_scan_divisor = convert_divisor * cmd->chanlist_len; - max_scan_divisor = - (convert_divisor * cmd->chanlist_len - 1) + - max_counter_value; - } else { - min_scan_divisor = min_scan_divisor_4020; - max_scan_divisor = max_counter_value + min_scan_divisor; - } - if (scan_divisor > max_scan_divisor) - scan_divisor = max_scan_divisor; - if (scan_divisor < min_scan_divisor) - scan_divisor = min_scan_divisor; - cmd->scan_begin_arg = scan_divisor * TIMER_BASE; - } - - return; -} - static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg, tmp_arg2; int i; @@ -2083,21 +2108,22 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); triggers = TRIG_TIMER; - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) triggers |= TRIG_OTHER; else triggers |= TRIG_FOLLOW; err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers); triggers = TRIG_TIMER; - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) triggers |= TRIG_NOW; else triggers |= TRIG_EXT; err |= cfc_check_trigger_src(&cmd->convert_src, triggers); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, - TRIG_COUNT | TRIG_EXT | TRIG_NONE); + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; @@ -2123,24 +2149,23 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* step 3: make sure arguments are trivially compatible */ if (cmd->convert_src == TRIG_TIMER) { - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { if (cmd->convert_arg) { cmd->convert_arg = 0; err++; } } else { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; + if (cmd->convert_arg < board(dev)->ai_speed) { + cmd->convert_arg = board(dev)->ai_speed; err++; } if (cmd->scan_begin_src == TRIG_TIMER) { - /* if scans are timed faster than - * conversion rate allows */ + /* if scans are timed faster than conversion rate allows */ if (cmd->convert_arg * cmd->chanlist_len > cmd->scan_begin_arg) { cmd->scan_begin_arg = - cmd->convert_arg * - cmd->chanlist_len; + cmd->convert_arg * + cmd->chanlist_len; err++; } } @@ -2205,7 +2230,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } } /* check 4020 chanlist */ - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { unsigned int first_channel = CR_CHAN(cmd->chanlist[0]); for (i = 1; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) != @@ -2263,18 +2288,76 @@ static void setup_sample_counters(struct comedi_device *dev, static inline unsigned int dma_transfer_size(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int num_samples; - num_samples = devpriv->ai_fifo_segment_length * - thisboard->ai_fifo->sample_packing_ratio; + num_samples = + devpriv->ai_fifo_segment_length * + board(dev)->ai_fifo->sample_packing_ratio; if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); return num_samples; } +static void disable_ai_pacing(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + disable_ai_interrupts(dev); + + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT; + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); + + /* disable pacing, triggering, etc */ + writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, + devpriv->main_iobase + ADC_CONTROL0_REG); +} + +static void disable_ai_interrupts(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->intr_enable_bits &= + ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & + ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & + ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); + + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); +} + +static void enable_ai_interrupts(struct comedi_device *dev, + const struct comedi_cmd *cmd) +{ + struct pcidas64_private *devpriv = dev->private; + uint32_t bits; + unsigned long flags; + + bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | + EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; + /* Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set. */ + if (cmd->flags & TRIG_WAKE_EOS) { + /* 4020 doesn't support pio transfers except for fifo dregs */ + if (board(dev)->layout != LAYOUT_4020) + bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; + } + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->intr_enable_bits |= bits; + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); + spin_unlock_irqrestore(&dev->spinlock, flags); +} + static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev, const struct comedi_cmd *cmd) { @@ -2286,13 +2369,12 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, struct comedi_cmd *cmd) { uint32_t count; - /* figure out how long we need to delay at end of scan */ switch (cmd->scan_begin_src) { case TRIG_TIMER: count = (cmd->scan_begin_arg - - (cmd->convert_arg * (cmd->chanlist_len - 1))) / - TIMER_BASE; + (cmd->convert_arg * (cmd->chanlist_len - 1))) + / TIMER_BASE; break; case TRIG_FOLLOW: count = cmd->convert_arg / TIMER_BASE; @@ -2351,9 +2433,7 @@ static void select_master_clock_4020(struct comedi_device *dev, static void select_master_clock(struct comedi_device *dev, const struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); - - switch (thisboard->layout) { + switch (board(dev)->layout) { case LAYOUT_4020: select_master_clock_4020(dev, cmd); break; @@ -2383,7 +2463,6 @@ static inline void dma_start_sync(struct comedi_device *dev, static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint32_t convert_counter = 0, scan_counter = 0; @@ -2391,7 +2470,7 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) select_master_clock(dev, cmd); - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { convert_counter = ai_convert_counter_4020(dev, cmd); } else { convert_counter = ai_convert_counter_6xxx(dev, cmd); @@ -2417,7 +2496,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) { int i; - for (i = 0; i + 1 < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i + 1]) != CR_CHAN(cmd->chanlist[i]) + 1) @@ -2434,12 +2512,11 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned short bits; int i; - if (thisboard->layout != LAYOUT_4020) { + if (board(dev)->layout != LAYOUT_4020) { if (use_internal_queue_6xxx(cmd)) { devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; writew(devpriv->hw_config_bits, @@ -2481,8 +2558,8 @@ static int setup_channel_queue(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; i++) { bits = 0; /* set channel */ - bits |= adc_chan_bits(CR_CHAN(cmd-> - chanlist[i])); + bits |= + adc_chan_bits(CR_CHAN(cmd->chanlist[i])); /* set gain */ bits |= ai_range_bits_6xxx(dev, CR_RANGE(cmd-> @@ -2498,13 +2575,13 @@ static int setup_channel_queue(struct comedi_device *dev, /* mark end of queue */ if (i == cmd->chanlist_len - 1) bits |= QUEUE_EOSCAN_BIT | - QUEUE_EOSEQ_BIT; + QUEUE_EOSEQ_BIT; writew(bits, devpriv->main_iobase + ADC_QUEUE_FIFO_REG); - DEBUG_PRINT( - "wrote 0x%x to external channel queue\n", - bits); + DEBUG_PRINT + ("wrote 0x%x to external channel queue\n", + bits); } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ @@ -2513,7 +2590,8 @@ static int setup_channel_queue(struct comedi_device *dev, writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } } else { - unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits; + unsigned short old_cal_range_bits = + devpriv->i2c_cal_range_bits; devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; /* select BNC inputs */ @@ -2525,13 +2603,12 @@ static int setup_channel_queue(struct comedi_device *dev, if (range == 0) devpriv->i2c_cal_range_bits |= - attenuate_bit(channel); + attenuate_bit(channel); else devpriv->i2c_cal_range_bits &= - ~attenuate_bit(channel); + ~attenuate_bit(channel); } - /* update calibration/range i2c register only if necessary, - * as it is very slow */ + /* update calibration/range i2c register only if necessary, as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, @@ -2573,7 +2650,6 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2602,14 +2678,12 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set mode, allow conversions through software gate */ devpriv->adc_control1_bits |= ADC_SW_GATE_BIT; devpriv->adc_control1_bits &= ~ADC_DITHER_BIT; - if (thisboard->layout != LAYOUT_4020) { + if (board(dev)->layout != LAYOUT_4020) { devpriv->adc_control1_bits &= ~ADC_MODE_MASK; if (cmd->convert_src == TRIG_EXT) - /* good old mode 13 */ - devpriv->adc_control1_bits |= adc_mode_bits(13); + devpriv->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */ else - /* mode 8. What else could you need? */ - devpriv->adc_control1_bits |= adc_mode_bits(8); + devpriv->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */ } else { devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; if (cmd->chanlist_len == 4) @@ -2618,11 +2692,12 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS; devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK; devpriv->adc_control1_bits |= - adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); + adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK; devpriv->adc_control1_bits |= - adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist - [cmd->chanlist_len - 1])); + adc_hi_chan_4020_bits(CR_CHAN + (cmd-> + chanlist[cmd->chanlist_len - 1])); } writew(devpriv->adc_control1_bits, devpriv->main_iobase + ADC_CONTROL1_REG); @@ -2633,14 +2708,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); if ((cmd->flags & TRIG_WAKE_EOS) == 0 || - thisboard->layout == LAYOUT_4020) { + board(dev)->layout == LAYOUT_4020) { devpriv->ai_dma_index = 0; /* set dma transfer size */ - for (i = 0; i < ai_dma_ring_count(thisboard); i++) + for (i = 0; i < ai_dma_ring_count(board(dev)); i++) devpriv->ai_dma_desc[i].transfer_size = - cpu_to_le32(dma_transfer_size(dev) * - sizeof(uint16_t)); + cpu_to_le32(dma_transfer_size(dev) * + sizeof(uint16_t)); /* give location of first dma descriptor */ load_first_dma_descriptor(dev, 1, @@ -2652,7 +2727,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dma_start_sync(dev, 1); } - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { /* set source for external triggers */ bits = 0; if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg)) @@ -2707,19 +2782,18 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) do { /* get least significant 15 bits */ - read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & - 0x7fff; - write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & - 0x7fff; - /* Get most significant bits (grey code). - * Different boards use different code so use a scheme - * that doesn't depend on encoding. This read must + read_index = + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + write_index = + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + /* Get most significant bits (grey code). Different boards use different code + * so use a scheme that doesn't depend on encoding. This read must * occur after reading least significant 15 bits to avoid race * with fifo switching to next segment. */ prepost_bits = readw(devpriv->main_iobase + PREPOST_REG); - /* if read and write pointers are not on the same fifo segment, - * read to the end of the read segment */ + /* if read and write pointers are not on the same fifo segment, read to the + * end of the read segment */ read_segment = adc_upper_read_ptr_code(prepost_bits); write_segment = adc_upper_write_ptr_code(prepost_bits); @@ -2729,7 +2803,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) if (read_segment != write_segment) num_samples = - devpriv->ai_fifo_segment_length - read_index; + devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; @@ -2759,10 +2833,10 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) } while (read_segment != write_segment); } -/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of - * pointers. The pci-4020 hardware only supports dma transfers (it only - * supports the use of pio for draining the last remaining points from the - * fifo when a data acquisition operation has completed). +/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers. + * The pci-4020 hardware only supports + * dma transfers (it only supports the use of pio for draining the last remaining + * points from the fifo when a data acquisition operation has completed). */ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { @@ -2774,9 +2848,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = - readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = - readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; if (cmd->stop_src == TRIG_COUNT) { if (max_transfer > devpriv->ai_count) @@ -2791,8 +2865,8 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff); i++; } - read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & - 0x7fff; + read_code = + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; } devpriv->ai_count -= i; } @@ -2800,9 +2874,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) /* empty fifo */ static void pio_drain_ai_fifo(struct comedi_device *dev) { - const struct pcidas64_board *thisboard = comedi_board(dev); - - if (thisboard->layout == LAYOUT_4020) + if (board(dev)->layout == LAYOUT_4020) pio_drain_ai_fifo_32(dev); else pio_drain_ai_fifo_16(dev); @@ -2810,7 +2882,6 @@ static void pio_drain_ai_fifo(struct comedi_device *dev) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; @@ -2828,10 +2899,10 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) /* loop until we have read all the full buffers */ for (j = 0, next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] || - next_transfer_addr >= + devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + || next_transfer_addr >= devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + - DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) { + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) { /* transfer data from dma buffer to comedi buffer */ num_samples = dma_transfer_size(dev); if (async->cmd.stop_src == TRIG_COUNT) { @@ -2841,25 +2912,25 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) } cfc_write_array_to_buffer(dev->read_subdev, devpriv->ai_buffer[devpriv-> - ai_dma_index], + ai_dma_index], num_samples * sizeof(uint16_t)); - devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % - ai_dma_ring_count(thisboard); + devpriv->ai_dma_index = + (devpriv->ai_dma_index + + 1) % ai_dma_ring_count(board(dev)); DEBUG_PRINT("next buffer addr 0x%lx\n", (unsigned long)devpriv-> ai_buffer_bus_addr[devpriv->ai_dma_index]); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } - /* XXX check for dma ring buffer overrun - * (use end-of-chain bit to mark last unused buffer) */ + /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last + * unused buffer) */ } static void handle_ai_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; @@ -2894,7 +2965,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, if ((status & ADC_DONE_BIT) || ((cmd->flags & TRIG_WAKE_EOS) && (status & ADC_INTR_PENDING_BIT) && - (thisboard->layout != LAYOUT_4020))) { + (board(dev)->layout != LAYOUT_4020))) { DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->ai_cmd_running) { @@ -2937,7 +3008,7 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) return 0; transfer_address = - readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index]) return 0; @@ -2978,7 +3049,7 @@ static void restart_ao_dma(struct comedi_device *dev) unsigned int dma_desc_bits; dma_desc_bits = - readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); @@ -2986,77 +3057,6 @@ static void restart_ao_dma(struct comedi_device *dev) dma_start_sync(dev, 0); } -static unsigned int load_ao_dma_buffer(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes, buffer_index, prev_buffer_index; - unsigned int next_bits; - - buffer_index = devpriv->ao_dma_index; - prev_buffer_index = prev_ao_dma_index(dev); - - DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, - (unsigned long long)devpriv->ao_buffer_bus_addr[ - buffer_index]); - - num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); - if (num_bytes > DMA_BUFFER_SIZE) - num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) - num_bytes = devpriv->ao_count; - num_bytes -= num_bytes % bytes_in_sample; - - if (num_bytes == 0) - return 0; - - DEBUG_PRINT("loading %i bytes\n", num_bytes); - - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv-> - ao_buffer[buffer_index], - num_bytes); - devpriv->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); - /* set end of chain bit so we catch underruns */ - next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); - next_bits |= PLX_END_OF_CHAIN_BIT; - devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); - /* clear end of chain bit on previous buffer now that we have set it - * for the last buffer */ - next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); - next_bits &= ~PLX_END_OF_CHAIN_BIT; - devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); - - devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - devpriv->ao_count -= num_bytes; - - return num_bytes; -} - -static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes; - unsigned int next_transfer_addr; - void __iomem *pci_addr_reg = - devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; - unsigned int buffer_index; - - do { - buffer_index = devpriv->ao_dma_index; - /* don't overwrite data that hasn't been transferred yet */ - next_transfer_addr = readl(pci_addr_reg); - if (next_transfer_addr >= - devpriv->ao_buffer_bus_addr[buffer_index] && - next_transfer_addr < - devpriv->ao_buffer_bus_addr[buffer_index] + - DMA_BUFFER_SIZE) - return; - num_bytes = load_ao_dma_buffer(dev, cmd); - } while (num_bytes >= DMA_BUFFER_SIZE); -} - static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { @@ -3077,8 +3077,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, spin_lock_irqsave(&dev->spinlock, flags); dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ - if ((dma0_status & PLX_DMA_EN_BIT) && - !(dma0_status & PLX_DMA_DONE_BIT)) + if ((dma0_status & PLX_DMA_EN_BIT) + && !(dma0_status & PLX_DMA_DONE_BIT)) writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); else @@ -3093,9 +3093,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, restart_ao_dma(dev); } DEBUG_PRINT(" cleared dma ch0 interrupt\n"); - } else { + } else spin_unlock_irqrestore(&dev->spinlock, flags); - } if ((status & DAC_DONE_BIT)) { async->events |= COMEDI_CB_EOA; @@ -3122,13 +3121,15 @@ static irqreturn_t handle_interrupt(int irq, void *d) plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); status = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status); + DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status); + DEBUG_PRINT("plx status 0x%x\n", plx_status); /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ if (dev->attached == 0) { - DEBUG_PRINT("premature interrupt, ignoring\n"); + DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring", + status); return IRQ_HANDLED; } handle_ai_interrupt(dev, status, plx_status); @@ -3146,6 +3147,19 @@ static irqreturn_t handle_interrupt(int irq, void *d) return IRQ_HANDLED; } +static void abort_dma(struct comedi_device *dev, unsigned int channel) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + /* spinlock for plx dma control/status reg */ + spin_lock_irqsave(&dev->spinlock, flags); + + plx9080_abort_dma(devpriv->plx9080_iobase, channel); + + spin_unlock_irqrestore(&dev->spinlock, flags); +} + static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcidas64_private *devpriv = dev->private; @@ -3170,7 +3184,6 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int range = CR_RANGE(insn->chanspec); @@ -3184,7 +3197,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->main_iobase + DAC_CONTROL1_REG); /* write to channel */ - if (thisboard->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) { writew(data[0] & 0xff, devpriv->main_iobase + dac_lsb_4020_reg(chan)); writew((data[0] >> 8) & 0xf, @@ -3215,7 +3228,7 @@ static void set_dac_control0_reg(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT | - WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; + WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; if (cmd->start_src == TRIG_EXT) { bits |= WAVEFORM_TRIG_EXT_BITS; @@ -3268,11 +3281,6 @@ static void set_dac_select_reg(struct comedi_device *dev, writew(bits, devpriv->main_iobase + DAC_SELECT_REG); } -static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) -{ - return get_divisor(ns, flags) - 2; -} - static void set_dac_interval_regs(struct comedi_device *dev, const struct comedi_cmd *cmd) { @@ -3293,79 +3301,123 @@ static void set_dac_interval_regs(struct comedi_device *dev, devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG); } -static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) +static unsigned int load_ao_dma_buffer(struct comedi_device *dev, + const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes; - int i; - - /* clear queue pointer too, since external queue has - * weird interactions with ao fifo */ - writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); - writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); - - num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && - num_bytes / bytes_in_sample > devpriv->ao_count) - num_bytes = devpriv->ao_count * bytes_in_sample; - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv->ao_bounce_buffer, - num_bytes); - for (i = 0; i < num_bytes / bytes_in_sample; i++) { - writew(devpriv->ao_bounce_buffer[i], - devpriv->main_iobase + DAC_FIFO_REG); - } - devpriv->ao_count -= num_bytes / bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) - return 0; - num_bytes = load_ao_dma_buffer(dev, cmd); - if (num_bytes == 0) - return -1; - if (num_bytes >= DMA_BUFFER_SIZE) ; - load_ao_dma(dev, cmd); + unsigned int num_bytes, buffer_index, prev_buffer_index; + unsigned int next_bits; - dma_start_sync(dev, 0); + buffer_index = devpriv->ao_dma_index; + prev_buffer_index = prev_ao_dma_index(dev); - return 0; -} + DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index, + devpriv->ao_buffer_bus_addr[buffer_index]); -static inline int external_ai_queue_in_use(struct comedi_device *dev) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); + num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); + if (num_bytes > DMA_BUFFER_SIZE) + num_bytes = DMA_BUFFER_SIZE; + if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) + num_bytes = devpriv->ao_count; + num_bytes -= num_bytes % bytes_in_sample; - if (dev->read_subdev->busy) - return 0; - if (thisboard->layout == LAYOUT_4020) - return 0; - else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd)) + if (num_bytes == 0) return 0; - return 1; -} -static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int trig_num) + DEBUG_PRINT("loading %i bytes\n", num_bytes); + + num_bytes = cfc_read_array_from_buffer(dev->write_subdev, + devpriv-> + ao_buffer[buffer_index], + num_bytes); + devpriv->ao_dma_desc[buffer_index].transfer_size = + cpu_to_le32(num_bytes); + /* set end of chain bit so we catch underruns */ + next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); + next_bits |= PLX_END_OF_CHAIN_BIT; + devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); + /* clear end of chain bit on previous buffer now that we have set it + * for the last buffer */ + next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); + next_bits &= ~PLX_END_OF_CHAIN_BIT; + devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); + + devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; + devpriv->ao_count -= num_bytes; + + return num_bytes; +} + +static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - int retval; + unsigned int num_bytes; + unsigned int next_transfer_addr; + void __iomem *pci_addr_reg = + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + unsigned int buffer_index; - if (trig_num != 0) - return -EINVAL; + do { + buffer_index = devpriv->ao_dma_index; + /* don't overwrite data that hasn't been transferred yet */ + next_transfer_addr = readl(pci_addr_reg); + if (next_transfer_addr >= + devpriv->ao_buffer_bus_addr[buffer_index] + && next_transfer_addr < + devpriv->ao_buffer_bus_addr[buffer_index] + + DMA_BUFFER_SIZE) + return; + num_bytes = load_ao_dma_buffer(dev, cmd); + } while (num_bytes >= DMA_BUFFER_SIZE); +} - retval = prep_ao_dma(dev, cmd); - if (retval < 0) - return -EPIPE; +static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned int num_bytes; + int i; - set_dac_control0_reg(dev, cmd); + /* clear queue pointer too, since external queue has + * weird interactions with ao fifo */ + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); - if (cmd->start_src == TRIG_INT) - writew(0, devpriv->main_iobase + DAC_START_REG); + num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; + if (cmd->stop_src == TRIG_COUNT && + num_bytes / bytes_in_sample > devpriv->ao_count) + num_bytes = devpriv->ao_count * bytes_in_sample; + num_bytes = cfc_read_array_from_buffer(dev->write_subdev, + devpriv->ao_bounce_buffer, + num_bytes); + for (i = 0; i < num_bytes / bytes_in_sample; i++) { + writew(devpriv->ao_bounce_buffer[i], + devpriv->main_iobase + DAC_FIFO_REG); + } + devpriv->ao_count -= num_bytes / bytes_in_sample; + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) + return 0; + num_bytes = load_ao_dma_buffer(dev, cmd); + if (num_bytes == 0) + return -1; + if (num_bytes >= DMA_BUFFER_SIZE) ; + load_ao_dma(dev, cmd); - s->async->inttrig = NULL; + dma_start_sync(dev, 0); return 0; } +static inline int external_ai_queue_in_use(struct comedi_device *dev) +{ + if (dev->read_subdev->busy) + return 0; + if (board(dev)->layout == LAYOUT_4020) + return 0; + else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd)) + return 0; + return 1; +} + static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcidas64_private *devpriv = dev->private; @@ -3392,10 +3444,33 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } +static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, + unsigned int trig_num) +{ + struct pcidas64_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + int retval; + + if (trig_num != 0) + return -EINVAL; + + retval = prep_ao_dma(dev, cmd); + if (retval < 0) + return -EPIPE; + + set_dac_control0_reg(dev, cmd); + + if (cmd->start_src == TRIG_INT) + writew(0, devpriv->main_iobase + DAC_START_REG); + + s->async->inttrig = NULL; + + return 0; +} + static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg; int i; @@ -3404,7 +3479,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_EXT); + TRIG_TIMER | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); @@ -3431,14 +3506,14 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* step 3: make sure arguments are trivially compatible */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { - cmd->scan_begin_arg = thisboard->ao_scan_speed; + if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) { + cmd->scan_begin_arg = board(dev)->ao_scan_speed; err++; } if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) > max_counter_value) { - cmd->scan_begin_arg = (max_counter_value + 2) * - TIMER_BASE; + cmd->scan_begin_arg = + (max_counter_value + 2) * TIMER_BASE; err++; } } @@ -3459,8 +3534,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (cmd->scan_begin_src == TRIG_TIMER) { tmp_arg = cmd->scan_begin_arg; - cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg, - cmd->flags) * TIMER_BASE; + cmd->scan_begin_arg = + get_divisor(cmd->scan_begin_arg, cmd->flags) * TIMER_BASE; if (tmp_arg != cmd->scan_begin_arg) err++; } @@ -3596,129 +3671,14 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -/* pci-6025 8800 caldac: - * address 0 == dac channel 0 offset - * address 1 == dac channel 0 gain - * address 2 == dac channel 1 offset - * address 3 == dac channel 1 gain - * address 4 == fine adc offset - * address 5 == coarse adc offset - * address 6 == coarse adc gain - * address 7 == fine adc gain - */ -/* pci-6402/16 uses all 8 channels for dac: - * address 0 == dac channel 0 fine gain - * address 1 == dac channel 0 coarse gain - * address 2 == dac channel 0 coarse offset - * address 3 == dac channel 1 coarse offset - * address 4 == dac channel 1 fine gain - * address 5 == dac channel 1 coarse gain - * address 6 == dac channel 0 fine offset - * address 7 == dac channel 1 fine offset -*/ - -static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value) -{ - struct pcidas64_private *devpriv = dev->private; - static const int num_caldac_channels = 8; - static const int bitstream_length = 11; - unsigned int bitstream = ((address & 0x7) << 8) | value; - unsigned int bit, register_bits; - static const int caldac_8800_udelay = 1; - - if (address >= num_caldac_channels) { - comedi_error(dev, "illegal caldac channel"); - return -1; - } - for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { - register_bits = 0; - if (bitstream & bit) - register_bits |= SERIAL_DATA_IN_BIT; - udelay(caldac_8800_udelay); - writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); - register_bits |= SERIAL_CLOCK_BIT; - udelay(caldac_8800_udelay); - writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); - } - udelay(caldac_8800_udelay); - writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - writew(0, devpriv->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - return 0; -} - -/* 4020 caldacs */ -static int caldac_i2c_write(struct comedi_device *dev, - unsigned int caldac_channel, unsigned int value) -{ - uint8_t serial_bytes[3]; - uint8_t i2c_addr; - enum pointer_bits { - /* manual has gain and offset bits switched */ - OFFSET_0_2 = 0x1, - GAIN_0_2 = 0x2, - OFFSET_1_3 = 0x4, - GAIN_1_3 = 0x8, - }; - enum data_bits { - NOT_CLEAR_REGISTERS = 0x20, - }; - - switch (caldac_channel) { - case 0: /* chan 0 offset */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = OFFSET_0_2; - break; - case 1: /* chan 1 offset */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = OFFSET_1_3; - break; - case 2: /* chan 2 offset */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = OFFSET_0_2; - break; - case 3: /* chan 3 offset */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = OFFSET_1_3; - break; - case 4: /* chan 0 gain */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = GAIN_0_2; - break; - case 5: /* chan 1 gain */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = GAIN_1_3; - break; - case 6: /* chan 2 gain */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = GAIN_0_2; - break; - case 7: /* chan 3 gain */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = GAIN_1_3; - break; - default: - comedi_error(dev, "invalid caldac channel\n"); - return -1; - break; - } - serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); - serial_bytes[2] = value & 0xff; - i2c_write(dev, i2c_addr, serial_bytes, 3); - return 0; -} - static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { - const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; devpriv->caldac_state[channel] = value; - switch (thisboard->layout) { + switch (board(dev)->layout) { case LAYOUT_60XX: case LAYOUT_64XX: caldac_8800_write(dev, channel, value); @@ -3831,7 +3791,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) unsigned int bitstream = (read_command << 8) | address; unsigned int bit; void __iomem * const plx_control_addr = - devpriv->plx9080_iobase + PLX_CONTROL_REG; + devpriv->plx9080_iobase + PLX_CONTROL_REG; uint16_t value; static const int value_length = 16; static const int eeprom_udelay = 1; @@ -3895,352 +3855,392 @@ static int eeprom_read_insn(struct comedi_device *dev, return 1; } -/* Allocate and initialize the subdevice structures. +/* utility function that rounds desired timing to an achievable time, and + * sets cmd members appropriately. + * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number */ -static int setup_subdevices(struct comedi_device *dev) +static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) { - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - struct comedi_subdevice *s; - void __iomem *dio_8255_iobase; - int i; - int ret; - - ret = comedi_alloc_subdevices(dev, 10); - if (ret) - return ret; + unsigned int convert_divisor = 0, scan_divisor; + static const int min_convert_divisor = 3; + static const int max_convert_divisor = + max_counter_value + min_convert_divisor; + static const int min_scan_divisor_4020 = 2; + unsigned long long max_scan_divisor, min_scan_divisor; - s = &dev->subdevices[0]; - /* analog input subdevice */ - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; - if (thisboard->layout == LAYOUT_60XX) - s->subdev_flags |= SDF_COMMON | SDF_DIFF; - else if (thisboard->layout == LAYOUT_64XX) - s->subdev_flags |= SDF_DIFF; - /* XXX Number of inputs in differential mode is ignored */ - s->n_chan = thisboard->ai_se_chans; - s->len_chanlist = 0x2000; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_range_table; - s->insn_read = ai_rinsn; - s->insn_config = ai_config_insn; - s->do_cmd = ai_cmd; - s->do_cmdtest = ai_cmdtest; - s->cancel = ai_cancel; - if (thisboard->layout == LAYOUT_4020) { - uint8_t data; - /* set adc to read from inputs - * (not internal calibration sources) */ - devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); - /* set channels to +-5 volt input ranges */ - for (i = 0; i < s->n_chan; i++) - devpriv->i2c_cal_range_bits |= attenuate_bit(i); - data = devpriv->i2c_cal_range_bits; - i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); - } - - /* analog output subdevice */ - s = &dev->subdevices[1]; - if (thisboard->ao_nchan) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | - SDF_GROUND | SDF_CMD_WRITE; - s->n_chan = thisboard->ao_nchan; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_range_table; - s->insn_read = ao_readback_insn; - s->insn_write = ao_winsn; - if (ao_cmd_is_supported(thisboard)) { - dev->write_subdev = s; - s->do_cmdtest = ao_cmdtest; - s->do_cmd = ao_cmd; - s->len_chanlist = thisboard->ao_nchan; - s->cancel = ao_cancel; + if (cmd->convert_src == TRIG_TIMER) { + if (board(dev)->layout == LAYOUT_4020) { + cmd->convert_arg = 0; + } else { + convert_divisor = + get_divisor(cmd->convert_arg, cmd->flags); + if (convert_divisor > max_convert_divisor) + convert_divisor = max_convert_divisor; + if (convert_divisor < min_convert_divisor) + convert_divisor = min_convert_divisor; + cmd->convert_arg = convert_divisor * TIMER_BASE; } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* digital input */ - s = &dev->subdevices[2]; - if (thisboard->layout == LAYOUT_64XX) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = di_rbits; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* digital output */ - if (thisboard->layout == LAYOUT_64XX) { - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = do_wbits; - } else - s->type = COMEDI_SUBD_UNUSED; + } else if (cmd->convert_src == TRIG_NOW) + cmd->convert_arg = 0; - /* 8255 */ - s = &dev->subdevices[4]; - if (thisboard->has_8255) { - if (thisboard->layout == LAYOUT_4020) { - dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; - subdev_8255_init(dev, s, dio_callback_4020, - (unsigned long)dio_8255_iobase); + if (cmd->scan_begin_src == TRIG_TIMER) { + scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); + if (cmd->convert_src == TRIG_TIMER) { + /* XXX check for integer overflows */ + min_scan_divisor = convert_divisor * cmd->chanlist_len; + max_scan_divisor = + (convert_divisor * cmd->chanlist_len - 1) + + max_counter_value; } else { - dio_8255_iobase = - devpriv->dio_counter_iobase + DIO_8255_OFFSET; - subdev_8255_init(dev, s, dio_callback, - (unsigned long)dio_8255_iobase); + min_scan_divisor = min_scan_divisor_4020; + max_scan_divisor = max_counter_value + min_scan_divisor; } - } else - s->type = COMEDI_SUBD_UNUSED; - - /* 8 channel dio for 60xx */ - s = &dev->subdevices[5]; - if (thisboard->layout == LAYOUT_60XX) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = dio_60xx_config_insn; - s->insn_bits = dio_60xx_wbits; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* caldac */ - s = &dev->subdevices[6]; - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 8; - if (thisboard->layout == LAYOUT_4020) - s->maxdata = 0xfff; - else - s->maxdata = 0xff; - s->insn_read = calib_read_insn; - s->insn_write = calib_write_insn; - for (i = 0; i < s->n_chan; i++) - caldac_write(dev, i, s->maxdata / 2); - - /* 2 channel ad8402 potentiometer */ - s = &dev->subdevices[7]; - if (thisboard->layout == LAYOUT_64XX) { - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 2; - s->insn_read = ad8402_read_insn; - s->insn_write = ad8402_write_insn; - s->maxdata = 0xff; - for (i = 0; i < s->n_chan; i++) - ad8402_write(dev, i, s->maxdata / 2); - } else - s->type = COMEDI_SUBD_UNUSED; + if (scan_divisor > max_scan_divisor) + scan_divisor = max_scan_divisor; + if (scan_divisor < min_scan_divisor) + scan_divisor = min_scan_divisor; + cmd->scan_begin_arg = scan_divisor * TIMER_BASE; + } - /* serial EEPROM, if present */ - s = &dev->subdevices[8]; - if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 128; - s->maxdata = 0xffff; - s->insn_read = eeprom_read_insn; - } else - s->type = COMEDI_SUBD_UNUSED; + return; +} - /* user counter subd XXX */ - s = &dev->subdevices[9]; - s->type = COMEDI_SUBD_UNUSED; +/* Gets nearest achievable timing given master clock speed, does not + * take into account possible minimum/maximum divisor values. Used + * by other timing checking functions. */ +static unsigned int get_divisor(unsigned int ns, unsigned int flags) +{ + unsigned int divisor; - return 0; + switch (flags & TRIG_ROUND_MASK) { + case TRIG_ROUND_UP: + divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; + break; + case TRIG_ROUND_DOWN: + divisor = ns / TIMER_BASE; + break; + case TRIG_ROUND_NEAREST: + default: + divisor = (ns + TIMER_BASE / 2) / TIMER_BASE; + break; + } + return divisor; } -static const struct pcidas64_board -*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) +static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) { - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) - if (pcidev->device == pcidas64_boards[i].device_id) - return &pcidas64_boards[i]; - return NULL; + return get_divisor(ns, flags) - 2; } -static int __devinit auto_attach(struct comedi_device *dev, - unsigned long context_unused) +/* adjusts the size of hardware fifo (which determines block size for dma xfers) */ +static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) { - const struct pcidas64_board *thisboard; - struct pcidas64_private *devpriv; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - uint32_t local_range, local_decode; + unsigned int num_fifo_entries; int retval; + const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; - dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); - if (!dev->board_ptr) { - dev_err(dev->class_dev, - "cb_pcidas64: does not support pci %s\n", - pci_name(pcidev)); - return -EINVAL; - } - thisboard = comedi_board(dev); + num_fifo_entries = num_samples / fifo->sample_packing_ratio; - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; + retval = set_ai_fifo_segment_length(dev, + num_fifo_entries / + fifo->num_segments); + if (retval < 0) + return retval; - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_warn(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } - pci_set_master(pcidev); + num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; - /* Initialize dev->board_name */ - dev->board_name = thisboard->name; + DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); - dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); + return num_samples; +} - devpriv->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); - devpriv->main_phys_iobase = dev->iobase; - devpriv->dio_counter_phys_iobase = - pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); +/* query length of fifo */ +static unsigned int ai_fifo_size(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; - /* remap, won't work with 2.0 kernels but who cares */ - devpriv->plx9080_iobase = - ioremap(devpriv->plx9080_phys_iobase, - pci_resource_len(pcidev, PLX9080_BADDRINDEX)); - devpriv->main_iobase = - ioremap(devpriv->main_phys_iobase, - pci_resource_len(pcidev, MAIN_BADDRINDEX)); - devpriv->dio_counter_iobase = - ioremap(devpriv->dio_counter_phys_iobase, - pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); + return devpriv->ai_fifo_segment_length * + board(dev)->ai_fifo->num_segments * + board(dev)->ai_fifo->sample_packing_ratio; +} - if (!devpriv->plx9080_iobase || !devpriv->main_iobase - || !devpriv->dio_counter_iobase) { - dev_warn(dev->class_dev, "failed to remap io memory\n"); - return -ENOMEM; - } +static int set_ai_fifo_segment_length(struct comedi_device *dev, + unsigned int num_entries) +{ + struct pcidas64_private *devpriv = dev->private; + static const int increment_size = 0x100; + const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + unsigned int num_increments; + uint16_t bits; - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); - DEBUG_PRINT(" diocounter remapped to 0x%p\n", - devpriv->dio_counter_iobase); + if (num_entries < increment_size) + num_entries = increment_size; + if (num_entries > fifo->max_segment_length) + num_entries = fifo->max_segment_length; - /* figure out what local addresses are */ - local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & - LRNG_MEM_MASK; - local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & - local_range & LMAP_MEM_MASK; - devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & - ~local_range) | local_decode; - local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & - LRNG_MEM_MASK; - local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & - local_range & LMAP_MEM_MASK; - devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & - ~local_range) | local_decode; + /* 1 == 256 entries, 2 == 512 entries, etc */ + num_increments = (num_entries + increment_size / 2) / increment_size; - DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); + bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; + devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask; + devpriv->fifo_size_bits |= bits; + writew(devpriv->fifo_size_bits, + devpriv->main_iobase + FIFO_SIZE_REG); - retval = alloc_and_init_dma_members(dev); - if (retval < 0) - return retval; + devpriv->ai_fifo_segment_length = num_increments * increment_size; - devpriv->hw_revision = - hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); - dev_dbg(dev->class_dev, "stc hardware revision %i\n", - devpriv->hw_revision); - init_plx9080(dev); - init_stc_registers(dev); - /* get irq */ - if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - "cb_pcidas64", dev)) { - dev_dbg(dev->class_dev, "unable to allocate irq %u\n", - pcidev->irq); - return -EINVAL; - } - dev->irq = pcidev->irq; - dev_dbg(dev->class_dev, "irq %u\n", dev->irq); + DEBUG_PRINT("set hardware fifo segment length to %i\n", + devpriv->ai_fifo_segment_length); - retval = setup_subdevices(dev); - if (retval < 0) - return retval; + return devpriv->ai_fifo_segment_length; +} +/* pci-6025 8800 caldac: + * address 0 == dac channel 0 offset + * address 1 == dac channel 0 gain + * address 2 == dac channel 1 offset + * address 3 == dac channel 1 gain + * address 4 == fine adc offset + * address 5 == coarse adc offset + * address 6 == coarse adc gain + * address 7 == fine adc gain + */ +/* pci-6402/16 uses all 8 channels for dac: + * address 0 == dac channel 0 fine gain + * address 1 == dac channel 0 coarse gain + * address 2 == dac channel 0 coarse offset + * address 3 == dac channel 1 coarse offset + * address 4 == dac channel 1 fine gain + * address 5 == dac channel 1 coarse gain + * address 6 == dac channel 0 fine offset + * address 7 == dac channel 1 fine offset +*/ + +static int caldac_8800_write(struct comedi_device *dev, unsigned int address, + uint8_t value) +{ + struct pcidas64_private *devpriv = dev->private; + static const int num_caldac_channels = 8; + static const int bitstream_length = 11; + unsigned int bitstream = ((address & 0x7) << 8) | value; + unsigned int bit, register_bits; + static const int caldac_8800_udelay = 1; + + if (address >= num_caldac_channels) { + comedi_error(dev, "illegal caldac channel"); + return -1; + } + for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { + register_bits = 0; + if (bitstream & bit) + register_bits |= SERIAL_DATA_IN_BIT; + udelay(caldac_8800_udelay); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); + register_bits |= SERIAL_CLOCK_BIT; + udelay(caldac_8800_udelay); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); + } + udelay(caldac_8800_udelay); + writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG); + udelay(caldac_8800_udelay); + writew(0, devpriv->main_iobase + CALIBRATION_REG); + udelay(caldac_8800_udelay); return 0; } -static void detach(struct comedi_device *dev) +/* 4020 caldacs */ +static int caldac_i2c_write(struct comedi_device *dev, + unsigned int caldac_channel, unsigned int value) +{ + uint8_t serial_bytes[3]; + uint8_t i2c_addr; + enum pointer_bits { + /* manual has gain and offset bits switched */ + OFFSET_0_2 = 0x1, + GAIN_0_2 = 0x2, + OFFSET_1_3 = 0x4, + GAIN_1_3 = 0x8, + }; + enum data_bits { + NOT_CLEAR_REGISTERS = 0x20, + }; + + switch (caldac_channel) { + case 0: /* chan 0 offset */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = OFFSET_0_2; + break; + case 1: /* chan 1 offset */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = OFFSET_1_3; + break; + case 2: /* chan 2 offset */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = OFFSET_0_2; + break; + case 3: /* chan 3 offset */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = OFFSET_1_3; + break; + case 4: /* chan 0 gain */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = GAIN_0_2; + break; + case 5: /* chan 1 gain */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = GAIN_1_3; + break; + case 6: /* chan 2 gain */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = GAIN_0_2; + break; + case 7: /* chan 3 gain */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = GAIN_1_3; + break; + default: + comedi_error(dev, "invalid caldac channel\n"); + return -1; + break; + } + serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); + serial_bytes[2] = value & 0xff; + i2c_write(dev, i2c_addr, serial_bytes, 3); + return 0; +} + +/* Their i2c requires a huge delay on setting clock or data high for some reason */ +static const int i2c_high_udelay = 1000; +static const int i2c_low_udelay = 10; + +/* set i2c data line high or low */ +static void i2c_set_sda(struct comedi_device *dev, int state) +{ + struct pcidas64_private *devpriv = dev->private; + static const int data_bit = CTL_EE_W; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; + + if (state) { + /* set data line high */ + devpriv->plx_control_bits &= ~data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_high_udelay); + } else { /* set data line low */ + + devpriv->plx_control_bits |= data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_low_udelay); + } +} + +/* set i2c clock line high or low */ +static void i2c_set_scl(struct comedi_device *dev, int state) +{ + struct pcidas64_private *devpriv = dev->private; + static const int clock_bit = CTL_USERO; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; + + if (state) { + /* set clock line high */ + devpriv->plx_control_bits &= ~clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_high_udelay); + } else { /* set clock line low */ + + devpriv->plx_control_bits |= clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_low_udelay); + } +} + +static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) +{ + uint8_t bit; + unsigned int num_bits = 8; + + DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); + + for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { + i2c_set_scl(dev, 0); + if ((byte & bit)) + i2c_set_sda(dev, 1); + else + i2c_set_sda(dev, 0); + i2c_set_scl(dev, 1); + } +} + +/* we can't really read the lines, so fake it */ +static int i2c_read_ack(struct comedi_device *dev) +{ + i2c_set_scl(dev, 0); + i2c_set_sda(dev, 1); + i2c_set_scl(dev, 1); + + return 0; /* return fake acknowledge bit */ +} + +/* send start bit */ +static void i2c_start(struct comedi_device *dev) +{ + i2c_set_scl(dev, 1); + i2c_set_sda(dev, 1); + i2c_set_sda(dev, 0); +} + +/* send stop bit */ +static void i2c_stop(struct comedi_device *dev) +{ + i2c_set_scl(dev, 0); + i2c_set_sda(dev, 0); + i2c_set_scl(dev, 1); + i2c_set_sda(dev, 1); +} + +static void i2c_write(struct comedi_device *dev, unsigned int address, + const uint8_t *data, unsigned int length) { - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pcidas64_private *devpriv = dev->private; unsigned int i; + uint8_t bitstream; + static const int read_bit = 0x1; - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (pcidev) { - if (devpriv->plx9080_iobase) { - disable_plx_interrupts(dev); - iounmap(devpriv->plx9080_iobase); - } - if (devpriv->main_iobase) - iounmap(devpriv->main_iobase); - if (devpriv->dio_counter_iobase) - iounmap(devpriv->dio_counter_iobase); - /* free pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(thisboard); i++) { - if (devpriv->ai_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - devpriv->ai_buffer[i], - devpriv->ai_buffer_bus_addr[i]); - } - for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (devpriv->ao_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - devpriv->ao_buffer[i], - devpriv->ao_buffer_bus_addr[i]); - } - /* free dma descriptors */ - if (devpriv->ai_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - ai_dma_ring_count(thisboard), - devpriv->ai_dma_desc, - devpriv->ai_dma_desc_bus_addr); - if (devpriv->ao_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - AO_DMA_RING_COUNT, - devpriv->ao_dma_desc, - devpriv->ao_dma_desc_bus_addr); - } +/* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */ + + /* make sure we dont send anything to eeprom */ + devpriv->plx_control_bits &= ~CTL_EE_CS; + + i2c_stop(dev); + i2c_start(dev); + + /* send address and write bit */ + bitstream = (address << 1) & ~read_bit; + i2c_write_byte(dev, bitstream); + + /* get acknowledge */ + if (i2c_read_ack(dev) != 0) { + comedi_error(dev, "i2c write failed: no acknowledge"); + i2c_stop(dev); + return; } - if (dev->subdevices) - subdev_8255_cleanup(dev, &dev->subdevices[4]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + /* write data bytes */ + for (i = 0; i < length; i++) { + i2c_write_byte(dev, data[i]); + if (i2c_read_ack(dev) != 0) { + comedi_error(dev, "i2c write failed: no acknowledge"); + i2c_stop(dev); + return; + } } + i2c_stop(dev); } static struct comedi_driver cb_pcidas64_driver = { .driver_name = "cb_pcidas64", .module = THIS_MODULE, - .auto_attach = auto_attach, + .attach = attach, .detach = detach, }; diff --git a/trunk/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/trunk/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c index 9a3528599f3c..7c13df295c11 100644 --- a/trunk/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c +++ b/trunk/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -10,32 +10,37 @@ #include "csr_wifi_hip_unifi.h" -struct sig_name { - s16 id; - const char *name; +struct sig_name +{ + s16 id; + const char *name; }; static const struct sig_name Unifi_bulkcmd_names[] = { - { 0, "SignalCmd" }, - { 1, "CopyToHost" }, - { 2, "CopyToHostAck" }, - { 3, "CopyFromHost" }, - { 4, "CopyFromHostAck" }, - { 5, "ClearSlot" }, - { 6, "CopyOverlay" }, - { 7, "CopyOverlayAck" }, - { 8, "CopyFromHostAndClearSlot" }, - { 15, "Padding" } + { 0, "SignalCmd" }, + { 1, "CopyToHost" }, + { 2, "CopyToHostAck" }, + { 3, "CopyFromHost" }, + { 4, "CopyFromHostAck" }, + { 5, "ClearSlot" }, + { 6, "CopyOverlay" }, + { 7, "CopyOverlayAck" }, + { 8, "CopyFromHostAndClearSlot" }, + { 15, "Padding" } }; -const char *lookup_bulkcmd_name(u16 id) +const char* lookup_bulkcmd_name(u16 id) { - if (id < 9) - return Unifi_bulkcmd_names[id].name; - if (id == 15) - return "Padding"; - - return "UNKNOWN"; + if (id < 9) + { + return Unifi_bulkcmd_names[id].name; + } + if (id == 15) + { + return "Padding"; + } + + return "UNKNOWN"; } diff --git a/trunk/drivers/staging/iio/adc/ad7887.h b/trunk/drivers/staging/iio/adc/ad7887.h index 2e09e54fc9c5..71e50925e066 100644 --- a/trunk/drivers/staging/iio/adc/ad7887.h +++ b/trunk/drivers/staging/iio/adc/ad7887.h @@ -72,9 +72,11 @@ struct ad7887_state { /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. + * Buffer needs to be large enough to hold two 16 bit samples and a + * 64 bit aligned 64 bit timestamp. */ - - unsigned char data[4] ____cacheline_aligned; + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; }; enum ad7887_supported_device_ids { diff --git a/trunk/drivers/staging/iio/adc/ad7887_ring.c b/trunk/drivers/staging/iio/adc/ad7887_ring.c index b39923bbeedc..f11925e62cdc 100644 --- a/trunk/drivers/staging/iio/adc/ad7887_ring.c +++ b/trunk/drivers/staging/iio/adc/ad7887_ring.c @@ -73,31 +73,20 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct ad7887_state *st = iio_priv(indio_dev); s64 time_ns; - __u8 *buf; int b_sent; - unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (buf == NULL) - goto done; - b_sent = spi_sync(st->spi, st->ring_msg); if (b_sent) goto done; time_ns = iio_get_time_ns(); - memcpy(buf, st->data, bytes); if (indio_dev->scan_timestamp) - memcpy(buf + indio_dev->scan_bytes - sizeof(s64), + memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, buf); + iio_push_to_buffer(indio_dev->buffer, st->data); done: - kfree(buf); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 035c2c762537..d6ce2182e672 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -3719,9 +3719,7 @@ int iscsi_target_tx_thread(void *arg) */ iscsit_thread_check_cpumask(conn, current, 1); - wait_event_interruptible(conn->queues_wq, - !iscsit_conn_all_queues_empty(conn) || - ts->status == ISCSI_THREAD_SET_RESET); + schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); if ((ts->status == ISCSI_THREAD_SET_RESET) || signal_pending(current)) diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index 21048dbf7d13..2ba9f9b9435c 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -486,7 +486,6 @@ struct iscsi_tmr_req { }; struct iscsi_conn { - wait_queue_head_t queues_wq; /* Authentication Successful for this connection */ u8 auth_complete; /* State connection is currently in */ diff --git a/trunk/drivers/target/iscsi/iscsi_target_login.c b/trunk/drivers/target/iscsi/iscsi_target_login.c index f8dbec05d5e5..cdc8a10939c3 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_login.c +++ b/trunk/drivers/target/iscsi/iscsi_target_login.c @@ -41,7 +41,6 @@ static int iscsi_login_init_conn(struct iscsi_conn *conn) { - init_waitqueue_head(&conn->queues_wq); INIT_LIST_HEAD(&conn->conn_list); INIT_LIST_HEAD(&conn->conn_cmd_list); INIT_LIST_HEAD(&conn->immed_queue_list); diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.c b/trunk/drivers/target/iscsi/iscsi_target_util.c index 1a91195ab619..afd98ccd40ae 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.c +++ b/trunk/drivers/target/iscsi/iscsi_target_util.c @@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( atomic_set(&conn->check_immediate_queue, 1); spin_unlock_bh(&conn->immed_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) @@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( atomic_inc(&cmd->response_queue_count); spin_unlock_bh(&conn->response_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) @@ -616,24 +616,6 @@ static void iscsit_remove_cmd_from_response_queue( } } -bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) -{ - bool empty; - - spin_lock_bh(&conn->immed_queue_lock); - empty = list_empty(&conn->immed_queue_list); - spin_unlock_bh(&conn->immed_queue_lock); - - if (!empty) - return empty; - - spin_lock_bh(&conn->response_queue_lock); - empty = list_empty(&conn->response_queue_list); - spin_unlock_bh(&conn->response_queue_lock); - - return empty; -} - void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.h b/trunk/drivers/target/iscsi/iscsi_target_util.h index 894d0f837924..44054bd35437 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.h +++ b/trunk/drivers/target/iscsi/iscsi_target_util.h @@ -25,7 +25,6 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); -extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); extern void iscsit_release_cmd(struct iscsi_cmd *); extern void iscsit_free_cmd(struct iscsi_cmd *); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index c123327499a3..015f5be27bf6 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -3206,8 +3206,7 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out; - ret = core_dev_setup_virtual_lun0(); - if (ret < 0) + if (core_dev_setup_virtual_lun0() < 0) goto out; return 0; diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 9abef9f8eb76..8d774da16320 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) { - u32 aligned_max_sectors; - u32 alignment; + u32 tmp, aligned_max_sectors; /* * Limit max_sectors to a PAGE_SIZE aligned value for modern * transport_allocate_data_tasks() operation. */ - alignment = max(1ul, PAGE_SIZE / block_size); - aligned_max_sectors = rounddown(max_sectors, alignment); - - if (max_sectors != aligned_max_sectors) - pr_info("Rounding down aligned max_sectors from %u to %u\n", - max_sectors, aligned_max_sectors); + tmp = rounddown((max_sectors * block_size), PAGE_SIZE); + aligned_max_sectors = (tmp / block_size); + if (max_sectors != aligned_max_sectors) { + printk(KERN_INFO "Rounding down aligned max_sectors from %u" + " to %u\n", max_sectors, aligned_max_sectors); + return aligned_max_sectors; + } - return aligned_max_sectors; + return max_sectors; } void se_dev_set_default_attribs( diff --git a/trunk/drivers/target/target_core_sbc.c b/trunk/drivers/target/target_core_sbc.c index a6e27d967c7b..868f8aa04f13 100644 --- a/trunk/drivers/target/target_core_sbc.c +++ b/trunk/drivers/target/target_core_sbc.c @@ -135,12 +135,6 @@ static int sbc_emulate_verify(struct se_cmd *cmd) return 0; } -static int sbc_emulate_noop(struct se_cmd *cmd) -{ - target_complete_cmd(cmd, GOOD); - return 0; -} - static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors) { return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; @@ -537,18 +531,6 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops) size = 0; cmd->execute_cmd = sbc_emulate_verify; break; - case REZERO_UNIT: - case SEEK_6: - case SEEK_10: - /* - * There are still clients out there which use these old SCSI-2 - * commands. This mainly happens when running VMs with legacy - * guest systems, connected via SCSI command pass-through to - * iSCSI targets. Make them happy and return status GOOD. - */ - size = 0; - cmd->execute_cmd = sbc_emulate_noop; - break; default: ret = spc_parse_cdb(cmd, &size); if (ret) diff --git a/trunk/drivers/target/target_core_spc.c b/trunk/drivers/target/target_core_spc.c index 6fd434d3d7e4..9229bd9ad61b 100644 --- a/trunk/drivers/target/target_core_spc.c +++ b/trunk/drivers/target/target_core_spc.c @@ -605,8 +605,6 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) unsigned char buf[SE_INQUIRY_BUF]; int p, ret; - memset(buf, 0, SE_INQUIRY_BUF); - if (dev == tpg->tpg_virt_lun0.lun_se_dev) buf[0] = 0x3f; /* Not connected */ else diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index be75c4331a92..1c59a3c23b2c 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -140,15 +140,15 @@ void core_tmr_abort_task( printk("ABORT_TASK: Found referenced %s task_tag: %u\n", se_cmd->se_tfo->get_fabric_name(), ref_tag); - spin_lock(&se_cmd->t_state_lock); + spin_lock_irq(&se_cmd->t_state_lock); if (se_cmd->transport_state & CMD_T_COMPLETE) { printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); goto out; } se_cmd->transport_state |= CMD_T_ABORTED; - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); list_del_init(&se_cmd->se_cmd_list); kref_get(&se_cmd->cmd_kref); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 9097155e9ebe..c33baff86aa6 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1616,6 +1616,7 @@ static void target_complete_tmr_failure(struct work_struct *work) se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; se_cmd->se_tfo->queue_tm_rsp(se_cmd); + transport_generic_free_cmd(se_cmd, 0); } /** diff --git a/trunk/drivers/thermal/exynos_thermal.c b/trunk/drivers/thermal/exynos_thermal.c index 6dd29e4ce36b..fd03e8581afc 100644 --- a/trunk/drivers/thermal/exynos_thermal.c +++ b/trunk/drivers/thermal/exynos_thermal.c @@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = { }, { }, }; -MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids); +MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids); static inline struct exynos_tmu_platform_data *exynos_get_driver_data( struct platform_device *pdev) diff --git a/trunk/drivers/thermal/rcar_thermal.c b/trunk/drivers/thermal/rcar_thermal.c index f7a1b574a304..d4452716aaab 100644 --- a/trunk/drivers/thermal/rcar_thermal.c +++ b/trunk/drivers/thermal/rcar_thermal.c @@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_free_priv; } - zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, + zone = thermal_zone_device_register("rcar_thermal", 0, priv, &rcar_thermal_zone_ops, 0, 0); if (IS_ERR(zone)) { dev_err(&pdev->dev, "thermal zone device is NULL\n"); diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index 4ec3c0d7a18b..6458764994ef 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "u_ether.h" @@ -296,7 +295,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); diff --git a/trunk/drivers/video/xen-fbfront.c b/trunk/drivers/video/xen-fbfront.c index 917bb5681684..b7f5173ff9e9 100644 --- a/trunk/drivers/video/xen-fbfront.c +++ b/trunk/drivers/video/xen-fbfront.c @@ -641,6 +641,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -669,10 +670,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, info->feature_resize = val; break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index 809b0de59c09..1e8659ca27ef 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -225,10 +225,8 @@ EXPORT_SYMBOL_GPL(register_virtio_device); void unregister_virtio_device(struct virtio_device *dev) { - int index = dev->index; /* save for after device release */ - device_unregister(&dev->dev); - ida_simple_remove(&virtio_index_ida, index); + ida_simple_remove(&virtio_index_ida, dev->index); } EXPORT_SYMBOL_GPL(unregister_virtio_device); diff --git a/trunk/drivers/xen/Makefile b/trunk/drivers/xen/Makefile index 74354708c6c4..0e8637035457 100644 --- a/trunk/drivers/xen/Makefile +++ b/trunk/drivers/xen/Makefile @@ -2,7 +2,6 @@ ifneq ($(CONFIG_ARM),y) obj-y += manage.o balloon.o obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o endif -obj-$(CONFIG_X86) += fallback.o obj-y += grant-table.o features.o events.o obj-y += xenbus/ diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 0be4df39e953..912ac81b6dbf 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -1395,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - irq_enter(); #ifdef CONFIG_X86 exit_idle(); #endif + irq_enter(); __xen_evtchn_do_upcall(); diff --git a/trunk/drivers/xen/fallback.c b/trunk/drivers/xen/fallback.c deleted file mode 100644 index 0ef7c4d40f86..000000000000 --- a/trunk/drivers/xen/fallback.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int xen_event_channel_op_compat(int cmd, void *arg) -{ - struct evtchn_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, event_channel_op_compat, &op); - - switch (cmd) { - case EVTCHNOP_close: - case EVTCHNOP_send: - case EVTCHNOP_bind_vcpu: - case EVTCHNOP_unmask: - /* no output */ - break; - -#define COPY_BACK(eop) \ - case EVTCHNOP_##eop: \ - memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ - break - - COPY_BACK(bind_interdomain); - COPY_BACK(bind_virq); - COPY_BACK(bind_pirq); - COPY_BACK(status); - COPY_BACK(alloc_unbound); - COPY_BACK(bind_ipi); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} -EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); - -int HYPERVISOR_physdev_op_compat(int cmd, void *arg) -{ - struct physdev_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, physdev_op_compat, &op); - - switch (cmd) { - case PHYSDEVOP_IRQ_UNMASK_NOTIFY: - case PHYSDEVOP_set_iopl: - case PHYSDEVOP_set_iobitmap: - case PHYSDEVOP_apic_write: - /* no output */ - break; - -#define COPY_BACK(pop, fld) \ - case PHYSDEVOP_##pop: \ - memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ - break - - COPY_BACK(irq_status_query, irq_status_query); - COPY_BACK(apic_read, apic_op); - COPY_BACK(ASSIGN_VECTOR, irq_op); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 2e22df2f7a3f..610bfc6be177 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -105,21 +105,6 @@ static void gntdev_print_maps(struct gntdev_priv *priv, #endif } -static void gntdev_free_map(struct grant_map *map) -{ - if (map == NULL) - return; - - if (map->pages) - free_xenballooned_pages(map->count, map->pages); - kfree(map->pages); - kfree(map->grants); - kfree(map->map_ops); - kfree(map->unmap_ops); - kfree(map->kmap_ops); - kfree(map); -} - static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) { struct grant_map *add; @@ -157,7 +142,12 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) return add; err: - gntdev_free_map(add); + kfree(add->pages); + kfree(add->grants); + kfree(add->map_ops); + kfree(add->unmap_ops); + kfree(add->kmap_ops); + kfree(add); return NULL; } @@ -208,9 +198,17 @@ static void gntdev_put_map(struct grant_map *map) evtchn_put(map->notify.event); } - if (map->pages && !use_ptemod) - unmap_grant_pages(map, 0, map->count); - gntdev_free_map(map); + if (map->pages) { + if (!use_ptemod) + unmap_grant_pages(map, 0, map->count); + + free_xenballooned_pages(map->count, map->pages); + } + kfree(map->pages); + kfree(map->grants); + kfree(map->map_ops); + kfree(map->unmap_ops); + kfree(map); } /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c index ac727028e658..89f76252a16f 100644 --- a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, goto out; /* Can't write a xenbus message larger we can buffer */ - if (len > sizeof(u->u.buffer) - u->len) { + if ((len + u->len) > sizeof(u->u.buffer)) { /* On error, dump existing buffer */ u->len = 0; rc = -EINVAL; diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index b96fc6ce4855..9298c65ad9c7 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -75,7 +75,6 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) unsigned int sz = sizeof(struct bio) + extra_size; struct kmem_cache *slab = NULL; struct bio_slab *bslab, *new_bio_slabs; - unsigned int new_bio_slab_max; unsigned int i, entry = -1; mutex_lock(&bio_slab_lock); @@ -98,13 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) goto out_unlock; if (bio_slab_nr == bio_slab_max && entry == -1) { - new_bio_slab_max = bio_slab_max << 1; + bio_slab_max <<= 1; new_bio_slabs = krealloc(bio_slabs, - new_bio_slab_max * sizeof(struct bio_slab), + bio_slab_max * sizeof(struct bio_slab), GFP_KERNEL); if (!new_bio_slabs) goto out_unlock; - bio_slab_max = new_bio_slab_max; bio_slabs = new_bio_slabs; } if (entry == -1) diff --git a/trunk/fs/ceph/export.c b/trunk/fs/ceph/export.c index 9349bb37a2fe..02ce90972d81 100644 --- a/trunk/fs/ceph/export.c +++ b/trunk/fs/ceph/export.c @@ -90,8 +90,6 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, *max_len = handle_length; type = 255; } - if (dentry) - dput(dentry); return type; } diff --git a/trunk/fs/cifs/cifsacl.c b/trunk/fs/cifs/cifsacl.c index 0fb15bbbe43c..fc783e264420 100644 --- a/trunk/fs/cifs/cifsacl.c +++ b/trunk/fs/cifs/cifsacl.c @@ -224,13 +224,6 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) } } -static void -cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) -{ - memcpy(dst, src, sizeof(*dst)); - dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); -} - static void id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, struct cifs_sid_id **psidid, char *typestr) @@ -255,7 +248,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, } } - cifs_copy_sid(&(*psidid)->sid, sidptr); + memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); (*psidid)->refcount = 0; @@ -361,7 +354,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) * any fields of the node after a reference is put . */ if (test_bit(SID_ID_MAPPED, &psidid->state)) { - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); psidid->time = jiffies; /* update ts for accessing */ goto id_sid_out; } @@ -377,14 +370,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) if (IS_ERR(sidkey)) { rc = -EINVAL; cFYI(1, "%s: Can't map and id to a SID", __func__); - } else if (sidkey->datalen < sizeof(struct cifs_sid)) { - rc = -EIO; - cFYI(1, "%s: Downcall contained malformed key " - "(datalen=%hu)", __func__, sidkey->datalen); } else { lsid = (struct cifs_sid *)sidkey->payload.data; - cifs_copy_sid(&psidid->sid, lsid); - cifs_copy_sid(ssid, &psidid->sid); + memcpy(&psidid->sid, lsid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); + memcpy(ssid, &psidid->sid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); set_bit(SID_ID_MAPPED, &psidid->state); key_put(sidkey); kfree(psidid->sidstr); @@ -403,7 +396,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) return rc; } if (test_bit(SID_ID_MAPPED, &psidid->state)) - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); else rc = -EINVAL; } @@ -682,6 +675,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) static void copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, __u32 sidsoffset) { + int i; + struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; @@ -697,14 +692,26 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); - cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + nowner_sid_ptr->revision = owner_sid_ptr->revision; + nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; /* copy group sid */ group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + sizeof(struct cifs_sid)); - cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + + ngroup_sid_ptr->revision = group_sid_ptr->revision; + ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; return; } @@ -1113,7 +1120,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(nowner_sid_ptr); return rc; } - cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); + memcpy(owner_sid_ptr, nowner_sid_ptr, + sizeof(struct cifs_sid)); kfree(nowner_sid_ptr); *aclflag = CIFS_ACL_OWNER; } @@ -1131,7 +1139,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(ngroup_sid_ptr); return rc; } - cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); + memcpy(group_sid_ptr, ngroup_sid_ptr, + sizeof(struct cifs_sid)); kfree(ngroup_sid_ptr); *aclflag = CIFS_ACL_GROUP; } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index d3671f2acb29..7c0a81283645 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -398,16 +398,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, * in network traffic in the other paths. */ if (!(oflags & O_CREAT)) { - struct dentry *res; - - /* - * Check for hashed negative dentry. We have already revalidated - * the dentry and it is fine. No need to perform another lookup. - */ - if (!d_unhashed(direntry)) - return -ENOENT; - - res = cifs_lookup(inode, direntry, 0); + struct dentry *res = cifs_lookup(inode, direntry, 0); if (IS_ERR(res)) return PTR_ERR(res); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index cd96649bfe62..da72250ddc1c 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p) /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ static inline int ep_op_has_event(int op) { - return op != EPOLL_CTL_DEL; + return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD; } /* Initialize the poll safe wake up structure */ @@ -676,6 +676,34 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) return 0; } +/* + * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item + * had no event flags set, indicating that another thread may be currently + * handling that item's events (in the case that EPOLLONESHOT was being + * used). Otherwise a zero result indicates that the item has been disabled + * from receiving events. A disabled item may be re-enabled via + * EPOLL_CTL_MOD. Must be called with "mtx" held. + */ +static int ep_disable(struct eventpoll *ep, struct epitem *epi) +{ + int result = 0; + unsigned long flags; + + spin_lock_irqsave(&ep->lock, flags); + if (epi->event.events & ~EP_PRIVATE_BITS) { + if (ep_is_linked(&epi->rdllink)) + list_del_init(&epi->rdllink); + /* Ensure ep_poll_callback will not add epi back onto ready + list: */ + epi->event.events &= EP_PRIVATE_BITS; + } + else + result = -EBUSY; + spin_unlock_irqrestore(&ep->lock, flags); + + return result; +} + static void ep_free(struct eventpoll *ep) { struct rb_node *rbp; @@ -1020,8 +1048,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) rb_insert_color(&epi->rbn, &ep->rbr); } - - #define PATH_ARR_SIZE 5 /* * These are the number paths of length 1 to 5, that we are allowing to emanate @@ -1787,6 +1813,12 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, } else error = -ENOENT; break; + case EPOLL_CTL_DISABLE: + if (epi) + error = ep_disable(ep, epi); + else + error = -ENOENT; + break; } mutex_unlock(&ep->mtx); diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index 3a100e7a62a8..4facdd29a350 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -725,10 +725,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, "inode=%lu", ino + 1); continue; } - BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); - err = ext4_journal_get_write_access(handle, inode_bitmap_bh); - if (err) - goto fail; ext4_lock_group(sb, group); ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); ext4_unlock_group(sb, group); @@ -742,11 +738,6 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, goto out; got: - BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); - err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); - if (err) - goto fail; - /* We may have to initialize the block bitmap if it isn't already */ if (ext4_has_group_desc_csum(sb) && gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { @@ -780,6 +771,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, goto fail; } + BUFFER_TRACE(inode_bitmap_bh, "get_write_access"); + err = ext4_journal_get_write_access(handle, inode_bitmap_bh); + if (err) + goto fail; + BUFFER_TRACE(group_desc_bh, "get_write_access"); err = ext4_journal_get_write_access(handle, group_desc_bh); if (err) @@ -827,6 +823,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode, } ext4_unlock_group(sb, group); + BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata"); + err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh); + if (err) + goto fail; + BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata"); err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh); if (err) diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 708d997a7748..d3b5fa80b71b 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -900,7 +900,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) return __close_fd(files, fd); if (fd >= rlimit(RLIMIT_NOFILE)) - return -EBADF; + return -EMFILE; spin_lock(&files->file_lock); err = expand_files(files, fd); @@ -926,7 +926,7 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) return -EINVAL; if (newfd >= rlimit(RLIMIT_NOFILE)) - return -EBADF; + return -EMFILE; spin_lock(&files->file_lock); err = expand_files(files, newfd); diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index e056b4ce4877..0def0504afc1 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -516,13 +516,15 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) struct gfs2_holder i_gh; int error; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + error = gfs2_glock_nq(&i_gh); + if (error == 0) { + file_accessed(file); + gfs2_glock_dq(&i_gh); + } + gfs2_holder_uninit(&i_gh); if (error) return error; - /* grab lock to update inode */ - gfs2_glock_dq_uninit(&i_gh); - file_accessed(file); } vma->vm_ops = &gfs2_vm_ops; @@ -675,8 +677,10 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, size_t writesize = iov_length(iov, nr_segs); struct dentry *dentry = file->f_dentry; struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + struct gfs2_sbd *sdp; int ret; + sdp = GFS2_SB(file->f_mapping->host); ret = gfs2_rs_alloc(ip); if (ret) return ret; diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index 9ceccb1595a3..8ff95a2d54ee 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -393,10 +393,12 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct gfs2_meta_header *mh; struct gfs2_trans *tr; + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); tr = current->journal_info; tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; @@ -412,6 +414,9 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) sdp->sd_log_num_buf++; list_add(&bd->bd_list, &sdp->sd_log_le_buf); tr->tr_num_buf_new++; +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } static void gfs2_check_magic(struct buffer_head *bh) @@ -616,6 +621,7 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) static void revoke_lo_before_commit(struct gfs2_sbd *sdp) { + struct gfs2_log_descriptor *ld; struct gfs2_meta_header *mh; unsigned int offset; struct list_head *head = &sdp->sd_log_le_revoke; @@ -628,6 +634,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64)); page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke); + ld = page_address(page); offset = sizeof(struct gfs2_log_descriptor); list_for_each_entry(bd, head, bd_list) { @@ -770,10 +777,12 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct address_space *mapping = bd->bd_bh->b_page->mapping; struct gfs2_inode *ip = GFS2_I(mapping->host); + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); if (tr) tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); if (gfs2_is_jdata(ip)) { @@ -784,6 +793,9 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) } else { list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); } +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } /** diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index c5af8e18f27a..40c4b0d42fa8 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -497,11 +497,8 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) struct gfs2_quota_data **qd; int error; - if (ip->i_res == NULL) { - error = gfs2_rs_alloc(ip); - if (error) - return error; - } + if (ip->i_res == NULL) + gfs2_rs_alloc(ip); qd = ip->i_res->rs_qa_qd; diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 38fe18f2f055..3cc402ce6fea 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -553,6 +553,7 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) */ int gfs2_rs_alloc(struct gfs2_inode *ip) { + int error = 0; struct gfs2_blkreserv *res; if (ip->i_res) @@ -560,7 +561,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); if (!res) - return -ENOMEM; + error = -ENOMEM; RB_CLEAR_NODE(&res->rs_node); @@ -570,7 +571,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) else ip->i_res = res; up_write(&ip->i_rw_mutex); - return 0; + return error; } static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) @@ -1262,9 +1263,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) int ret = 0; u64 amt; u64 trimmed = 0; - u64 start, end, minlen; unsigned int x; - unsigned bs_shift = sdp->sd_sb.sb_bsize_shift; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1272,25 +1271,19 @@ int gfs2_fitrim(struct file *filp, void __user *argp) if (!blk_queue_discard(q)) return -EOPNOTSUPP; - if (copy_from_user(&r, argp, sizeof(r))) + if (argp == NULL) { + r.start = 0; + r.len = ULLONG_MAX; + r.minlen = 0; + } else if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; ret = gfs2_rindex_update(sdp); if (ret) return ret; - start = r.start >> bs_shift; - end = start + (r.len >> bs_shift); - minlen = max_t(u64, r.minlen, - q->limits.discard_granularity) >> bs_shift; - - rgd = gfs2_blk2rgrpd(sdp, start, 0); - rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); - - if (end <= start || - minlen > sdp->sd_max_rg_data || - start > rgd_end->rd_data0 + rgd_end->rd_data) - return -EINVAL; + rgd = gfs2_blk2rgrpd(sdp, r.start, 0); + rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); while (1) { @@ -1302,9 +1295,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) /* Trim each bitmap in the rgrp */ for (x = 0; x < rgd->rd_length; x++) { struct gfs2_bitmap *bi = rgd->rd_bits + x; - ret = gfs2_rgrp_send_discards(sdp, - rgd->rd_data0, NULL, bi, minlen, - &amt); + ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); if (ret) { gfs2_glock_dq_uninit(&gh); goto out; @@ -1333,7 +1324,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) out: r.len = trimmed << 9; - if (copy_to_user(argp, &r, sizeof(r))) + if (argp && copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return ret; diff --git a/trunk/fs/gfs2/super.c b/trunk/fs/gfs2/super.c index d6488674d916..bc737261f234 100644 --- a/trunk/fs/gfs2/super.c +++ b/trunk/fs/gfs2/super.c @@ -810,8 +810,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) return; } need_unlock = 1; - } else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE)) - return; + } if (current->journal_info == NULL) { ret = gfs2_trans_begin(sdp, RES_DINODE, 0); diff --git a/trunk/fs/gfs2/trans.c b/trunk/fs/gfs2/trans.c index 413627072f36..adbd27875ef9 100644 --- a/trunk/fs/gfs2/trans.c +++ b/trunk/fs/gfs2/trans.c @@ -155,22 +155,14 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_bufdata *bd; - lock_buffer(bh); - gfs2_log_lock(sdp); bd = bh->b_private; if (bd) gfs2_assert(sdp, bd->bd_gl == gl); else { - gfs2_log_unlock(sdp); - unlock_buffer(bh); gfs2_attach_bufdata(gl, bh, meta); bd = bh->b_private; - lock_buffer(bh); - gfs2_log_lock(sdp); } lops_add(sdp, bd); - gfs2_log_unlock(sdp); - unlock_buffer(bh); } void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) diff --git a/trunk/fs/nfs/dns_resolve.c b/trunk/fs/nfs/dns_resolve.c index ca4b11ec87a2..31c26c4dcc23 100644 --- a/trunk/fs/nfs/dns_resolve.c +++ b/trunk/fs/nfs/dns_resolve.c @@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) { char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; struct nfs_dns_ent key, *item; - unsigned int ttl; + unsigned long ttl; ssize_t len; int ret = -EINVAL; @@ -240,8 +240,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) key.namelen = len; memset(&key.h, 0, sizeof(key.h)); - if (get_uint(&buf, &ttl) < 0) - goto out; + ttl = get_expiry(&buf); if (ttl == 0) goto out; key.h.expiry_time = ttl + seconds_since_boot(); diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 6fa01aea2488..5c7325c5c5e6 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -685,10 +685,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) if (ctx->cred != NULL) put_rpccred(ctx->cred); dput(ctx->dentry); - if (is_sync) - nfs_sb_deactive(sb); - else - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(ctx->mdsthreshold); kfree(ctx); } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 05521cadac2e..59b133c5d652 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -351,12 +351,10 @@ extern int __init register_nfs_fs(void); extern void __exit unregister_nfs_fs(void); extern void nfs_sb_active(struct super_block *sb); extern void nfs_sb_deactive(struct super_block *sb); -extern void nfs_sb_deactive_async(struct super_block *sb); /* namespace.c */ -#define NFS_PATH_CANONICAL 1 extern char *nfs_path(char **p, struct dentry *dentry, - char *buffer, ssize_t buflen, unsigned flags); + char *buffer, ssize_t buflen); extern struct vfsmount *nfs_d_automount(struct path *path); struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, struct nfs_fh *, struct nfs_fattr *); @@ -500,7 +498,7 @@ static inline char *nfs_devname(struct dentry *dentry, char *buffer, ssize_t buflen) { char *dummy; - return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); + return nfs_path(&dummy, dentry, buffer, buflen); } /* diff --git a/trunk/fs/nfs/mount_clnt.c b/trunk/fs/nfs/mount_clnt.c index 015f71f8f62c..8e65c7f1f87c 100644 --- a/trunk/fs/nfs/mount_clnt.c +++ b/trunk/fs/nfs/mount_clnt.c @@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) else msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; - status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); + status = rpc_call_sync(mnt_clnt, &msg, 0); rpc_shutdown_client(mnt_clnt); if (status < 0) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index dd057bc6b65b..655925373b91 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -33,7 +33,6 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * @dentry - pointer to dentry * @buffer - result buffer * @buflen - length of buffer - * @flags - options (see below) * * Helper function for constructing the server pathname * by arbitrary hashed dentry. @@ -41,14 +40,8 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * This is mainly for use in figuring out the path on the * server side when automounting on top of an existing partition * and in generating /proc/mounts and friends. - * - * Supported flags: - * NFS_PATH_CANONICAL: ensure there is exactly one slash after - * the original device (export) name - * (if unset, the original name is returned verbatim) */ -char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, - unsigned flags) +char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) { char *end; int namelen; @@ -81,7 +74,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, rcu_read_unlock(); goto rename_retry; } - if ((flags & NFS_PATH_CANONICAL) && *end != '/') { + if (*end != '/') { if (--buflen < 0) { spin_unlock(&dentry->d_lock); rcu_read_unlock(); @@ -98,11 +91,9 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, return end; } namelen = strlen(base); - if (flags & NFS_PATH_CANONICAL) { - /* Strip off excess slashes in base string */ - while (namelen > 0 && base[namelen - 1] == '/') - namelen--; - } + /* Strip off excess slashes in base string */ + while (namelen > 0 && base[namelen - 1] == '/') + namelen--; buflen -= namelen; if (buflen < 0) { spin_unlock(&dentry->d_lock); diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index 1e09eb78543b..79fbb61ce202 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -81,8 +81,7 @@ static char *nfs_path_component(const char *nfspath, const char *end) static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) { char *limit; - char *path = nfs_path(&limit, dentry, buffer, buflen, - NFS_PATH_CANONICAL); + char *path = nfs_path(&limit, dentry, buffer, buflen); if (!IS_ERR(path)) { char *path_component = nfs_path_component(path, limit); if (path_component) diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 5eec4429970c..68b21d81b7ac 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -339,7 +339,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc dprintk("%s ERROR: %d Reset session\n", __func__, errorcode); nfs4_schedule_session_recovery(clp->cl_session, errorcode); - goto wait_on_recovery; + exception->retry = 1; + break; #endif /* defined(CONFIG_NFS_V4_1) */ case -NFS4ERR_FILE_OPEN: if (exception->timeout > HZ) { @@ -1571,11 +1572,9 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, - &data->o_res.seq_res, - task) != 0) - nfs_release_seqid(data->o_arg.seqid); - else - rpc_call_start(task); + &data->o_res.seq_res, task)) + return; + rpc_call_start(task); return; unlock_no_action: rcu_read_unlock(); @@ -1749,7 +1748,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred, /* even though OPEN succeeded, access is denied. Close the file */ nfs4_close_state(state, fmode); - return -EACCES; + return -NFS4ERR_ACCESS; } /* @@ -2197,7 +2196,7 @@ static void nfs4_free_closedata(void *data) nfs4_put_open_state(calldata->state); nfs_free_seqid(calldata->arg.seqid); nfs4_put_state_owner(sp); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(calldata); } @@ -2297,10 +2296,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) if (nfs4_setup_sequence(NFS_SERVER(inode), &calldata->arg.seq_args, &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + task)) + goto out; + rpc_call_start(task); out: dprintk("%s: done!\n", __func__); } @@ -4531,7 +4529,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) rpc_restart_call_prepare(task); } - nfs_release_seqid(calldata->arg.seqid); } static void nfs4_locku_prepare(struct rpc_task *task, void *data) @@ -4548,11 +4545,9 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) calldata->timestamp = jiffies; if (nfs4_setup_sequence(calldata->server, &calldata->arg.seq_args, - &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + &calldata->res.seq_res, task)) + return; + rpc_call_start(task); } static const struct rpc_call_ops nfs4_locku_ops = { @@ -4697,7 +4692,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) /* Do we need to do an open_to_lock_owner? */ if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) - goto out_release_lock_seqid; + return; data->arg.open_stateid = &state->stateid; data->arg.new_lock_owner = 1; data->res.open_seqid = data->arg.open_seqid; @@ -4706,15 +4701,10 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->server, &data->arg.seq_args, - &data->res.seq_res, - task) == 0) { - rpc_call_start(task); + &data->res.seq_res, task)) return; - } - nfs_release_seqid(data->arg.open_seqid); -out_release_lock_seqid: - nfs_release_seqid(data->arg.lock_seqid); - dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); + rpc_call_start(task); + dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); } static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) @@ -5677,7 +5667,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, tbl->slots = new; tbl->max_slots = max_slots; } - tbl->highest_used_slotid = NFS4_NO_SLOT; + tbl->highest_used_slotid = -1; /* no slot is currently used */ for (i = 0; i < tbl->max_slots; i++) tbl->slots[i].seq_nr = ivalue; spin_unlock(&tbl->slot_tbl_lock); diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 2878f97bd78d..fe624c91bd00 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -925,8 +925,8 @@ pnfs_find_alloc_layout(struct inode *ino, if (likely(nfsi->layout == NULL)) { /* Won the race? */ nfsi->layout = new; return new; - } else if (new != NULL) - pnfs_free_layout_hdr(new); + } + pnfs_free_layout_hdr(new); out_existing: pnfs_get_layout_hdr(nfsi->layout); return nfsi->layout; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 652d3f7176a9..e831bce49766 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -54,7 +54,6 @@ #include #include #include -#include #include @@ -416,54 +415,6 @@ void nfs_sb_deactive(struct super_block *sb) } EXPORT_SYMBOL_GPL(nfs_sb_deactive); -static int nfs_deactivate_super_async_work(void *ptr) -{ - struct super_block *sb = ptr; - - deactivate_super(sb); - module_put_and_exit(0); - return 0; -} - -/* - * same effect as deactivate_super, but will do final unmount in kthread - * context - */ -static void nfs_deactivate_super_async(struct super_block *sb) -{ - struct task_struct *task; - char buf[INET6_ADDRSTRLEN + 1]; - struct nfs_server *server = NFS_SB(sb); - struct nfs_client *clp = server->nfs_client; - - if (!atomic_add_unless(&sb->s_active, -1, 1)) { - rcu_read_lock(); - snprintf(buf, sizeof(buf), - rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); - rcu_read_unlock(); - - __module_get(THIS_MODULE); - task = kthread_run(nfs_deactivate_super_async_work, sb, - "%s-deactivate-super", buf); - if (IS_ERR(task)) { - pr_err("%s: kthread_run: %ld\n", - __func__, PTR_ERR(task)); - /* make synchronous call and hope for the best */ - deactivate_super(sb); - module_put(THIS_MODULE); - } - } -} - -void nfs_sb_deactive_async(struct super_block *sb) -{ - struct nfs_server *server = NFS_SB(sb); - - if (atomic_dec_and_test(&server->active)) - nfs_deactivate_super_async(sb); -} -EXPORT_SYMBOL_GPL(nfs_sb_deactive_async); - /* * Deliver file system statistics to userspace */ @@ -820,7 +771,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root) int err = 0; if (!page) return -ENOMEM; - devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); + devname = nfs_path(&dummy, root, page, PAGE_SIZE); if (IS_ERR(devname)) err = PTR_ERR(devname); else diff --git a/trunk/fs/nfs/unlink.c b/trunk/fs/nfs/unlink.c index 3f79c77153b8..13cea637eff8 100644 --- a/trunk/fs/nfs/unlink.c +++ b/trunk/fs/nfs/unlink.c @@ -95,7 +95,7 @@ static void nfs_async_unlink_release(void *calldata) nfs_dec_sillycount(data->dir); nfs_free_unlinkdata(data); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); } static void nfs_unlink_prepare(struct rpc_task *task, void *calldata) diff --git a/trunk/fs/notify/fanotify/fanotify.c b/trunk/fs/notify/fanotify/fanotify.c index a50636025364..f35794b97e8e 100644 --- a/trunk/fs/notify/fanotify/fanotify.c +++ b/trunk/fs/notify/fanotify/fanotify.c @@ -21,7 +21,6 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) if ((old->path.mnt == new->path.mnt) && (old->path.dentry == new->path.dentry)) return true; - break; case (FSNOTIFY_EVENT_NONE): return true; default: diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index 335206a9c698..4f33c32affe3 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -1866,7 +1866,6 @@ xfs_alloc_fix_freelist( /* * Initialize the args structure. */ - memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; targs.agbp = agbp; @@ -2208,7 +2207,7 @@ xfs_alloc_read_agf( * group or loop over the allocation groups to find the result. */ int /* error */ -xfs_alloc_vextent( +__xfs_alloc_vextent( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_agblock_t agsize; /* allocation group size */ @@ -2418,6 +2417,46 @@ xfs_alloc_vextent( return error; } +static void +xfs_alloc_vextent_worker( + struct work_struct *work) +{ + struct xfs_alloc_arg *args = container_of(work, + struct xfs_alloc_arg, work); + unsigned long pflags; + + /* we are in a transaction context here */ + current_set_flags_nested(&pflags, PF_FSTRANS); + + args->result = __xfs_alloc_vextent(args); + complete(args->done); + + current_restore_flags_nested(&pflags, PF_FSTRANS); +} + +/* + * Data allocation requests often come in with little stack to work on. Push + * them off to a worker thread so there is lots of stack to use. Metadata + * requests, OTOH, are generally from low stack usage paths, so avoid the + * context switch overhead here. + */ +int +xfs_alloc_vextent( + struct xfs_alloc_arg *args) +{ + DECLARE_COMPLETION_ONSTACK(done); + + if (!args->userdata) + return __xfs_alloc_vextent(args); + + + args->done = &done; + INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); + queue_work(xfs_alloc_wq, &args->work); + wait_for_completion(&done); + return args->result; +} + /* * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent diff --git a/trunk/fs/xfs/xfs_alloc.h b/trunk/fs/xfs/xfs_alloc.h index feacb061bab7..93be4a667ca1 100644 --- a/trunk/fs/xfs/xfs_alloc.h +++ b/trunk/fs/xfs/xfs_alloc.h @@ -120,6 +120,9 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ + struct completion *done; + struct work_struct work; + int result; } xfs_alloc_arg_t; /* diff --git a/trunk/fs/xfs/xfs_alloc_btree.c b/trunk/fs/xfs/xfs_alloc_btree.c index f7876c6d6165..f1647caace8f 100644 --- a/trunk/fs/xfs/xfs_alloc_btree.c +++ b/trunk/fs/xfs/xfs_alloc_btree.c @@ -121,8 +121,6 @@ xfs_allocbt_free_block( xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, XFS_EXTENT_BUSY_SKIP_DISCARD); xfs_trans_agbtree_delta(cur->bc_tp, -1); - - xfs_trans_binval(cur->bc_tp, bp); return 0; } diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 83d0cf3df930..848ffa77707b 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -2437,7 +2437,6 @@ xfs_bmap_btalloc( * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; - memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; args.fsbno = ap->blkno; @@ -3083,7 +3082,6 @@ xfs_bmap_extents_to_btree( * Convert to a btree with two levels, one record in root. */ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; args.firstblock = *firstblock; @@ -3239,7 +3237,6 @@ xfs_bmap_local_to_extents( xfs_buf_t *bp; /* buffer for extent block */ xfs_bmbt_rec_host_t *ep;/* extent record pointer */ - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; args.firstblock = *firstblock; @@ -4619,11 +4616,12 @@ xfs_bmapi_delay( STATIC int -__xfs_bmapi_allocate( - struct xfs_bmalloca *bma) +xfs_bmapi_allocate( + struct xfs_bmalloca *bma, + int flags) { struct xfs_mount *mp = bma->ip->i_mount; - int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? + int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); int tmp_logflags = 0; @@ -4656,27 +4654,24 @@ __xfs_bmapi_allocate( * Indicate if this is the first user data in the file, or just any * user data. */ - if (!(bma->flags & XFS_BMAPI_METADATA)) { + if (!(flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; } - bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; + bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1; /* * Only want to do the alignment at the eof if it is userdata and * allocation length is larger than a stripe unit. */ if (mp->m_dalign && bma->length >= mp->m_dalign && - !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { + !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { error = xfs_bmap_isaeof(bma, whichfork); if (error) return error; } - if (bma->flags & XFS_BMAPI_STACK_SWITCH) - bma->stack_switch = 1; - error = xfs_bmap_alloc(bma); if (error) return error; @@ -4711,7 +4706,7 @@ __xfs_bmapi_allocate( * A wasdelay extent has been initialized, so shouldn't be flagged * as unwritten. */ - if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && + if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) && xfs_sb_version_hasextflgbit(&mp->m_sb)) bma->got.br_state = XFS_EXT_UNWRITTEN; @@ -4739,45 +4734,6 @@ __xfs_bmapi_allocate( return 0; } -static void -xfs_bmapi_allocate_worker( - struct work_struct *work) -{ - struct xfs_bmalloca *args = container_of(work, - struct xfs_bmalloca, work); - unsigned long pflags; - - /* we are in a transaction context here */ - current_set_flags_nested(&pflags, PF_FSTRANS); - - args->result = __xfs_bmapi_allocate(args); - complete(args->done); - - current_restore_flags_nested(&pflags, PF_FSTRANS); -} - -/* - * Some allocation requests often come in with little stack to work on. Push - * them off to a worker thread so there is lots of stack to use. Otherwise just - * call directly to avoid the context switch overhead here. - */ -int -xfs_bmapi_allocate( - struct xfs_bmalloca *args) -{ - DECLARE_COMPLETION_ONSTACK(done); - - if (!args->stack_switch) - return __xfs_bmapi_allocate(args); - - - args->done = &done; - INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); - queue_work(xfs_alloc_wq, &args->work); - wait_for_completion(&done); - return args->result; -} - STATIC int xfs_bmapi_convert_unwritten( struct xfs_bmalloca *bma, @@ -4963,7 +4919,6 @@ xfs_bmapi_write( bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.offset = bno; - bma.flags = flags; /* * There's a 32/64 bit type mismatch between the @@ -4979,7 +4934,7 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(bma.length > 0); - error = xfs_bmapi_allocate(&bma); + error = xfs_bmapi_allocate(&bma, flags); if (error) goto error0; if (bma.blkno == NULLFSBLOCK) diff --git a/trunk/fs/xfs/xfs_bmap.h b/trunk/fs/xfs/xfs_bmap.h index 5f469c3516eb..803b56d7ce16 100644 --- a/trunk/fs/xfs/xfs_bmap.h +++ b/trunk/fs/xfs/xfs_bmap.h @@ -77,7 +77,6 @@ typedef struct xfs_bmap_free * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x040 -#define XFS_BMAPI_STACK_SWITCH 0x080 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ @@ -86,8 +85,7 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" }, \ - { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } + { XFS_BMAPI_CONVERT, "CONVERT" } static inline int xfs_bmapi_aflag(int w) @@ -135,11 +133,6 @@ typedef struct xfs_bmalloca { char userdata;/* set if is user data */ char aeof; /* allocated space at eof */ char conv; /* overwriting unwritten extents */ - char stack_switch; - int flags; - struct completion *done; - struct work_struct work; - int result; } xfs_bmalloca_t; /* diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index becf4a97efc6..a8d0ed911196 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -526,25 +526,7 @@ xfs_buf_item_unpin( } xfs_buf_relse(bp); } else if (freed && remove) { - /* - * There are currently two references to the buffer - the active - * LRU reference and the buf log item. What we are about to do - * here - simulate a failed IO completion - requires 3 - * references. - * - * The LRU reference is removed by the xfs_buf_stale() call. The - * buf item reference is removed by the xfs_buf_iodone() - * callback that is run by xfs_buf_do_callbacks() during ioend - * processing (via the bp->b_iodone callback), and then finally - * the ioend processing will drop the IO reference if the buffer - * is marked XBF_ASYNC. - * - * Hence we need to take an additional reference here so that IO - * completion processing doesn't free the buffer prematurely. - */ xfs_buf_lock(bp); - xfs_buf_hold(bp); - bp->b_flags |= XBF_ASYNC; xfs_buf_ioerror(bp, EIO); XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 4beaede43277..c25b094efbf7 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -399,26 +399,9 @@ xfs_growfs_data_private( /* update secondary superblocks. */ for (agno = 1; agno < nagcount; agno++) { - error = 0; - /* - * new secondary superblocks need to be zeroed, not read from - * disk as the contents of the new area we are growing into is - * completely unknown. - */ - if (agno < oagcount) { - error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp); - } else { - bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, - XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), - XFS_FSS_TO_BB(mp, 1), 0); - if (bp) - xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); - else - error = ENOMEM; - } - if (error) { xfs_warn(mp, "error %d reading secondary superblock for ag %d", @@ -440,7 +423,7 @@ xfs_growfs_data_private( break; /* no point in continuing */ } } - return error; + return 0; error0: xfs_trans_cancel(tp, XFS_TRANS_ABORT); diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index c5c4ef4f2bdb..445bf1aef31c 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -250,7 +250,6 @@ xfs_ialloc_ag_alloc( /* boundary */ struct xfs_perag *pag; - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = tp->t_mountp; diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 1938b41ee9f5..2778258fcfa2 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -1509,8 +1509,7 @@ xfs_ifree_cluster( * to mark all the active inodes on the buffer stale. */ bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, - mp->m_bsize * blks_per_cluster, - XBF_UNMAPPED); + mp->m_bsize * blks_per_cluster, 0); if (!bp) return ENOMEM; diff --git a/trunk/fs/xfs/xfs_ioctl.c b/trunk/fs/xfs/xfs_ioctl.c index c1df3c623de2..8305f2ac6773 100644 --- a/trunk/fs/xfs/xfs_ioctl.c +++ b/trunk/fs/xfs/xfs_ioctl.c @@ -70,7 +70,7 @@ xfs_find_handle( int hsize; xfs_handle_t handle; struct inode *inode; - struct fd f = {0}; + struct fd f; struct path path; int error; struct xfs_inode *ip; diff --git a/trunk/fs/xfs/xfs_iomap.c b/trunk/fs/xfs/xfs_iomap.c index 7f537663365b..973dff6ad935 100644 --- a/trunk/fs/xfs/xfs_iomap.c +++ b/trunk/fs/xfs/xfs_iomap.c @@ -584,9 +584,7 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, - XFS_BMAPI_STACK_SWITCH, - &first_block, 1, + count_fsb, 0, &first_block, 1, imap, &nimaps, &free_list); if (error) goto trans_cancel; diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 4dad756962d0..7f4f9370d0e7 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -2387,27 +2387,14 @@ xlog_state_do_callback( /* - * Completion of a iclog IO does not imply that - * a transaction has completed, as transactions - * can be large enough to span many iclogs. We - * cannot change the tail of the log half way - * through a transaction as this may be the only - * transaction in the log and moving th etail to - * point to the middle of it will prevent - * recovery from finding the start of the - * transaction. Hence we should only update the - * last_sync_lsn if this iclog contains - * transaction completion callbacks on it. - * - * We have to do this before we drop the + * update the last_sync_lsn before we drop the * icloglock to ensure we are the only one that * can update it. */ ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); - if (iclog->ic_callback) - atomic64_set(&log->l_last_sync_lsn, - be64_to_cpu(iclog->ic_header.h_lsn)); + atomic64_set(&log->l_last_sync_lsn, + be64_to_cpu(iclog->ic_header.h_lsn)); } else ioerrors++; diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index d308749fabf1..5da3ace352bf 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( * - order is important. */ error = xlog_bread_offset(log, 0, - bblks - split_bblks, dbp, + bblks - split_bblks, hbp, offset + BBTOB(split_bblks)); if (error) goto bread_err2; diff --git a/trunk/include/linux/hashtable.h b/trunk/include/linux/hashtable.h deleted file mode 100644 index 227c62424f3c..000000000000 --- a/trunk/include/linux/hashtable.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Statically sized hash table implementation - * (C) 2012 Sasha Levin - */ - -#ifndef _LINUX_HASHTABLE_H -#define _LINUX_HASHTABLE_H - -#include -#include -#include -#include -#include - -#define DEFINE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] = \ - { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } - -#define DECLARE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] - -#define HASH_SIZE(name) (ARRAY_SIZE(name)) -#define HASH_BITS(name) ilog2(HASH_SIZE(name)) - -/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ -#define hash_min(val, bits) \ - (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) - -static inline void __hash_init(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - INIT_HLIST_HEAD(&ht[i]); -} - -/** - * hash_init - initialize a hash table - * @hashtable: hashtable to be initialized - * - * Calculates the size of the hashtable from the given parameter, otherwise - * same as hash_init_size. - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_add - add an object to a hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add(hashtable, node, key) \ - hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_add_rcu - add an object to a rcu enabled hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add_rcu(hashtable, node, key) \ - hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_hashed - check whether an object is in any hashtable - * @node: the &struct hlist_node of the object to be checked - */ -static inline bool hash_hashed(struct hlist_node *node) -{ - return !hlist_unhashed(node); -} - -static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - if (!hlist_empty(&ht[i])) - return false; - - return true; -} - -/** - * hash_empty - check whether a hashtable is empty - * @hashtable: hashtable to check - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_del - remove an object from a hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del(struct hlist_node *node) -{ - hlist_del_init(node); -} - -/** - * hash_del_rcu - remove an object from a rcu enabled hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del_rcu(struct hlist_node *node) -{ - hlist_del_init_rcu(node); -} - -/** - * hash_for_each - iterate over a hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry(obj, node, &name[bkt], member) - -/** - * hash_for_each_rcu - iterate over a rcu enabled hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_rcu(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_rcu(obj, node, &name[bkt], member) - -/** - * hash_for_each_safe - iterate over a hashtable safe against removal of - * hash entry - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member) - -/** - * hash_for_each_possible - iterate over all possible objects hashing to the - * same bucket - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible(name, obj, node, member, key) \ - hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_rcu - iterate over all possible objects hashing to the - * same bucket in an rcu enabled hashtable - * in a rcu enabled hashtable - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_rcu(name, obj, node, member, key) \ - hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_safe - iterate over all possible objects hashing to the - * same bucket safe against removals - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \ - hlist_for_each_entry_safe(obj, node, tmp, \ - &name[hash_min(key, HASH_BITS(name))], member) - - -#endif diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index ecc554374e44..93bfc9f9815c 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -42,8 +42,19 @@ */ #define KVM_MEMSLOT_INVALID (1UL << 16) -/* Two fragments for cross MMIO pages. */ -#define KVM_MAX_MMIO_FRAGMENTS 2 +/* + * If we support unaligned MMIO, at most one fragment will be split into two: + */ +#ifdef KVM_UNALIGNED_MMIO +# define KVM_EXTRA_MMIO_FRAGMENTS 1 +#else +# define KVM_EXTRA_MMIO_FRAGMENTS 0 +#endif + +#define KVM_USER_MMIO_SIZE 8 + +#define KVM_MAX_MMIO_FRAGMENTS \ + (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS) /* * For the normal pfn, the highest 12 bits should be zero, diff --git a/trunk/include/linux/mmc/dw_mmc.h b/trunk/include/linux/mmc/dw_mmc.h index 96531664a061..7c6a1139d8fa 100644 --- a/trunk/include/linux/mmc/dw_mmc.h +++ b/trunk/include/linux/mmc/dw_mmc.h @@ -137,7 +137,7 @@ struct dw_mci { dma_addr_t sg_dma; void *sg_cpu; - const struct dw_mci_dma_ops *dma_ops; + struct dw_mci_dma_ops *dma_ops; #ifdef CONFIG_MMC_DW_IDMAC unsigned int ring_size; #else @@ -162,7 +162,7 @@ struct dw_mci { u16 data_offset; struct device *dev; struct dw_mci_board *pdata; - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; void *priv; struct clk *biu_clk; struct clk *ciu_clk; @@ -186,7 +186,7 @@ struct dw_mci { struct regulator *vmmc; /* Power regulator */ unsigned long irq_flags; /* IRQ flags */ - int irq; + unsigned int irq; }; /* DMA ops for Internal/External DMAC interface */ diff --git a/trunk/include/linux/mmc/sdhci.h b/trunk/include/linux/mmc/sdhci.h index 1edcb4dad8c4..fa8529a859b8 100644 --- a/trunk/include/linux/mmc/sdhci.h +++ b/trunk/include/linux/mmc/sdhci.h @@ -91,7 +91,6 @@ struct sdhci_host { unsigned int quirks2; /* More deviations from spec. */ #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) -#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ diff --git a/trunk/include/linux/of_address.h b/trunk/include/linux/of_address.h index e20e3af68fb6..a1984dd037da 100644 --- a/trunk/include/linux/of_address.h +++ b/trunk/include/linux/of_address.h @@ -28,13 +28,11 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #else /* CONFIG_OF_ADDRESS */ -#ifndef of_address_to_resource static inline int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { return -EINVAL; } -#endif static inline struct device_node *of_find_matching_node_by_address( struct device_node *from, const struct of_device_id *matches, diff --git a/trunk/include/linux/ptp_clock_kernel.h b/trunk/include/linux/ptp_clock_kernel.h index 38a993508327..f2dc6d8fc680 100644 --- a/trunk/include/linux/ptp_clock_kernel.h +++ b/trunk/include/linux/ptp_clock_kernel.h @@ -54,8 +54,7 @@ struct ptp_clock_request { * clock operations * * @adjfreq: Adjusts the frequency of the hardware clock. - * parameter delta: Desired frequency offset from nominal frequency - * in parts per billion + * parameter delta: Desired period change in parts per billion. * * @adjtime: Shifts the time of the hardware clock. * parameter delta: Desired change in nanoseconds. diff --git a/trunk/include/linux/raid/Kbuild b/trunk/include/linux/raid/Kbuild index e69de29bb2d1..2415a64c5e51 100644 --- a/trunk/include/linux/raid/Kbuild +++ b/trunk/include/linux/raid/Kbuild @@ -0,0 +1,2 @@ +header-y += md_p.h +header-y += md_u.h diff --git a/trunk/include/uapi/linux/raid/md_p.h b/trunk/include/linux/raid/md_p.h similarity index 100% rename from trunk/include/uapi/linux/raid/md_p.h rename to trunk/include/linux/raid/md_p.h diff --git a/trunk/include/linux/raid/md_u.h b/trunk/include/linux/raid/md_u.h index 358c04bfbe2a..fb1abb3367e9 100644 --- a/trunk/include/linux/raid/md_u.h +++ b/trunk/include/linux/raid/md_u.h @@ -11,10 +11,149 @@ (for example /usr/src/linux/COPYING); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #ifndef _MD_U_H #define _MD_U_H -#include +/* + * Different major versions are not compatible. + * Different minor versions are only downward compatible. + * Different patchlevel versions are downward and upward compatible. + */ +#define MD_MAJOR_VERSION 0 +#define MD_MINOR_VERSION 90 +/* + * MD_PATCHLEVEL_VERSION indicates kernel functionality. + * >=1 means different superblock formats are selectable using SET_ARRAY_INFO + * and major_version/minor_version accordingly + * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT + * in the super status byte + * >=3 means that bitmap superblock version 4 is supported, which uses + * little-ending representation rather than host-endian + */ +#define MD_PATCHLEVEL_VERSION 3 + +/* ioctls */ + +/* status */ +#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) +#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) +#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) +#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) +#define RAID_AUTORUN _IO (MD_MAJOR, 0x14) +#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) + +/* configuration */ +#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) +#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) +#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) +#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) +#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) +#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) +#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) +#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) +#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) +#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) +#define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a) +#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) +/* usage */ +#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) +/* 0x31 was START_ARRAY */ +#define STOP_ARRAY _IO (MD_MAJOR, 0x32) +#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) +#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) + +/* 63 partitions with the alternate major number (mdp) */ +#define MdpMinorShift 6 +#ifdef __KERNEL__ extern int mdp_major; +#endif + +typedef struct mdu_version_s { + int major; + int minor; + int patchlevel; +} mdu_version_t; + +typedef struct mdu_array_info_s { + /* + * Generic constant information + */ + int major_version; + int minor_version; + int patch_version; + int ctime; + int level; + int size; + int nr_disks; + int raid_disks; + int md_minor; + int not_persistent; + + /* + * Generic state information + */ + int utime; /* 0 Superblock update time */ + int state; /* 1 State bits (clean, ...) */ + int active_disks; /* 2 Number of currently active disks */ + int working_disks; /* 3 Number of working disks */ + int failed_disks; /* 4 Number of failed disks */ + int spare_disks; /* 5 Number of spare disks */ + + /* + * Personality information + */ + int layout; /* 0 the array's physical layout */ + int chunk_size; /* 1 chunk size in bytes */ + +} mdu_array_info_t; + +/* non-obvious values for 'level' */ +#define LEVEL_MULTIPATH (-4) +#define LEVEL_LINEAR (-1) +#define LEVEL_FAULTY (-5) + +/* we need a value for 'no level specified' and 0 + * means 'raid0', so we need something else. This is + * for internal use only + */ +#define LEVEL_NONE (-1000000) + +typedef struct mdu_disk_info_s { + /* + * configuration/status of one particular disk + */ + int number; + int major; + int minor; + int raid_disk; + int state; + +} mdu_disk_info_t; + +typedef struct mdu_start_info_s { + /* + * configuration/status of one particular disk + */ + int major; + int minor; + int raid_disk; + int state; + +} mdu_start_info_t; + +typedef struct mdu_bitmap_file_s +{ + char pathname[4096]; +} mdu_bitmap_file_t; + +typedef struct mdu_param_s +{ + int personality; /* 1,2,3,4 */ + int chunk_size; /* in bytes */ + int max_fault; /* unused for now */ +} mdu_param_t; + #endif + diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 7d5b6000378b..f8cd4cf3fad8 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -2651,15 +2651,6 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); -/** - * ieee80211_get_mesh_hdrlen - get mesh extension header length - * @meshhdr: the mesh extension header, only the flags field - * (first byte) will be accessed - * Returns the length of the extension header, which is always at - * least 6 bytes and at most 18 if address 5 and 6 are present. - */ -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); - /** * DOC: Data path helpers * diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index 93896ad1fcdd..bc056687f647 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -132,7 +132,6 @@ struct snd_card { int shutdown; /* this card is going down */ int free_on_last_close; /* free in context of file_release */ wait_queue_head_t shutdown_sleep; - atomic_t refcount; /* refcount for disconnection */ struct device *dev; /* device assigned to this card */ struct device *card_dev; /* cardX object for sysfs */ @@ -190,7 +189,6 @@ struct snd_minor { const struct file_operations *f_ops; /* file operations */ void *private_data; /* private data for f_ops->open */ struct device *dev; /* device for sysfs */ - struct snd_card *card_ptr; /* assigned card instance */ }; /* return a device pointer linked to each sound device as a parent */ @@ -297,7 +295,6 @@ int snd_card_info_done(void); int snd_component_add(struct snd_card *card, const char *component); int snd_card_file_add(struct snd_card *card, struct file *file); int snd_card_file_remove(struct snd_card *card, struct file *file); -void snd_card_unref(struct snd_card *card); #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) diff --git a/trunk/include/trace/events/xen.h b/trunk/include/trace/events/xen.h index d06b6da5c1e3..15ba03bdd7c6 100644 --- a/trunk/include/trace/events/xen.h +++ b/trunk/include/trace/events/xen.h @@ -377,14 +377,6 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); -TRACE_EVENT(xen_mmu_flush_tlb_all, - TP_PROTO(int x), - TP_ARGS(x), - TP_STRUCT__entry(__array(char, x, 0)), - TP_fast_assign((void)x), - TP_printk("%s", "") - ); - TRACE_EVENT(xen_mmu_flush_tlb, TP_PROTO(int x), TP_ARGS(x), diff --git a/trunk/include/uapi/linux/eventpoll.h b/trunk/include/uapi/linux/eventpoll.h index 2c267bcbb85c..8c99ce7202c5 100644 --- a/trunk/include/uapi/linux/eventpoll.h +++ b/trunk/include/uapi/linux/eventpoll.h @@ -25,6 +25,7 @@ #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_DEL 2 #define EPOLL_CTL_MOD 3 +#define EPOLL_CTL_DISABLE 4 /* * Request the handling of system wakeup events so as to prevent system suspends diff --git a/trunk/include/uapi/linux/raid/Kbuild b/trunk/include/uapi/linux/raid/Kbuild index e2c3d25405d7..aafaa5aa54d4 100644 --- a/trunk/include/uapi/linux/raid/Kbuild +++ b/trunk/include/uapi/linux/raid/Kbuild @@ -1,3 +1 @@ # UAPI Header export list -header-y += md_p.h -header-y += md_u.h diff --git a/trunk/include/uapi/linux/raid/md_u.h b/trunk/include/uapi/linux/raid/md_u.h deleted file mode 100644 index 4133e744e4e6..000000000000 --- a/trunk/include/uapi/linux/raid/md_u.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - md_u.h : user <=> kernel API between Linux raidtools and RAID drivers - Copyright (C) 1998 Ingo Molnar - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - You should have received a copy of the GNU General Public License - (for example /usr/src/linux/COPYING); if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _UAPI_MD_U_H -#define _UAPI_MD_U_H - -/* - * Different major versions are not compatible. - * Different minor versions are only downward compatible. - * Different patchlevel versions are downward and upward compatible. - */ -#define MD_MAJOR_VERSION 0 -#define MD_MINOR_VERSION 90 -/* - * MD_PATCHLEVEL_VERSION indicates kernel functionality. - * >=1 means different superblock formats are selectable using SET_ARRAY_INFO - * and major_version/minor_version accordingly - * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT - * in the super status byte - * >=3 means that bitmap superblock version 4 is supported, which uses - * little-ending representation rather than host-endian - */ -#define MD_PATCHLEVEL_VERSION 3 - -/* ioctls */ - -/* status */ -#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) -#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) -#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) -#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) -#define RAID_AUTORUN _IO (MD_MAJOR, 0x14) -#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) - -/* configuration */ -#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) -#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) -#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) -#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) -#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) -#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) -#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) -#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) -#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) -#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) -#define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a) -#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) - -/* usage */ -#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) -/* 0x31 was START_ARRAY */ -#define STOP_ARRAY _IO (MD_MAJOR, 0x32) -#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) -#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) - -/* 63 partitions with the alternate major number (mdp) */ -#define MdpMinorShift 6 - -typedef struct mdu_version_s { - int major; - int minor; - int patchlevel; -} mdu_version_t; - -typedef struct mdu_array_info_s { - /* - * Generic constant information - */ - int major_version; - int minor_version; - int patch_version; - int ctime; - int level; - int size; - int nr_disks; - int raid_disks; - int md_minor; - int not_persistent; - - /* - * Generic state information - */ - int utime; /* 0 Superblock update time */ - int state; /* 1 State bits (clean, ...) */ - int active_disks; /* 2 Number of currently active disks */ - int working_disks; /* 3 Number of working disks */ - int failed_disks; /* 4 Number of failed disks */ - int spare_disks; /* 5 Number of spare disks */ - - /* - * Personality information - */ - int layout; /* 0 the array's physical layout */ - int chunk_size; /* 1 chunk size in bytes */ - -} mdu_array_info_t; - -/* non-obvious values for 'level' */ -#define LEVEL_MULTIPATH (-4) -#define LEVEL_LINEAR (-1) -#define LEVEL_FAULTY (-5) - -/* we need a value for 'no level specified' and 0 - * means 'raid0', so we need something else. This is - * for internal use only - */ -#define LEVEL_NONE (-1000000) - -typedef struct mdu_disk_info_s { - /* - * configuration/status of one particular disk - */ - int number; - int major; - int minor; - int raid_disk; - int state; - -} mdu_disk_info_t; - -typedef struct mdu_start_info_s { - /* - * configuration/status of one particular disk - */ - int major; - int minor; - int raid_disk; - int state; - -} mdu_start_info_t; - -typedef struct mdu_bitmap_file_s -{ - char pathname[4096]; -} mdu_bitmap_file_t; - -typedef struct mdu_param_s -{ - int personality; /* 1,2,3,4 */ - int chunk_size; /* in bytes */ - int max_fault; /* unused for now */ -} mdu_param_t; - -#endif /* _UAPI_MD_U_H */ diff --git a/trunk/include/xen/hvm.h b/trunk/include/xen/hvm.h index 13e43e41637d..b193fa2f9fdd 100644 --- a/trunk/include/xen/hvm.h +++ b/trunk/include/xen/hvm.h @@ -5,36 +5,6 @@ #include #include -static const char *param_name(int op) -{ -#define PARAM(x) [HVM_PARAM_##x] = #x - static const char *const names[] = { - PARAM(CALLBACK_IRQ), - PARAM(STORE_PFN), - PARAM(STORE_EVTCHN), - PARAM(PAE_ENABLED), - PARAM(IOREQ_PFN), - PARAM(BUFIOREQ_PFN), - PARAM(TIMER_MODE), - PARAM(HPET_ENABLED), - PARAM(IDENT_PT), - PARAM(DM_DOMAIN), - PARAM(ACPI_S_STATE), - PARAM(VM86_TSS), - PARAM(VPT_ALIGN), - PARAM(CONSOLE_PFN), - PARAM(CONSOLE_EVTCHN), - }; -#undef PARAM - - if (op >= ARRAY_SIZE(names)) - return "unknown"; - - if (!names[op]) - return "reserved"; - - return names[op]; -} static inline int hvm_get_parameter(int idx, uint64_t *value) { struct xen_hvm_param xhv; @@ -44,8 +14,8 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) xhv.index = idx; r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); if (r < 0) { - printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n", - param_name(idx), idx, r); + printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n", + idx, r); return r; } *value = xhv.value; diff --git a/trunk/init/main.c b/trunk/init/main.c index e33e09df3cbc..9cf77ab138a6 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -442,11 +442,9 @@ void __init __weak smp_setup_processor_id(void) { } -# if THREAD_SIZE >= PAGE_SIZE void __init __weak thread_info_cache_init(void) { } -#endif /* * Set up kernel memory allocators diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 6e48c3a43599..6085f5ef88ea 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2293,17 +2293,12 @@ static void layout_symtab(struct module *mod, struct load_info *info) src = (void *)info->hdr + symsect->sh_offset; nsrc = symsect->sh_size / sizeof(*src); - /* strtab always starts with a nul, so offset 0 is the empty string. */ - strtab_size = 1; - /* Compute total space required for the core symbols' strtab. */ - for (ndst = i = 0; i < nsrc; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - strtab_size += strlen(&info->strtab[src[i].st_name])+1; + for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) + if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { + strtab_size += strlen(&info->strtab[src->st_name]) + 1; ndst++; } - } /* Append room for core symbols at end of core part. */ info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); @@ -2337,15 +2332,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) mod->core_symtab = dst = mod->module_core + info->symoffs; mod->core_strtab = s = mod->module_core + info->stroffs; src = mod->symtab; + *dst = *src; *s++ = 0; - for (ndst = i = 0; i < mod->num_symtab; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - dst[ndst] = src[i]; - dst[ndst++].st_name = s - mod->core_strtab; - s += strlcpy(s, &mod->strtab[src[i].st_name], - KSYM_NAME_LEN) + 1; - } + for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { + if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) + continue; + + dst[ndst] = *src; + dst[ndst++].st_name = s - mod->core_strtab; + s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; } mod->core_num_syms = ndst; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 8b055e9379bc..2624edcfb420 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -3017,8 +3017,6 @@ static int kswapd(void *p) &balanced_classzone_idx); } } - - current->reclaim_state = NULL; return 0; } diff --git a/trunk/net/ceph/messenger.c b/trunk/net/ceph/messenger.c index 3ef1759403b4..159aa8bef9e7 100644 --- a/trunk/net/ceph/messenger.c +++ b/trunk/net/ceph/messenger.c @@ -2300,11 +2300,10 @@ static void con_work(struct work_struct *work) mutex_unlock(&con->mutex); return; } else { + con->ops->put(con); dout("con_work %p FAILED to back off %lu\n", con, con->delay); - set_bit(CON_FLAG_BACKOFF, &con->flags); } - goto done; } if (con->state == CON_STATE_STANDBY) { @@ -2750,8 +2749,7 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) msg = con->ops->alloc_msg(con, hdr, skip); mutex_lock(&con->mutex); if (con->state != CON_STATE_OPEN) { - if (msg) - ceph_msg_put(msg); + ceph_msg_put(msg); return -EAGAIN; } con->in_msg = msg; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index bda6d004f9f0..09cb3f6dc40c 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) { - if (!ptype->af_packet_priv || !skb->sk) + if (ptype->af_packet_priv == NULL) return false; if (ptype->id_match) diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index fad649ae4dec..76d4c2c3c89b 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -2192,8 +2192,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, goto skip; err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, - portid, seq, - RTM_NEWNEIGH, NTF_SELF); + portid, seq, 0, NTF_SELF); if (err < 0) return err; skip: diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 0c34bfabc11f..535584c00f91 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -892,16 +892,13 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; - int err = 0; handler = inet_diag_lock_handler(r->sdiag_protocol); if (!IS_ERR(handler)) handler->dump(skb, cb, r, bc); - else - err = PTR_ERR(handler); inet_diag_unlock_handler(handler); - return err ? : skb->len; + return skb->len; } static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) diff --git a/trunk/net/ipv4/netfilter/iptable_nat.c b/trunk/net/ipv4/netfilter/iptable_nat.c index a82047282dbb..9e0ffaf1d942 100644 --- a/trunk/net/ipv4/netfilter/iptable_nat.c +++ b/trunk/net/ipv4/netfilter/iptable_nat.c @@ -184,8 +184,7 @@ nf_nat_ipv4_out(unsigned int hooknum, if ((ct->tuplehash[dir].tuple.src.u3.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET) < 0) ret = NF_DROP; @@ -222,7 +221,6 @@ nf_nat_ipv4_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET) < 0) diff --git a/trunk/net/ipv4/tcp_illinois.c b/trunk/net/ipv4/tcp_illinois.c index 834857f3c871..813b43a76fec 100644 --- a/trunk/net/ipv4/tcp_illinois.c +++ b/trunk/net/ipv4/tcp_illinois.c @@ -313,13 +313,11 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, .tcpv_rttcnt = ca->cnt_rtt, .tcpv_minrtt = ca->base_rtt, }; + u64 t = ca->sum_rtt; - if (info.tcpv_rttcnt > 0) { - u64 t = ca->sum_rtt; + do_div(t, ca->cnt_rtt); + info.tcpv_rtt = t; - do_div(t, info.tcpv_rttcnt); - info.tcpv_rtt = t; - } nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); } } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 2c2b13a999ea..1db663983587 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -4529,9 +4529,6 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) struct tcphdr *th; bool fragstolen; - if (size == 0) - return 0; - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); if (!skb) goto err; diff --git a/trunk/net/ipv4/tcp_metrics.c b/trunk/net/ipv4/tcp_metrics.c index 53bc5847bfa8..4c752a6e0bcd 100644 --- a/trunk/net/ipv4/tcp_metrics.c +++ b/trunk/net/ipv4/tcp_metrics.c @@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr, } a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; if (a) { - if (nla_len(a) != sizeof(struct in6_addr)) + if (nla_len(a) != sizeof(sizeof(struct in6_addr))) return -EINVAL; addr->family = AF_INET6; memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); diff --git a/trunk/net/ipv6/ip6_gre.c b/trunk/net/ipv6/ip6_gre.c index d5cb3c4e66f8..0185679c5f53 100644 --- a/trunk/net/ipv6/ip6_gre.c +++ b/trunk/net/ipv6/ip6_gre.c @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) /* IFLA_GRE_OKEY */ nla_total_size(4) + /* IFLA_GRE_LOCAL */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_REMOTE */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_TTL */ nla_total_size(1) + /* IFLA_GRE_TOS */ @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || - nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || - nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 2edce30ef733..ff36194a71aa 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; - struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + struct in6_addr mcaddr; idev = in6_dev_get(dev); if (!idev) @@ -543,6 +543,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { + addrconf_addr_solict_mult(&ifa->addr, &mcaddr); ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, /*router=*/ !!idev->cnf.forwarding, /*solicited=*/ false, /*override=*/ true, diff --git a/trunk/net/ipv6/netfilter/ip6table_nat.c b/trunk/net/ipv6/netfilter/ip6table_nat.c index d57dab17a182..e418bd6350a4 100644 --- a/trunk/net/ipv6/netfilter/ip6table_nat.c +++ b/trunk/net/ipv6/netfilter/ip6table_nat.c @@ -186,8 +186,7 @@ nf_nat_ipv6_out(unsigned int hooknum, if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET6) < 0) ret = NF_DROP; @@ -223,7 +222,6 @@ nf_nat_ipv6_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET6)) diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 22c8ea951185..18bd9bbbd1c6 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { { } }; -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { struct ctl_table *table; struct ctl_table_header *hdr; @@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) } #else -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { return 0; } diff --git a/trunk/net/l2tp/l2tp_eth.c b/trunk/net/l2tp/l2tp_eth.c index 76125c57ee6d..37b8b8ba31f7 100644 --- a/trunk/net/l2tp/l2tp_eth.c +++ b/trunk/net/l2tp/l2tp_eth.c @@ -291,7 +291,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p out_del_dev: free_netdev(dev); - spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index bf87c70ac6c5..5f3620f0bc0a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; - memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 00ade7feb2e3..61c621e9273f 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -531,11 +531,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; - - /* make sure category field is present */ - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) - return RX_DROP_MONITOR; - mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && @@ -888,16 +883,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { - unsigned int hdrlen; - __be16 ethertype; - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - if (rx->skb->len < hdrlen + 8) - return RX_DROP_MONITOR; - - skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); - if (ethertype == rx->sdata->control_port_protocol) + u16 ethertype; + u8 *payload; + + payload = rx->skb->data + + ieee80211_hdrlen(hdr->frame_control); + ethertype = (payload[6] << 8) | payload[7]; + if (cpu_to_be16(ethertype) == + rx->sdata->control_port_protocol) return RX_CONTINUE; } @@ -1469,14 +1462,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; - - if (ieee80211_is_ctl(fc)) - return RX_CONTINUE; - sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || + (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; @@ -1899,20 +1889,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); - - /* make sure fixed part of mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, hdrlen + 6)) - return RX_DROP_MONITOR; - - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* make sure full mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, - hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) - return RX_DROP_MONITOR; - - /* reload pointers */ - hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ @@ -1921,8 +1897,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; - if (!ieee80211_is_data(hdr->frame_control) || - !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!ieee80211_is_data(hdr->frame_control)) return RX_CONTINUE; if (!mesh_hdr->ttl) @@ -1936,12 +1911,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; - } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { - /* has_a4 already checked in ieee80211_rx_mesh_check */ + } else { mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; - } else { - return RX_DROP_MONITOR; } rcu_read_lock(); @@ -1969,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) + goto out; + if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); - goto out; + return RX_DROP_MONITOR; } if (!ifmsh->mshcfg.dot11MeshForwarding) @@ -2378,10 +2353,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.self_prot.action_code))) - break; - switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: @@ -2400,10 +2371,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.mesh_action.action_code))) - break; - if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && @@ -2946,15 +2913,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; - if (ieee80211_is_mgmt(fc)) { - /* drop frame if too short for header */ - if (skb->len < ieee80211_hdrlen(fc)) - err = -ENOBUFS; - else - err = skb_linearize(skb); - } else { + if (ieee80211_is_mgmt(fc)) + err = skb_linearize(skb); + else err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); - } if (err) { dev_kfree_skb(skb); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 239391807ca9..94e586873979 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -643,41 +643,13 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, break; } - switch (id) { - case WLAN_EID_SSID: - case WLAN_EID_SUPP_RATES: - case WLAN_EID_FH_PARAMS: - case WLAN_EID_DS_PARAMS: - case WLAN_EID_CF_PARAMS: - case WLAN_EID_TIM: - case WLAN_EID_IBSS_PARAMS: - case WLAN_EID_CHALLENGE: - case WLAN_EID_RSN: - case WLAN_EID_ERP_INFO: - case WLAN_EID_EXT_SUPP_RATES: - case WLAN_EID_HT_CAPABILITY: - case WLAN_EID_HT_OPERATION: - case WLAN_EID_VHT_CAPABILITY: - case WLAN_EID_VHT_OPERATION: - case WLAN_EID_MESH_ID: - case WLAN_EID_MESH_CONFIG: - case WLAN_EID_PEER_MGMT: - case WLAN_EID_PREQ: - case WLAN_EID_PREP: - case WLAN_EID_PERR: - case WLAN_EID_RANN: - case WLAN_EID_CHANNEL_SWITCH: - case WLAN_EID_EXT_CHANSWITCH_ANN: - case WLAN_EID_COUNTRY: - case WLAN_EID_PWR_CONSTRAINT: - case WLAN_EID_TIMEOUT_INTERVAL: - if (test_bit(id, seen_elems)) { - elems->parse_error = true; - left -= elen; - pos += elen; - continue; - } - break; + if (id != WLAN_EID_VENDOR_SPECIFIC && + id != WLAN_EID_QUIET && + test_bit(id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; + continue; } if (calc_crc && id < 64 && (filter & (1ULL << id))) diff --git a/trunk/net/netfilter/nf_conntrack_h323_main.c b/trunk/net/netfilter/nf_conntrack_h323_main.c index 962795e839ab..1b30b0dee708 100644 --- a/trunk/net/netfilter/nf_conntrack_h323_main.c +++ b/trunk/net/netfilter/nf_conntrack_h323_main.c @@ -753,8 +753,7 @@ static int callforward_do_filter(const union nf_inet_addr *src, flowi4_to_flowi(&fl1), false)) { if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, flowi4_to_flowi(&fl2), false)) { - if (rt_nexthop(rt1, fl1.daddr) == - rt_nexthop(rt2, fl2.daddr) && + if (rt1->rt_gateway == rt2->rt_gateway && rt1->dst.dev == rt2->dst.dev) ret = 1; dst_release(&rt2->dst); diff --git a/trunk/net/sched/sch_qfq.c b/trunk/net/sched/sch_qfq.c index 9687fa1c2275..f0dd83cff906 100644 --- a/trunk/net/sched/sch_qfq.c +++ b/trunk/net/sched/sch_qfq.c @@ -84,19 +84,18 @@ * grp->index is the index of the group; and grp->slot_shift * is the shift for the corresponding (scaled) sigma_i. */ -#define QFQ_MAX_INDEX 24 -#define QFQ_MAX_WSHIFT 12 +#define QFQ_MAX_INDEX 19 +#define QFQ_MAX_WSHIFT 16 #define QFQ_MAX_WEIGHT (1<wsum += delta_w; } -static void qfq_update_reactivate_class(struct qfq_sched *q, - struct qfq_class *cl, - u32 inv_w, u32 lmax, int delta_w) -{ - bool need_reactivation = false; - int i = qfq_calc_index(inv_w, lmax); - - if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { - /* - * shift cl->F back, to not charge the - * class for the not-yet-served head - * packet - */ - cl->F = cl->S; - /* remove class from its slot in the old group */ - qfq_deactivate_class(q, cl); - need_reactivation = true; - } - - qfq_update_class_params(q, cl, lmax, inv_w, delta_w); - - if (need_reactivation) /* activate in new group */ - qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); -} - - static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg) { @@ -265,7 +238,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct qfq_class *cl = (struct qfq_class *)*arg; struct nlattr *tb[TCA_QFQ_MAX + 1]; u32 weight, lmax, inv_w; - int err; + int i, err; int delta_w; if (tca[TCA_OPTIONS] == NULL) { @@ -297,14 +270,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tb[TCA_QFQ_LMAX]) { lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); - if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { + if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { pr_notice("qfq: invalid max length %u\n", lmax); return -EINVAL; } } else - lmax = psched_mtu(qdisc_dev(sch)); + lmax = 1UL << QFQ_MTU_SHIFT; if (cl != NULL) { + bool need_reactivation = false; + if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, &cl->rate_est, qdisc_root_sleeping_lock(sch), @@ -316,8 +291,24 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (lmax == cl->lmax && inv_w == cl->inv_w) return 0; /* nothing to update */ + i = qfq_calc_index(inv_w, lmax); sch_tree_lock(sch); - qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); + if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { + /* + * shift cl->F back, to not charge the + * class for the not-yet-served head + * packet + */ + cl->F = cl->S; + /* remove class from its slot in the old group */ + qfq_deactivate_class(q, cl); + need_reactivation = true; + } + + qfq_update_class_params(q, cl, lmax, inv_w, delta_w); + + if (need_reactivation) /* activate in new group */ + qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); sch_tree_unlock(sch); return 0; @@ -672,48 +663,15 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) /* - * If the weight and lmax (max_pkt_size) of the classes do not change, - * then QFQ guarantees that the slot index is never higher than - * 2 + ((1<S rounded on grp->slot_shift bits. */ static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, u64 roundedS) { u64 slot = (roundedS - grp->S) >> grp->slot_shift; - unsigned int i; /* slot index in the bucket list */ - - if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { - u64 deltaS = roundedS - grp->S - - ((u64)(QFQ_MAX_SLOTS - 2)<slot_shift); - cl->S -= deltaS; - cl->F -= deltaS; - slot = QFQ_MAX_SLOTS - 2; - } - - i = (grp->front + slot) % QFQ_MAX_SLOTS; + unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; hlist_add_head(&cl->next, &grp->slots[i]); __set_bit(slot, &grp->full_slots); @@ -934,13 +892,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) } pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); - if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { - pr_debug("qfq: increasing maxpkt from %u to %u for class %u", - cl->lmax, qdisc_pkt_len(skb), cl->common.classid); - qfq_update_reactivate_class(q, cl, cl->inv_w, - qdisc_pkt_len(skb), 0); - } - err = qdisc_enqueue(skb, cl->qdisc); if (unlikely(err != NET_XMIT_SUCCESS)) { pr_debug("qfq_enqueue: enqueue failed %d\n", err); diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index a60d1f8b41c5..59d16ea927f0 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -974,7 +974,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, void *addr_buf; struct sctp_af *af; - SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p" + SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); if (unlikely(addrs_size <= 0)) diff --git a/trunk/net/sunrpc/backchannel_rqst.c b/trunk/net/sunrpc/backchannel_rqst.c index a9c0bbccad6b..5a3d675d2f2f 100644 --- a/trunk/net/sunrpc/backchannel_rqst.c +++ b/trunk/net/sunrpc/backchannel_rqst.c @@ -172,7 +172,7 @@ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) xprt_free_allocation(req); dprintk("RPC: setup backchannel transport failed\n"); - return -ENOMEM; + return -1; } EXPORT_SYMBOL_GPL(xprt_setup_backchannel); diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c index b36f0fcd9bdf..111ff8300ae5 100644 --- a/trunk/net/tipc/handler.c +++ b/trunk/net/tipc/handler.c @@ -116,6 +116,7 @@ void tipc_handler_stop(void) return; handler_enabled = 0; + tasklet_disable(&tipc_tasklet); tasklet_kill(&tipc_tasklet); spin_lock_bh(&qitem_lock); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 3f7253052088..443d4d7deea2 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -526,7 +526,8 @@ int wiphy_register(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; - sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mag = + sband->channels[i].max_antenna_gain; sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band; diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index bcc7d7ee5a51..3b8cbbc214db 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -908,7 +908,7 @@ static void handle_channel(struct wiphy *wiphy, map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = chan->orig_mag = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = chan->orig_mpwr = + chan->max_power = chan->orig_mpwr = (int) MBM_TO_DBM(power_rule->max_eirp); return; } @@ -1331,8 +1331,7 @@ static void handle_channel_custom(struct wiphy *wiphy, chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = - (int) MBM_TO_DBM(power_rule->max_eirp); + chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 2762e8329986..ef35f4ef2aa6 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -309,21 +309,23 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) +static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) { int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 802.11-2012, 8.2.4.7.3 */ + /* 7.1.3.5a.2 */ switch (ae) { - default: case 0: return 6; case MESH_FLAGS_AE_A4: return 12; case MESH_FLAGS_AE_A5_A6: return 18; + case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): + return 24; + default: + return 6; } } -EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype) @@ -371,8 +373,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A4) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), @@ -397,8 +397,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A5_A6) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A4) skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), diff --git a/trunk/scripts/Makefile.modinst b/trunk/scripts/Makefile.modinst index ecbb44797e28..dda4b2b61927 100644 --- a/trunk/scripts/Makefile.modinst +++ b/trunk/scripts/Makefile.modinst @@ -16,9 +16,8 @@ PHONY += $(modules) __modinst: $(modules) @: -# Don't stop modules_install if we can't sign external modules. quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index f18750e3bd6c..21a9f5de0a21 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1890,10 +1890,8 @@ sub process { } if ($realfile =~ m@^(drivers/net/|net/)@ && - $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ - $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ - $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ - $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ && + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { WARN("NETWORKING_BLOCK_COMMENT_STYLE", "networking block comments put the trailing */ on a separate line\n" . $herecurr); } diff --git a/trunk/sound/core/compress_offload.c b/trunk/sound/core/compress_offload.c index ad11dc994792..c40ae573346d 100644 --- a/trunk/sound/core/compress_offload.c +++ b/trunk/sound/core/compress_offload.c @@ -100,15 +100,12 @@ static int snd_compr_open(struct inode *inode, struct file *f) if (dirn != compr->direction) { pr_err("this device doesn't support this direction\n"); - snd_card_unref(compr->card); return -EINVAL; } data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - snd_card_unref(compr->card); + if (!data) return -ENOMEM; - } data->stream.ops = compr->ops; data->stream.direction = dirn; data->stream.private_data = compr->private_data; @@ -116,7 +113,6 @@ static int snd_compr_open(struct inode *inode, struct file *f) runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); if (!runtime) { kfree(data); - snd_card_unref(compr->card); return -ENOMEM; } runtime->state = SNDRV_PCM_STATE_OPEN; @@ -130,8 +126,7 @@ static int snd_compr_open(struct inode *inode, struct file *f) kfree(runtime); kfree(data); } - snd_card_unref(compr->card); - return 0; + return ret; } static int snd_compr_free(struct inode *inode, struct file *f) diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 8c7c2c9bba61..7e86a5b9f3b5 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -86,7 +86,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file) write_lock_irqsave(&card->ctl_files_rwlock, flags); list_add_tail(&ctl->list, &card->ctl_files); write_unlock_irqrestore(&card->ctl_files_rwlock, flags); - snd_card_unref(card); return 0; __error: @@ -94,8 +93,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file) __error2: snd_card_file_remove(card, file); __error1: - if (card) - snd_card_unref(card); return err; } @@ -1437,8 +1434,6 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer, spin_unlock_irq(&ctl->read_lock); schedule(); remove_wait_queue(&ctl->change_sleep, &wait); - if (ctl->card->shutdown) - return -ENODEV; if (signal_pending(current)) return -ERESTARTSYS; spin_lock_irq(&ctl->read_lock); diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index 3f7f6628cf7b..75ea16f35b1a 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -100,10 +100,8 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) if (hw == NULL) return -ENODEV; - if (!try_module_get(hw->card->module)) { - snd_card_unref(hw->card); + if (!try_module_get(hw->card->module)) return -EFAULT; - } init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); @@ -131,10 +129,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); schedule(); mutex_lock(&hw->open_mutex); - if (hw->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -154,7 +148,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); if (err < 0) module_put(hw->card->module); - snd_card_unref(hw->card); return err; } @@ -466,15 +459,12 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) mutex_unlock(®ister_mutex); return -EINVAL; } - mutex_lock(&hwdep->open_mutex); - wake_up(&hwdep->open_wait); #ifdef CONFIG_SND_OSSEMUL if (hwdep->ossreg) snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); #endif snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); list_del_init(&hwdep->list); - mutex_unlock(&hwdep->open_mutex); mutex_unlock(®ister_mutex); return 0; } diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index 7b012d15c2cf..d8ec849af128 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -213,7 +213,6 @@ int snd_card_create(int idx, const char *xid, spin_lock_init(&card->files_lock); INIT_LIST_HEAD(&card->files_list); init_waitqueue_head(&card->shutdown_sleep); - atomic_set(&card->refcount, 0); #ifdef CONFIG_PM mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); @@ -447,36 +446,21 @@ static int snd_card_do_free(struct snd_card *card) return 0; } -/** - * snd_card_unref - release the reference counter - * @card: the card instance - * - * Decrements the reference counter. When it reaches to zero, wake up - * the sleeper and call the destructor if needed. - */ -void snd_card_unref(struct snd_card *card) -{ - if (atomic_dec_and_test(&card->refcount)) { - wake_up(&card->shutdown_sleep); - if (card->free_on_last_close) - snd_card_do_free(card); - } -} -EXPORT_SYMBOL(snd_card_unref); - int snd_card_free_when_closed(struct snd_card *card) { - int ret; - - atomic_inc(&card->refcount); - ret = snd_card_disconnect(card); - if (ret) { - atomic_dec(&card->refcount); + int free_now = 0; + int ret = snd_card_disconnect(card); + if (ret) return ret; - } - card->free_on_last_close = 1; - if (atomic_dec_and_test(&card->refcount)) + spin_lock(&card->files_lock); + if (list_empty(&card->files_list)) + free_now = 1; + else + card->free_on_last_close = 1; + spin_unlock(&card->files_lock); + + if (free_now) snd_card_do_free(card); return 0; } @@ -490,7 +474,7 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ - wait_event(card->shutdown_sleep, !atomic_read(&card->refcount)); + wait_event(card->shutdown_sleep, list_empty(&card->files_list)); snd_card_do_free(card); return 0; } @@ -902,7 +886,6 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENODEV; } list_add(&mfile->list, &card->files_list); - atomic_inc(&card->refcount); spin_unlock(&card->files_lock); return 0; } @@ -925,6 +908,7 @@ EXPORT_SYMBOL(snd_card_file_add); int snd_card_file_remove(struct snd_card *card, struct file *file) { struct snd_monitor_file *mfile, *found = NULL; + int last_close = 0; spin_lock(&card->files_lock); list_for_each_entry(mfile, &card->files_list, list) { @@ -939,13 +923,19 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) break; } } + if (list_empty(&card->files_list)) + last_close = 1; spin_unlock(&card->files_lock); + if (last_close) { + wake_up(&card->shutdown_sleep); + if (card->free_on_last_close) + snd_card_do_free(card); + } if (!found) { snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); return -ENOENT; } kfree(found); - snd_card_unref(card); return 0; } diff --git a/trunk/sound/core/oss/mixer_oss.c b/trunk/sound/core/oss/mixer_oss.c index e8a1d18774b2..29f6ded02555 100644 --- a/trunk/sound/core/oss/mixer_oss.c +++ b/trunk/sound/core/oss/mixer_oss.c @@ -52,19 +52,14 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) SNDRV_OSS_DEVICE_TYPE_MIXER); if (card == NULL) return -ENODEV; - if (card->mixer_oss == NULL) { - snd_card_unref(card); + if (card->mixer_oss == NULL) return -ENODEV; - } err = snd_card_file_add(card, file); - if (err < 0) { - snd_card_unref(card); + if (err < 0) return err; - } fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); if (fmixer == NULL) { snd_card_file_remove(card, file); - snd_card_unref(card); return -ENOMEM; } fmixer->card = card; @@ -73,10 +68,8 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) if (!try_module_get(card->module)) { kfree(fmixer); snd_card_file_remove(card, file); - snd_card_unref(card); return -EFAULT; } - snd_card_unref(card); return 0; } diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 4c1cc51772e6..08fde0060fd9 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -2441,10 +2441,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) mutex_unlock(&pcm->open_mutex); schedule(); mutex_lock(&pcm->open_mutex); - if (pcm->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -2454,7 +2450,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) mutex_unlock(&pcm->open_mutex); if (err < 0) goto __error; - snd_card_unref(pcm->card); return err; __error: @@ -2462,8 +2457,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) __error2: snd_card_file_remove(pcm->card, file); __error1: - if (pcm) - snd_card_unref(pcm->card); return err; } diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 030102caeee9..f2991940b271 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -1086,19 +1086,11 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) if (list_empty(&pcm->list)) goto unlock; - mutex_lock(&pcm->open_mutex); - wake_up(&pcm->open_wait); list_del_init(&pcm->list); for (cidx = 0; cidx < 2; cidx++) - for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { - snd_pcm_stream_lock_irq(substream); - if (substream->runtime) { + for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) + if (substream->runtime) substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; - wake_up(&substream->runtime->sleep); - wake_up(&substream->runtime->tsleep); - } - snd_pcm_stream_unlock_irq(substream); - } list_for_each_entry(notify, &snd_pcm_notify_list, list) { notify->n_disconnect(pcm); } @@ -1118,7 +1110,6 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) pcm->streams[cidx].chmap_kctl = NULL; } } - mutex_unlock(&pcm->open_mutex); unlock: mutex_unlock(®ister_mutex); return 0; diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index f9ddecf2f4cd..5e12e5bacbba 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -369,14 +369,6 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) return usecs; } -static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state) -{ - snd_pcm_stream_lock_irq(substream); - if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED) - substream->runtime->status->state = state; - snd_pcm_stream_unlock_irq(substream); -} - static int snd_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -460,7 +452,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, runtime->boundary *= 2; snd_pcm_timer_resolution_change(substream); - snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP); + runtime->status->state = SNDRV_PCM_STATE_SETUP; if (pm_qos_request_active(&substream->latency_pm_qos_req)) pm_qos_remove_request(&substream->latency_pm_qos_req); @@ -472,7 +464,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, /* hardware might be unusable from this time, so we force application to retry to set the correct hardware parameter settings */ - snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + runtime->status->state = SNDRV_PCM_STATE_OPEN; if (substream->ops->hw_free != NULL) substream->ops->hw_free(substream); return err; @@ -520,7 +512,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) return -EBADFD; if (substream->ops->hw_free) result = substream->ops->hw_free(substream); - snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN); + runtime->status->state = SNDRV_PCM_STATE_OPEN; pm_qos_remove_request(&substream->latency_pm_qos_req); return result; } @@ -1328,7 +1320,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state) { struct snd_pcm_runtime *runtime = substream->runtime; runtime->control->appl_ptr = runtime->status->hw_ptr; - snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); + runtime->status->state = SNDRV_PCM_STATE_PREPARED; } static struct action_ops snd_pcm_action_prepare = { @@ -1518,10 +1510,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, down_read(&snd_pcm_link_rwsem); snd_pcm_stream_lock_irq(substream); remove_wait_queue(&to_check->sleep, &wait); - if (card->shutdown) { - result = -ENODEV; - break; - } if (tout == 0) { if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) result = -ESTRPIPE; @@ -1646,7 +1634,6 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) write_unlock_irq(&snd_pcm_link_rwlock); up_write(&snd_pcm_link_rwsem); _nolock: - snd_card_unref(substream1->pcm->card); fput_light(file, fput_needed); if (res < 0) kfree(group); @@ -2121,10 +2108,7 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_PLAYBACK); - err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); - if (pcm) - snd_card_unref(pcm->card); - return err; + return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); } static int snd_pcm_capture_open(struct inode *inode, struct file *file) @@ -2135,10 +2119,7 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_CAPTURE); - err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); - if (pcm) - snd_card_unref(pcm->card); - return err; + return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); } static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) @@ -2175,10 +2156,6 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) mutex_unlock(&pcm->open_mutex); schedule(); mutex_lock(&pcm->open_mutex); - if (pcm->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index 1bb95aeea084..ebf6e49ad3d4 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -379,10 +379,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) if (rmidi == NULL) return -ENODEV; - if (!try_module_get(rmidi->card->module)) { - snd_card_unref(rmidi->card); + if (!try_module_get(rmidi->card->module)) return -ENXIO; - } mutex_lock(&rmidi->open_mutex); card = rmidi->card; @@ -424,10 +422,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) mutex_unlock(&rmidi->open_mutex); schedule(); mutex_lock(&rmidi->open_mutex); - if (rmidi->card->shutdown) { - err = -ENODEV; - break; - } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -446,7 +440,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) #endif file->private_data = rawmidi_file; mutex_unlock(&rmidi->open_mutex); - snd_card_unref(rmidi->card); return 0; __error: @@ -454,7 +447,6 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) __error_card: mutex_unlock(&rmidi->open_mutex); module_put(rmidi->card->module); - snd_card_unref(rmidi->card); return err; } @@ -999,8 +991,6 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun spin_unlock_irq(&runtime->lock); schedule(); remove_wait_queue(&runtime->sleep, &wait); - if (rfile->rmidi->card->shutdown) - return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; if (!runtime->avail) @@ -1244,8 +1234,6 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, spin_unlock_irq(&runtime->lock); timeout = schedule_timeout(30 * HZ); remove_wait_queue(&runtime->sleep, &wait); - if (rfile->rmidi->card->shutdown) - return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; if (!runtime->avail && !timeout) @@ -1621,20 +1609,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) static int snd_rawmidi_dev_disconnect(struct snd_device *device) { struct snd_rawmidi *rmidi = device->device_data; - int dir; mutex_lock(®ister_mutex); - mutex_lock(&rmidi->open_mutex); - wake_up(&rmidi->open_wait); list_del_init(&rmidi->list); - for (dir = 0; dir < 2; dir++) { - struct snd_rawmidi_substream *s; - list_for_each_entry(s, &rmidi->streams[dir].substreams, list) { - if (s->runtime) - wake_up(&s->runtime->sleep); - } - } - #ifdef CONFIG_SND_OSSEMUL if (rmidi->ossreg) { if ((int)rmidi->device == midi_map[rmidi->card->number]) { @@ -1649,7 +1626,6 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) } #endif /* CONFIG_SND_OSSEMUL */ snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); - mutex_unlock(&rmidi->open_mutex); mutex_unlock(®ister_mutex); return 0; } diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 70ccdab74153..643976000ce8 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -98,10 +98,6 @@ static void snd_request_other(int minor) * * Checks that a minor device with the specified type is registered, and returns * its user data pointer. - * - * This function increments the reference counter of the card instance - * if an associated instance with the given minor number and type is found. - * The caller must call snd_card_unref() appropriately later. */ void *snd_lookup_minor_data(unsigned int minor, int type) { @@ -112,11 +108,9 @@ void *snd_lookup_minor_data(unsigned int minor, int type) return NULL; mutex_lock(&sound_mutex); mreg = snd_minors[minor]; - if (mreg && mreg->type == type) { + if (mreg && mreg->type == type) private_data = mreg->private_data; - if (private_data && mreg->card_ptr) - atomic_inc(&mreg->card_ptr->refcount); - } else + else private_data = NULL; mutex_unlock(&sound_mutex); return private_data; @@ -281,7 +275,6 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - preg->card_ptr = card; mutex_lock(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS minor = snd_find_free_minor(type); diff --git a/trunk/sound/core/sound_oss.c b/trunk/sound/core/sound_oss.c index 726a49ac9725..e9528333e36d 100644 --- a/trunk/sound/core/sound_oss.c +++ b/trunk/sound/core/sound_oss.c @@ -40,9 +40,6 @@ static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; static DEFINE_MUTEX(sound_oss_mutex); -/* NOTE: This function increments the refcount of the associated card like - * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately - */ void *snd_lookup_oss_minor_data(unsigned int minor, int type) { struct snd_minor *mreg; @@ -52,11 +49,9 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) return NULL; mutex_lock(&sound_oss_mutex); mreg = snd_oss_minors[minor]; - if (mreg && mreg->type == type) { + if (mreg && mreg->type == type) private_data = mreg->private_data; - if (private_data && mreg->card_ptr) - atomic_inc(&mreg->card_ptr->refcount); - } else + else private_data = NULL; mutex_unlock(&sound_oss_mutex); return private_data; @@ -128,7 +123,6 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - preg->card_ptr = card; mutex_lock(&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); diff --git a/trunk/sound/i2c/other/ak4113.c b/trunk/sound/i2c/other/ak4113.c index e04e750a77ed..ef68d710d08c 100644 --- a/trunk/sound/i2c/other/ak4113.c +++ b/trunk/sound/i2c/other/ak4113.c @@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4113_spdif_pinfo, diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index 5bf4fca19e48..816e7d225fb0 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_spdif_pinfo, .get = snd_ak4114_spdif_pget, diff --git a/trunk/sound/i2c/other/ak4117.c b/trunk/sound/i2c/other/ak4117.c index 40e33c9f2b09..b4b2a51fc117 100644 --- a/trunk/sound/i2c/other/ak4117.c +++ b/trunk/sound/i2c/other/ak4117.c @@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4117_spdif_pinfo, .get = snd_ak4117_spdif_pget, diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index 50169bcfd903..5d0e568fdea1 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -2655,8 +2655,6 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { { TYPE_MAESTRO2E, 0x1179 }, { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ { TYPE_MAESTRO2E, 0x1558 }, - { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ - { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ }; static struct ess_device_list mpu_blacklist[] __devinitdata = { diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index cd2dbaf1be78..72b085ae7d46 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -3563,8 +3563,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, - { PCI_DEVICE(0x6549, 0x2200), - .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, /* Creative X-Fi (CA0110-IBG) */ /* CTHDA chips */ { PCI_DEVICE(0x1102, 0x0010), diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 1eeba7386666..cdd43eadbc67 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -545,7 +545,6 @@ static int ad198x_build_pcms(struct hda_codec *codec) if (spec->multiout.dig_out_nid) { info++; codec->num_pcms++; - codec->spdif_status_reset = 1; info->name = "AD198x Digital"; info->pcm_type = HDA_PCM_TYPE_SPDIF; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index d5f3a26d608d..61a71131711c 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -101,8 +101,8 @@ enum { #define CS420X_VENDOR_NID 0x11 #define CS_DIG_OUT1_PIN_NID 0x10 #define CS_DIG_OUT2_PIN_NID 0x15 -#define CS_DMIC1_PIN_NID 0x0e -#define CS_DMIC2_PIN_NID 0x12 +#define CS_DMIC1_PIN_NID 0x12 +#define CS_DMIC2_PIN_NID 0x0e /* coef indices */ #define IDX_SPDIF_STAT 0x0000 @@ -1079,18 +1079,14 @@ static void init_input(struct hda_codec *codec) cs_automic(codec, NULL); coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ - cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); - - coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); if (is_active_pin(codec, CS_DMIC2_PIN_NID)) - coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ + coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ if (is_active_pin(codec, CS_DMIC1_PIN_NID)) - coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off + coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off * No effect if SPDIF_OUT2 is * selected in IDX_SPDIF_CTL. */ - - cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); + cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); } else { if (spec->mic_detect) cs_automic(codec, NULL); @@ -1111,7 +1107,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { | 0x0400 /* Disable Coefficient Auto increment */ )}, /* Beep */ - {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, + {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ {} /* terminator */ @@ -1732,7 +1728,8 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, } -static const struct snd_kcontrol_new cs421x_capture_source = { +static struct snd_kcontrol_new cs421x_capture_source = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -1949,7 +1946,7 @@ static int cs421x_suspend(struct hda_codec *codec) } #endif -static const struct hda_codec_ops cs421x_patch_ops = { +static struct hda_codec_ops cs421x_patch_ops = { .build_controls = cs421x_build_controls, .build_pcms = cs_build_pcms, .init = cs421x_init, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index c0ce3b1f04b4..f7397ad02a0d 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5840,7 +5840,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) return alc_parse_auto_config(codec, alc269_ignore, ssids); } -static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) +static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); if (power_up) @@ -5857,10 +5857,10 @@ static void alc269_shutup(struct hda_codec *codec) if (spec->codec_variant != ALC269_TYPE_ALC269VB) return; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && - (alc_get_coef0(codec) & 0x00ff) == 0x018) { + if ((alc_get_coef0(codec) & 0x00ff) == 0x017) + alc269_toggle_power_output(codec, 0); + if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } } @@ -5870,22 +5870,24 @@ static int alc269_resume(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } codec->patch_ops.init(codec); - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 1); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x017) { + alc269_toggle_power_output(codec, 1); msleep(200); } + if (spec->codec_variant == ALC269_TYPE_ALC269VB || + (alc_get_coef0(codec) & 0x00ff) == 0x018) + alc269_toggle_power_output(codec, 1); + snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); hda_call_check_power_status(codec, 0x01); @@ -7077,7 +7079,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc662 }, { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, - { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, @@ -7095,7 +7096,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, - { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 9ba8af056170..770013ff556f 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -1763,8 +1763,6 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "HP", STAC_HP_ZEPHYR), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660, "HP Mini", STAC_92HD83XXX_HP_LED), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x144E, - "HP Pavilion dv5", STAC_92HD83XXX_HP_INV_LED), {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 019e1a00414a..72a2f60b087c 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; - int i; + int i, dac_num; hda_nid_t nid; - spec->multiout.num_dacs = 0; spec->multiout.dac_nids = spec->private_dac_nids; + dac_num = 0; for (i = 0; i < cfg->line_outs; i++) { hda_nid_t dac = 0; nid = cfg->line_out_pins[i]; @@ -1824,13 +1824,16 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) if (!i && parse_output_path(codec, nid, dac, 1, &spec->out_mix_path)) dac = spec->out_mix_path.path[0]; - if (dac) - spec->private_dac_nids[spec->multiout.num_dacs++] = dac; + if (dac) { + spec->private_dac_nids[i] = dac; + dac_num++; + } } if (!spec->out_path[0].depth && spec->out_mix_path.depth) { spec->out_path[0] = spec->out_mix_path; spec->out_mix_path.depth = 0; } + spec->multiout.num_dacs = dac_num; return 0; } @@ -3625,7 +3628,6 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) */ enum { VIA_FIXUP_INTMIC_BOOST, - VIA_FIXUP_ASUS_G75, }; static void via_fixup_intmic_boost(struct hda_codec *codec, @@ -3640,35 +3642,13 @@ static const struct hda_fixup via_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = via_fixup_intmic_boost, }, - [VIA_FIXUP_ASUS_G75] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { - /* set 0x24 and 0x33 as speakers */ - { 0x24, 0x991301f0 }, - { 0x33, 0x991301f1 }, /* subwoofer */ - { } - } - }, }; static const struct snd_pci_quirk vt2002p_fixups[] = { - SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), {} }; -/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e - * Replace this with mixer NID 0x1c - */ -static void fix_vt1802_connections(struct hda_codec *codec) -{ - static hda_nid_t conn_24[] = { 0x14, 0x1c }; - static hda_nid_t conn_33[] = { 0x1c }; - - snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); - snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); -} - /* patch for vt2002P */ static int patch_vt2002P(struct hda_codec *codec) { @@ -3683,8 +3663,6 @@ static int patch_vt2002P(struct hda_codec *codec) spec->aa_mix_nid = 0x21; override_mic_boost(codec, 0x2b, 0, 3, 40); override_mic_boost(codec, 0x29, 0, 3, 40); - if (spec->codec_type == VT1802) - fix_vt1802_connections(codec); add_secret_dac_path(codec); snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 245d874891ba..3050a5279253 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -2859,12 +2859,7 @@ static int snd_vt1724_resume(struct device *dev) ice->set_spdif_clock(ice, 0); } else { /* internal on-card clock */ - int rate; - if (ice->cur_rate) - rate = ice->cur_rate; - else - rate = ice->pro_rate_default; - snd_vt1724_set_pro_rate(ice, rate, 1); + snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); } update_spdif_bits(ice, ice->pm_saved_spdif_ctrl); diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 748e36c66603..f1cd1e387801 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -3979,8 +3979,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, case 8: /* SYNC IN */ val = hdspm_sync_in_sync_check(hdspm); break; default: - val = hdspm_s1_sync_check(hdspm, - kcontrol->private_value-1); + val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); } break; @@ -4900,7 +4899,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, insel = "Coaxial"; break; default: - insel = "Unknown"; + insel = "Unkown"; } snd_iprintf(buffer, diff --git a/trunk/sound/soc/codecs/cs42l52.c b/trunk/sound/soc/codecs/cs42l52.c index 4d8db3685e96..61599298fb26 100644 --- a/trunk/sound/soc/codecs/cs42l52.c +++ b/trunk/sound/soc/codecs/cs42l52.c @@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { cs42l52->sysclk = freq; } else { - dev_err(codec->dev, "Invalid freq parameter\n"); + dev_err(codec->dev, "Invalid freq paramter\n"); return -EINVAL; } return 0; diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index b2b2b37131bd..3fddc7ad1127 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -3722,7 +3722,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) } while (count--); if (count == 0) - dev_warn(codec->dev, "No impedance range reported for jack\n"); + dev_warn(codec->dev, "No impedence range reported for jack\n"); #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); diff --git a/trunk/sound/soc/omap/omap-dmic.c b/trunk/sound/soc/omap/omap-dmic.c index 5a6aeaf552a8..68f2cd1a9206 100644 --- a/trunk/sound/soc/omap/omap-dmic.c +++ b/trunk/sound/soc/omap/omap-dmic.c @@ -464,9 +464,9 @@ static __devinit int asoc_dmic_probe(struct platform_device *pdev) mutex_init(&dmic->mutex); - dmic->fclk = clk_get(dmic->dev, "fck"); + dmic->fclk = clk_get(dmic->dev, "dmic_fck"); if (IS_ERR(dmic->fclk)) { - dev_err(dmic->dev, "cant get fck\n"); + dev_err(dmic->dev, "cant get dmic_fck\n"); return -ENODEV; } diff --git a/trunk/sound/soc/omap/zoom2.c b/trunk/sound/soc/omap/zoom2.c index 1ff6bb9ade5c..677b567935f8 100644 --- a/trunk/sound/soc/omap/zoom2.c +++ b/trunk/sound/soc/omap/zoom2.c @@ -21,14 +21,15 @@ #include #include -#include #include #include #include #include +#include +#include +#include #include -#include /* Register descriptions for twl4030 codec part */ #include diff --git a/trunk/sound/usb/card.c b/trunk/sound/usb/card.c index 282f0fc9fed1..561bb74fd364 100644 --- a/trunk/sound/usb/card.c +++ b/trunk/sound/usb/card.c @@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, } mutex_init(&chip->mutex); - init_rwsem(&chip->shutdown_rwsem); + mutex_init(&chip->shutdown_mutex); chip->index = idx; chip->dev = dev; chip->card = card; @@ -560,7 +560,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, card = chip->card; mutex_lock(®ister_mutex); - down_write(&chip->shutdown_rwsem); + mutex_lock(&chip->shutdown_mutex); chip->shutdown = 1; chip->num_interfaces--; if (chip->num_interfaces <= 0) { @@ -582,11 +582,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - up_write(&chip->shutdown_rwsem); + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); } else { - up_write(&chip->shutdown_rwsem); + mutex_unlock(&chip->shutdown_mutex); mutex_unlock(®ister_mutex); } } @@ -618,20 +618,16 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) { int err = -ENODEV; - down_read(&chip->shutdown_rwsem); if (!chip->shutdown && !chip->probing) err = usb_autopm_get_interface(chip->pm_intf); - up_read(&chip->shutdown_rwsem); return err; } void snd_usb_autosuspend(struct snd_usb_audio *chip) { - down_read(&chip->shutdown_rwsem); if (!chip->shutdown && !chip->probing) usb_autopm_put_interface(chip->pm_intf); - up_read(&chip->shutdown_rwsem); } static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) diff --git a/trunk/sound/usb/card.h b/trunk/sound/usb/card.h index 814cb357ff88..afa4f9e9b27a 100644 --- a/trunk/sound/usb/card.h +++ b/trunk/sound/usb/card.h @@ -126,7 +126,6 @@ struct snd_usb_substream { struct snd_usb_endpoint *sync_endpoint; unsigned long flags; bool need_setup_ep; /* (re)configure EP at prepare? */ - unsigned int speed; /* USB_SPEED_XXX */ u64 formats; /* format bitmasks (all or'ed) */ unsigned int num_formats; /* number of supported audio formats (list) */ diff --git a/trunk/sound/usb/endpoint.c b/trunk/sound/usb/endpoint.c index 34de6f2faf61..7f78c6d782b0 100644 --- a/trunk/sound/usb/endpoint.c +++ b/trunk/sound/usb/endpoint.c @@ -35,7 +35,6 @@ #define EP_FLAG_ACTIVATED 0 #define EP_FLAG_RUNNING 1 -#define EP_FLAG_STOPPING 2 /* * snd_usb_endpoint is a model that abstracts everything related to an @@ -503,20 +502,10 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) if (alive) snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", alive, ep->ep_num); - clear_bit(EP_FLAG_STOPPING, &ep->flags); return 0; } -/* sync the pending stop operation; - * this function itself doesn't trigger the stop operation - */ -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) -{ - if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) - wait_clear_urbs(ep); -} - /* * unlink active urbs. */ @@ -929,8 +918,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, if (wait) wait_clear_urbs(ep); - else - set_bit(EP_FLAG_STOPPING, &ep->flags); } } diff --git a/trunk/sound/usb/endpoint.h b/trunk/sound/usb/endpoint.h index 3d4c9705041f..6376ccf10fd4 100644 --- a/trunk/sound/usb/endpoint.h +++ b/trunk/sound/usb/endpoint.h @@ -19,7 +19,6 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, int force, int can_sleep, int wait); -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_free(struct list_head *head); diff --git a/trunk/sound/usb/mixer.c b/trunk/sound/usb/mixer.c index 298070e8f2d4..fe56c9da38e9 100644 --- a/trunk/sound/usb/mixer.c +++ b/trunk/sound/usb/mixer.c @@ -287,32 +287,25 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v unsigned char buf[2]; int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; int timeout = 10; - int idx = 0, err; + int err; err = snd_usb_autoresume(cval->mixer->chip); if (err < 0) return -EIO; - down_read(&chip->shutdown_rwsem); while (timeout-- > 0) { - if (chip->shutdown) - break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, val_len) >= val_len) { + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, val_len) >= val_len) { *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); - err = 0; - goto out; + snd_usb_autosuspend(cval->mixer->chip); + return 0; } } - snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", - request, validx, idx, cval->val_type); - err = -EINVAL; - - out: - up_read(&chip->shutdown_rwsem); snd_usb_autosuspend(cval->mixer->chip); - return err; + snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); + return -EINVAL; } static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) @@ -320,7 +313,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v struct snd_usb_audio *chip = cval->mixer->chip; unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ unsigned char *val; - int idx = 0, ret, size; + int ret, size; __u8 bRequest; if (request == UAC_GET_CUR) { @@ -337,22 +330,16 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v if (ret) goto error; - down_read(&chip->shutdown_rwsem); - if (chip->shutdown) - ret = -ENODEV; - else { - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); - ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, + ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, size); - } - up_read(&chip->shutdown_rwsem); + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, size); snd_usb_autosuspend(chip); if (ret < 0) { error: snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", - request, validx, idx, cval->val_type); + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); return ret; } @@ -430,7 +417,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, { struct snd_usb_audio *chip = cval->mixer->chip; unsigned char buf[2]; - int idx = 0, val_len, err, timeout = 10; + int val_len, err, timeout = 10; if (cval->mixer->protocol == UAC_VERSION_1) { val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; @@ -453,27 +440,19 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, err = snd_usb_autoresume(chip); if (err < 0) return -EIO; - down_read(&chip->shutdown_rwsem); - while (timeout-- > 0) { - if (chip->shutdown) - break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + while (timeout-- > 0) if (snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx, idx, buf, val_len) >= 0) { - err = 0; - goto out; + validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), + buf, val_len) >= 0) { + snd_usb_autosuspend(chip); + return 0; } - } - snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", - request, validx, idx, cval->val_type, buf[0], buf[1]); - err = -EINVAL; - - out: - up_read(&chip->shutdown_rwsem); snd_usb_autosuspend(chip); - return err; + snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", + request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); + return -EINVAL; } static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) diff --git a/trunk/sound/usb/mixer_quirks.c b/trunk/sound/usb/mixer_quirks.c index ae2b71435220..690000db0ec0 100644 --- a/trunk/sound/usb/mixer_quirks.c +++ b/trunk/sound/usb/mixer_quirks.c @@ -283,11 +283,6 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e if (value > 1) return -EINVAL; changed = value != mixer->audigy2nx_leds[index]; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) { - err = -ENODEV; - goto out; - } if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, @@ -304,8 +299,6 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, value, index + 2, NULL, 0); - out: - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; mixer->audigy2nx_leds[index] = value; @@ -399,16 +392,11 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, for (i = 0; jacks[i].name; ++i) { snd_iprintf(buffer, "%s: ", jacks[i].name); - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = 0; - else - err = snd_usb_ctl_msg(mixer->chip->dev, + err = snd_usb_ctl_msg(mixer->chip->dev, usb_rcvctrlpipe(mixer->chip->dev, 0), UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, jacks[i].unitid << 8, buf, 3); - up_read(&mixer->chip->shutdown_rwsem); if (err == 3 && (buf[0] == 3 || buf[0] == 6)) snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); else @@ -438,15 +426,10 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, else new_status = old_status & ~0x02; changed = new_status != old_status; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(mixer->chip->dev, + err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 50, 0, &new_status, 1); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; mixer->xonar_u1_status = new_status; @@ -485,17 +468,11 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, u8 bRequest = (kcontrol->private_value >> 16) & 0xff; u16 wIndex = kcontrol->private_value & 0xffff; u8 tmp; - int ret; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; - else - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, + int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0, cpu_to_le16(wIndex), &tmp, sizeof(tmp), 1000); - up_read(&mixer->chip->shutdown_rwsem); if (ret < 0) { snd_printk(KERN_ERR @@ -516,17 +493,11 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, u8 bRequest = (kcontrol->private_value >> 16) & 0xff; u16 wIndex = kcontrol->private_value & 0xffff; u16 wValue = ucontrol->value.integer.value[0]; - int ret; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; - else - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, + int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, cpu_to_le16(wValue), cpu_to_le16(wIndex), NULL, 0, 1000); - up_read(&mixer->chip->shutdown_rwsem); if (ret < 0) { snd_printk(KERN_ERR @@ -685,16 +656,11 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, return -EINVAL; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; @@ -737,16 +703,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, if (!pval->is_cached) { /* Read current value */ - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; @@ -758,16 +719,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, if (cur_val != new_val) { value[0] = new_val; value[1] = 0; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, + err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), value, val_len); - up_read(&mixer->chip->shutdown_rwsem); if (err < 0) return err; diff --git a/trunk/sound/usb/pcm.c b/trunk/sound/usb/pcm.c index 5c12a3fe8c3e..55e19e1b80ec 100644 --- a/trunk/sound/usb/pcm.c +++ b/trunk/sound/usb/pcm.c @@ -71,8 +71,6 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream unsigned int hwptr_done; subs = (struct snd_usb_substream *)substream->runtime->private_data; - if (subs->stream->chip->shutdown) - return SNDRV_PCM_POS_XRUN; spin_lock(&subs->lock); hwptr_done = subs->hwptr_done; substream->runtime->delay = snd_usb_pcm_delay(subs, @@ -446,6 +444,7 @@ static int configure_endpoint(struct snd_usb_substream *subs) { int ret; + mutex_lock(&subs->stream->chip->shutdown_mutex); /* format changed */ stop_endpoints(subs, 0, 0, 0); ret = snd_usb_endpoint_set_params(subs->data_endpoint, @@ -456,7 +455,7 @@ static int configure_endpoint(struct snd_usb_substream *subs) subs->cur_audiofmt, subs->sync_endpoint); if (ret < 0) - return ret; + goto unlock; if (subs->sync_endpoint) ret = snd_usb_endpoint_set_params(subs->data_endpoint, @@ -466,6 +465,9 @@ static int configure_endpoint(struct snd_usb_substream *subs) subs->cur_rate, subs->cur_audiofmt, NULL); + +unlock: + mutex_unlock(&subs->stream->chip->shutdown_mutex); return ret; } @@ -503,13 +505,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - down_read(&subs->stream->chip->shutdown_rwsem); - if (subs->stream->chip->shutdown) - ret = -ENODEV; - else - ret = set_format(subs, fmt); - up_read(&subs->stream->chip->shutdown_rwsem); - if (ret < 0) + if ((ret = set_format(subs, fmt)) < 0) return ret; subs->interface = fmt->iface; @@ -531,12 +527,10 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) subs->cur_audiofmt = NULL; subs->cur_rate = 0; subs->period_bytes = 0; - down_read(&subs->stream->chip->shutdown_rwsem); - if (!subs->stream->chip->shutdown) { - stop_endpoints(subs, 0, 1, 1); - deactivate_endpoints(subs); - } - up_read(&subs->stream->chip->shutdown_rwsem); + mutex_lock(&subs->stream->chip->shutdown_mutex); + stop_endpoints(subs, 0, 1, 1); + deactivate_endpoints(subs); + mutex_unlock(&subs->stream->chip->shutdown_mutex); return snd_pcm_lib_free_vmalloc_buffer(substream); } @@ -558,22 +552,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) return -ENXIO; } - down_read(&subs->stream->chip->shutdown_rwsem); - if (subs->stream->chip->shutdown) { - ret = -ENODEV; - goto unlock; - } - if (snd_BUG_ON(!subs->data_endpoint)) { - ret = -EIO; - goto unlock; - } - - snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); - snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); + if (snd_BUG_ON(!subs->data_endpoint)) + return -EIO; ret = set_format(subs, subs->cur_audiofmt); if (ret < 0) - goto unlock; + return ret; iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface); alts = &iface->altsetting[subs->cur_audiofmt->altset_idx]; @@ -583,12 +567,12 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->cur_audiofmt, subs->cur_rate); if (ret < 0) - goto unlock; + return ret; if (subs->need_setup_ep) { ret = configure_endpoint(subs); if (ret < 0) - goto unlock; + return ret; subs->need_setup_ep = false; } @@ -608,11 +592,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) /* for playback, submit the URBs now; otherwise, the first hwptr_done * updates for all URBs would happen at the same time when starting */ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) - ret = start_endpoints(subs, 1); + return start_endpoints(subs, 1); - unlock: - up_read(&subs->stream->chip->shutdown_rwsem); - return ret; + return 0; } static struct snd_pcm_hardware snd_usb_hardware = @@ -665,7 +647,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, return 0; } /* check whether the period time is >= the data packet interval */ - if (subs->speed != USB_SPEED_FULL) { + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { ptime = 125 * (1 << fp->datainterval); if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); @@ -943,7 +925,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return err; param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; - if (subs->speed == USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) /* full speed devices have fixed data packet interval */ ptmin = 1000; if (ptmin == 1000) diff --git a/trunk/sound/usb/proc.c b/trunk/sound/usb/proc.c index d218f763501f..ebc1a5b5b3f1 100644 --- a/trunk/sound/usb/proc.c +++ b/trunk/sound/usb/proc.c @@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s } snd_iprintf(buffer, "\n"); } - if (subs->speed != USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) snd_iprintf(buffer, " Data packet interval: %d us\n", 125 * (1 << fp->datainterval)); // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); @@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs, return; snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", - subs->speed == USB_SPEED_FULL + snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ? get_full_speed_hz(ep->freqm) : get_high_speed_hz(ep->freqm), ep->freqm >> 16, ep->freqm & 0xffff); diff --git a/trunk/sound/usb/stream.c b/trunk/sound/usb/stream.c index 1de0c8c002a8..083ed81160e5 100644 --- a/trunk/sound/usb/stream.c +++ b/trunk/sound/usb/stream.c @@ -90,7 +90,6 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, subs->direction = stream; subs->dev = as->chip->dev; subs->txfr_quirk = as->chip->txfr_quirk; - subs->speed = snd_usb_get_speed(subs->dev); snd_usb_set_pcm_ops(as->pcm, stream); diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index ef42797f56fb..b8233ebe250f 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -37,7 +37,7 @@ struct snd_usb_audio { struct usb_interface *pm_intf; u32 usb_id; struct mutex mutex; - struct rw_semaphore shutdown_rwsem; + struct mutex shutdown_mutex; unsigned int shutdown:1; unsigned int probing:1; unsigned int autosuspended:1; diff --git a/trunk/tools/testing/selftests/Makefile b/trunk/tools/testing/selftests/Makefile index 85baf11e2acd..43480149119e 100644 --- a/trunk/tools/testing/selftests/Makefile +++ b/trunk/tools/testing/selftests/Makefile @@ -1,4 +1,4 @@ -TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug +TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll all: for TARGET in $(TARGETS); do \ diff --git a/trunk/tools/testing/selftests/epoll/Makefile b/trunk/tools/testing/selftests/epoll/Makefile new file mode 100644 index 000000000000..19806ed62f50 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/Makefile @@ -0,0 +1,11 @@ +# Makefile for epoll selftests + +all: test_epoll +%: %.c + gcc -pthread -g -o $@ $^ + +run_tests: all + ./test_epoll + +clean: + $(RM) test_epoll diff --git a/trunk/tools/testing/selftests/epoll/test_epoll.c b/trunk/tools/testing/selftests/epoll/test_epoll.c new file mode 100644 index 000000000000..f7525392ce84 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/test_epoll.c @@ -0,0 +1,344 @@ +/* + * tools/testing/selftests/epoll/test_epoll.c + * + * Copyright 2012 Adobe Systems Incorporated + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Paton J. Lewis + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * A pointer to an epoll_item_private structure will be stored in the epoll + * item's event structure so that we can get access to the epoll_item_private + * data after calling epoll_wait: + */ +struct epoll_item_private { + int index; /* Position of this struct within the epoll_items array. */ + int fd; + uint32_t events; + pthread_mutex_t mutex; /* Guards the following variables... */ + int stop; + int status; /* Stores any error encountered while handling item. */ + /* The following variable allows us to test whether we have encountered + a problem while attempting to cancel and delete the associated + event. When the test program exits, 'deleted' should be exactly + one. If it is greater than one, then the failed test reflects a real + world situation where we would have tried to access the epoll item's + private data after deleting it: */ + int deleted; +}; + +struct epoll_item_private *epoll_items; + +/* + * Delete the specified item from the epoll set. In a real-world secneario this + * is where we would free the associated data structure, but in this testing + * environment we retain the structure so that we can test for double-deletion: + */ +void delete_item(int index) +{ + __sync_fetch_and_add(&epoll_items[index].deleted, 1); +} + +/* + * A pointer to a read_thread_data structure will be passed as the argument to + * each read thread: + */ +struct read_thread_data { + int stop; + int status; /* Indicates any error encountered by the read thread. */ + int epoll_set; +}; + +/* + * The function executed by the read threads: + */ +void *read_thread_function(void *function_data) +{ + struct read_thread_data *thread_data = + (struct read_thread_data *)function_data; + struct epoll_event event_data; + struct epoll_item_private *item_data; + char socket_data; + + /* Handle events until we encounter an error or this thread's 'stop' + condition is set: */ + while (1) { + int result = epoll_wait(thread_data->epoll_set, + &event_data, + 1, /* Number of desired events */ + 1000); /* Timeout in ms */ + if (result < 0) { + /* Breakpoints signal all threads. Ignore that while + debugging: */ + if (errno == EINTR) + continue; + thread_data->status = errno; + return 0; + } else if (thread_data->stop) + return 0; + else if (result == 0) /* Timeout */ + continue; + + /* We need the mutex here because checking for the stop + condition and re-enabling the epoll item need to be done + together as one atomic operation when EPOLL_CTL_DISABLE is + available: */ + item_data = (struct epoll_item_private *)event_data.data.ptr; + pthread_mutex_lock(&item_data->mutex); + + /* Remove the item from the epoll set if we want to stop + handling that event: */ + if (item_data->stop) + delete_item(item_data->index); + else { + /* Clear the data that was written to the other end of + our non-blocking socket: */ + do { + if (read(item_data->fd, &socket_data, 1) < 1) { + if ((errno == EAGAIN) || + (errno == EWOULDBLOCK)) + break; + else + goto error_unlock; + } + } while (item_data->events & EPOLLET); + + /* The item was one-shot, so re-enable it: */ + event_data.events = item_data->events; + if (epoll_ctl(thread_data->epoll_set, + EPOLL_CTL_MOD, + item_data->fd, + &event_data) < 0) + goto error_unlock; + } + + pthread_mutex_unlock(&item_data->mutex); + } + +error_unlock: + thread_data->status = item_data->status = errno; + pthread_mutex_unlock(&item_data->mutex); + return 0; +} + +/* + * A pointer to a write_thread_data structure will be passed as the argument to + * the write thread: + */ +struct write_thread_data { + int stop; + int status; /* Indicates any error encountered by the write thread. */ + int n_fds; + int *fds; +}; + +/* + * The function executed by the write thread. It writes a single byte to each + * socket in turn until the stop condition for this thread is set. If writing to + * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for + * the moment and just move on to the next socket in the list. We don't care + * about the order in which we deliver events to the epoll set. In fact we don't + * care about the data we're writing to the pipes at all; we just want to + * trigger epoll events: + */ +void *write_thread_function(void *function_data) +{ + const char data = 'X'; + int index; + struct write_thread_data *thread_data = + (struct write_thread_data *)function_data; + while (!thread_data->stop) + for (index = 0; + !thread_data->stop && (index < thread_data->n_fds); + ++index) + if ((write(thread_data->fds[index], &data, 1) < 1) && + (errno != EAGAIN) && + (errno != EWOULDBLOCK)) { + thread_data->status = errno; + return; + } +} + +/* + * Arguments are currently ignored: + */ +int main(int argc, char **argv) +{ + const int n_read_threads = 100; + const int n_epoll_items = 500; + int index; + int epoll_set = epoll_create1(0); + struct write_thread_data write_thread_data = { + 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int)) + }; + struct read_thread_data *read_thread_data = + malloc(n_read_threads * sizeof(struct read_thread_data)); + pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t)); + pthread_t write_thread; + + printf("-----------------\n"); + printf("Runing test_epoll\n"); + printf("-----------------\n"); + + epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private)); + + if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 || + read_thread_data == 0 || read_threads == 0) + goto error; + + if (sysconf(_SC_NPROCESSORS_ONLN) < 2) { + printf("Error: please run this test on a multi-core system.\n"); + goto error; + } + + /* Create the socket pairs and epoll items: */ + for (index = 0; index < n_epoll_items; ++index) { + int socket_pair[2]; + struct epoll_event event_data; + if (socketpair(AF_UNIX, + SOCK_STREAM | SOCK_NONBLOCK, + 0, + socket_pair) < 0) + goto error; + write_thread_data.fds[index] = socket_pair[0]; + epoll_items[index].index = index; + epoll_items[index].fd = socket_pair[1]; + if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0) + goto error; + /* We always use EPOLLONESHOT because this test is currently + structured to demonstrate the need for EPOLL_CTL_DISABLE, + which only produces useful information in the EPOLLONESHOT + case (without EPOLLONESHOT, calling epoll_ctl with + EPOLL_CTL_DISABLE will never return EBUSY). If support for + testing events without EPOLLONESHOT is desired, it should + probably be implemented in a separate unit test. */ + epoll_items[index].events = EPOLLIN | EPOLLONESHOT; + if (index < n_epoll_items / 2) + epoll_items[index].events |= EPOLLET; + epoll_items[index].stop = 0; + epoll_items[index].status = 0; + epoll_items[index].deleted = 0; + event_data.events = epoll_items[index].events; + event_data.data.ptr = &epoll_items[index]; + if (epoll_ctl(epoll_set, + EPOLL_CTL_ADD, + epoll_items[index].fd, + &event_data) < 0) + goto error; + } + + /* Create and start the read threads: */ + for (index = 0; index < n_read_threads; ++index) { + read_thread_data[index].stop = 0; + read_thread_data[index].status = 0; + read_thread_data[index].epoll_set = epoll_set; + if (pthread_create(&read_threads[index], + NULL, + read_thread_function, + &read_thread_data[index]) != 0) + goto error; + } + + if (pthread_create(&write_thread, + NULL, + write_thread_function, + &write_thread_data) != 0) + goto error; + + /* Cancel all event pollers: */ +#ifdef EPOLL_CTL_DISABLE + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + if (epoll_ctl(epoll_set, + EPOLL_CTL_DISABLE, + epoll_items[index].fd, + NULL) == 0) + delete_item(index); + else if (errno != EBUSY) { + pthread_mutex_unlock(&epoll_items[index].mutex); + goto error; + } + /* EBUSY means events were being handled; allow the other thread + to delete the item. */ + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#else + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + pthread_mutex_unlock(&epoll_items[index].mutex); + /* Wait in case a thread running read_thread_function is + currently executing code between epoll_wait and + pthread_mutex_lock with this item. Note that a longer delay + would make double-deletion less likely (at the expense of + performance), but there is no guarantee that any delay would + ever be sufficient. Note also that we delete all event + pollers at once for testing purposes, but in a real-world + environment we are likely to want to be able to cancel event + pollers at arbitrary times. Therefore we can't improve this + situation by just splitting this loop into two loops + (i.e. signal 'stop' for all items, sleep, and then delete all + items). We also can't fix the problem via EPOLL_CTL_DEL + because that command can't prevent the case where some other + thread is executing read_thread_function within the region + mentioned above: */ + usleep(1); + pthread_mutex_lock(&epoll_items[index].mutex); + if (!epoll_items[index].deleted) + delete_item(index); + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#endif + + /* Shut down the read threads: */ + for (index = 0; index < n_read_threads; ++index) + __sync_fetch_and_add(&read_thread_data[index].stop, 1); + for (index = 0; index < n_read_threads; ++index) { + if (pthread_join(read_threads[index], NULL) != 0) + goto error; + if (read_thread_data[index].status) + goto error; + } + + /* Shut down the write thread: */ + __sync_fetch_and_add(&write_thread_data.stop, 1); + if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status) + goto error; + + /* Check for final error conditions: */ + for (index = 0; index < n_epoll_items; ++index) { + if (epoll_items[index].status != 0) + goto error; + if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0) + goto error; + } + for (index = 0; index < n_epoll_items; ++index) + if (epoll_items[index].deleted != 1) { + printf("Error: item data deleted %1d times.\n", + epoll_items[index].deleted); + goto error; + } + + printf("[PASS]\n"); + return 0; + + error: + printf("[FAIL]\n"); + return errno; +}