From 455c290f7d7a1611604894ff91a08c412f24408f Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Sun, 13 May 2007 16:05:59 +0200 Subject: [PATCH] --- yaml --- r: 56485 b: refs/heads/master c: 5d1938c83ca826891a02badef7c9ea8ed57e01a2 h: refs/heads/master i: 56483: 9c406a0e0d6ae89a438d2f1010f244fbc3781de3 v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 3 +- trunk/arch/arm/kernel/stacktrace.c | 2 - trunk/arch/avr32/kernel/irq.c | 9 - trunk/arch/i386/kernel/Makefile | 1 - .../i386/kernel/cpu/cpufreq/powernow-k7.c | 36 +- .../i386/kernel/cpu/cpufreq/powernow-k8.c | 2 +- .../i386/kernel/cpu/cpufreq/powernow-k8.h | 4 +- trunk/arch/i386/kernel/smp.c | 65 +- trunk/arch/i386/kernel/smpboot.c | 22 + trunk/arch/i386/kernel/smpcommon.c | 79 --- trunk/arch/i386/kernel/traps.c | 5 + trunk/arch/i386/mach-voyager/voyager_smp.c | 106 ++-- trunk/arch/i386/mm/discontig.c | 9 +- trunk/arch/ia64/kernel/acpi.c | 2 +- trunk/arch/ia64/kernel/crash.c | 24 +- trunk/arch/ia64/kernel/entry.S | 3 - trunk/arch/ia64/kernel/irq.c | 6 +- trunk/arch/ia64/kernel/irq_lsapic.c | 2 +- trunk/arch/ia64/kernel/kprobes.c | 15 +- trunk/arch/ia64/kernel/mca.c | 5 +- trunk/arch/ia64/kernel/mca_drv.c | 4 +- trunk/arch/ia64/kernel/module.c | 2 +- trunk/arch/ia64/kernel/perfmon.c | 18 +- trunk/arch/ia64/kernel/perfmon_mckinley.h | 2 +- trunk/arch/ia64/kernel/sal.c | 2 +- trunk/arch/ia64/kernel/salinfo.c | 2 +- trunk/arch/ia64/kernel/setup.c | 6 +- trunk/arch/ia64/kernel/smp.c | 12 +- trunk/arch/ia64/kernel/smpboot.c | 6 +- trunk/arch/ia64/kernel/traps.c | 2 +- trunk/arch/ia64/kernel/unwind.c | 2 +- trunk/arch/ia64/mm/discontig.c | 2 +- trunk/arch/ia64/mm/fault.c | 41 +- trunk/arch/ia64/sn/kernel/bte.c | 12 +- trunk/arch/ia64/sn/kernel/bte_error.c | 4 +- trunk/arch/ia64/sn/kernel/io_common.c | 2 +- trunk/arch/ia64/sn/kernel/setup.c | 2 +- trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c | 2 +- trunk/arch/ia64/sn/kernel/xpc_channel.c | 8 +- trunk/arch/ia64/sn/kernel/xpnet.c | 2 +- trunk/arch/ia64/sn/pci/pci_dma.c | 8 +- trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c | 6 +- trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c | 2 +- trunk/arch/ia64/sn/pci/tioca_provider.c | 6 +- trunk/arch/ia64/sn/pci/tioce_provider.c | 16 +- trunk/arch/m68k/lib/uaccess.c | 4 +- trunk/arch/sh64/Kconfig | 3 - trunk/arch/sh64/configs/cayman_defconfig | 199 +++---- trunk/arch/sh64/kernel/entry.S | 4 +- trunk/arch/sh64/kernel/irq.c | 4 +- trunk/arch/sh64/kernel/pci_sh5.c | 17 +- trunk/arch/sh64/kernel/pci_sh5.h | 2 +- trunk/arch/sh64/kernel/process.c | 2 +- trunk/arch/sh64/kernel/signal.c | 33 +- trunk/arch/sh64/kernel/syscalls.S | 36 +- trunk/arch/sh64/kernel/time.c | 18 +- trunk/arch/sh64/lib/.gitignore | 1 - trunk/arch/sh64/mach-cayman/irq.c | 4 +- trunk/arch/sh64/mach-cayman/setup.c | 2 +- trunk/arch/sh64/mm/fault.c | 2 +- trunk/arch/sh64/mm/init.c | 2 +- trunk/arch/sh64/mm/tlbmiss.c | 4 +- trunk/arch/sparc/defconfig | 151 ++--- trunk/arch/sparc/kernel/head.S | 2 +- trunk/arch/sparc64/defconfig | 26 +- trunk/arch/sparc64/kernel/Makefile | 2 +- trunk/arch/sparc64/kernel/entry.S | 94 --- trunk/arch/sparc64/kernel/hvapi.c | 189 ------ trunk/arch/sparc64/kernel/of_device.c | 7 - trunk/arch/sparc64/kernel/setup.c | 3 - trunk/arch/sparc64/kernel/smp.c | 3 - .../um/include/sysdep-x86_64/kernel-offsets.h | 9 - .../arch/um/include/sysdep-x86_64/syscalls.h | 3 +- trunk/arch/um/sys-x86_64/syscall_table.c | 5 +- trunk/arch/x86_64/kernel/traps.c | 3 + trunk/block/ll_rw_blk.c | 1 + trunk/drivers/block/loop.c | 17 +- trunk/drivers/char/agp/via-agp.c | 6 +- trunk/drivers/char/ipmi/ipmi_watchdog.c | 134 +++-- trunk/drivers/firewire/fw-ohci.c | 1 - trunk/drivers/ide/Kconfig | 15 +- trunk/drivers/ide/cris/ide-cris.c | 14 +- trunk/drivers/ide/ide-dma.c | 53 +- trunk/drivers/ide/ide-io.c | 1 - trunk/drivers/ide/ide-lib.c | 12 + trunk/drivers/ide/ide.c | 1 - trunk/drivers/ide/pci/alim15x3.c | 69 ++- trunk/drivers/ide/pci/cmd64x.c | 15 +- trunk/drivers/ide/pci/cs5530.c | 160 ++--- trunk/drivers/ide/pci/it821x.c | 21 +- trunk/drivers/ide/pci/pdc202xx_new.c | 29 +- trunk/drivers/ide/pci/pdc202xx_old.c | 184 ++++-- trunk/drivers/ide/pci/sc1200.c | 161 ++--- trunk/drivers/ide/pci/scc_pata.c | 22 +- trunk/drivers/ide/pci/serverworks.c | 77 ++- trunk/drivers/ide/pci/siimage.c | 24 +- trunk/drivers/ide/pci/sis5513.c | 85 +-- trunk/drivers/ide/pci/sl82c105.c | 76 +-- trunk/drivers/infiniband/core/cma.c | 106 ++-- .../drivers/infiniband/hw/ehca/ehca_classes.h | 1 - trunk/drivers/infiniband/hw/ehca/ehca_irq.c | 7 +- trunk/drivers/infiniband/hw/ehca/ehca_main.c | 94 +-- trunk/drivers/infiniband/hw/ehca/ehca_qp.c | 17 +- trunk/drivers/infiniband/hw/ehca/hcp_if.c | 13 +- .../infiniband/hw/ipath/ipath_iba6120.c | 7 +- .../drivers/infiniband/hw/ipath/ipath_intr.c | 7 +- .../infiniband/hw/ipath/ipath_kernel.h | 2 - .../drivers/infiniband/hw/ipath/ipath_verbs.c | 12 +- trunk/drivers/infiniband/hw/mlx4/main.c | 1 - trunk/drivers/infiniband/hw/mthca/mthca_cq.c | 4 +- trunk/drivers/infiniband/hw/mthca/mthca_qp.c | 1 - trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c | 11 +- trunk/drivers/input/joystick/Kconfig | 1 - trunk/drivers/input/misc/Kconfig | 5 - trunk/drivers/input/mouse/Kconfig | 1 - trunk/drivers/input/tablet/Kconfig | 4 - trunk/drivers/input/touchscreen/Kconfig | 1 - trunk/drivers/media/video/em28xx/Kconfig | 2 +- trunk/drivers/media/video/ivtv/Kconfig | 2 +- trunk/drivers/mmc/card/block.c | 17 +- trunk/drivers/mmc/host/au1xmmc.c | 35 +- trunk/drivers/mmc/host/pxamci.c | 18 +- trunk/drivers/mmc/host/sdhci.c | 9 - trunk/drivers/net/Kconfig | 1 - trunk/drivers/net/mlx4/alloc.c | 1 - trunk/drivers/net/mlx4/eq.c | 1 - trunk/drivers/net/mlx4/icm.c | 1 - trunk/drivers/net/mlx4/main.c | 2 + trunk/drivers/net/mlx4/mlx4.h | 1 + trunk/drivers/net/mlx4/reset.c | 1 - trunk/drivers/net/pasemi_mac.c | 45 +- trunk/drivers/net/pasemi_mac.h | 4 +- trunk/drivers/net/smc911x.c | 6 +- trunk/drivers/net/ucc_geth.c | 40 +- trunk/drivers/net/ucc_geth_mii.c | 9 +- trunk/drivers/net/ucc_geth_mii.h | 10 +- trunk/drivers/parport/parport_pc.c | 1 - trunk/drivers/pci/hotplug/rpadlpar_sysfs.c | 5 +- trunk/drivers/sbus/char/bbc_i2c.c | 1 - trunk/drivers/sbus/char/display7seg.c | 1 - trunk/drivers/scsi/Kconfig | 8 - trunk/drivers/serial/sunhv.c | 280 +++------ trunk/drivers/spi/spidev.c | 2 +- trunk/drivers/video/Kconfig | 4 +- trunk/fs/afs/super.c | 1 + trunk/fs/afs/write.c | 3 +- trunk/fs/eventpoll.c | 561 ++++++++++-------- trunk/include/asm-alpha/mmu_context.h | 2 +- trunk/include/asm-h8300/atomic.h | 1 - trunk/include/asm-i386/kdebug.h | 1 + trunk/include/asm-i386/processor.h | 4 - trunk/include/asm-ia64/kdebug.h | 16 +- trunk/include/asm-ia64/kprobes.h | 1 - trunk/include/asm-ia64/unistd.h | 5 +- trunk/include/asm-m32r/system.h | 3 +- trunk/include/asm-m68k/uaccess.h | 4 +- trunk/include/asm-sh64/dma-mapping.h | 14 +- trunk/include/asm-sh64/irq_regs.h | 1 - trunk/include/asm-sh64/pgalloc.h | 100 +++- trunk/include/asm-sh64/sci.h | 1 - trunk/include/asm-sh64/thread_info.h | 6 - trunk/include/asm-sh64/unistd.h | 43 +- trunk/include/asm-sparc/kdebug.h | 8 +- trunk/include/asm-sparc/system.h | 1 - trunk/include/asm-sparc64/dma-mapping.h | 44 +- trunk/include/asm-sparc64/hypervisor.h | 83 +-- trunk/include/asm-x86_64/kdebug.h | 1 + trunk/include/linux/compat.h | 6 - trunk/include/linux/ide.h | 3 + trunk/include/linux/init.h | 7 +- trunk/include/linux/io.h | 8 - trunk/include/linux/major.h | 2 - trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/slub_def.h | 6 +- trunk/kernel/auditfilter.c | 2 - trunk/kernel/power/main.c | 15 +- trunk/kernel/time/clocksource.c | 10 +- trunk/kernel/time/timekeeping.c | 2 - trunk/kernel/timer.c | 2 + trunk/mm/Kconfig | 2 +- trunk/mm/filemap.c | 3 +- trunk/mm/slub.c | 2 +- trunk/net/ipv4/proc.c | 21 - trunk/net/ipv6/ip6_input.c | 2 +- trunk/net/sched/sch_prio.c | 2 +- trunk/net/xfrm/xfrm_hash.c | 3 +- trunk/net/xfrm/xfrm_policy.c | 4 - 188 files changed, 2065 insertions(+), 2329 deletions(-) delete mode 100644 trunk/arch/i386/kernel/smpcommon.c delete mode 100644 trunk/arch/sh64/lib/.gitignore delete mode 100644 trunk/arch/sparc64/kernel/hvapi.c delete mode 100644 trunk/include/asm-sh64/irq_regs.h delete mode 100644 trunk/include/asm-sh64/sci.h diff --git a/[refs] b/[refs] index 06be716bf5cf..f85179d3fb2d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e0f88db3028798b5e6d62d1c65c991240bf317f3 +refs/heads/master: 5d1938c83ca826891a02badef7c9ea8ed57e01a2 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index bbeb5b6b5b05..68a56add73e3 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1712,6 +1712,8 @@ L: Linux-Kernel@vger.kernel.org S: Maintained i386 SETUP CODE / CPU ERRATA WORKAROUNDS +P: Dave Jones +M: davej@codemonkey.org.uk P: H. Peter Anvin M: hpa@zytor.com S: Maintained @@ -3267,7 +3269,6 @@ W: http://tpmdd.sourceforge.net P: Marcel Selhorst M: tpm@selhorst.net W: http://www.prosec.rub.de/tpm/ -L: tpmdd-devel@lists.sourceforge.net S: Maintained Telecom Clock Driver for MCPL0010 diff --git a/trunk/arch/arm/kernel/stacktrace.c b/trunk/arch/arm/kernel/stacktrace.c index 8b63ad89d0a8..398d0c0511eb 100644 --- a/trunk/arch/arm/kernel/stacktrace.c +++ b/trunk/arch/arm/kernel/stacktrace.c @@ -1,4 +1,3 @@ -#include #include #include @@ -31,7 +30,6 @@ int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, return 0; } -EXPORT_SYMBOL(walk_stackframe); #ifdef CONFIG_STACKTRACE struct stack_trace_data { diff --git a/trunk/arch/avr32/kernel/irq.c b/trunk/arch/avr32/kernel/irq.c index fd311248c143..61f2de266f62 100644 --- a/trunk/arch/avr32/kernel/irq.c +++ b/trunk/arch/avr32/kernel/irq.c @@ -7,15 +7,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * This file contains the code used by various IRQ handling routines: - * asking for different IRQ's should be done through these routines - * instead of just grabbing them. Thus setups with different IRQ numbers - * shouldn't result in any weird surprises, and installing new handlers - * should be easier. - * - * IRQ's are in fact implemented a bit like signal handlers for the kernel. - * Naturally it's not a 1:1 relation, but there are similarities. */ #include diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 06da59f6f837..91cff8dc9e1a 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_X86_SMP) += smp.o smpboot.o tsc_sync.o -obj-$(CONFIG_SMP) += smpcommon.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index ca3e1d341889..837b04166a47 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -341,17 +341,15 @@ static int powernow_acpi_init(void) pc.val = (unsigned long) acpi_processor_perf->states[0].control; for (i = 0; i < number_scales; i++) { u8 fid, vid; - struct acpi_processor_px *state = - &acpi_processor_perf->states[i]; - unsigned int speed, speed_mhz; + unsigned int speed; - pc.val = (unsigned long) state->control; + pc.val = (unsigned long) acpi_processor_perf->states[i].control; dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", i, - (u32) state->core_frequency, - (u32) state->power, - (u32) state->transition_latency, - (u32) state->control, + (u32) acpi_processor_perf->states[i].core_frequency, + (u32) acpi_processor_perf->states[i].power, + (u32) acpi_processor_perf->states[i].transition_latency, + (u32) acpi_processor_perf->states[i].control, pc.bits.sgtc); vid = pc.bits.vid; @@ -362,18 +360,6 @@ static int powernow_acpi_init(void) powernow_table[i].index |= (vid << 8); /* upper 8 bits */ speed = powernow_table[i].frequency; - speed_mhz = speed / 1000; - - /* processor_perflib will multiply the MHz value by 1000 to - * get a KHz value (e.g. 1266000). However, powernow-k7 works - * with true KHz values (e.g. 1266768). To ensure that all - * powernow frequencies are available, we must ensure that - * ACPI doesn't restrict them, so we round up the MHz value - * to ensure that perflib's computed KHz value is greater than - * or equal to powernow's KHz value. - */ - if (speed % 1000 > 0) - speed_mhz++; if ((fid_codes[fid] % 10)==5) { if (have_a0 == 1) @@ -382,16 +368,10 @@ static int powernow_acpi_init(void) dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, - fid_codes[fid] % 10, speed_mhz, vid, + fid_codes[fid] % 10, speed/1000, vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000); - if (state->core_frequency != speed_mhz) { - state->core_frequency = speed_mhz; - dprintk(" Corrected ACPI frequency to %d\n", - speed_mhz); - } - if (latency < pc.bits.sgtc) latency = pc.bits.sgtc; @@ -622,7 +602,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) result = powernow_acpi_init(); if (result) { printk (KERN_INFO PFX "ACPI and legacy methods failed\n"); - printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n"); + printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n"); } } else { /* SGTC use the bus clock as timer */ diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 4ade55c5f333..7cf3d207b6b3 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -521,7 +521,7 @@ static int check_supported_cpu(unsigned int cpu) if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || - ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { + ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); goto out; } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index b06c812208ca..95be5013c984 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -46,8 +46,8 @@ struct powernow_k8_data { #define CPUID_XFAM 0x0ff00000 /* extended family */ #define CPUID_XFAM_K8 0 #define CPUID_XMOD 0x000f0000 /* extended model */ -#define CPUID_XMOD_REV_MASK 0x00080000 -#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ +#define CPUID_XMOD_REV_G 0x00060000 +#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ #define CPUID_USE_XFAM_XMOD 0x00000f00 #define CPUID_GET_MAX_CAPABILITIES 0x80000000 #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index c9a7c9835aba..706bda72dc60 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -467,7 +467,7 @@ void flush_tlb_all(void) * it goes straight through and wastes no time serializing * anything. Worst case is that we lose a reschedule ... */ -static void native_smp_send_reschedule(int cpu) +void native_smp_send_reschedule(int cpu) { WARN_ON(cpu_is_offline(cpu)); send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); @@ -546,10 +546,9 @@ static void __smp_call_function(void (*func) (void *info), void *info, * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -static int -native_smp_call_function_mask(cpumask_t mask, - void (*func)(void *), void *info, - int wait) +int native_smp_call_function_mask(cpumask_t mask, + void (*func)(void *), void *info, + int wait) { struct call_data_struct data; cpumask_t allbutself; @@ -600,6 +599,60 @@ native_smp_call_function_mask(cpumask_t mask, return 0; } +/** + * smp_call_function(): Run a function on all other CPUs. + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Unused. + * @wait: If true, wait (atomically) until function has completed on other CPUs. + * + * Returns 0 on success, else a negative status code. + * + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. + */ +int smp_call_function(void (*func) (void *info), void *info, int nonatomic, + int wait) +{ + return smp_call_function_mask(cpu_online_map, func, info, wait); +} +EXPORT_SYMBOL(smp_call_function); + +/** + * smp_call_function_single - Run a function on another CPU + * @cpu: The target CPU. Cannot be the calling CPU. + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Unused. + * @wait: If true, wait until function has completed on other CPUs. + * + * Returns 0 on success, else a negative status code. + * + * If @wait is true, then returns once @func has returned; otherwise + * it returns just before the target cpu calls @func. + */ +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + /* prevent preemption and reschedule on another processor */ + int ret; + int me = get_cpu(); + if (cpu == me) { + WARN_ON(1); + put_cpu(); + return -EBUSY; + } + + ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); + + put_cpu(); + return ret; +} +EXPORT_SYMBOL(smp_call_function_single); + static void stop_this_cpu (void * dummy) { local_irq_disable(); @@ -617,7 +670,7 @@ static void stop_this_cpu (void * dummy) * this function calls the 'stop' function on all other CPUs in the system. */ -static void native_smp_send_stop(void) +void native_smp_send_stop(void) { /* Don't deadlock on the call lock in panic */ int nolock = !spin_trylock(&call_lock); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 08f07a74a9d3..b92cc4e8b3bb 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -98,6 +98,9 @@ EXPORT_SYMBOL(x86_cpu_to_apicid); u8 apicid_2_node[MAX_APICID]; +DEFINE_PER_CPU(unsigned long, this_cpu_off); +EXPORT_PER_CPU_SYMBOL(this_cpu_off); + /* * Trampoline 80x86 program as an array. */ @@ -760,6 +763,25 @@ static inline struct task_struct * alloc_idle_task(int cpu) #define alloc_idle_task(cpu) fork_idle(cpu) #endif +/* Initialize the CPU's GDT. This is either the boot CPU doing itself + (still using the master per-cpu area), or a CPU doing it for a + secondary which will soon come up. */ +static __cpuinit void init_gdt(int cpu) +{ + struct desc_struct *gdt = get_cpu_gdt_table(cpu); + + pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, + (u32 *)&gdt[GDT_ENTRY_PERCPU].b, + __per_cpu_offset[cpu], 0xFFFFF, + 0x80 | DESCTYPE_S | 0x2, 0x8); + + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; + per_cpu(cpu_number, cpu) = cpu; +} + +/* Defined in head.S */ +extern struct Xgt_desc_struct early_gdt_descr; + static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad diff --git a/trunk/arch/i386/kernel/smpcommon.c b/trunk/arch/i386/kernel/smpcommon.c deleted file mode 100644 index 1868ae18eb4d..000000000000 --- a/trunk/arch/i386/kernel/smpcommon.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SMP stuff which is common to all sub-architectures. - */ -#include -#include - -DEFINE_PER_CPU(unsigned long, this_cpu_off); -EXPORT_PER_CPU_SYMBOL(this_cpu_off); - -/* Initialize the CPU's GDT. This is either the boot CPU doing itself - (still using the master per-cpu area), or a CPU doing it for a - secondary which will soon come up. */ -__cpuinit void init_gdt(int cpu) -{ - struct desc_struct *gdt = get_cpu_gdt_table(cpu); - - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU].b, - __per_cpu_offset[cpu], 0xFFFFF, - 0x80 | DESCTYPE_S | 0x2, 0x8); - - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; - per_cpu(cpu_number, cpu) = cpu; -} - - -/** - * smp_call_function(): Run a function on all other CPUs. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Unused. - * @wait: If true, wait (atomically) until function has completed on other CPUs. - * - * Returns 0 on success, else a negative status code. - * - * If @wait is true, then returns once @func has returned; otherwise - * it returns just before the target cpu calls @func. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function(void (*func) (void *info), void *info, int nonatomic, - int wait) -{ - return smp_call_function_mask(cpu_online_map, func, info, wait); -} -EXPORT_SYMBOL(smp_call_function); - -/** - * smp_call_function_single - Run a function on another CPU - * @cpu: The target CPU. Cannot be the calling CPU. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Unused. - * @wait: If true, wait until function has completed on other CPUs. - * - * Returns 0 on success, else a negative status code. - * - * If @wait is true, then returns once @func has returned; otherwise - * it returns just before the target cpu calls @func. - */ -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - /* prevent preemption and reschedule on another processor */ - int ret; - int me = get_cpu(); - if (cpu == me) { - WARN_ON(1); - put_cpu(); - return -EBUSY; - } - - ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); - - put_cpu(); - return ret; -} -EXPORT_SYMBOL(smp_call_function_single); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 90da0575fcff..c05e7e861b29 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -733,6 +733,11 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) */ if (nmi_watchdog_tick(regs, reason)) return; +#endif + if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0) + == NOTIFY_STOP) + return; +#ifdef CONFIG_X86_LOCAL_APIC if (!do_nmi_callback(regs, smp_processor_id())) #endif unknown_nmi_error(reason, regs); diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index b87f8548e75a..50d9c52070b1 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -27,6 +27,7 @@ #include #include #include +#include /* TLB state -- visible externally, indexed physically */ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; @@ -421,7 +422,7 @@ find_smp_config(void) VOYAGER_SUS_IN_CONTROL_PORT); current_thread_info()->cpu = boot_cpu_id; - x86_write_percpu(cpu_number, boot_cpu_id); + write_pda(cpu_number, boot_cpu_id); } /* @@ -434,7 +435,7 @@ smp_store_cpu_info(int id) *c = boot_cpu_data; - identify_secondary_cpu(c); + identify_cpu(c); } /* set up the trampoline and return the physical address of the code */ @@ -458,7 +459,7 @@ start_secondary(void *unused) /* external functions not defined in the headers */ extern void calibrate_delay(void); - cpu_init(); + secondary_cpu_init(); /* OK, we're in the routine */ ack_CPI(VIC_CPU_BOOT_CPI); @@ -571,9 +572,7 @@ do_boot_cpu(__u8 cpu) /* init_tasks (in sched.c) is indexed logically */ stack_start.esp = (void *) idle->thread.esp; - init_gdt(cpu); - per_cpu(current_task, cpu) = idle; - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); + init_gdt(cpu, idle); irq_ctx_init(cpu); /* Note: Don't modify initial ss override */ @@ -860,8 +859,8 @@ smp_invalidate_interrupt(void) /* This routine is called with a physical cpu mask */ static void -voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, - unsigned long va) +flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, + unsigned long va) { int stuck = 50000; @@ -913,7 +912,7 @@ flush_tlb_current_task(void) cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); local_flush_tlb(); if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } @@ -935,7 +934,7 @@ flush_tlb_mm (struct mm_struct * mm) leave_mm(smp_processor_id()); } if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } @@ -956,7 +955,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) } if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, va); + flush_tlb_others(cpu_mask, mm, va); preempt_enable(); } @@ -1045,12 +1044,10 @@ smp_call_function_interrupt(void) } static int -voyager_smp_call_function_mask (cpumask_t cpumask, - void (*func) (void *info), void *info, - int wait) +__smp_call_function_mask (void (*func) (void *info), void *info, int retry, + int wait, __u32 mask) { struct call_data_struct data; - u32 mask = cpus_addr(cpumask)[0]; mask &= ~(1< The function to run. This must be fast and non-blocking. + An arbitrary pointer to pass to the function. + If true, keep retrying until ready. + If true, wait until function has completed on other CPUs. + [RETURNS] 0 on success, else a negative status code. Does not return until + remote CPUs are nearly ready to execute <> or are or have executed. +*/ +int +smp_call_function(void (*func) (void *info), void *info, int retry, + int wait) +{ + __u32 mask = cpus_addr(cpu_online_map)[0]; + + return __smp_call_function_mask(func, info, retry, wait, mask); +} +EXPORT_SYMBOL(smp_call_function); + +/* + * smp_call_function_single - Run a function on another CPU + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Currently unused. + * @wait: If true, wait until function has completed on other CPUs. + * + * Retrurns 0 on success, else a negative status code. + * + * Does not return until the remote CPU is nearly ready to execute + * or is or has executed. + */ + +int +smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + __u32 mask = 1 << cpu; + + return __smp_call_function_mask(func, info, nonatomic, wait, mask); +} +EXPORT_SYMBOL(smp_call_function_single); + /* Sorry about the name. In an APIC based system, the APICs * themselves are programmed to send a timer interrupt. This is used * by linux to reschedule the processor. Voyager doesn't have this, @@ -1199,8 +1237,8 @@ smp_alloc_memory(void) } /* send a reschedule CPI to one CPU by physical CPU number*/ -static void -voyager_smp_send_reschedule(int cpu) +void +smp_send_reschedule(int cpu) { send_one_CPI(cpu, VIC_RESCHEDULE_CPI); } @@ -1229,8 +1267,8 @@ safe_smp_processor_id(void) } /* broadcast a halt to all other CPUs */ -static void -voyager_smp_send_stop(void) +void +smp_send_stop(void) { smp_call_function(smp_stop_cpu_function, NULL, 1, 1); } @@ -1892,26 +1930,23 @@ smp_voyager_power_off(void *dummy) smp_stop_cpu_function(NULL); } -static void __init -voyager_smp_prepare_cpus(unsigned int max_cpus) +void __init +smp_prepare_cpus(unsigned int max_cpus) { /* FIXME: ignore max_cpus for now */ smp_boot_cpus(); } -static void __devinit voyager_smp_prepare_boot_cpu(void) +void __devinit smp_prepare_boot_cpu(void) { - init_gdt(smp_processor_id()); - switch_to_new_gdt(); - cpu_set(smp_processor_id(), cpu_online_map); cpu_set(smp_processor_id(), cpu_callout_map); cpu_set(smp_processor_id(), cpu_possible_map); cpu_set(smp_processor_id(), cpu_present_map); } -static int __devinit -voyager_cpu_up(unsigned int cpu) +int __devinit +__cpu_up(unsigned int cpu) { /* This only works at boot for x86. See "rewrite" above. */ if (cpu_isset(cpu, smp_commenced_mask)) @@ -1927,8 +1962,8 @@ voyager_cpu_up(unsigned int cpu) return 0; } -static void __init -voyager_smp_cpus_done(unsigned int max_cpus) +void __init +smp_cpus_done(unsigned int max_cpus) { zap_low_mappings(); } @@ -1937,16 +1972,5 @@ void __init smp_setup_processor_id(void) { current_thread_info()->cpu = hard_smp_processor_id(); - x86_write_percpu(cpu_number, hard_smp_processor_id()); + write_pda(cpu_number, hard_smp_processor_id()); } - -struct smp_ops smp_ops = { - .smp_prepare_boot_cpu = voyager_smp_prepare_boot_cpu, - .smp_prepare_cpus = voyager_smp_prepare_cpus, - .cpu_up = voyager_cpu_up, - .smp_cpus_done = voyager_smp_cpus_done, - - .smp_send_stop = voyager_smp_send_stop, - .smp_send_reschedule = voyager_smp_send_reschedule, - .smp_call_function_mask = voyager_smp_call_function_mask, -}; diff --git a/trunk/arch/i386/mm/discontig.c b/trunk/arch/i386/mm/discontig.c index 860e912a3fbb..aa58720f6871 100644 --- a/trunk/arch/i386/mm/discontig.c +++ b/trunk/arch/i386/mm/discontig.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -98,8 +97,14 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn, #endif extern unsigned long find_max_low_pfn(void); +extern void find_max_pfn(void); extern void add_one_highpage_init(struct page *, int, int); + +extern struct e820map e820; extern unsigned long highend_pfn, highstart_pfn; +extern unsigned long max_low_pfn; +extern unsigned long totalram_pages; +extern unsigned long totalhigh_pages; #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) @@ -355,9 +360,7 @@ void __init zone_sizes_init(void) max_zone_pfns[ZONE_DMA] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; max_zone_pfns[ZONE_NORMAL] = max_low_pfn; -#ifdef CONFIG_HIGHMEM max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; -#endif /* If SRAT has not registered memory, register it now */ if (find_max_pfn_with_active_regions() == 0) { diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index c4784494970e..3549c94467b8 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -791,7 +791,7 @@ static __init int setup_additional_cpus(char *s) early_param("additional_cpus", setup_additional_cpus); /* - * cpu_possible_map should be static, it cannot change as CPUs + * cpu_possible_map should be static, it cannot change as cpu's * are onlined, or offlined. The reason is per-cpu data-structures * are allocated by some modules at init time, and dont expect to * do this dynamically on cpu arrival/departure. diff --git a/trunk/arch/ia64/kernel/crash.c b/trunk/arch/ia64/kernel/crash.c index 1d64ef478dde..aeb79fb28f0b 100644 --- a/trunk/arch/ia64/kernel/crash.c +++ b/trunk/arch/ia64/kernel/crash.c @@ -156,30 +156,24 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) if (!kdump_on_init) return NOTIFY_DONE; - if (val != DIE_INIT_MONARCH_LEAVE && - val != DIE_INIT_SLAVE_LEAVE && - val != DIE_INIT_MONARCH_PROCESS && + if (val != DIE_INIT_MONARCH_ENTER && + val != DIE_INIT_SLAVE_ENTER && val != DIE_MCA_RENDZVOUS_LEAVE && val != DIE_MCA_MONARCH_LEAVE) return NOTIFY_DONE; nd = (struct ia64_mca_notify_die *)args->err; - /* Reason code 1 means machine check rendezvous*/ - if ((val == DIE_INIT_MONARCH_LEAVE || val == DIE_INIT_SLAVE_LEAVE - || val == DIE_INIT_MONARCH_PROCESS) && nd->sos->rv_rc == 1) + /* Reason code 1 means machine check rendezous*/ + if ((val == DIE_INIT_MONARCH_ENTER || val == DIE_INIT_SLAVE_ENTER) && + nd->sos->rv_rc == 1) return NOTIFY_DONE; switch (val) { - case DIE_INIT_MONARCH_PROCESS: - atomic_set(&kdump_in_progress, 1); - *(nd->monarch_cpu) = -1; - break; - case DIE_INIT_MONARCH_LEAVE: + case DIE_INIT_MONARCH_ENTER: machine_kdump_on_init(); break; - case DIE_INIT_SLAVE_LEAVE: - if (atomic_read(&kdump_in_progress)) - unw_init_running(kdump_cpu_freeze, NULL); + case DIE_INIT_SLAVE_ENTER: + unw_init_running(kdump_cpu_freeze, NULL); break; case DIE_MCA_RENDZVOUS_LEAVE: if (atomic_read(&kdump_in_progress)) @@ -221,10 +215,8 @@ static ctl_table sys_table[] = { static int machine_crash_setup(void) { - /* be notified before default_monarch_init_process */ static struct notifier_block kdump_init_notifier_nb = { .notifier_call = kdump_init_notifier, - .priority = 1, }; int ret; if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0) diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index 95f517515235..144b056282af 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1585,8 +1585,5 @@ sys_call_table: data8 sys_getcpu data8 sys_epoll_pwait // 1305 data8 sys_utimensat - data8 sys_signalfd - data8 sys_timerfd - data8 sys_eventfd .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 407b45870489..b4c239685d2e 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -4,7 +4,7 @@ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * * This file contains the code used by various IRQ handling routines: - * asking for different IRQs should be done through these routines + * asking for different IRQ's should be done through these routines * instead of just grabbing them. Thus setups with different IRQ numbers * shouldn't result in any weird surprises, and installing new handlers * should be easier. @@ -12,7 +12,7 @@ * Copyright (C) Ashok Raj, Intel Corporation 2004 * * 4/14/2004: Added code to handle cpu migration and do safe irq - * migration without losing interrupts for iosapic + * migration without lossing interrupts for iosapic * architecture. */ @@ -190,7 +190,7 @@ void fixup_irqs(void) } /* - * Phase 1: Locate IRQs bound to this cpu and + * Phase 1: Locate irq's bound to this cpu and * relocate them for cpu removal. */ migrate_irqs(); diff --git a/trunk/arch/ia64/kernel/irq_lsapic.c b/trunk/arch/ia64/kernel/irq_lsapic.c index e56a7a36aca3..c2f07beb1759 100644 --- a/trunk/arch/ia64/kernel/irq_lsapic.c +++ b/trunk/arch/ia64/kernel/irq_lsapic.c @@ -23,7 +23,7 @@ lsapic_noop_startup (unsigned int irq) static void lsapic_noop (unsigned int irq) { - /* nothing to do... */ + /* nuthing to do... */ } static int lsapic_retrigger(unsigned int irq) diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 5bc46f151344..72e593e94053 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -151,12 +151,12 @@ static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot, cmp_inst.l = kprobe_inst; if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) { - /* Integer compare - Register Register (A6 type)*/ + /* Integere compare - Register Register (A6 type)*/ if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1)) ctype_unc = 1; } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) { - /* Integer compare - Immediate Register (A8 type)*/ + /* Integere compare - Immediate Register (A8 type)*/ if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1)) ctype_unc = 1; } @@ -820,7 +820,7 @@ static int __kprobes post_kprobes_handler(struct pt_regs *regs) return 1; } -int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) +static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -904,6 +904,13 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, if (post_kprobes_handler(args->regs)) ret = NOTIFY_STOP; break; + case DIE_PAGE_FAULT: + /* kprobe_running() needs smp_processor_id() */ + preempt_disable(); + if (kprobe_running() && + kprobes_fault_handler(args->regs, args->trapnr)) + ret = NOTIFY_STOP; + preempt_enable(); default: break; } @@ -947,7 +954,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) /* * Callee owns the argument space and could overwrite it, eg * tail call optimization. So to be absolutely safe - * we save the argument space before transferring the control + * we save the argument space before transfering the control * to instrumented jprobe function which runs in * the process context */ diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 1ead5ea6c5ce..26814de6c29a 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -273,6 +273,7 @@ static void ia64_mlogbuf_finish(int wait) mlogbuf_finished = 1; } +EXPORT_SYMBOL(ia64_mlogbuf_finish); /* * Print buffered messages from INIT context. @@ -1476,10 +1477,6 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi struct task_struct *g, *t; if (val != DIE_INIT_MONARCH_PROCESS) return NOTIFY_DONE; -#ifdef CONFIG_KEXEC - if (atomic_read(&kdump_in_progress)) - return NOTIFY_DONE; -#endif /* * FIXME: mlogbuf will brim over with INIT stack dumps. diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index aba813c2c150..70b8bdbb7e6f 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -438,7 +438,7 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci, * @peidx: pointer of index of processor error section * * Return value: - * target address on Success / 0 on Failure + * target address on Success / 0 on Failue */ static u64 get_target_identifier(peidx_table_t *peidx) @@ -701,7 +701,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, return fatal_mca("External bus check fatal status"); /* - * This is a local MCA and estimated as a recoverable error. + * This is a local MCA and estimated as a recoverble error. */ if (platform) return recover_from_platform_error(slidx, peidx, pbci, sos); diff --git a/trunk/arch/ia64/kernel/module.c b/trunk/arch/ia64/kernel/module.c index 196287928bae..158e3c51bb77 100644 --- a/trunk/arch/ia64/kernel/module.c +++ b/trunk/arch/ia64/kernel/module.c @@ -861,7 +861,7 @@ apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex, /* * Modules contain a single unwind table which covers both the core and the init text * sections but since the two are not contiguous, we need to split this table up such that - * we can register (and unregister) each "segment" separately. Fortunately, this sounds + * we can register (and unregister) each "segment" seperately. Fortunately, this sounds * more complicated than it really is. */ static void diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index b7133cabdbea..e7191ca30b16 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -1318,7 +1318,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) { unsigned long flags; /* - * validity checks on cpu_mask have been done upstream + * validy checks on cpu_mask have been done upstream */ LOCK_PFS(flags); @@ -1384,7 +1384,7 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) { unsigned long flags; /* - * validity checks on cpu_mask have been done upstream + * validy checks on cpu_mask have been done upstream */ LOCK_PFS(flags); @@ -1835,7 +1835,7 @@ pfm_flush(struct file *filp, fl_owner_t id) /* * remove our file from the async queue, if we use this mode. * This can be done without the context being protected. We come - * here when the context has become unreachable by other tasks. + * here when the context has become unreacheable by other tasks. * * We may still have active monitoring at this point and we may * end up in pfm_overflow_handler(). However, fasync_helper() @@ -2132,7 +2132,7 @@ pfm_close(struct inode *inode, struct file *filp) filp->private_data = NULL; /* - * if we free on the spot, the context is now completely unreachable + * if we free on the spot, the context is now completely unreacheable * from the callers side. The monitored task side is also cut, so we * can freely cut. * @@ -2562,7 +2562,7 @@ pfm_reset_pmu_state(pfm_context_t *ctx) ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1; /* - * bitmask of all PMDs that are accessible to this context + * bitmask of all PMDs that are accesible to this context */ ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0]; @@ -3395,7 +3395,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) if (unlikely(!PMD_IS_IMPL(cnum))) goto error; /* * we can only read the register that we use. That includes - * the one we explicitly initialize AND the one we want included + * the one we explicitely initialize AND the one we want included * in the sampling buffer (smpl_regs). * * Having this restriction allows optimization in the ctxsw routine @@ -3715,7 +3715,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * if non-blocking, then we ensure that the task will go into * pfm_handle_work() before returning to user mode. * - * We cannot explicitly reset another task, it MUST always + * We cannot explicitely reset another task, it MUST always * be done by the task itself. This works for system wide because * the tool that is controlling the session is logically doing * "self-monitoring". @@ -4644,7 +4644,7 @@ pfm_exit_thread(struct task_struct *task) switch(state) { case PFM_CTX_UNLOADED: /* - * only comes to this function if pfm_context is not NULL, i.e., cannot + * only comes to thios function if pfm_context is not NULL, i.e., cannot * be in unloaded state */ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid); @@ -5247,7 +5247,7 @@ pfm_end_notify_user(pfm_context_t *ctx) /* * main overflow processing routine. - * it can be called from the interrupt path or explicitly during the context switch code + * it can be called from the interrupt path or explicitely during the context switch code */ static void pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs) diff --git a/trunk/arch/ia64/kernel/perfmon_mckinley.h b/trunk/arch/ia64/kernel/perfmon_mckinley.h index c4bec7a9d18f..9becccda2897 100644 --- a/trunk/arch/ia64/kernel/perfmon_mckinley.h +++ b/trunk/arch/ia64/kernel/perfmon_mckinley.h @@ -181,7 +181,7 @@ static pmu_config_t pmu_conf_mck={ .pmc_desc = pfm_mck_pmc_desc, .num_ibrs = 8, .num_dbrs = 8, - .use_rr_dbregs = 1 /* debug register are use for range restrictions */ + .use_rr_dbregs = 1 /* debug register are use for range retrictions */ }; diff --git a/trunk/arch/ia64/kernel/sal.c b/trunk/arch/ia64/kernel/sal.c index 27c2ef445a56..37c876f95dba 100644 --- a/trunk/arch/ia64/kernel/sal.c +++ b/trunk/arch/ia64/kernel/sal.c @@ -134,7 +134,7 @@ set_smp_redirect (int flag) * interrupt redirection. The reason is this would require that * All interrupts be stopped and hard bind the irq to a cpu. * Later when the interrupt is fired we need to set the redir hint - * on again in the vector. This is cumbersome for something that the + * on again in the vector. This is combersome for something that the * user mode irq balancer will solve anyways. */ no_int_routing=1; diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index 25cd75f50ab1..89f6b138a62c 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -162,7 +162,7 @@ static DEFINE_SPINLOCK(data_saved_lock); /** salinfo_platform_oemdata - optional callback to decode oemdata from an error * record. * @sect_header: pointer to the start of the section to decode. - * @oemdata: returns vmalloc area containing the decoded output. + * @oemdata: returns vmalloc area containing the decded output. * @oemdata_size: returns length of decoded output (strlen). * * Description: If user space asks for oem data to be decoded by the kernel diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index eaa6a24bc0b6..9df1efe7487d 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -576,7 +576,7 @@ setup_arch (char **cmdline_p) } /* - * Display cpu info for all CPUs. + * Display cpu info for all cpu's. */ static int show_cpuinfo (struct seq_file *m, void *v) @@ -761,7 +761,7 @@ identify_cpu (struct cpuinfo_ia64 *c) c->cpu = smp_processor_id(); /* below default values will be overwritten by identify_siblings() - * for Multi-Threading/Multi-Core capable CPUs + * for Multi-Threading/Multi-Core capable cpu's */ c->threads_per_core = c->cores_per_socket = c->num_log = 1; c->socket_id = -1; @@ -947,7 +947,7 @@ cpu_init (void) ia32_cpu_init(); #endif - /* Clear ITC to eliminate sched_clock() overflows in human time. */ + /* Clear ITC to eliminiate sched_clock() overflows in human time. */ ia64_set_itc(0); /* disable all local interrupt sources: */ diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index b3a47f986e1e..221de3804560 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -186,7 +186,7 @@ handle_IPI (int irq, void *dev_id) } /* - * Called with preemption disabled. + * Called with preeemption disabled. */ static inline void send_IPI_single (int dest_cpu, int op) @@ -196,7 +196,7 @@ send_IPI_single (int dest_cpu, int op) } /* - * Called with preemption disabled. + * Called with preeemption disabled. */ static inline void send_IPI_allbutself (int op) @@ -210,7 +210,7 @@ send_IPI_allbutself (int op) } /* - * Called with preemption disabled. + * Called with preeemption disabled. */ static inline void send_IPI_all (int op) @@ -223,7 +223,7 @@ send_IPI_all (int op) } /* - * Called with preemption disabled. + * Called with preeemption disabled. */ static inline void send_IPI_self (int op) @@ -252,7 +252,7 @@ kdump_smp_send_init(void) } #endif /* - * Called with preemption disabled. + * Called with preeemption disabled. */ void smp_send_reschedule (int cpu) @@ -261,7 +261,7 @@ smp_send_reschedule (int cpu) } /* - * Called with preemption disabled. + * Called with preeemption disabled. */ static void smp_send_local_flush_tlb (int cpu) diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 542958079f1b..a44792d0f3a9 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -694,7 +694,7 @@ int migrate_platform_irqs(unsigned int cpu) set_cpei_target_cpu(new_cpei_cpu); desc = irq_desc + ia64_cpe_irq; /* - * Switch for now, immediately, we need to do fake intr + * Switch for now, immediatly, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ @@ -840,7 +840,7 @@ __cpu_up (unsigned int cpu) } /* - * Assume that CPUs have been discovered by some platform-dependent interface. For + * Assume that CPU's have been discovered by some platform-dependent interface. For * SoftSDV/Lion, that would be ACPI. * * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP(). @@ -854,7 +854,7 @@ init_smp_config(void) } *ap_startup; long sal_ret; - /* Tell SAL where to drop the APs. */ + /* Tell SAL where to drop the AP's. */ ap_startup = (struct fptr *) start_ap; sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0); diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index 15ad85da15a9..b8e0d70bf989 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -304,7 +304,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) * Lower 4 bits are used as a count. Upper bits are a sequence * number that is updated when count is reset. The cmpxchg will * fail is seqno has changed. This minimizes mutiple cpus - * resetting the count. + * reseting the count. */ if (current_jiffies > last.time) (void) cmpxchg_acq(&last.count, count, 16 + (count & ~15)); diff --git a/trunk/arch/ia64/kernel/unwind.c b/trunk/arch/ia64/kernel/unwind.c index 7d3dd6cdafa4..fe1426266b9b 100644 --- a/trunk/arch/ia64/kernel/unwind.c +++ b/trunk/arch/ia64/kernel/unwind.c @@ -2,7 +2,7 @@ * Copyright (C) 1999-2004 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 2003 Fenghua Yu - * - Change pt_regs_off() to make it less dependent on pt_regs structure. + * - Change pt_regs_off() to make it less dependant on pt_regs structure. */ /* * This file implements call frame unwind support for the Linux diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 0dbf0e81f8c0..38085ac18338 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -317,7 +317,7 @@ static void __meminit scatter_node_data(void) * node_online_map is not set for hot-added nodes at this time, * because we are halfway through initialization of the new node's * structures. If for_each_online_node() is used, a new node's - * pg_data_ptrs will be not initialized. Instead of using it, + * pg_data_ptrs will be not initialized. Insted of using it, * pgdat_list[] is checked. */ for_each_node(node) { diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c index b87f785c2416..21658e02116c 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -19,24 +19,36 @@ extern void die (char *, struct pt_regs *, long); #ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, int trap) +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) { - int ret = 0; - - if (!user_mode(regs)) { - /* kprobe_running() needs smp_processor_id() */ - preempt_disable(); - if (kprobe_running() && kprobes_fault_handler(regs, trap)) - ret = 1; - preempt_enable(); - } + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} - return ret; +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } #else -static inline int notify_page_fault(struct pt_regs *regs, int trap) +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) { - return 0; + return NOTIFY_DONE; } #endif @@ -105,7 +117,8 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re /* * This is to handle the kprobes on user space access instructions */ - if (notify_page_fault(regs, TRAP_BRKPT)) + if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, + SIGSEGV) == NOTIFY_STOP) return; down_read(&mm->mmap_sem); diff --git a/trunk/arch/ia64/sn/kernel/bte.c b/trunk/arch/ia64/sn/kernel/bte.c index b362d6d6a8c8..ff1c55601178 100644 --- a/trunk/arch/ia64/sn/kernel/bte.c +++ b/trunk/arch/ia64/sn/kernel/bte.c @@ -63,7 +63,7 @@ static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode) * Use the block transfer engine to move kernel memory from src to dest * using the assigned mode. * - * Parameters: + * Paramaters: * src - physical address of the transfer source. * dest - physical address of the transfer destination. * len - number of bytes to transfer from source to dest. @@ -247,7 +247,7 @@ EXPORT_SYMBOL(bte_copy); * use the block transfer engine to move kernel * memory from src to dest using the assigned mode. * - * Parameters: + * Paramaters: * src - physical address of the transfer source. * dest - physical address of the transfer destination. * len - number of bytes to transfer from source to dest. @@ -255,7 +255,7 @@ EXPORT_SYMBOL(bte_copy); * for IBCT0/1 in the SGI documentation. * * NOTE: If the source, dest, and len are all cache line aligned, - * then it would be _FAR_ preferable to use bte_copy instead. + * then it would be _FAR_ preferrable to use bte_copy instead. */ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) { @@ -300,7 +300,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) * a standard bte copy. * * One nasty exception to the above rule is when the - * source and destination are not symmetrically + * source and destination are not symetrically * mis-aligned. If the source offset from the first * cache line is different from the destination offset, * we make the first section be the entire transfer @@ -337,7 +337,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) if (footBcopyDest == (headBcopyDest + headBcopyLen)) { /* - * We have two contiguous bcopy + * We have two contigous bcopy * blocks. Merge them. */ headBcopyLen += footBcopyLen; @@ -375,7 +375,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) } else { /* - * The transfer is not symmetric, we will + * The transfer is not symetric, we will * allocate a buffer large enough for all the * data, bte_copy into that buffer and then * bcopy to the destination. diff --git a/trunk/arch/ia64/sn/kernel/bte_error.c b/trunk/arch/ia64/sn/kernel/bte_error.c index 27c5936ccfe9..b6fcf8164f2b 100644 --- a/trunk/arch/ia64/sn/kernel/bte_error.c +++ b/trunk/arch/ia64/sn/kernel/bte_error.c @@ -105,7 +105,7 @@ int shub1_bte_error_handler(unsigned long _nodepda) } BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, smp_processor_id())); - /* Re-enable both bte interfaces */ + /* Reenable both bte interfaces */ imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM); imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1; REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval); @@ -243,7 +243,7 @@ bte_crb_error_handler(cnodeid_t cnode, int btenum, /* * The caller has already figured out the error type, we save that - * in the bte handle structure for the thread exercising the + * in the bte handle structure for the thread excercising the * interface to consume. */ bte->bh_error = ioe->ie_errortype + BTEFAIL_OFFSET; diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index 787ed642dd49..7ed72d3faf73 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -479,7 +479,7 @@ sn_io_early_init(void) } /* - * prime sn_pci_provider[]. Individual provider init routines will + * prime sn_pci_provider[]. Individial provider init routines will * override their respective default entries. */ diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index a574fcd163dd..a9bed5ca2ed8 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -167,7 +167,7 @@ void __init early_sn_setup(void) * IO on SN2 is done via SAL calls, early_printk won't work without this. * * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c. - * Any changes to those file may have to be made here as well. + * Any changes to those file may have to be made hereas well. */ efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab); config_tables = __va(efi_systab->tables); diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c index 033c8a9f000e..5d318b579fb1 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -104,7 +104,7 @@ static inline unsigned long wait_piowc(void) * * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order. * Context switching user threads which have memory-mapped MMIO may cause - * PIOs to issue from separate CPUs, thus the PIO writes must be drained + * PIOs to issue from seperate CPUs, thus the PIO writes must be drained * from the previous CPU's Shub before execution resumes on the new CPU. */ void sn_migrate(struct task_struct *task) diff --git a/trunk/arch/ia64/sn/kernel/xpc_channel.c b/trunk/arch/ia64/sn/kernel/xpc_channel.c index 44ccc0d789c9..c08db9c2375d 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_channel.c +++ b/trunk/arch/ia64/sn/kernel/xpc_channel.c @@ -293,7 +293,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, /* - * Pull the remote per partition specific variables from the specified + * Pull the remote per partititon specific variables from the specified * partition. */ enum xpc_retval @@ -461,7 +461,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between // >>> iterations of the for-loop, bail if set? - // >>> should we impose a minimum #of entries? like 4 or 8? + // >>> should we impose a minumum #of entries? like 4 or 8? for (nentries = ch->local_nentries; nentries > 0; nentries--) { nbytes = nentries * ch->msg_size; @@ -514,7 +514,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between // >>> iterations of the for-loop, bail if set? - // >>> should we impose a minimum #of entries? like 4 or 8? + // >>> should we impose a minumum #of entries? like 4 or 8? for (nentries = ch->remote_nentries; nentries > 0; nentries--) { nbytes = nentries * ch->msg_size; @@ -1478,7 +1478,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part) /* - * Before proceeding with the teardown we have to wait until all + * Before proceding with the teardown we have to wait until all * existing references cease. */ wait_event(part->teardown_wq, (atomic_read(&part->references) == 0)); diff --git a/trunk/arch/ia64/sn/kernel/xpnet.c b/trunk/arch/ia64/sn/kernel/xpnet.c index e58fcadff2e9..da7213530972 100644 --- a/trunk/arch/ia64/sn/kernel/xpnet.c +++ b/trunk/arch/ia64/sn/kernel/xpnet.c @@ -531,7 +531,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp); /* - * If we wanted to allow promiscuous mode to work like an + * If we wanted to allow promiscous mode to work like an * unswitched network, this would be a good point to OR in a * mask of partitions which should be receiving all packets. */ diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index d79ddacfba2d..7a291a271511 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -333,7 +333,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) /* * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work * around hw issues at the pci bus level. SGI proms older than - * 4.10 don't implement this. + * 4.10 don't implment this. */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, @@ -348,7 +348,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) /* * If the above failed, retry using the SAL_PROBE call which should * be present in all proms (but which cannot work round PCI chipset - * bugs). This code is retained for compatibility with old + * bugs). This code is retained for compatability with old * pre-4.10 proms, and should be removed at some point in the future. */ @@ -379,7 +379,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) /* * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work * around hw issues at the pci bus level. SGI proms older than - * 4.10 don't implement this. + * 4.10 don't implment this. */ SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, @@ -394,7 +394,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) /* * If the above failed, retry using the SAL_PROBE call which should * be present in all proms (but which cannot work round PCI chipset - * bugs). This code is retained for compatibility with old + * bugs). This code is retained for compatability with old * pre-4.10 proms, and should be removed at some point in the future. */ diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 239b3cedcf2b..935029fc400d 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -30,7 +30,7 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number, /* * find_free_ate: Find the first free ate index starting from the given - * index for the desired consecutive count. + * index for the desired consequtive count. */ static int find_free_ate(struct ate_resource *ate_resource, int start, int count) @@ -88,7 +88,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, return -1; /* - * Find the required number of free consecutive ates. + * Find the required number of free consequtive ates. */ start_index = find_free_ate(ate_resource, ate_resource->lowest_free_index, @@ -105,7 +105,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource, /* * Allocate "count" contiguous Bridge Address Translation Entries * on the specified bridge to be used for PCI to XTALK mappings. - * Indices in rm map range from 1..num_entries. Indices returned + * Indices in rm map range from 1..num_entries. Indicies returned * to caller range from 0..num_entries-1. * * Return the start index on success, -1 on failure. diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index e626e50a938a..95af40cb22f2 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -201,7 +201,7 @@ pcibr_dmatrans_direct32(struct pcidev_info * info, } /* - * Wrapper routine for freeing DMA maps + * Wrapper routine for free'ing DMA maps * DMA mappings for Direct 64 and 32 do not have any DMA maps. */ void diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index b9bedbd6e1d6..8a2cb4e691fd 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -223,7 +223,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) /* * Scan all vga controllers on this bus making sure they all - * support FW. If not, return. + * suport FW. If not, return. */ list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) { @@ -364,7 +364,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr) * @req_size: len (bytes) to map * * Map @paddr into CA address space using the GART mechanism. The mapped - * dma_addr_t is guaranteed to be contiguous in CA bus space. + * dma_addr_t is guarenteed to be contiguous in CA bus space. */ static dma_addr_t tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size) @@ -526,7 +526,7 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags) return 0; /* - * If card is 64 or 48 bit addressable, use a direct mapping. 32 + * If card is 64 or 48 bit addresable, use a direct mapping. 32 * bit direct is so restrictive w.r.t. where the memory resides that * we don't use it even though CA has some support. */ diff --git a/trunk/arch/ia64/sn/pci/tioce_provider.c b/trunk/arch/ia64/sn/pci/tioce_provider.c index f4c0b961a939..35f854fb6120 100644 --- a/trunk/arch/ia64/sn/pci/tioce_provider.c +++ b/trunk/arch/ia64/sn/pci/tioce_provider.c @@ -256,9 +256,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base, * @ct_addr: the coretalk address to map * @len: number of bytes to map * - * Given the addressing type, set up various parameters that define the + * Given the addressing type, set up various paramaters that define the * ATE pool to use. Search for a contiguous block of entries to cover the - * length, and if enough resources exist, fill in the ATEs and construct a + * length, and if enough resources exist, fill in the ATE's and construct a * tioce_dmamap struct to track the mapping. */ static u64 @@ -581,8 +581,8 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, */ if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) { /* - * We have two options for 40-bit mappings: 16GB "super" ATEs - * and 64MB "regular" ATEs. We'll try both if needed for a + * We have two options for 40-bit mappings: 16GB "super" ATE's + * and 64MB "regular" ATE's. We'll try both if needed for a * given mapping but which one we try first depends on the * size. For requests >64MB, prefer to use a super page with * regular as the fallback. Otherwise, try in the reverse order. @@ -687,8 +687,8 @@ tioce_error_intr_handler(int irq, void *arg) } /** - * tioce_reserve_m32 - reserve M32 ATEs for the indicated address range - * @tioce_kernel: TIOCE context to reserve ATEs for + * tioce_reserve_m32 - reserve M32 ate's for the indicated address range + * @tioce_kernel: TIOCE context to reserve ate's for * @base: starting bus address to reserve * @limit: last bus address to reserve * @@ -763,7 +763,7 @@ tioce_kern_init(struct tioce_common *tioce_common) /* * Set PMU pagesize to the largest size available, and zero out - * the ATEs. + * the ate's. */ tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base; @@ -784,7 +784,7 @@ tioce_kern_init(struct tioce_common *tioce_common) } /* - * Reserve ATEs corresponding to reserved address ranges. These + * Reserve ATE's corresponding to reserved address ranges. These * include: * * Memory space covered by each PPB mem base/limit register diff --git a/trunk/arch/m68k/lib/uaccess.c b/trunk/arch/m68k/lib/uaccess.c index 13854ed8cd9a..865f9fb9e686 100644 --- a/trunk/arch/m68k/lib/uaccess.c +++ b/trunk/arch/m68k/lib/uaccess.c @@ -181,7 +181,7 @@ EXPORT_SYMBOL(strnlen_user); * Zero Userspace */ -unsigned long __clear_user(void __user *to, unsigned long n) +unsigned long clear_user(void __user *to, unsigned long n) { unsigned long res; @@ -219,4 +219,4 @@ unsigned long __clear_user(void __user *to, unsigned long n) return res; } -EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(clear_user); diff --git a/trunk/arch/sh64/Kconfig b/trunk/arch/sh64/Kconfig index ff654204b7d4..e14b533558c8 100644 --- a/trunk/arch/sh64/Kconfig +++ b/trunk/arch/sh64/Kconfig @@ -17,9 +17,6 @@ config MMU bool default y -config QUICKLIST - def_bool y - config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/sh64/configs/cayman_defconfig b/trunk/arch/sh64/configs/cayman_defconfig index ed035084b053..d81df574a7f7 100644 --- a/trunk/arch/sh64/configs/cayman_defconfig +++ b/trunk/arch/sh64/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc1 -# Mon May 14 08:43:31 2007 +# Linux kernel version: 2.6.18 +# Tue Oct 3 13:30:51 2006 # CONFIG_SUPERH=y CONFIG_SUPERH64=y @@ -10,8 +10,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -35,15 +33,13 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -53,19 +49,14 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -144,7 +135,7 @@ CONFIG_SH64_ID2815_WORKAROUND=y # CONFIG_HEARTBEAT=y CONFIG_HDSP253_LED=y -# CONFIG_SH_DMA is not set +CONFIG_SH_DMA=y CONFIG_PREEMPT=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -155,20 +146,23 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# # CONFIG_HOTPLUG_PCI is not set # @@ -186,13 +180,13 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -213,13 +207,11 @@ CONFIG_IP_PNP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -264,16 +256,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set # # Device Drivers @@ -286,13 +269,16 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -303,7 +289,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -321,17 +306,10 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_BLINK is not set - # # ATA/ATAPI/MFM/RLL support # @@ -342,7 +320,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -362,7 +339,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -402,16 +378,18 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set -# CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set # @@ -430,7 +408,6 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -451,6 +428,10 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set + +# +# PHY device support +# # CONFIG_PHYLIB is not set # @@ -498,8 +479,10 @@ CONFIG_NET_PCI=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set -CONFIG_NETDEV_1000=y + +# +# Ethernet (1000 Mbit) +# # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -515,16 +498,14 @@ CONFIG_NETDEV_1000=y # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -CONFIG_NETDEV_10000=y + +# +# Ethernet (10000 Mbit) +# # CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_MLX4_CORE is not set -CONFIG_MLX4_DEBUG=y # # Token Ring devices @@ -532,10 +513,13 @@ CONFIG_MLX4_DEBUG=y # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -587,17 +571,9 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -643,6 +619,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -659,8 +639,13 @@ CONFIG_WATCHDOG=y # CONFIG_WDTPCI is not set CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -668,7 +653,11 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y +# CONFIG_TELCLOCK is not set + +# +# I2C support +# # CONFIG_I2C is not set # @@ -680,60 +669,44 @@ CONFIG_DEVPORT=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # -# Multifunction device drivers +# Misc devices # -# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -CONFIG_DAB=y +CONFIG_VIDEO_V4L2=y # -# Graphics support +# Digital Video Broadcasting Devices # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DVB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -CONFIG_FB=y CONFIG_FIRMWARE_EDID=y -# CONFIG_FB_DDC is not set +CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -747,17 +720,13 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set CONFIG_FB_KYRO=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set # CONFIG_FB_VIRTUAL is not set # @@ -777,6 +746,10 @@ CONFIG_FONT_8x16=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -784,18 +757,13 @@ CONFIG_LOGO=y # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_LOGO_SUPERH_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound # # CONFIG_SOUND is not set -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - # # USB support # @@ -812,6 +780,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# # CONFIG_MMC is not set # @@ -864,7 +836,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -872,7 +843,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=y CONFIG_ROMFS_FS=y @@ -942,7 +912,6 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -972,18 +941,12 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set # # Native Language Support # # CONFIG_NLS is not set -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - # # Profiling support # @@ -996,29 +959,28 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y CONFIG_SCHEDSTATS=y -# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set CONFIG_SH64_PROC_TLB=y @@ -1042,15 +1004,10 @@ CONFIG_SH64_SR_WATCH=y # # Library routines # -CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/trunk/arch/sh64/kernel/entry.S b/trunk/arch/sh64/kernel/entry.S index 7013fcb6665c..40d45346248d 100644 --- a/trunk/arch/sh64/kernel/entry.S +++ b/trunk/arch/sh64/kernel/entry.S @@ -947,14 +947,14 @@ ret_with_reschedule: ! FIXME:!!! ! no handling of TIF_SYSCALL_TRACE yet!! - movi _TIF_NEED_RESCHED, r8 + movi (1 << TIF_NEED_RESCHED), r8 and r8, r7, r8 pta work_resched, tr0 bne r8, ZERO, tr0 pta restore_all, tr1 - movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 + movi (1 << TIF_SIGPENDING), r8 and r8, r7, r8 pta work_notifysig, tr0 bne r8, ZERO, tr0 diff --git a/trunk/arch/sh64/kernel/irq.c b/trunk/arch/sh64/kernel/irq.c index 9412b7166700..f68b4f6c9b31 100644 --- a/trunk/arch/sh64/kernel/irq.c +++ b/trunk/arch/sh64/kernel/irq.c @@ -94,7 +94,6 @@ asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs) */ asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs) { - struct pt_regs *old_regs = set_irq_regs(regs); int irq; irq_enter(); @@ -102,14 +101,13 @@ asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs) irq = irq_demux(vector_num); if (irq >= 0) { - __do_IRQ(irq); + __do_IRQ(irq, regs); } else { printk("unexpected IRQ trap at vector %03lx\n", vector_num); } irq_exit(); - set_irq_regs(old_regs); return 1; } diff --git a/trunk/arch/sh64/kernel/pci_sh5.c b/trunk/arch/sh64/kernel/pci_sh5.c index fb51660847c8..49862e165c06 100644 --- a/trunk/arch/sh64/kernel/pci_sh5.c +++ b/trunk/arch/sh64/kernel/pci_sh5.c @@ -340,9 +340,8 @@ static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin) return result; } -static irqreturn_t pcish5_err_irq(int irq, void *dev_id) +irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); unsigned pci_int, pci_air, pci_cir, pci_aint; pci_int = SH5PCI_READ(INT); @@ -369,13 +368,15 @@ static irqreturn_t pcish5_err_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t pcish5_serr_irq(int irq, void *dev_id) +irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs) { printk("SERR IRQ\n"); return IRQ_NONE; } +#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) + static void __init pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, struct resource *memr) @@ -432,8 +433,8 @@ pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, mem_res.end -= mem_res.start; /* Align the sizes up by bridge rules */ - io_res.end = ALIGN(io_res.end, 4*1024) - 1; - mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1; + io_res.end = ROUND_UP(io_res.end, 4*1024) - 1; + mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1; /* Adjust the bridge's allocation requirements */ bridge->resource[0].end = bridge->resource[0].start + io_res.end; @@ -446,16 +447,18 @@ pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, /* adjust parent's resource requirements */ if (ior) { - ior->end = ALIGN(ior->end, 4*1024); + ior->end = ROUND_UP(ior->end, 4*1024); ior->end += io_res.end; } if (memr) { - memr->end = ALIGN(memr->end, 1*1024*1024); + memr->end = ROUND_UP(memr->end, 1*1024*1024); memr->end += mem_res.end; } } +#undef ROUND_UP + static void __init pcibios_size_bridges(void) { struct resource io_res, mem_res; diff --git a/trunk/arch/sh64/kernel/pci_sh5.h b/trunk/arch/sh64/kernel/pci_sh5.h index c71159dd04b9..8f21f5d2aa3e 100644 --- a/trunk/arch/sh64/kernel/pci_sh5.h +++ b/trunk/arch/sh64/kernel/pci_sh5.h @@ -4,7 +4,7 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * - * Definitions for the SH5 PCI hardware. + * Defintions for the SH5 PCI hardware. */ /* Product ID */ diff --git a/trunk/arch/sh64/kernel/process.c b/trunk/arch/sh64/kernel/process.c index 1b89c9dfb93d..525d0ec19b78 100644 --- a/trunk/arch/sh64/kernel/process.c +++ b/trunk/arch/sh64/kernel/process.c @@ -387,7 +387,7 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) * NOTE! Only a kernel-only process(ie the swapper or direct descendants * who haven't done an "execve()") should use this: it will work within * a system call from a "real" process, but the process memory space will - * not be freed until both the parent and the child have exited. + * not be free'd until both the parent and the child have exited. */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { diff --git a/trunk/arch/sh64/kernel/signal.c b/trunk/arch/sh64/kernel/signal.c index c8525ade0564..b76bdfa473d6 100644 --- a/trunk/arch/sh64/kernel/signal.c +++ b/trunk/arch/sh64/kernel/signal.c @@ -698,9 +698,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (try_to_freeze()) goto no_signal; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else if (!oldset) + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, 0); @@ -708,15 +706,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, oldset, regs); - - /* - * If a signal was successfully delivered, the saved sigmask - * is in its frame, and we can clear the TIF_RESTORE_SIGMASK - * flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - return 1; } @@ -724,27 +713,13 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* Did we come from a system call? */ if (regs->syscall_nr >= 0) { /* Restart the system call - no handlers present */ - switch (regs->regs[REG_RET]) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: + if (regs->regs[REG_RET] == -ERESTARTNOHAND || + regs->regs[REG_RET] == -ERESTARTSYS || + regs->regs[REG_RET] == -ERESTARTNOINTR) { /* Decode Syscall # */ regs->regs[REG_RET] = regs->syscall_nr; regs->pc -= 4; - break; - - case -ERESTART_RESTARTBLOCK: - regs->regs[REG_RET] = __NR_restart_syscall; - regs->pc -= 4; - break; } } - - /* No signal to deliver -- put the saved sigmask back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } - return 0; } diff --git a/trunk/arch/sh64/kernel/syscalls.S b/trunk/arch/sh64/kernel/syscalls.S index a5c680d29384..c0079d54c850 100644 --- a/trunk/arch/sh64/kernel/syscalls.S +++ b/trunk/arch/sh64/kernel/syscalls.S @@ -2,7 +2,7 @@ * arch/sh64/kernel/syscalls.S * * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2004 - 2007 Paul Mundt + * Copyright (C) 2004 Paul Mundt * Copyright (C) 2003, 2004 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -20,7 +20,7 @@ */ .globl sys_call_table sys_call_table: - .long sys_restart_syscall /* 0 - old "setup()" system call */ + .long sys_ni_syscall /* 0 - old "setup()" system call */ .long sys_exit .long sys_fork .long sys_read @@ -347,34 +347,4 @@ sys_call_table: .long sys_inotify_init .long sys_inotify_add_watch .long sys_inotify_rm_watch /* 320 */ - .long sys_ni_syscall - .long sys_migrate_pages - .long sys_openat - .long sys_mkdirat - .long sys_mknodat /* 325 */ - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 - .long sys_unlinkat - .long sys_renameat /* 330 */ - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat - .long sys_fchmodat - .long sys_faccessat /* 335 */ - .long sys_pselect6 - .long sys_ppoll - .long sys_unshare - .long sys_set_robust_list - .long sys_get_robust_list /* 340 */ - .long sys_splice - .long sys_sync_file_range - .long sys_tee - .long sys_vmsplice - .long sys_move_pages /* 345 */ - .long sys_getcpu - .long sys_epoll_pwait - .long sys_utimensat - .long sys_signalfd - .long sys_timerfd /* 350 */ - .long sys_eventfd + diff --git a/trunk/arch/sh64/kernel/time.c b/trunk/arch/sh64/kernel/time.c index b37f4f4981d2..390b40de7cef 100644 --- a/trunk/arch/sh64/kernel/time.c +++ b/trunk/arch/sh64/kernel/time.c @@ -123,7 +123,7 @@ static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */ static unsigned long long scaled_recip_ctc_ticks_per_jiffy; /* Estimate number of microseconds that have elapsed since the last timer tick, - by scaling the delta that has occurred in the CTC register. + by scaling the delta that has occured in the CTC register. WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this @@ -282,7 +282,7 @@ static long last_rtc_update = 0; * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -static inline void do_timer_interrupt(void) +static inline void do_timer_interrupt(int irq, struct pt_regs *regs) { unsigned long long current_ctc; asm ("getcon cr62, %0" : "=r" (current_ctc)); @@ -290,10 +290,9 @@ static inline void do_timer_interrupt(void) do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); + update_process_times(user_mode(regs)); #endif - if (current->pid) - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_HEARTBEAT { @@ -324,7 +323,7 @@ static inline void do_timer_interrupt(void) * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. */ -static irqreturn_t timer_interrupt(int irq, void *dev_id) +static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long timer_status; @@ -341,7 +340,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) * locally disabled. -arca */ write_lock(&xtime_lock); - do_timer_interrupt(); + do_timer_interrupt(irq, regs); write_unlock(&xtime_lock); return IRQ_HANDLED; @@ -466,10 +465,9 @@ static __init unsigned int get_cpu_hz(void) #endif } -static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id) +static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); - ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ regs->regs[3] = 1; /* Using r3 */ diff --git a/trunk/arch/sh64/lib/.gitignore b/trunk/arch/sh64/lib/.gitignore deleted file mode 100644 index 3508c2cb23c4..000000000000 --- a/trunk/arch/sh64/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -syscalltab.h diff --git a/trunk/arch/sh64/mach-cayman/irq.c b/trunk/arch/sh64/mach-cayman/irq.c index aaad36d37d1f..228ce61c3515 100644 --- a/trunk/arch/sh64/mach-cayman/irq.c +++ b/trunk/arch/sh64/mach-cayman/irq.c @@ -29,13 +29,13 @@ unsigned long epld_virt; /* Note the SMSC SuperIO chip and SMSC LAN chip interrupts are all muxed onto the same SH-5 interrupt */ -static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id) +static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_INFO "CAYMAN: spurious SMSC interrupt\n"); return IRQ_NONE; } -static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id) +static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq); return IRQ_NONE; diff --git a/trunk/arch/sh64/mach-cayman/setup.c b/trunk/arch/sh64/mach-cayman/setup.c index c3611cc2735f..3ed87cd059d0 100644 --- a/trunk/arch/sh64/mach-cayman/setup.c +++ b/trunk/arch/sh64/mach-cayman/setup.c @@ -213,7 +213,7 @@ static int __init smsc_superio_setup(void) SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ #endif - /* Exit the configuration state */ + /* Exit the configuraton state */ outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); return 0; diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c index 3cd93ba5d826..4dd8ee8f01ce 100644 --- a/trunk/arch/sh64/mm/fault.c +++ b/trunk/arch/sh64/mm/fault.c @@ -135,7 +135,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, /* SIM * Note this is now called with interrupts still disabled * This is to cope with being called for a missing IO port - * address with interrupts disabled. This should be fixed as + * address with interupts disabled. This should be fixed as * soon as we have a better 'fast path' miss handler. * * Plus take care how you try and debug this stuff. diff --git a/trunk/arch/sh64/mm/init.c b/trunk/arch/sh64/mm/init.c index 559717f30d1f..5dc08787259c 100644 --- a/trunk/arch/sh64/mm/init.c +++ b/trunk/arch/sh64/mm/init.c @@ -84,7 +84,7 @@ void show_mem(void) printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); - printk("%ld pages in page table cache\n", quicklist_total_size()); + printk("%ld pages in page table cache\n",pgtable_cache_size); } /* diff --git a/trunk/arch/sh64/mm/tlbmiss.c b/trunk/arch/sh64/mm/tlbmiss.c index b767d6cff72f..d4c5334186d0 100644 --- a/trunk/arch/sh64/mm/tlbmiss.c +++ b/trunk/arch/sh64/mm/tlbmiss.c @@ -14,7 +14,7 @@ * IMPORTANT NOTES : * The do_fast_page_fault function is called from a context in entry.S where very few registers * have been saved. In particular, the code in this file must be compiled not to use ANY - * caller-save registers that are not part of the restricted save set. Also, it means that + * caller-save regiseters that are not part of the restricted save set. Also, it means that * code in this file must not make calls to functions elsewhere in the kernel, or else the * excepting context will see corruption in its caller-save registers. Plus, the entry.S save * area is non-reentrant, so this code has to run with SR.BL==1, i.e. no interrupts taken inside @@ -249,7 +249,7 @@ asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long /* SIM * Note this is now called with interrupts still disabled * This is to cope with being called for a missing IO port - * address with interrupts disabled. This should be fixed as + * address with interupts disabled. This should be fixed as * soon as we have a better 'fast path' miss handler. * * Plus take care how you try and debug this stuff. diff --git a/trunk/arch/sparc/defconfig b/trunk/arch/sparc/defconfig index 38bd79fe6e75..79e54894529d 100644 --- a/trunk/arch/sparc/defconfig +++ b/trunk/arch/sparc/defconfig @@ -1,11 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc1 -# Mon May 14 03:25:14 2007 +# Linux kernel version: 2.6.20-rc1 +# Sun Dec 17 14:20:47 2006 # CONFIG_MMU=y CONFIG_HIGHMEM=y -CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -24,17 +23,14 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -50,19 +46,14 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -116,7 +107,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_SUN_PM=y # CONFIG_SUN4 is not set CONFIG_PCI=y -# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m # CONFIG_SPARC_LED is not set @@ -133,7 +124,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 # # Networking @@ -143,15 +133,14 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m # CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -181,7 +170,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y # CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -241,18 +229,7 @@ CONFIG_NET_PKTGEN=m # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set # # Device Drivers @@ -265,13 +242,16 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -282,7 +262,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -301,16 +280,15 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # -# CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set -# CONFIG_BLINK is not set # # ATA/ATAPI/MFM/RLL support @@ -344,12 +322,11 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports # -CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_SPI_ATTRS=m # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set @@ -389,9 +366,12 @@ CONFIG_SCSI_QLOGICPTI=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -CONFIG_SCSI_ESP_CORE=y CONFIG_SCSI_SUNESP=y # CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set # @@ -410,7 +390,6 @@ CONFIG_SCSI_SUNESP=y # # IEEE 1394 (FireWire) support # -# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -431,6 +410,10 @@ CONFIG_TUN=m # ARCnet devices # # CONFIG_ARCNET is not set + +# +# PHY device support +# # CONFIG_PHYLIB is not set # @@ -452,7 +435,10 @@ CONFIG_SUNQE=m # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_PCI is not set -CONFIG_NETDEV_1000=y + +# +# Ethernet (1000 Mbit) +# # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -468,16 +454,15 @@ CONFIG_NETDEV_1000=y # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -CONFIG_NETDEV_10000=y + +# +# Ethernet (10000 Mbit) +# # CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set -# CONFIG_MLX4_CORE is not set -CONFIG_MLX4_DEBUG=y # # Token Ring devices @@ -485,10 +470,13 @@ CONFIG_MLX4_DEBUG=y # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -540,17 +528,9 @@ CONFIG_KEYBOARD_SUNKBD=m # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=m -# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -598,9 +578,14 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=m CONFIG_RTC=m +# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set @@ -610,7 +595,10 @@ CONFIG_RTC=m # TPM devices # # CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y + +# +# I2C support +# # CONFIG_I2C is not set # @@ -623,39 +611,32 @@ CONFIG_DEVPORT=y # Dallas's 1-wire bus # # CONFIG_W1 is not set + +# +# Hardware Monitoring support +# CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83627HF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set # -# Graphics support +# Digital Video Broadcasting Devices # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DVB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -663,6 +644,7 @@ CONFIG_HWMON=y # # CONFIG_PROM_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -673,7 +655,6 @@ CONFIG_DUMMY_CONSOLE=y # HID Devices # CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # # USB support @@ -691,6 +672,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# # CONFIG_MMC is not set # @@ -733,6 +718,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # +# +# Virtualization +# + # # Misc Linux/SPARC drivers # @@ -812,7 +801,6 @@ CONFIG_RAMFS=y # # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set CONFIG_BEFS_FS=m @@ -839,7 +827,6 @@ CONFIG_LOCKD=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_BIND34 is not set CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -852,7 +839,7 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set CONFIG_AFS_FS=m -# CONFIG_AFS_DEBUG is not set +CONFIG_RXRPC=m # CONFIG_9P_FS is not set # @@ -926,14 +913,15 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -944,14 +932,12 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_STACK_USAGE is not set # # Security options # -CONFIG_KEYS=y -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # @@ -975,11 +961,8 @@ CONFIG_CRYPTO_SHA512=m # CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_TWOFISH_COMMON=m @@ -994,7 +977,6 @@ CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m -# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # @@ -1007,12 +989,9 @@ CONFIG_CRYPTO_CRC32C=m CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y +CONFIG_IOMAP_COPY=y diff --git a/trunk/arch/sparc/kernel/head.S b/trunk/arch/sparc/kernel/head.S index 9a219e8b5ddb..97da13c52563 100644 --- a/trunk/arch/sparc/kernel/head.S +++ b/trunk/arch/sparc/kernel/head.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include /* TI_UWINMASK */ #include diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 65840a62bb9c..585ef4fb7591 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc1 -# Mon May 14 04:17:48 2007 +# Linux kernel version: 2.6.21 +# Fri May 11 14:31:45 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -508,6 +508,10 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SUNESP is not set # CONFIG_SCSI_SRP is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set # @@ -564,6 +568,10 @@ CONFIG_DUMMY=m # ARCnet devices # # CONFIG_ARCNET is not set + +# +# PHY device support +# # CONFIG_PHYLIB is not set # @@ -603,7 +611,10 @@ CONFIG_NET_PCI=y # CONFIG_SUNDANCE is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set -CONFIG_NETDEV_1000=y + +# +# Ethernet (1000 Mbit) +# # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=m @@ -623,7 +634,10 @@ CONFIG_TIGON3=m CONFIG_BNX2=m # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set -CONFIG_NETDEV_10000=y + +# +# Ethernet (10000 Mbit) +# # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set @@ -653,6 +667,10 @@ CONFIG_MLX4_DEBUG=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set + +# +# Wan interfaces +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set diff --git a/trunk/arch/sparc64/kernel/Makefile b/trunk/arch/sparc64/kernel/Makefile index c749dccacc32..6bf6fb65bc20 100644 --- a/trunk/arch/sparc64/kernel/Makefile +++ b/trunk/arch/sparc64/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \ unaligned.o central.o pci.o starfire.o semaphore.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ - visemul.o prom.o of_device.o hvapi.o + visemul.o prom.o of_device.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ diff --git a/trunk/arch/sparc64/kernel/entry.S b/trunk/arch/sparc64/kernel/entry.S index 732b77cb71f8..c15a3edcb826 100644 --- a/trunk/arch/sparc64/kernel/entry.S +++ b/trunk/arch/sparc64/kernel/entry.S @@ -1843,97 +1843,3 @@ sun4v_cpu_state: mov %o1, %o0 1: retl nop - - /* %o0: API group number - * %o1: pointer to unsigned long major number storage - * %o2: pointer to unsigned long minor number storage - * - * returns %o0: status - */ - .globl sun4v_get_version -sun4v_get_version: - mov HV_CORE_GET_VER, %o5 - mov %o1, %o3 - mov %o2, %o4 - ta HV_CORE_TRAP - stx %o1, [%o3] - retl - stx %o2, [%o4] - - /* %o0: API group number - * %o1: desired major number - * %o2: desired minor number - * %o3: pointer to unsigned long actual minor number storage - * - * returns %o0: status - */ - .globl sun4v_set_version -sun4v_set_version: - mov HV_CORE_SET_VER, %o5 - mov %o3, %o4 - ta HV_CORE_TRAP - retl - stx %o1, [%o4] - - /* %o0: pointer to unsigned long status - * - * returns %o0: signed character - */ - .globl sun4v_con_getchar -sun4v_con_getchar: - mov %o0, %o4 - mov HV_FAST_CONS_GETCHAR, %o5 - clr %o0 - clr %o1 - ta HV_FAST_TRAP - stx %o0, [%o4] - retl - sra %o1, 0, %o0 - - /* %o0: signed long character - * - * returns %o0: status - */ - .globl sun4v_con_putchar -sun4v_con_putchar: - mov HV_FAST_CONS_PUTCHAR, %o5 - ta HV_FAST_TRAP - retl - sra %o0, 0, %o0 - - /* %o0: buffer real address - * %o1: buffer size - * %o2: pointer to unsigned long bytes_read - * - * returns %o0: status - */ - .globl sun4v_con_read -sun4v_con_read: - mov %o2, %o4 - mov HV_FAST_CONS_READ, %o5 - ta HV_FAST_TRAP - brnz %o0, 1f - cmp %o1, -1 /* break */ - be,a,pn %icc, 1f - mov %o1, %o0 - cmp %o1, -2 /* hup */ - be,a,pn %icc, 1f - mov %o1, %o0 - stx %o1, [%o4] -1: retl - nop - - /* %o0: buffer real address - * %o1: buffer size - * %o2: pointer to unsigned long bytes_written - * - * returns %o0: status - */ - .globl sun4v_con_write -sun4v_con_write: - mov %o2, %o4 - mov HV_FAST_CONS_WRITE, %o5 - ta HV_FAST_TRAP - stx %o1, [%o4] - retl - nop diff --git a/trunk/arch/sparc64/kernel/hvapi.c b/trunk/arch/sparc64/kernel/hvapi.c deleted file mode 100644 index f03ffc829c7a..000000000000 --- a/trunk/arch/sparc64/kernel/hvapi.c +++ /dev/null @@ -1,189 +0,0 @@ -/* hvapi.c: Hypervisor API management. - * - * Copyright (C) 2007 David S. Miller - */ -#include -#include -#include -#include - -#include -#include - -/* If the hypervisor indicates that the API setting - * calls are unsupported, by returning HV_EBADTRAP or - * HV_ENOTSUPPORTED, we assume that API groups with the - * PRE_API flag set are major 1 minor 0. - */ -struct api_info { - unsigned long group; - unsigned long major; - unsigned long minor; - unsigned int refcnt; - unsigned int flags; -#define FLAG_PRE_API 0x00000001 -}; - -static struct api_info api_table[] = { - { .group = HV_GRP_SUN4V, .flags = FLAG_PRE_API }, - { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, - { .group = HV_GRP_INTR, }, - { .group = HV_GRP_SOFT_STATE, }, - { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, - { .group = HV_GRP_LDOM, }, - { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, - { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, - { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, - { .group = HV_GRP_FIRE_PERF, }, - { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, -}; - -static DEFINE_SPINLOCK(hvapi_lock); - -static struct api_info *__get_info(unsigned long group) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(api_table); i++) { - if (api_table[i].group == group) - return &api_table[i]; - } - return NULL; -} - -static void __get_ref(struct api_info *p) -{ - p->refcnt++; -} - -static void __put_ref(struct api_info *p) -{ - if (--p->refcnt == 0) { - unsigned long ignore; - - sun4v_set_version(p->group, 0, 0, &ignore); - p->major = p->minor = 0; - } -} - -/* Register a hypervisor API specification. It indicates the - * API group and desired major+minor. - * - * If an existing API registration exists '0' (success) will - * be returned if it is compatible with the one being registered. - * Otherwise a negative error code will be returned. - * - * Otherwise an attempt will be made to negotiate the requested - * API group/major/minor with the hypervisor, and errors returned - * if that does not succeed. - */ -int sun4v_hvapi_register(unsigned long group, unsigned long major, - unsigned long *minor) -{ - struct api_info *p; - unsigned long flags; - int ret; - - spin_lock_irqsave(&hvapi_lock, flags); - p = __get_info(group); - ret = -EINVAL; - if (p) { - if (p->refcnt) { - ret = -EINVAL; - if (p->major == major) { - *minor = p->minor; - ret = 0; - } - } else { - unsigned long actual_minor; - unsigned long hv_ret; - - hv_ret = sun4v_set_version(group, major, *minor, - &actual_minor); - ret = -EINVAL; - if (hv_ret == HV_EOK) { - *minor = actual_minor; - p->major = major; - p->minor = actual_minor; - ret = 0; - } else if (hv_ret == HV_EBADTRAP || - HV_ENOTSUPPORTED) { - if (p->flags & FLAG_PRE_API) { - if (major == 1) { - p->major = 1; - p->minor = 0; - *minor = 0; - ret = 0; - } - } - } - } - - if (ret == 0) - __get_ref(p); - } - spin_unlock_irqrestore(&hvapi_lock, flags); - - return ret; -} -EXPORT_SYMBOL(sun4v_hvapi_register); - -void sun4v_hvapi_unregister(unsigned long group) -{ - struct api_info *p; - unsigned long flags; - - spin_lock_irqsave(&hvapi_lock, flags); - p = __get_info(group); - if (p) - __put_ref(p); - spin_unlock_irqrestore(&hvapi_lock, flags); -} -EXPORT_SYMBOL(sun4v_hvapi_unregister); - -int sun4v_hvapi_get(unsigned long group, - unsigned long *major, - unsigned long *minor) -{ - struct api_info *p; - unsigned long flags; - int ret; - - spin_lock_irqsave(&hvapi_lock, flags); - ret = -EINVAL; - p = __get_info(group); - if (p && p->refcnt) { - *major = p->major; - *minor = p->minor; - ret = 0; - } - spin_unlock_irqrestore(&hvapi_lock, flags); - - return ret; -} -EXPORT_SYMBOL(sun4v_hvapi_get); - -void __init sun4v_hvapi_init(void) -{ - unsigned long group, major, minor; - - group = HV_GRP_SUN4V; - major = 1; - minor = 0; - if (sun4v_hvapi_register(group, major, &minor)) - goto bad; - - group = HV_GRP_CORE; - major = 1; - minor = 1; - if (sun4v_hvapi_register(group, major, &minor)) - goto bad; - - return; - -bad: - prom_printf("HVAPI: Cannot register API group " - "%lx with major(%u) minor(%u)\n", - group, major, minor); - prom_halt(); -} diff --git a/trunk/arch/sparc64/kernel/of_device.c b/trunk/arch/sparc64/kernel/of_device.c index 16cc46a71872..7455f5d05519 100644 --- a/trunk/arch/sparc64/kernel/of_device.c +++ b/trunk/arch/sparc64/kernel/of_device.c @@ -537,13 +537,6 @@ static int __init build_one_resource(struct device_node *parent, return 0; } - /* When we miss an I/O space match on PCI, just pass it up - * to the next PCI bridge and/or controller. - */ - if (!strcmp(bus->name, "pci") && - (addr[0] & 0x03000000) == 0x01000000) - return 0; - return 1; } diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index dea9c3c9ec5f..451028341c75 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -269,7 +269,6 @@ void __init per_cpu_patch(void) void __init sun4v_patch(void) { - extern void sun4v_hvapi_init(void); struct sun4v_1insn_patch_entry *p1; struct sun4v_2insn_patch_entry *p2; @@ -301,8 +300,6 @@ void __init sun4v_patch(void) p2++; } - - sun4v_hvapi_init(); } #ifdef CONFIG_SMP diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index 24fdf1d0adc5..8087d67a0cf8 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -561,9 +561,6 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t unsigned long flags, status; int cnt, retries, this_cpu, prev_sent, i; - if (cpus_empty(mask)) - return; - /* We have to do this whole thing with interrupts fully disabled. * Otherwise if we send an xcall from interrupt context it will * corrupt both our mondo block and cpu list state. diff --git a/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h b/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h index c978b589df41..a307237b7964 100644 --- a/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/trunk/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -17,16 +17,7 @@ #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); -#define __NO_STUBS 1 -#undef __SYSCALL -#undef _ASM_X86_64_UNISTD_H_ -#define __SYSCALL(nr, sym) [nr] = 1, -static char syscalls[] = { -#include -}; - void foo(void) { #include -DEFINE(UM_NR_syscall_max, sizeof(syscalls) - 1); } diff --git a/trunk/arch/um/include/sysdep-x86_64/syscalls.h b/trunk/arch/um/include/sysdep-x86_64/syscalls.h index cf72256609e4..5e86aa047b2b 100644 --- a/trunk/arch/um/include/sysdep-x86_64/syscalls.h +++ b/trunk/arch/um/include/sysdep-x86_64/syscalls.h @@ -9,7 +9,6 @@ #include #include -#include typedef long syscall_handler_t(void); @@ -30,6 +29,6 @@ extern long old_mmap(unsigned long addr, unsigned long len, extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_arch_prctl; -#define NR_syscalls (UM_NR_syscall_max + 1) +#define NR_syscalls (__NR_syscall_max + 1) #endif diff --git a/trunk/arch/um/sys-x86_64/syscall_table.c b/trunk/arch/um/sys-x86_64/syscall_table.c index 5133988d3610..9e9ad72c2ba4 100644 --- a/trunk/arch/um/sys-x86_64/syscall_table.c +++ b/trunk/arch/um/sys-x86_64/syscall_table.c @@ -4,7 +4,6 @@ #include #include #include -#include #define __NO_STUBS @@ -46,8 +45,8 @@ typedef void (*sys_call_ptr_t)(void); extern void sys_ni_syscall(void); -sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { +sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ - [0 ... UM_NR_syscall_max] = &sys_ni_syscall, + [0 ... __NR_syscall_max] = &sys_ni_syscall, #include }; diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index cb29fb96948d..d28f01379b9b 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -776,6 +776,9 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) */ if (nmi_watchdog_tick(regs,reason)) return; + if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0) + == NOTIFY_STOP) + return; if (!do_nmi_callback(regs,cpu)) unknown_nmi_error(reason, regs); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 6b5173ac8131..74a567afb830 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -3802,6 +3802,7 @@ static struct io_context *current_io_context(gfp_t gfp_flags, int node) return ret; } +EXPORT_SYMBOL(current_io_context); /* * If the current task has no IO context then create one and initialise it. diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 5526eadb6592..e2fc4b6734cf 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -1399,11 +1399,6 @@ static struct loop_device *loop_init_one(int i) struct loop_device *lo; struct gendisk *disk; - list_for_each_entry(lo, &loop_devices, lo_list) { - if (lo->lo_number == i) - return lo; - } - lo = kzalloc(sizeof(*lo), GFP_KERNEL); if (!lo) goto out; @@ -1448,13 +1443,17 @@ static void loop_del_one(struct loop_device *lo) kfree(lo); } +static int loop_lock(dev_t dev, void *data) +{ + mutex_lock(&loop_devices_mutex); + return 0; +} + static struct kobject *loop_probe(dev_t dev, int *part, void *data) { - struct loop_device *lo; + struct loop_device *lo = loop_init_one(dev & MINORMASK); struct kobject *kobj; - mutex_lock(&loop_devices_mutex); - lo = loop_init_one(dev & MINORMASK); kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); mutex_unlock(&loop_devices_mutex); @@ -1467,7 +1466,7 @@ static int __init loop_init(void) if (register_blkdev(LOOP_MAJOR, "loop")) return -EIO; blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, - THIS_MODULE, loop_probe, NULL, NULL); + THIS_MODULE, loop_probe, loop_lock, NULL); if (max_loop) { printk(KERN_INFO "loop: the max_loop option is obsolete " diff --git a/trunk/drivers/char/agp/via-agp.c b/trunk/drivers/char/agp/via-agp.c index 9aaf401a8975..a2bb4eccaab4 100644 --- a/trunk/drivers/char/agp/via-agp.c +++ b/trunk/drivers/char/agp/via-agp.c @@ -384,9 +384,9 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_VIA_P4M800CE, .chipset_name = "VT3314", }, - /* VT3324 / CX700 */ + /* CX700 */ { - .device_id = PCI_DEVICE_ID_VIA_VT3324, + .device_id = PCI_DEVICE_ID_VIA_CX700, .chipset_name = "CX700", }, /* VT3336 */ @@ -540,7 +540,7 @@ static const struct pci_device_id agp_via_pci_table[] = { ID(PCI_DEVICE_ID_VIA_83_87XX_1), ID(PCI_DEVICE_ID_VIA_3296_0), ID(PCI_DEVICE_ID_VIA_P4M800CE), - ID(PCI_DEVICE_ID_VIA_VT3324), + ID(PCI_DEVICE_ID_VIA_CX700), ID(PCI_DEVICE_ID_VIA_VT3336), ID(PCI_DEVICE_ID_VIA_P4M890), { } diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 41f78e2c158f..147c12047cf3 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -50,10 +50,18 @@ #include #include #include +#include #include -#ifdef CONFIG_X86_LOCAL_APIC -#include +#ifdef CONFIG_X86 +/* This is ugly, but I've determined that x86 is the only architecture + that can reasonably support the IPMI NMI watchdog timeout at this + time. If another architecture adds this capability somehow, it + will have to be a somewhat different mechanism and I have no idea + how it will work. So in the unlikely event that another + architecture supports this, we can figure out a good generic + mechanism for it at that time. */ +#define HAVE_DIE_NMI_POST #endif #define PFX "IPMI Watchdog: " @@ -319,6 +327,11 @@ static unsigned char ipmi_version_minor; /* If a pretimeout occurs, this is used to allow only one panic to happen. */ static atomic_t preop_panic_excl = ATOMIC_INIT(-1); +#ifdef HAVE_DIE_NMI_POST +static int testing_nmi; +static int nmi_handler_registered; +#endif + static int ipmi_heartbeat(void); static void panic_halt_ipmi_heartbeat(void); @@ -360,6 +373,10 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, int hbnow = 0; + /* These can be cleared as we are setting the timeout. */ + ipmi_start_timer_on_heartbeat = 0; + pretimeout_since_last_heartbeat = 0; + data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); @@ -434,13 +451,12 @@ static int ipmi_set_timeout(int do_heartbeat) wait_for_completion(&set_timeout_wait); + mutex_unlock(&set_timeout_lock); + if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) || ((send_heartbeat_now) && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) - { rv = ipmi_heartbeat(); - } - mutex_unlock(&set_timeout_lock); out: return rv; @@ -520,12 +536,10 @@ static int ipmi_heartbeat(void) int rv; struct ipmi_system_interface_addr addr; - if (ipmi_ignore_heartbeat) { + if (ipmi_ignore_heartbeat) return 0; - } if (ipmi_start_timer_on_heartbeat) { - ipmi_start_timer_on_heartbeat = 0; ipmi_watchdog_state = action_val; return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); } else if (pretimeout_since_last_heartbeat) { @@ -533,7 +547,6 @@ static int ipmi_heartbeat(void) We don't want to set the action, though, we want to leave that alone (thus it can't be combined with the above operation. */ - pretimeout_since_last_heartbeat = 0; return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } @@ -921,6 +934,45 @@ static void ipmi_register_watchdog(int ipmi_intf) printk(KERN_CRIT PFX "Unable to register misc device\n"); } +#ifdef HAVE_DIE_NMI_POST + if (nmi_handler_registered) { + int old_pretimeout = pretimeout; + int old_timeout = timeout; + int old_preop_val = preop_val; + + /* Set the pretimeout to go off in a second and give + ourselves plenty of time to stop the timer. */ + ipmi_watchdog_state = WDOG_TIMEOUT_RESET; + preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ + pretimeout = 99; + timeout = 100; + + testing_nmi = 1; + + rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); + if (rv) { + printk(KERN_WARNING PFX "Error starting timer to" + " test NMI: 0x%x. The NMI pretimeout will" + " likely not work\n", rv); + rv = 0; + goto out_restore; + } + + msleep(1500); + + if (testing_nmi != 2) { + printk(KERN_WARNING PFX "IPMI NMI didn't seem to" + " occur. The NMI pretimeout will" + " likely not work\n"); + } + out_restore: + testing_nmi = 0; + preop_val = old_preop_val; + pretimeout = old_pretimeout; + timeout = old_timeout; + } +#endif + out: up_write(®ister_sem); @@ -930,6 +982,10 @@ static void ipmi_register_watchdog(int ipmi_intf) ipmi_watchdog_state = action_val; ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); printk(KERN_INFO PFX "Starting now!\n"); + } else { + /* Stop the timer now. */ + ipmi_watchdog_state = WDOG_TIMEOUT_NONE; + ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); } } @@ -966,17 +1022,28 @@ static void ipmi_unregister_watchdog(int ipmi_intf) up_write(®ister_sem); } -#ifdef HAVE_NMI_HANDLER +#ifdef HAVE_DIE_NMI_POST static int -ipmi_nmi(void *dev_id, int cpu, int handled) +ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) { + if (val != DIE_NMI_POST) + return NOTIFY_OK; + + if (testing_nmi) { + testing_nmi = 2; + return NOTIFY_STOP; + } + /* If we are not expecting a timeout, ignore it. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) - return NOTIFY_DONE; + return NOTIFY_OK; + + if (preaction_val != WDOG_PRETIMEOUT_NMI) + return NOTIFY_OK; /* If no one else handled the NMI, we assume it was the IPMI watchdog. */ - if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { + if (preop_val == WDOG_PREOP_PANIC) { /* On some machines, the heartbeat will give an error and not work unless we re-enable the timer. So do so. */ @@ -985,18 +1052,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled) panic(PFX "pre-timeout"); } - return NOTIFY_DONE; + return NOTIFY_STOP; } -static struct nmi_handler ipmi_nmi_handler = -{ - .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), - .dev_name = "ipmi_watchdog", - .dev_id = NULL, - .handler = ipmi_nmi, - .priority = 0, /* Call us last. */ +static struct notifier_block ipmi_nmi_handler = { + .notifier_call = ipmi_nmi }; -int nmi_handler_registered; #endif static int wdog_reboot_handler(struct notifier_block *this, @@ -1113,7 +1174,7 @@ static int preaction_op(const char *inval, char *outval) preaction_val = WDOG_PRETIMEOUT_NONE; else if (strcmp(inval, "pre_smi") == 0) preaction_val = WDOG_PRETIMEOUT_SMI; -#ifdef HAVE_NMI_HANDLER +#ifdef HAVE_DIE_NMI_POST else if (strcmp(inval, "pre_nmi") == 0) preaction_val = WDOG_PRETIMEOUT_NMI; #endif @@ -1147,7 +1208,7 @@ static int preop_op(const char *inval, char *outval) static void check_parms(void) { -#ifdef HAVE_NMI_HANDLER +#ifdef HAVE_DIE_NMI_POST int do_nmi = 0; int rv; @@ -1160,20 +1221,9 @@ static void check_parms(void) preop_op("preop_none", NULL); do_nmi = 0; } -#ifdef CONFIG_X86_LOCAL_APIC - if (nmi_watchdog == NMI_IO_APIC) { - printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" - " mode (value is %d), that is incompatible" - " with using NMI in the IPMI watchdog." - " Disabling IPMI nmi pretimeout.\n", - nmi_watchdog); - preaction_val = WDOG_PRETIMEOUT_NONE; - do_nmi = 0; - } -#endif } if (do_nmi && !nmi_handler_registered) { - rv = request_nmi(&ipmi_nmi_handler); + rv = register_die_notifier(&ipmi_nmi_handler); if (rv) { printk(KERN_WARNING PFX "Can't register nmi handler\n"); @@ -1181,7 +1231,7 @@ static void check_parms(void) } else nmi_handler_registered = 1; } else if (!do_nmi && nmi_handler_registered) { - release_nmi(&ipmi_nmi_handler); + unregister_die_notifier(&ipmi_nmi_handler); nmi_handler_registered = 0; } #endif @@ -1217,9 +1267,9 @@ static int __init ipmi_wdog_init(void) rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { -#ifdef HAVE_NMI_HANDLER - if (preaction_val == WDOG_PRETIMEOUT_NMI) - release_nmi(&ipmi_nmi_handler); +#ifdef HAVE_DIE_NMI_POST + if (nmi_handler_registered) + unregister_die_notifier(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); @@ -1238,9 +1288,9 @@ static void __exit ipmi_wdog_exit(void) ipmi_smi_watcher_unregister(&smi_watcher); ipmi_unregister_watchdog(watchdog_ifnum); -#ifdef HAVE_NMI_HANDLER +#ifdef HAVE_DIE_NMI_POST if (nmi_handler_registered) - release_nmi(&ipmi_nmi_handler); + unregister_die_notifier(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, diff --git a/trunk/drivers/firewire/fw-ohci.c b/trunk/drivers/firewire/fw-ohci.c index c17342d3e6fd..1f5c70461b8b 100644 --- a/trunk/drivers/firewire/fw-ohci.c +++ b/trunk/drivers/firewire/fw-ohci.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index b1a9b81c211f..9040809d2c25 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -4,10 +4,13 @@ # Andre Hedrick # -menuconfig IDE - tristate "ATA/ATAPI/MFM/RLL support" - depends on BLOCK +if BLOCK + +menu "ATA/ATAPI/MFM/RLL support" depends on HAS_IOMEM + +config IDE + tristate "ATA/ATAPI/MFM/RLL support" ---help--- If you say Y here, your kernel will be able to manage low cost mass storage units such as ATA/(E)IDE and ATAPI units. The most common @@ -1096,4 +1099,8 @@ config BLK_DEV_HD_ONLY config BLK_DEV_HD def_bool BLK_DEV_HD_IDE || BLK_DEV_HD_ONLY -endif # IDE +endif + +endmenu + +endif diff --git a/trunk/drivers/ide/cris/ide-cris.c b/trunk/drivers/ide/cris/ide-cris.c index ca0341c05e55..c04cb25a01ff 100644 --- a/trunk/drivers/ide/cris/ide-cris.c +++ b/trunk/drivers/ide/cris/ide-cris.c @@ -1002,6 +1002,18 @@ static int cris_ide_build_dmatable (ide_drive_t *drive) return 1; /* let the PIO routines handle this weirdness */ } +static int cris_config_drive_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!speed) + return 0; + + speed_cris_ide(drive, speed); + + return ide_dma_enable(drive); +} + /* * cris_dma_intr() is the handler for disk read/write DMA interrupts */ @@ -1031,7 +1043,7 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive) static int cris_dma_check(ide_drive_t *drive) { - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && cris_config_drive_for_dma(drive)) return 0; return -1; diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index b77b7d138c49..5fe85191d49c 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -670,6 +670,41 @@ int __ide_dma_good_drive (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_good_drive); +int ide_use_dma(ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = drive->hwif; + + if ((id->capability & 1) == 0 || drive->autodma == 0) + return 0; + + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + return 0; + + /* capable of UltraDMA modes */ + if (id->field_valid & 4) { + if (hwif->ultra_mask & id->dma_ultra) + return 1; + } + + /* capable of regular DMA modes */ + if (id->field_valid & 2) { + if (hwif->mwdma_mask & id->dma_mword) + return 1; + if (hwif->swdma_mask & id->dma_1word) + return 1; + } + + /* consult the list of known "good" drives */ + if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) + return 1; + + return 0; +} + +EXPORT_SYMBOL_GPL(ide_use_dma); + static const u8 xfer_mode_bases[] = { XFER_UDMA_0, XFER_MW_DMA_0, @@ -696,12 +731,10 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) mask &= 0x07; break; case XFER_MW_DMA_0: - if (id->field_valid & 2) - mask = id->dma_mword & hwif->mwdma_mask; + mask = id->dma_mword & hwif->mwdma_mask; break; case XFER_SW_DMA_0: - if (id->field_valid & 2) - mask = id->dma_1word & hwif->swdma_mask; + mask = id->dma_1word & hwif->swdma_mask; break; default: BUG(); @@ -750,11 +783,8 @@ int ide_tune_dma(ide_drive_t *drive) { u8 speed; - if ((drive->id->capability & 1) == 0 || drive->autodma == 0) - return 0; - - /* consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) + /* TODO: use only ide_max_dma_mode() */ + if (!ide_use_dma(drive)) return 0; speed = ide_max_dma_mode(drive); @@ -762,10 +792,9 @@ int ide_tune_dma(ide_drive_t *drive) if (!speed) return 0; - if (drive->hwif->speedproc(drive, speed)) - return 0; + drive->hwif->speedproc(drive, speed); - return 1; + return ide_dma_enable(drive); } EXPORT_SYMBOL_GPL(ide_tune_dma); diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index bfe8f1b712ba..8e568143d90d 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -223,7 +223,6 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * break; if (drive->hwif->ide_dma_check == NULL) break; - drive->hwif->dma_off_quietly(drive); ide_set_dma(drive); break; } diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 074bb32a4a40..3be3c69383f2 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -111,6 +111,18 @@ u8 ide_rate_filter(ide_drive_t *drive, u8 speed) EXPORT_SYMBOL(ide_rate_filter); +int ide_dma_enable (ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + struct hd_driveid *id = drive->id; + + return ((int) ((((id->dma_ultra >> 8) & hwif->ultra_mask) || + ((id->dma_mword >> 8) & hwif->mwdma_mask) || + ((id->dma_1word >> 8) & hwif->swdma_mask)) ? 1 : 0)); +} + +EXPORT_SYMBOL(ide_dma_enable); + int ide_use_fast_pio(ide_drive_t *drive) { struct hd_driveid *id = drive->id; diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 6002713a20a1..f2b547ff7722 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -910,7 +910,6 @@ int set_using_dma(ide_drive_t *drive, int arg) err = 0; if (arg) { - hwif->dma_off_quietly(drive); if (ide_set_dma(drive) || hwif->ide_dma_on(drive)) err = -EIO; } else diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index 27525ec2e19a..428efdae0c7b 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/drivers/ide/pci/alim15x3.c @@ -455,6 +455,28 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } + +/** + * config_chipset_for_dma - set up DMA mode + * @drive: drive to configure for + * + * Place a drive into DMA mode and tune the chipset for + * the selected speed. + * + * Returns true if DMA mode can be used + */ + +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!(speed)) + return 0; + + (void) ali15x3_tune_chipset(drive, speed); + return ide_dma_enable(drive); +} + /** * ali15x3_config_drive_for_dma - configure for DMA * @drive: drive to configure @@ -465,14 +487,48 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int ali15x3_config_drive_for_dma(ide_drive_t *drive) { - drive->init_speed = 0; + ide_hwif_t *hwif = HWIF(drive); + struct hd_driveid *id = drive->id; - if (ide_tune_dma(drive)) - return 0; + if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) + goto ata_pio; - ali15x3_tune_drive(drive, 255); + drive->init_speed = 0; - return -1; + if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { + /* Consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + goto ata_pio; + if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { + if (id->dma_ultra & hwif->ultra_mask) { + /* Force if Capable UltraDMA */ + int dma = config_chipset_for_dma(drive); + if ((id->field_valid & 2) && !dma) + goto try_dma_modes; + } + } else if (id->field_valid & 2) { +try_dma_modes: + if ((id->dma_mword & hwif->mwdma_mask) || + (id->dma_1word & hwif->swdma_mask)) { + /* Force if Capable regular DMA modes */ + if (!config_chipset_for_dma(drive)) + goto ata_pio; + } + } else if (__ide_dma_good_drive(drive) && + (id->eide_dma_time < 150)) { + /* Consult the list of known "good" drives */ + if (!config_chipset_for_dma(drive)) + goto ata_pio; + } else { + goto ata_pio; + } + } else { +ata_pio: + hwif->tuneproc(drive, 255); + return -1; + } + + return 0; } /** @@ -683,8 +739,7 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) return; } - if (m5229_revision > 0x20) - hwif->atapi_dma = 1; + hwif->atapi_dma = 1; if (m5229_revision <= 0x20) hwif->ultra_mask = 0x00; /* no udma */ diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 7c57dc696f52..61ea96b5555c 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -352,9 +352,22 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) return ide_config_drive_speed(drive, speed); } +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!speed) + return 0; + + if (cmd64x_tune_chipset(drive, speed)) + return 0; + + return ide_dma_enable(drive); +} + static int cmd64x_config_drive_for_dma (ide_drive_t *drive) { - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/trunk/drivers/ide/pci/cs5530.c b/trunk/drivers/ide/pci/cs5530.c index 1eec1f308d16..b2d7c132ef4b 100644 --- a/trunk/drivers/ide/pci/cs5530.c +++ b/trunk/drivers/ide/pci/cs5530.c @@ -1,10 +1,10 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.7 Sept 10, 2002 * * Copyright (C) 2000 Andre Hedrick - * Copyright (C) 2000 Mark Lord - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz + * Ditto of GNU General Public License. * + * Copyright (C) 2000 Mark Lord * May be copied or modified under the terms of the GNU General Public License * * Development of this chipset driver was funded @@ -62,14 +62,6 @@ static unsigned int cs5530_pio_timings[2][5] = { #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) #define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) -static void cs5530_tunepio(ide_drive_t *drive, u8 pio) -{ - unsigned long basereg = CS5530_BASEREG(drive->hwif); - unsigned int format = (inl(basereg + 4) >> 31) & 1; - - outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); -} - /** * cs5530_tuneproc - select/set PIO modes * @@ -82,78 +74,98 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio) static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */ { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - - if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) - cs5530_tunepio(drive, pio); -} - -/** - * cs5530_udma_filter - UDMA filter - * @drive: drive - * - * cs5530_udma_filter() does UDMA mask filtering for the given drive - * taking into the consideration capabilities of the mate device. - * - * The CS5530 specifies that two drives sharing a cable cannot mix - * UDMA/MDMA. It has to be one or the other, for the pair, though - * different timings can still be chosen for each drive. We could - * set the appropriate timing bits on the fly, but that might be - * a bit confusing. So, for now we statically handle this requirement - * by looking at our mate drive to see what it is capable of, before - * choosing a mode for our own drive. - * - * Note: This relies on the fact we never fail from UDMA to MWDMA2 - * but instead drop to PIO. - */ - -static u8 cs5530_udma_filter(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - ide_drive_t *mate = &hwif->drives[(drive->dn & 1) ^ 1]; - struct hd_driveid *mateid = mate->id; - u8 mask = hwif->ultra_mask; + ide_hwif_t *hwif = HWIF(drive); + unsigned int format; + unsigned long basereg = CS5530_BASEREG(hwif); + static u8 modes[5] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; - if (mate->present == 0) - goto out; - - if ((mateid->capability & 1) && __ide_dma_bad_drive(mate) == 0) { - if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) - goto out; - if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) - mask = 0; + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + if (!cs5530_set_xfer_mode(drive, modes[pio])) { + format = (inl(basereg + 4) >> 31) & 1; + outl(cs5530_pio_timings[format][pio], + basereg+(drive->select.b.unit<<3)); } -out: - return mask; } /** - * cs5530_config_dma - set DMA/UDMA mode + * cs5530_config_dma - select/set DMA and UDMA modes * @drive: drive to tune * - * cs5530_config_dma() handles setting of DMA/UDMA mode - * for both the chipset and drive. + * cs5530_config_dma() handles selection/setting of DMA/UDMA modes + * for both the chipset and drive. The CS5530 has limitations about + * mixing DMA/UDMA on the same cable. */ - -static int cs5530_config_dma(ide_drive_t *drive) + +static int cs5530_config_dma (ide_drive_t *drive) { - if (ide_tune_dma(drive)) - return 0; + int udma_ok = 1, mode = 0; + ide_hwif_t *hwif = HWIF(drive); + int unit = drive->select.b.unit; + ide_drive_t *mate = &hwif->drives[unit^1]; + struct hd_driveid *id = drive->id; + unsigned int reg, timings = 0; + unsigned long basereg; - return 1; -} + /* + * Default to DMA-off in case we run into trouble here. + */ + hwif->dma_off_quietly(drive); -static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode) -{ - unsigned long basereg; - unsigned int reg, timings = 0; + /* + * The CS5530 specifies that two drives sharing a cable cannot + * mix UDMA/MDMA. It has to be one or the other, for the pair, + * though different timings can still be chosen for each drive. + * We could set the appropriate timing bits on the fly, + * but that might be a bit confusing. So, for now we statically + * handle this requirement by looking at our mate drive to see + * what it is capable of, before choosing a mode for our own drive. + * + * Note: This relies on the fact we never fail from UDMA to MWDMA_2 + * but instead drop to PIO + */ + if (mate->present) { + struct hd_driveid *mateid = mate->id; + if (mateid && (mateid->capability & 1) && + !__ide_dma_bad_drive(mate)) { + if ((mateid->field_valid & 4) && + (mateid->dma_ultra & 7)) + udma_ok = 1; + else if ((mateid->field_valid & 2) && + (mateid->dma_mword & 7)) + udma_ok = 0; + else + udma_ok = 1; + } + } - mode = ide_rate_filter(drive, mode); + /* + * Now see what the current drive is capable of, + * selecting UDMA only if the mate said it was ok. + */ + if (id && (id->capability & 1) && drive->autodma && + !__ide_dma_bad_drive(drive)) { + if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { + if (id->dma_ultra & 4) + mode = XFER_UDMA_2; + else if (id->dma_ultra & 2) + mode = XFER_UDMA_1; + else if (id->dma_ultra & 1) + mode = XFER_UDMA_0; + } + if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { + if (id->dma_mword & 4) + mode = XFER_MW_DMA_2; + else if (id->dma_mword & 2) + mode = XFER_MW_DMA_1; + else if (id->dma_mword & 1) + mode = XFER_MW_DMA_0; + } + } /* * Tell the drive to switch to the new mode; abort on failure. */ - if (cs5530_set_xfer_mode(drive, mode)) + if (!mode || cs5530_set_xfer_mode(drive, mode)) return 1; /* failure */ /* @@ -166,21 +178,14 @@ static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode) case XFER_MW_DMA_0: timings = 0x00077771; break; case XFER_MW_DMA_1: timings = 0x00012121; break; case XFER_MW_DMA_2: timings = 0x00002020; break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - cs5530_tunepio(drive, mode - XFER_PIO_0); - return 0; default: BUG(); break; } - basereg = CS5530_BASEREG(drive->hwif); + basereg = CS5530_BASEREG(hwif); reg = inl(basereg + 4); /* get drive0 config register */ timings |= reg & 0x80000000; /* preserve PIO format bit */ - if ((drive-> dn & 1) == 0) { /* are we configuring drive0? */ + if (unit == 0) { /* are we configuring drive0? */ outl(timings, basereg + 4); /* write drive0 config register */ } else { if (timings & 0x00100000) @@ -306,8 +311,6 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->serialized = hwif->mate->serialized = 1; hwif->tuneproc = &cs5530_tuneproc; - hwif->speedproc = &cs5530_tune_chipset; - basereg = CS5530_BASEREG(hwif); d0_timings = inl(basereg + 0); if (CS5530_BAD_PIO(d0_timings)) { @@ -329,7 +332,6 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; - hwif->udma_filter = cs5530_udma_filter; hwif->ide_dma_check = &cs5530_config_dma; if (!noautodma) hwif->autodma = 1; diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index 5faaff87d580..442f658c6ae7 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -463,6 +463,25 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) return ide_config_drive_speed(drive, speed); } +/** + * config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by the IDE layer when it wants the timings set up. + */ + +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (speed == 0) + return 0; + + it821x_tune_chipset(drive, speed); + + return ide_dma_enable(drive); +} + /** * it821x_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up @@ -475,7 +494,7 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) static int it821x_config_drive_for_dma (ide_drive_t *drive) { - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; it821x_tuneproc(drive, 255); diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index cc0bfdcf1f19..65b1e124edf7 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -228,11 +228,38 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif) return get_indexed_reg(hwif, 0x0b) & 0x04; } +static int config_chipset_for_dma(ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + u8 speed; + + if (id->capability & 4) { + /* + * Set IORDY_EN & PREFETCH_EN (this seems to have + * NO real effect since this register is reloaded + * by hardware when the transfer mode is selected) + */ + u8 tmp, adj = (drive->dn & 1) ? 0x08 : 0x00; + + tmp = get_indexed_reg(hwif, 0x13 + adj); + set_indexed_reg(hwif, 0x13 + adj, tmp | 0x03); + } + + speed = ide_max_dma_mode(drive); + + if (!speed) + return 0; + + (void) hwif->speedproc(drive, speed); + return ide_dma_enable(drive); +} + static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) { drive->init_speed = 0; - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 23844687deea..7146fe3f6ba7 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -1,9 +1,8 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 * * Copyright (C) 1998-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this * compiled into the kernel if you have more than one card installed. @@ -61,7 +60,45 @@ static const char *pdc_quirk_drives[] = { NULL }; -static void pdc_old_disable_66MHz_clock(ide_hwif_t *); +/* A Register */ +#define SYNC_ERRDY_EN 0xC0 + +#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */ +#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */ +#define IORDY_EN 0x20 /* PIO: IOREADY */ +#define PREFETCH_EN 0x10 /* PIO: PREFETCH */ + +#define PA3 0x08 /* PIO"A" timing */ +#define PA2 0x04 /* PIO"A" timing */ +#define PA1 0x02 /* PIO"A" timing */ +#define PA0 0x01 /* PIO"A" timing */ + +/* B Register */ + +#define MB2 0x80 /* DMA"B" timing */ +#define MB1 0x40 /* DMA"B" timing */ +#define MB0 0x20 /* DMA"B" timing */ + +#define PB4 0x10 /* PIO_FORCE 1:0 */ + +#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */ +#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */ +#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */ +#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */ + +/* C Register */ +#define IORDYp_NO_SPEED 0x4F +#define SPEED_DIS 0x0F + +#define DMARQp 0x80 +#define IORDYp 0x40 +#define DMAR_EN 0x20 +#define DMAW_EN 0x10 + +#define MC3 0x08 /* DMA"C" timing */ +#define MC2 0x04 /* DMA"C" timing */ +#define MC1 0x02 /* DMA"C" timing */ +#define MC0 0x01 /* DMA"C" timing */ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) { @@ -70,25 +107,52 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) u8 drive_pci = 0x60 + (drive->dn << 2); u8 speed = ide_rate_filter(drive, xferspeed); - u8 AP = 0, BP = 0, CP = 0; + u32 drive_conf; + u8 AP, BP, CP, DP; u8 TA = 0, TB = 0, TC = 0; -#if PDC202XX_DEBUG_DRIVE_INFO - u32 drive_conf = 0; + if (drive->media != ide_disk && + drive->media != ide_cdrom && speed < XFER_SW_DMA_0) + return -1; + pci_read_config_dword(dev, drive_pci, &drive_conf); -#endif + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, (drive_pci)|0x03, &DP); - /* - * TODO: do this once per channel - */ - if (dev->device != PCI_DEVICE_ID_PROMISE_20246) - pdc_old_disable_66MHz_clock(hwif); + if (speed < XFER_SW_DMA_0) { + if ((AP & 0x0F) || (BP & 0x07)) { + /* clear PIO modes of lower 8421 bits of A Register */ + pci_write_config_byte(dev, (drive_pci), AP &~0x0F); + pci_read_config_byte(dev, (drive_pci), &AP); + + /* clear PIO modes of lower 421 bits of B Register */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + } + } else { + if ((BP & 0xF0) && (CP & 0x0F)) { + /* clear DMA modes of upper 842 bits of B Register */ + /* clear PIO forced mode upper 1 bit of B Register */ + pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + + /* clear DMA modes of lower 8421 bits of C Register */ + pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + } + } - pci_read_config_byte(dev, drive_pci, &AP); - pci_read_config_byte(dev, drive_pci + 1, &BP); - pci_read_config_byte(dev, drive_pci + 2, &CP); + pci_read_config_byte(dev, (drive_pci), &AP); + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); switch(speed) { + case XFER_UDMA_6: speed = XFER_UDMA_5; case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; @@ -97,7 +161,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_UDMA_0: case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; - case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break; + case XFER_MW_DMA_0: case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; @@ -110,39 +174,25 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) } if (speed < XFER_SW_DMA_0) { - /* - * preserve SYNC_INT / ERDDY_EN bits while clearing - * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A - */ - AP &= ~0x3f; - if (drive->id->capability & 4) - AP |= 0x20; /* set IORDY_EN bit */ - if (drive->media == ide_disk) - AP |= 0x10; /* set Prefetch_EN bit */ - /* clear PB[4:0] bits of register B */ - BP &= ~0x1f; - pci_write_config_byte(dev, drive_pci, AP | TA); - pci_write_config_byte(dev, drive_pci + 1, BP | TB); + pci_write_config_byte(dev, (drive_pci), AP|TA); + pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); } else { - /* clear MB[2:0] bits of register B */ - BP &= ~0xe0; - /* clear MC[3:0] bits of register C */ - CP &= ~0x0f; - pci_write_config_byte(dev, drive_pci + 1, BP | TB); - pci_write_config_byte(dev, drive_pci + 2, CP | TC); + pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); + pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); } #if PDC202XX_DEBUG_DRIVE_INFO printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", drive->name, ide_xfer_verbose(speed), drive->dn, drive_conf); - pci_read_config_dword(dev, drive_pci, &drive_conf); + pci_read_config_dword(dev, drive_pci, &drive_conf); printk("0x%08x\n", drive_conf); -#endif +#endif /* PDC202XX_DEBUG_DRIVE_INFO */ - return ide_config_drive_speed(drive, speed); + return (ide_config_drive_speed(drive, speed)); } + static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4, NULL); @@ -160,8 +210,6 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) * Set the control register to use the 66MHz system * clock for UDMA 3/4/5 mode operation when necessary. * - * FIXME: this register is shared by both channels, some locking is needed - * * It may also be possible to leave the 66MHz clock on * and readjust the timing parameters. */ @@ -181,11 +229,65 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); } +static int config_chipset_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 drive_conf = 0; + u8 drive_pci = 0x60 + (drive->dn << 2); + u8 test1 = 0, test2 = 0, speed = -1; + u8 AP = 0; + + if (dev->device != PCI_DEVICE_ID_PROMISE_20246) + pdc_old_disable_66MHz_clock(drive->hwif); + + drive_pci = 0x60 + (drive->dn << 2); + pci_read_config_dword(dev, drive_pci, &drive_conf); + if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) + goto chipset_is_set; + + pci_read_config_byte(dev, drive_pci, &test1); + if (!(test1 & SYNC_ERRDY_EN)) { + if (drive->select.b.unit & 0x01) { + pci_read_config_byte(dev, drive_pci - 4, &test2); + if ((test2 & SYNC_ERRDY_EN) && + !(test1 & SYNC_ERRDY_EN)) { + pci_write_config_byte(dev, drive_pci, + test1|SYNC_ERRDY_EN); + } + } else { + pci_write_config_byte(dev, drive_pci, + test1|SYNC_ERRDY_EN); + } + } + +chipset_is_set: + + pci_read_config_byte(dev, (drive_pci), &AP); + if (id->capability & 4) /* IORDY_EN */ + pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); + pci_read_config_byte(dev, (drive_pci), &AP); + if (drive->media == ide_disk) /* PREFETCH_EN */ + pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); + + speed = ide_max_dma_mode(drive); + + if (!(speed)) { + /* restore original pci-config space */ + pci_write_config_dword(dev, drive_pci, drive_conf); + return 0; + } + + (void) hwif->speedproc(drive, speed); + return ide_dma_enable(drive); +} + static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) { drive->init_speed = 0; - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index 523363c93794..b5ae0c50e216 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -1,9 +1,7 @@ /* - * linux/drivers/ide/pci/sc1200.c Version 0.94 Mar 10 2007 + * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 * * Copyright (C) 2000-2002 Mark Lord - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz - * * May be copied or modified under the terms of the GNU General Public License * * Development of this chipset driver was funded @@ -95,50 +93,64 @@ static const unsigned int sc1200_pio_timings[4][5] = */ //#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172) -static void sc1200_tunepio(ide_drive_t *drive, u8 pio) +static int sc1200_autoselect_dma_mode (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *pdev = hwif->pci_dev; - unsigned int basereg = hwif->channel ? 0x50 : 0x40, format = 0; - - pci_read_config_dword(pdev, basereg + 4, &format); - format = (format >> 31) & 1; - if (format) - format += sc1200_get_pci_clock(); - pci_write_config_dword(pdev, basereg + ((drive->dn & 1) << 3), - sc1200_pio_timings[format][pio]); -} + int udma_ok = 1, mode = 0; + ide_hwif_t *hwif = HWIF(drive); + int unit = drive->select.b.unit; + ide_drive_t *mate = &hwif->drives[unit^1]; + struct hd_driveid *id = drive->id; -/* - * The SC1200 specifies that two drives sharing a cable cannot mix - * UDMA/MDMA. It has to be one or the other, for the pair, though - * different timings can still be chosen for each drive. We could - * set the appropriate timing bits on the fly, but that might be - * a bit confusing. So, for now we statically handle this requirement - * by looking at our mate drive to see what it is capable of, before - * choosing a mode for our own drive. - */ -static u8 sc1200_udma_filter(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - ide_drive_t *mate = &hwif->drives[(drive->dn & 1) ^ 1]; - struct hd_driveid *mateid = mate->id; - u8 mask = hwif->ultra_mask; - - if (mate->present == 0) - goto out; - - if ((mateid->capability & 1) && __ide_dma_bad_drive(mate) == 0) { - if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) - goto out; - if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) - mask = 0; + /* + * The SC1200 specifies that two drives sharing a cable cannot + * mix UDMA/MDMA. It has to be one or the other, for the pair, + * though different timings can still be chosen for each drive. + * We could set the appropriate timing bits on the fly, + * but that might be a bit confusing. So, for now we statically + * handle this requirement by looking at our mate drive to see + * what it is capable of, before choosing a mode for our own drive. + */ + if (mate->present) { + struct hd_driveid *mateid = mate->id; + if (mateid && (mateid->capability & 1) && !__ide_dma_bad_drive(mate)) { + if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) + udma_ok = 1; + else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) + udma_ok = 0; + else + udma_ok = 1; + } } -out: - return mask; + /* + * Now see what the current drive is capable of, + * selecting UDMA only if the mate said it was ok. + */ + if (id && (id->capability & 1) && hwif->autodma && !__ide_dma_bad_drive(drive)) { + if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { + if (id->dma_ultra & 4) + mode = XFER_UDMA_2; + else if (id->dma_ultra & 2) + mode = XFER_UDMA_1; + else if (id->dma_ultra & 1) + mode = XFER_UDMA_0; + } + if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { + if (id->dma_mword & 4) + mode = XFER_MW_DMA_2; + else if (id->dma_mword & 2) + mode = XFER_MW_DMA_1; + else if (id->dma_mword & 1) + mode = XFER_MW_DMA_0; + } + } + return mode; } -static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) +/* + * sc1200_config_dma2() handles selection/setting of DMA/UDMA modes + * for both the chipset and drive. + */ +static int sc1200_config_dma2 (ide_drive_t *drive, int mode) { ide_hwif_t *hwif = HWIF(drive); int unit = drive->select.b.unit; @@ -146,26 +158,20 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; - mode = ide_rate_filter(drive, mode); + /* + * Default to DMA-off in case we run into trouble here. + */ + hwif->dma_off_quietly(drive); /* turn off DMA while we fiddle */ + outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ /* * Tell the drive to switch to the new mode; abort on failure. */ - if (sc1200_set_xfer_mode(drive, mode)) { + if (!mode || sc1200_set_xfer_mode(drive, mode)) { printk("SC1200: set xfer mode failure\n"); return 1; /* failure */ } - switch (mode) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - sc1200_tunepio(drive, mode - XFER_PIO_0); - return 0; - } - pci_clock = sc1200_get_pci_clock(); /* @@ -218,9 +224,11 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) case PCI_CLK_66: timings = 0x00015151; break; } break; - default: - BUG(); - break; + } + + if (timings == 0) { + printk("%s: sc1200_config_dma: huh? mode=%02x clk=%x \n", drive->name, mode, pci_clock); + return 1; /* failure */ } if (unit == 0) { /* are we configuring drive0? */ @@ -231,6 +239,8 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) pci_write_config_dword(hwif->pci_dev, basereg+12, timings); } + outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ + return 0; /* success */ } @@ -240,10 +250,7 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) */ static int sc1200_config_dma (ide_drive_t *drive) { - if (ide_tune_dma(drive)) - return 0; - - return 1; + return sc1200_config_dma2(drive, sc1200_autoselect_dma_mode(drive)); } @@ -283,11 +290,10 @@ static int sc1200_ide_dma_end (ide_drive_t *drive) static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */ { ide_hwif_t *hwif = HWIF(drive); + unsigned int format; + static byte modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; int mode = -1; - /* - * bad abuse of ->tuneproc interface - */ switch (pio) { case 200: mode = XFER_UDMA_0; break; case 201: mode = XFER_UDMA_1; break; @@ -298,17 +304,20 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au } if (mode != -1) { printk("SC1200: %s: changing (U)DMA mode\n", drive->name); - hwif->dma_off_quietly(drive); - if (sc1200_tune_chipset(drive, mode) == 0) - hwif->dma_host_on(drive); + (void)sc1200_config_dma2(drive, mode); return; } pio = ide_get_best_pio_mode(drive, pio, 4, NULL); printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio); - - if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) - sc1200_tunepio(drive, pio); + if (!sc1200_set_xfer_mode(drive, modes[pio])) { + unsigned int basereg = hwif->channel ? 0x50 : 0x40; + pci_read_config_dword (hwif->pci_dev, basereg+4, &format); + format = (format >> 31) & 1; + if (format) + format += sc1200_get_pci_clock(); + pci_write_config_dword(hwif->pci_dev, basereg + (drive->select.b.unit << 3), sc1200_pio_timings[format][pio]); + } } #ifdef CONFIG_PM @@ -429,12 +438,12 @@ static int sc1200_resume (struct pci_dev *dev) for (d = 0; d < MAX_DRIVES; ++d) { ide_drive_t *drive = &(hwif->drives[d]); if (drive->present && !__ide_dma_bad_drive(drive)) { - int enable_dma = drive->using_dma; + int was_using_dma = drive->using_dma; hwif->dma_off_quietly(drive); - if (sc1200_config_dma(drive)) - enable_dma = 0; - if (enable_dma) - hwif->dma_host_on(drive); + sc1200_config_dma(drive); + if (!was_using_dma && drive->using_dma) { + hwif->dma_off_quietly(drive); + } } } } @@ -452,13 +461,11 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) hwif->serialized = hwif->mate->serialized = 1; hwif->autodma = 0; if (hwif->dma_base) { - hwif->udma_filter = sc1200_udma_filter; hwif->ide_dma_check = &sc1200_config_dma; hwif->ide_dma_end = &sc1200_ide_dma_end; if (!noautodma) hwif->autodma = 1; hwif->tuneproc = &sc1200_tuneproc; - hwif->speedproc = &sc1200_tune_chipset; } hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; diff --git a/trunk/drivers/ide/pci/scc_pata.c b/trunk/drivers/ide/pci/scc_pata.c index 55bc0a32e34f..cbf936325355 100644 --- a/trunk/drivers/ide/pci/scc_pata.c +++ b/trunk/drivers/ide/pci/scc_pata.c @@ -321,6 +321,26 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) return ide_config_drive_speed(drive, speed); } +/** + * scc_config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by scc_config_drive_for_dma(). + */ + +static int scc_config_chipset_for_dma(ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!speed) + return 0; + + if (scc_tune_chipset(drive, speed)) + return 0; + + return ide_dma_enable(drive); +} + /** * scc_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up @@ -334,7 +354,7 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) static int scc_config_drive_for_dma(ide_drive_t *drive) { - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index 6234f806c6b5..2fa6d92d16cc 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -1,10 +1,9 @@ /* - * linux/drivers/ide/pci/serverworks.c Version 0.9 Mar 4 2007 + * linux/drivers/ide/pci/serverworks.c Version 0.8 25 Ebr 2003 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz * Copyright (C) 1998-2000 Andre Hedrick - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * Portions copyright (c) 2001 Sun Microsystems * * @@ -137,14 +136,19 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(drive, xferspeed); - u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL); + u8 speed; + u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL); u8 unit = (drive->select.b.unit & 0x01); u8 csb5 = svwks_csb_check(dev); u8 ultra_enable = 0, ultra_timing = 0; u8 dma_timing = 0, pio_timing = 0; u16 csb5_pio = 0; + if (xferspeed == 255) /* PIO auto-tuning */ + speed = XFER_PIO_0 + pio; + else + speed = ide_rate_filter(drive, xferspeed); + /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ @@ -227,9 +231,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - /* - * TODO: always setup PIO mode so this won't be needed - */ pio_timing |= pio_modes[pio]; csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; @@ -241,9 +242,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: - /* - * TODO: always setup PIO mode so this won't be needed - */ pio_timing |= pio_modes[pio]; csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[2]; @@ -264,21 +262,72 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } +static void config_chipset_for_pio (ide_drive_t *drive) +{ + u16 eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; + u16 xfer_pio = drive->id->eide_pio_modes; + u8 timing, speed, pio; + + pio = ide_get_best_pio_mode(drive, 255, 5, NULL); + + if (xfer_pio > 4) + xfer_pio = 0; + + if (drive->id->eide_pio_iordy > 0) + for (xfer_pio = 5; + xfer_pio>0 && + drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; + xfer_pio--); + else + xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : + (drive->id->eide_pio_modes & 2) ? 0x04 : + (drive->id->eide_pio_modes & 1) ? 0x03 : + (drive->id->tPIO & 2) ? 0x02 : + (drive->id->tPIO & 1) ? 0x01 : xfer_pio; + + timing = (xfer_pio >= pio) ? xfer_pio : pio; + + switch(timing) { + case 4: speed = XFER_PIO_4;break; + case 3: speed = XFER_PIO_3;break; + case 2: speed = XFER_PIO_2;break; + case 1: speed = XFER_PIO_1;break; + default: + speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; + break; + } + (void) svwks_tune_chipset(drive, speed); + drive->current_speed = speed; +} + static void svwks_tune_drive (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio); + if(pio == 255) + (void) svwks_tune_chipset(drive, 255); + else + (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio)); +} + +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!(speed)) + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + + (void) svwks_tune_chipset(drive, speed); + return ide_dma_enable(drive); } static int svwks_config_drive_xfer_rate (ide_drive_t *drive) { drive->init_speed = 0; - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) - svwks_tune_drive(drive, 255); + config_chipset_for_pio(drive); return -1; } diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index 1a4444e7226a..d09e74c2996e 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -374,6 +374,28 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) return (ide_config_drive_speed(drive, speed)); } +/** + * config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by the IDE layer when it wants the timings set up. + * For the CMD680 we also need to set up the PIO timings and + * enable DMA. + */ + +static int config_chipset_for_dma (ide_drive_t *drive) +{ + u8 speed = ide_max_dma_mode(drive); + + if (!speed) + return 0; + + if (siimage_tune_chipset(drive, speed)) + return 0; + + return ide_dma_enable(drive); +} + /** * siimage_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up @@ -386,7 +408,7 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) static int siimage_config_drive_for_dma (ide_drive_t *drive) { - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index bb6cc4aedd63..2bde1b92784a 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -1,11 +1,9 @@ /* - * linux/drivers/ide/pci/sis5513.c Version 0.20 Mar 4, 2007 + * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 * * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2002 Lionel Bouton , Maintainer * Copyright (C) 2003 Vojtech Pavlik - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz - * * May be copied or modified under the terms of the GNU General Public License * * @@ -450,15 +448,36 @@ static void config_drive_art_rwp (ide_drive_t *drive) pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); } + /* Set per-drive active and recovery time */ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 drive_pci, test1, test2; + u8 timing, drive_pci, test1, test2; + + u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; + u16 xfer_pio = drive->id->eide_pio_modes; config_drive_art_rwp(drive); + pio = ide_get_best_pio_mode(drive, 255, pio, NULL); + + if (xfer_pio> 4) + xfer_pio = 0; + + if (drive->id->eide_pio_iordy > 0) { + for (xfer_pio = 5; + (xfer_pio > 0) && + (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]); + xfer_pio--); + } else { + xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : + (drive->id->eide_pio_modes & 2) ? 0x04 : + (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; + } + + timing = (xfer_pio >= pio) ? xfer_pio : pio; /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ drive_pci = 0x40; @@ -481,18 +500,17 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) test1 &= ~0x0F; test2 &= ~0x07; - switch(pio) { + switch(timing) { case 4: test1 |= 0x01; test2 |= 0x03; break; case 3: test1 |= 0x03; test2 |= 0x03; break; case 2: test1 |= 0x04; test2 |= 0x04; break; case 1: test1 |= 0x07; test2 |= 0x06; break; - case 0: /* PIO0: register setting == X000 */ default: break; } pci_write_config_byte(dev, drive_pci, test1); pci_write_config_byte(dev, drive_pci+1, test2); } else if (chipset_family < ATA_133) { - switch(pio) { /* active recovery + switch(timing) { /* active recovery v v */ case 4: test1 = 0x30|0x01; break; case 3: test1 = 0x30|0x03; break; @@ -507,28 +525,24 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) pci_read_config_dword(dev, drive_pci, &test3); test3 &= 0xc0c00fff; if (test3 & 0x08) { - test3 |= ini_time_value[ATA_133][pio] << 12; - test3 |= act_time_value[ATA_133][pio] << 16; - test3 |= rco_time_value[ATA_133][pio] << 24; + test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; + test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; + test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; } else { - test3 |= ini_time_value[ATA_100][pio] << 12; - test3 |= act_time_value[ATA_100][pio] << 16; - test3 |= rco_time_value[ATA_100][pio] << 24; + test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; + test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; + test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; } pci_write_config_dword(dev, drive_pci, test3); } } -static int sis5513_tune_drive(ide_drive_t *drive, u8 pio) +static int config_chipset_for_pio (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + if (pio == 255) + pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - -static void sis5513_tuneproc(ide_drive_t *drive, u8 pio) -{ - (void)sis5513_tune_drive(drive, pio); + return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); } static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) @@ -608,26 +622,25 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_SW_DMA_1: case XFER_SW_DMA_0: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: + case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); + case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); + case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); + case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); case XFER_PIO_0: - return sis5513_tune_drive(drive, speed - XFER_PIO_0); - default: - BUG(); - break; + default: return((int) config_chipset_for_pio(drive, 0)); } - return ide_config_drive_speed(drive, speed); + return ((int) ide_config_drive_speed(drive, speed)); +} + +static void sis5513_tune_drive (ide_drive_t *drive, u8 pio) +{ + (void) config_chipset_for_pio(drive, pio); } static int sis5513_config_xfer_rate(ide_drive_t *drive) { - /* - * TODO: always set PIO mode and remove this - */ - sis5513_tuneproc(drive, 255); + config_art_rwp_pio(drive, 5); drive->init_speed = 0; @@ -635,7 +648,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - sis5513_tuneproc(drive, 255); + sis5513_tune_drive(drive, 5); return -1; } @@ -823,7 +836,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; - hwif->tuneproc = &sis5513_tuneproc; + hwif->tuneproc = &sis5513_tune_drive; hwif->speedproc = &sis5513_tune_chipset; if (!(hwif->dma_base)) { diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 7c383d9cc472..fe3b4b91f854 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -82,14 +82,7 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) pio = ide_get_best_pio_mode(drive, pio, 5, &p); - drv_ctrl = get_pio_timings(&p); - - /* - * Store the PIO timings so that we can restore them - * in case DMA will be turned off... - */ - drive->drive_data &= 0xffff0000; - drive->drive_data |= drv_ctrl; + drive->drive_data = drv_ctrl = get_pio_timings(&p); if (!drive->using_dma) { /* @@ -107,55 +100,17 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) } /* - * Configure the drive and chipset for a new transfer speed. + * Configure the drive for DMA. + * We'll program the chipset only when DMA is actually turned on. */ -static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) +static int config_for_dma(ide_drive_t *drive) { - static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; - u16 drv_ctrl; - - DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", - drive->name, ide_xfer_verbose(speed))); + DBG(("config_for_dma(drive:%s)\n", drive->name)); - speed = ide_rate_filter(drive, speed); - - switch (speed) { - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0]; - - /* - * Store the DMA timings so that we can actually program - * them when DMA will be turned on... - */ - drive->drive_data &= 0x0000ffff; - drive->drive_data |= (unsigned long)drv_ctrl << 16; - - /* - * If we are already using DMA, we just reprogram - * the drive control register. - */ - if (drive->using_dma) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int reg = 0x44 + drive->dn * 4; - - pci_write_config_word(dev, reg, drv_ctrl); - } - break; - case XFER_PIO_5: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - (void) sl82c105_tune_pio(drive, speed - XFER_PIO_0); - break; - default: - return -1; - } + if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) + return 0; - return ide_config_drive_speed(drive, speed); + return ide_dma_enable(drive); } /* @@ -165,7 +120,7 @@ static int sl82c105_ide_dma_check(ide_drive_t *drive) { DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - if (ide_tune_dma(drive)) + if (ide_use_dma(drive) && config_for_dma(drive)) return 0; return -1; @@ -264,7 +219,7 @@ static int sl82c105_ide_dma_on(ide_drive_t *drive) rc = __ide_dma_on(drive); if (rc == 0) { - pci_write_config_word(dev, reg, drive->drive_data >> 16); + pci_write_config_word(dev, reg, 0x0200); printk(KERN_INFO "%s: DMA enabled\n", drive->name); } @@ -349,7 +304,7 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) /* * The bridge should be part of the same device, but function 0. */ - bridge = pci_get_bus_and_slot(dev->bus->number, + bridge = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (!bridge) return -1; @@ -359,15 +314,13 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) */ if (bridge->vendor != PCI_VENDOR_ID_WINBOND || bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || - bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) { - pci_dev_put(bridge); + bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) return -1; - } + /* * We need to find function 0's revision, not function 1 */ pci_read_config_byte(bridge, PCI_REVISION_ID, &rev); - pci_dev_put(bridge); return rev; } @@ -404,7 +357,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); hwif->tuneproc = &sl82c105_tune_drive; - hwif->speedproc = &sl82c105_tune_chipset; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc; @@ -436,7 +388,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) } hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; + hwif->mwdma_mask = 0x04; hwif->ide_dma_check = &sl82c105_ide_dma_check; hwif->ide_dma_on = &sl82c105_ide_dma_on; diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 2eb52b7a71da..fde92ce45153 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -346,33 +346,12 @@ static void cma_deref_id(struct rdma_id_private *id_priv) complete(&id_priv->comp); } -static int cma_disable_remove(struct rdma_id_private *id_priv, - enum cma_state state) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&id_priv->lock, flags); - if (id_priv->state == state) { - atomic_inc(&id_priv->dev_remove); - ret = 0; - } else - ret = -EINVAL; - spin_unlock_irqrestore(&id_priv->lock, flags); - return ret; -} - -static void cma_enable_remove(struct rdma_id_private *id_priv) +static void cma_release_remove(struct rdma_id_private *id_priv) { if (atomic_dec_and_test(&id_priv->dev_remove)) wake_up(&id_priv->wait_remove); } -static int cma_has_cm_dev(struct rdma_id_private *id_priv) -{ - return (id_priv->id.device && id_priv->cm_id.ib); -} - struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler, void *context, enum rdma_port_space ps) { @@ -905,8 +884,9 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) struct rdma_cm_event event; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) - return 0; + atomic_inc(&id_priv->dev_remove); + if (!cma_comp(id_priv, CMA_CONNECT)) + goto out; memset(&event, 0, sizeof event); switch (ib_event->event) { @@ -962,12 +942,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.ib = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + cma_release_remove(id_priv); rdma_destroy_id(&id_priv->id); return ret; } out: - cma_enable_remove(id_priv); + cma_release_remove(id_priv); return ret; } @@ -1077,8 +1057,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) int offset, ret; listen_id = cm_id->context; - if (cma_disable_remove(listen_id, CMA_LISTEN)) - return -ECONNABORTED; + atomic_inc(&listen_id->dev_remove); + if (!cma_comp(listen_id, CMA_LISTEN)) { + ret = -ECONNABORTED; + goto out; + } memset(&event, 0, sizeof event); offset = cma_user_data_offset(listen_id->id.ps); @@ -1118,11 +1101,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) release_conn_id: cma_exch(conn_id, CMA_DESTROYING); - cma_enable_remove(conn_id); + cma_release_remove(conn_id); rdma_destroy_id(&conn_id->id); out: - cma_enable_remove(listen_id); + cma_release_remove(listen_id); return ret; } @@ -1188,10 +1171,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) struct sockaddr_in *sin; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) - return 0; - memset(&event, 0, sizeof event); + atomic_inc(&id_priv->dev_remove); + switch (iw_event->event) { case IW_CM_EVENT_CLOSE: event.event = RDMA_CM_EVENT_DISCONNECTED; @@ -1232,12 +1214,12 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.iw = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + cma_release_remove(id_priv); rdma_destroy_id(&id_priv->id); return ret; } - cma_enable_remove(id_priv); + cma_release_remove(id_priv); return ret; } @@ -1252,8 +1234,11 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, int ret; listen_id = cm_id->context; - if (cma_disable_remove(listen_id, CMA_LISTEN)) - return -ECONNABORTED; + atomic_inc(&listen_id->dev_remove); + if (!cma_comp(listen_id, CMA_LISTEN)) { + ret = -ECONNABORTED; + goto out; + } /* Create a new RDMA id for the new IW CM ID */ new_cm_id = rdma_create_id(listen_id->id.event_handler, @@ -1270,13 +1255,13 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr); if (!dev) { ret = -EADDRNOTAVAIL; - cma_enable_remove(conn_id); + cma_release_remove(conn_id); rdma_destroy_id(new_cm_id); goto out; } ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL); if (ret) { - cma_enable_remove(conn_id); + cma_release_remove(conn_id); rdma_destroy_id(new_cm_id); goto out; } @@ -1285,7 +1270,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, ret = cma_acquire_dev(conn_id); mutex_unlock(&lock); if (ret) { - cma_enable_remove(conn_id); + cma_release_remove(conn_id); rdma_destroy_id(new_cm_id); goto out; } @@ -1308,14 +1293,14 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, /* User wants to destroy the CM ID */ conn_id->cm_id.iw = NULL; cma_exch(conn_id, CMA_DESTROYING); - cma_enable_remove(conn_id); + cma_release_remove(conn_id); rdma_destroy_id(&conn_id->id); } out: if (dev) dev_put(dev); - cma_enable_remove(listen_id); + cma_release_remove(listen_id); return ret; } @@ -1534,7 +1519,7 @@ static void cma_work_handler(struct work_struct *_work) destroy = 1; } out: - cma_enable_remove(id_priv); + cma_release_remove(id_priv); cma_deref_id(id_priv); if (destroy) rdma_destroy_id(&id_priv->id); @@ -1726,13 +1711,13 @@ static void addr_handler(int status, struct sockaddr *src_addr, if (id_priv->id.event_handler(&id_priv->id, &event)) { cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + cma_release_remove(id_priv); cma_deref_id(id_priv); rdma_destroy_id(&id_priv->id); return; } out: - cma_enable_remove(id_priv); + cma_release_remove(id_priv); cma_deref_id(id_priv); } @@ -2057,10 +2042,11 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) - return 0; - memset(&event, 0, sizeof event); + atomic_inc(&id_priv->dev_remove); + if (!cma_comp(id_priv, CMA_CONNECT)) + goto out; + switch (ib_event->event) { case IB_CM_SIDR_REQ_ERROR: event.event = RDMA_CM_EVENT_UNREACHABLE; @@ -2098,12 +2084,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.ib = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + cma_release_remove(id_priv); rdma_destroy_id(&id_priv->id); return ret; } out: - cma_enable_remove(id_priv); + cma_release_remove(id_priv); return ret; } @@ -2427,7 +2413,7 @@ int rdma_notify(struct rdma_cm_id *id, enum ib_event_type event) int ret; id_priv = container_of(id, struct rdma_id_private, id); - if (!cma_has_cm_dev(id_priv)) + if (!cma_comp(id_priv, CMA_CONNECT)) return -EINVAL; switch (id->device->node_type) { @@ -2449,7 +2435,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data, int ret; id_priv = container_of(id, struct rdma_id_private, id); - if (!cma_has_cm_dev(id_priv)) + if (!cma_comp(id_priv, CMA_CONNECT)) return -EINVAL; switch (rdma_node_get_transport(id->device->node_type)) { @@ -2480,7 +2466,8 @@ int rdma_disconnect(struct rdma_cm_id *id) int ret; id_priv = container_of(id, struct rdma_id_private, id); - if (!cma_has_cm_dev(id_priv)) + if (!cma_comp(id_priv, CMA_CONNECT) && + !cma_comp(id_priv, CMA_DISCONNECT)) return -EINVAL; switch (rdma_node_get_transport(id->device->node_type)) { @@ -2512,9 +2499,10 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) int ret; id_priv = mc->id_priv; - if (cma_disable_remove(id_priv, CMA_ADDR_BOUND) && - cma_disable_remove(id_priv, CMA_ADDR_RESOLVED)) - return 0; + atomic_inc(&id_priv->dev_remove); + if (!cma_comp(id_priv, CMA_ADDR_BOUND) && + !cma_comp(id_priv, CMA_ADDR_RESOLVED)) + goto out; if (!status && id_priv->id.qp) status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid, @@ -2536,12 +2524,12 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) ret = id_priv->id.event_handler(&id_priv->id, &event); if (ret) { cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + cma_release_remove(id_priv); rdma_destroy_id(&id_priv->id); return 0; } - - cma_enable_remove(id_priv); +out: + cma_release_remove(id_priv); return 0; } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h index 1d286d3cc2d5..f64d42b08674 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h @@ -277,7 +277,6 @@ void ehca_cleanup_mrmw_cache(void); extern spinlock_t ehca_qp_idr_lock; extern spinlock_t ehca_cq_idr_lock; -extern spinlock_t hcall_lock; extern struct idr ehca_qp_idr; extern struct idr ehca_cq_idr; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c index 100329ba3343..82dda2faf4d0 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c @@ -517,11 +517,12 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) else { struct ehca_cq *cq = eq->eqe_cache[i].cq; comp_event_callback(cq); - spin_lock(&ehca_cq_idr_lock); + spin_lock_irqsave(&ehca_cq_idr_lock, flags); cq->nr_events--; if (!cq->nr_events) wake_up(&cq->wait_completion); - spin_unlock(&ehca_cq_idr_lock); + spin_unlock_irqrestore(&ehca_cq_idr_lock, + flags); } } else { ehca_dbg(&shca->ib_device, "Got non completion event"); @@ -710,7 +711,6 @@ static void destroy_comp_task(struct ehca_comp_pool *pool, kthread_stop(task); } -#ifdef CONFIG_HOTPLUG_CPU static void take_over_work(struct ehca_comp_pool *pool, int cpu) { @@ -735,6 +735,7 @@ static void take_over_work(struct ehca_comp_pool *pool, } +#ifdef CONFIG_HOTPLUG_CPU static int comp_pool_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index c3f99f33b49c..fe90e7454560 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -52,7 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Christoph Raisch "); MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); -MODULE_VERSION("SVNEHCA_0023"); +MODULE_VERSION("SVNEHCA_0022"); int ehca_open_aqp1 = 0; int ehca_debug_level = 0; @@ -62,7 +62,7 @@ int ehca_use_hp_mr = 0; int ehca_port_act_time = 30; int ehca_poll_all_eqs = 1; int ehca_static_rate = -1; -int ehca_scaling_code = 0; +int ehca_scaling_code = 1; module_param_named(open_aqp1, ehca_open_aqp1, int, 0); module_param_named(debug_level, ehca_debug_level, int, 0); @@ -98,7 +98,6 @@ MODULE_PARM_DESC(scaling_code, spinlock_t ehca_qp_idr_lock; spinlock_t ehca_cq_idr_lock; -spinlock_t hcall_lock; DEFINE_IDR(ehca_qp_idr); DEFINE_IDR(ehca_cq_idr); @@ -454,14 +453,15 @@ static ssize_t ehca_store_debug_level(struct device_driver *ddp, DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR, ehca_show_debug_level, ehca_store_debug_level); -static struct attribute *ehca_drv_attrs[] = { - &driver_attr_debug_level.attr, - NULL -}; +void ehca_create_driver_sysfs(struct ibmebus_driver *drv) +{ + driver_create_file(&drv->driver, &driver_attr_debug_level); +} -static struct attribute_group ehca_drv_attr_grp = { - .attrs = ehca_drv_attrs -}; +void ehca_remove_driver_sysfs(struct ibmebus_driver *drv) +{ + driver_remove_file(&drv->driver, &driver_attr_debug_level); +} #define EHCA_RESOURCE_ATTR(name) \ static ssize_t ehca_show_##name(struct device *dev, \ @@ -523,28 +523,44 @@ static ssize_t ehca_show_adapter_handle(struct device *dev, } static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); -static struct attribute *ehca_dev_attrs[] = { - &dev_attr_adapter_handle.attr, - &dev_attr_num_ports.attr, - &dev_attr_hw_ver.attr, - &dev_attr_max_eq.attr, - &dev_attr_cur_eq.attr, - &dev_attr_max_cq.attr, - &dev_attr_cur_cq.attr, - &dev_attr_max_qp.attr, - &dev_attr_cur_qp.attr, - &dev_attr_max_mr.attr, - &dev_attr_cur_mr.attr, - &dev_attr_max_mw.attr, - &dev_attr_cur_mw.attr, - &dev_attr_max_pd.attr, - &dev_attr_max_ah.attr, - NULL -}; -static struct attribute_group ehca_dev_attr_grp = { - .attrs = ehca_dev_attrs -}; +void ehca_create_device_sysfs(struct ibmebus_dev *dev) +{ + device_create_file(&dev->ofdev.dev, &dev_attr_adapter_handle); + device_create_file(&dev->ofdev.dev, &dev_attr_num_ports); + device_create_file(&dev->ofdev.dev, &dev_attr_hw_ver); + device_create_file(&dev->ofdev.dev, &dev_attr_max_eq); + device_create_file(&dev->ofdev.dev, &dev_attr_cur_eq); + device_create_file(&dev->ofdev.dev, &dev_attr_max_cq); + device_create_file(&dev->ofdev.dev, &dev_attr_cur_cq); + device_create_file(&dev->ofdev.dev, &dev_attr_max_qp); + device_create_file(&dev->ofdev.dev, &dev_attr_cur_qp); + device_create_file(&dev->ofdev.dev, &dev_attr_max_mr); + device_create_file(&dev->ofdev.dev, &dev_attr_cur_mr); + device_create_file(&dev->ofdev.dev, &dev_attr_max_mw); + device_create_file(&dev->ofdev.dev, &dev_attr_cur_mw); + device_create_file(&dev->ofdev.dev, &dev_attr_max_pd); + device_create_file(&dev->ofdev.dev, &dev_attr_max_ah); +} + +void ehca_remove_device_sysfs(struct ibmebus_dev *dev) +{ + device_remove_file(&dev->ofdev.dev, &dev_attr_adapter_handle); + device_remove_file(&dev->ofdev.dev, &dev_attr_num_ports); + device_remove_file(&dev->ofdev.dev, &dev_attr_hw_ver); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_eq); + device_remove_file(&dev->ofdev.dev, &dev_attr_cur_eq); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_cq); + device_remove_file(&dev->ofdev.dev, &dev_attr_cur_cq); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_qp); + device_remove_file(&dev->ofdev.dev, &dev_attr_cur_qp); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_mr); + device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mr); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_mw); + device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mw); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_pd); + device_remove_file(&dev->ofdev.dev, &dev_attr_max_ah); +} static int __devinit ehca_probe(struct ibmebus_dev *dev, const struct of_device_id *id) @@ -652,10 +668,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, } } - ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp); - if (ret) /* only complain; we can live without attributes */ - ehca_err(&shca->ib_device, - "Cannot create device attributes ret=%d", ret); + ehca_create_device_sysfs(dev); spin_lock(&shca_list_lock); list_add(&shca->shca_list, &shca_list); @@ -707,7 +720,7 @@ static int __devexit ehca_remove(struct ibmebus_dev *dev) struct ehca_shca *shca = dev->ofdev.dev.driver_data; int ret; - sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp); + ehca_remove_device_sysfs(dev); if (ehca_open_aqp1 == 1) { int i; @@ -799,12 +812,11 @@ int __init ehca_module_init(void) int ret; printk(KERN_INFO "eHCA Infiniband Device Driver " - "(Rel.: SVNEHCA_0023)\n"); + "(Rel.: SVNEHCA_0022)\n"); idr_init(&ehca_qp_idr); idr_init(&ehca_cq_idr); spin_lock_init(&ehca_qp_idr_lock); spin_lock_init(&ehca_cq_idr_lock); - spin_lock_init(&hcall_lock); INIT_LIST_HEAD(&shca_list); spin_lock_init(&shca_list_lock); @@ -826,9 +838,7 @@ int __init ehca_module_init(void) goto module_init2; } - ret = sysfs_create_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp); - if (ret) /* only complain; we can live without attributes */ - ehca_gen_err("Cannot create driver attributes ret=%d", ret); + ehca_create_driver_sysfs(&ehca_driver); if (ehca_poll_all_eqs != 1) { ehca_gen_err("WARNING!!!"); @@ -855,7 +865,7 @@ void __exit ehca_module_exit(void) if (ehca_poll_all_eqs == 1) del_timer_sync(&poll_eqs_timer); - sysfs_remove_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp); + ehca_remove_driver_sysfs(&ehca_driver); ibmebus_unregister_driver(&ehca_driver); ehca_destroy_slab_caches(); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index b5bc787c77b6..df0516f24379 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -523,8 +523,6 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, goto create_qp_exit1; } - my_qp->ib_qp.qp_num = my_qp->real_qp_num; - switch (init_attr->qp_type) { case IB_QPT_RC: if (isdaqp == 0) { @@ -570,7 +568,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, parms.act_nr_recv_wqes = init_attr->cap.max_recv_wr; parms.act_nr_send_sges = init_attr->cap.max_send_sge; parms.act_nr_recv_sges = init_attr->cap.max_recv_sge; - my_qp->ib_qp.qp_num = + my_qp->real_qp_num = (init_attr->qp_type == IB_QPT_SMI) ? 0 : 1; } @@ -597,6 +595,7 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, my_qp->ib_qp.recv_cq = init_attr->recv_cq; my_qp->ib_qp.send_cq = init_attr->send_cq; + my_qp->ib_qp.qp_num = my_qp->real_qp_num; my_qp->ib_qp.qp_type = init_attr->qp_type; my_qp->qp_type = init_attr->qp_type; @@ -969,21 +968,17 @@ static int internal_modify_qp(struct ib_qp *ibqp, ((ehca_mult - 1) / ah_mult) : 0; else mqpcb->max_static_rate = 0; - update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1); - /* - * Always supply the GRH flag, even if it's zero, to give the - * hypervisor a clear "yes" or "no" instead of a "perhaps" - */ - update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG, 1); + update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE, 1); /* * only if GRH is TRUE we might consider SOURCE_GID_IDX * and DEST_GID otherwise phype will return H_ATTR_PARM!!! */ if (attr->ah_attr.ah_flags == IB_AH_GRH) { - mqpcb->send_grh_flag = 1; - + mqpcb->send_grh_flag = 1 << 31; + update_mask |= + EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG, 1); mqpcb->source_gid_idx = attr->ah_attr.grh.sgid_index; update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX, 1); diff --git a/trunk/drivers/infiniband/hw/ehca/hcp_if.c b/trunk/drivers/infiniband/hw/ehca/hcp_if.c index 7f0beec74f70..b564fcd3b282 100644 --- a/trunk/drivers/infiniband/hw/ehca/hcp_if.c +++ b/trunk/drivers/infiniband/hw/ehca/hcp_if.c @@ -154,8 +154,7 @@ static long ehca_plpar_hcall9(unsigned long opcode, unsigned long arg9) { long ret; - int i, sleep_msecs, lock_is_set = 0; - unsigned long flags; + int i, sleep_msecs; ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", @@ -163,18 +162,10 @@ static long ehca_plpar_hcall9(unsigned long opcode, arg8, arg9); for (i = 0; i < 5; i++) { - if ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)) { - spin_lock_irqsave(&hcall_lock, flags); - lock_is_set = 1; - } - ret = plpar_hcall9(opcode, outs, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - if (lock_is_set) - spin_unlock_irqrestore(&hcall_lock, flags); - if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); @@ -202,11 +193,11 @@ static long ehca_plpar_hcall9(unsigned long opcode, opcode, ret, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); return ret; + } return H_BUSY; } - u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle, struct ehca_pfeq *pfeq, const u32 neq_control, diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c index 4e2e3dfeb2c8..1b9c30857754 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c @@ -747,6 +747,7 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd) static int ipath_pe_intconfig(struct ipath_devdata *dd) { + u64 val; u32 chiprev; /* @@ -759,9 +760,9 @@ static int ipath_pe_intconfig(struct ipath_devdata *dd) if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) { /* Rev2+ reports extra errors via internal GPIO pins */ dd->ipath_flags |= IPATH_GPIO_ERRINTRS; - dd->ipath_gpio_mask |= IPATH_GPIO_ERRINTR_MASK; - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, - dd->ipath_gpio_mask); + val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); + val |= IPATH_GPIO_ERRINTR_MASK; + ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); } return 0; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c index a90d3b5699c4..45d033169c6e 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c @@ -1056,7 +1056,7 @@ irqreturn_t ipath_intr(int irq, void *data) gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT); chk0rcv = 1; } - if (gpiostatus) { + if (unlikely(gpiostatus)) { /* * Some unexpected bits remain. If they could have * caused the interrupt, complain and clear. @@ -1065,8 +1065,9 @@ irqreturn_t ipath_intr(int irq, void *data) * GPIO interrupts, possibly on a "three strikes" * basis. */ - const u32 mask = (u32) dd->ipath_gpio_mask; - + u32 mask; + mask = ipath_read_kreg32( + dd, dd->ipath_kregs->kr_gpio_mask); if (mask & gpiostatus) { ipath_dbg("Unexpected GPIO IRQ bits %x\n", gpiostatus & mask); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h index 12194f3dd8cc..e900c2593f44 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -397,8 +397,6 @@ struct ipath_devdata { unsigned long ipath_pioavailshadow[8]; /* shadow of kr_gpio_out, for rmw ops */ u64 ipath_gpio_out; - /* shadow the gpio mask register */ - u64 ipath_gpio_mask; /* kr_revision shadow */ u64 ipath_revision; /* diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index bb70845279b8..12933e77c7e9 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -1387,12 +1387,13 @@ static int enable_timer(struct ipath_devdata *dd) * processing. */ if (dd->ipath_flags & IPATH_GPIO_INTR) { + u64 val; ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect, 0x2074076542310ULL); /* Enable GPIO bit 2 interrupt */ - dd->ipath_gpio_mask |= (u64) (1 << IPATH_GPIO_PORT0_BIT); - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, - dd->ipath_gpio_mask); + val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); + val |= (u64) (1 << IPATH_GPIO_PORT0_BIT); + ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); } init_timer(&dd->verbs_timer); @@ -1411,9 +1412,8 @@ static int disable_timer(struct ipath_devdata *dd) u64 val; /* Disable GPIO bit 2 interrupt */ val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); - dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, - dd->ipath_gpio_mask); + val &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); + ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); /* * We might want to undo changes to debugportselect, * but how? diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index 402f3a20ec0a..688ecb4c39f3 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -489,7 +489,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) ibdev->uar_map = ioremap(ibdev->priv_uar.pfn << PAGE_SHIFT, PAGE_SIZE); if (!ibdev->uar_map) goto err_uar; - MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock); INIT_LIST_HEAD(&ibdev->pgdir_list); mutex_init(&ibdev->pgdir_mutex); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index ca224d018af2..cf0868f6e965 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -284,7 +284,7 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, { struct mthca_cqe *cqe; u32 prod_index; - int i, nfreed = 0; + int nfreed = 0; spin_lock_irq(&cq->lock); @@ -321,8 +321,6 @@ void mthca_cq_clean(struct mthca_dev *dev, struct mthca_cq *cq, u32 qpn, } if (nfreed) { - for (i = 0; i < nfreed; ++i) - set_cqe_hw(get_cqe(cq, (cq->cons_index + i) & cq->ibcq.cqe)); wmb(); cq->cons_index += nfreed; update_cons_index(dev, cq, nfreed); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 72fabb822f1c..fee60c852d14 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1862,7 +1862,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, dev->kar + MTHCA_RECEIVE_DOORBELL, MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); - qp->rq.next_ind = ind; qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB; size0 = 0; } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c index eec833b81e9b..785bc8505f2a 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -257,11 +257,10 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even cm_id->context = p; p->jiffies = jiffies; spin_lock_irq(&priv->lock); - if (list_empty(&priv->cm.passive_ids)) - queue_delayed_work(ipoib_workqueue, - &priv->cm.stale_task, IPOIB_CM_RX_DELAY); list_add(&p->list, &priv->cm.passive_ids); spin_unlock_irq(&priv->lock); + queue_delayed_work(ipoib_workqueue, + &priv->cm.stale_task, IPOIB_CM_RX_DELAY); return 0; err_rep: @@ -379,6 +378,8 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) if (!list_empty(&p->list)) list_move(&p->list, &priv->cm.passive_ids); spin_unlock_irqrestore(&priv->lock, flags); + queue_delayed_work(ipoib_workqueue, + &priv->cm.stale_task, IPOIB_CM_RX_DELAY); } } @@ -1099,10 +1100,6 @@ static void ipoib_cm_stale_task(struct work_struct *work) kfree(p); spin_lock_irq(&priv->lock); } - - if (!list_empty(&priv->cm.passive_ids)) - queue_delayed_work(ipoib_workqueue, - &priv->cm.stale_task, IPOIB_CM_RX_DELAY); spin_unlock_irq(&priv->lock); } diff --git a/trunk/drivers/input/joystick/Kconfig b/trunk/drivers/input/joystick/Kconfig index b0023452ec90..82f563e24fdb 100644 --- a/trunk/drivers/input/joystick/Kconfig +++ b/trunk/drivers/input/joystick/Kconfig @@ -255,7 +255,6 @@ config JOYSTICK_JOYDUMP config JOYSTICK_XPAD tristate "X-Box gamepad support" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the X-Box pad with your computer. diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 842a7b4d16f8..6013ace94d98 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -84,7 +84,6 @@ config INPUT_ATLAS_BTNS config INPUT_ATI_REMOTE tristate "ATI / X10 USB RF remote control" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an ATI or X10 "Lola" USB remote control. @@ -100,7 +99,6 @@ config INPUT_ATI_REMOTE config INPUT_ATI_REMOTE2 tristate "ATI / Philips USB RF remote control" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an ATI or Philips USB RF remote control. @@ -116,7 +114,6 @@ config INPUT_ATI_REMOTE2 config INPUT_KEYSPAN_REMOTE tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use a Keyspan DMR USB remote control. @@ -131,7 +128,6 @@ config INPUT_KEYSPAN_REMOTE config INPUT_POWERMATE tristate "Griffin PowerMate and Contour Jog support" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use Griffin PowerMate or Contour Jog devices. @@ -148,7 +144,6 @@ config INPUT_POWERMATE config INPUT_YEALINK tristate "Yealink usb-p1k voip phone" depends EXPERIMENTAL - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to enable keyboard and LCD functions of the diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index eb0167e9f0cb..2ccc114b3ff6 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -111,7 +111,6 @@ config MOUSE_SERIAL config MOUSE_APPLETOUCH tristate "Apple USB Touchpad support" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an Apple USB Touchpad. diff --git a/trunk/drivers/input/tablet/Kconfig b/trunk/drivers/input/tablet/Kconfig index d371c0bdc0bd..12dfb0eb3262 100644 --- a/trunk/drivers/input/tablet/Kconfig +++ b/trunk/drivers/input/tablet/Kconfig @@ -13,7 +13,6 @@ if INPUT_TABLET config TABLET_USB_ACECAD tristate "Acecad Flair tablet support (USB)" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Acecad Flair @@ -26,7 +25,6 @@ config TABLET_USB_ACECAD config TABLET_USB_AIPTEK tristate "Aiptek 6000U/8000U tablet support (USB)" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Aiptek 6000U @@ -51,7 +49,6 @@ config TABLET_USB_GTCO config TABLET_USB_KBTAB tristate "KB Gear JamStudio tablet support (USB)" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the KB Gear @@ -64,7 +61,6 @@ config TABLET_USB_KBTAB config TABLET_USB_WACOM tristate "Wacom Intuos/Graphire tablet support (USB)" - depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Wacom Intuos diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 4f091800bfeb..5e640aeb03cd 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -166,7 +166,6 @@ config TOUCHSCREEN_UCB1400 config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" - depends on USB_ARCH_HAS_HCD select USB help USB Touchscreen driver for: diff --git a/trunk/drivers/media/video/em28xx/Kconfig b/trunk/drivers/media/video/em28xx/Kconfig index 2c450bd05af5..3823b62da4a4 100644 --- a/trunk/drivers/media/video/em28xx/Kconfig +++ b/trunk/drivers/media/video/em28xx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && I2C && PCI + depends on VIDEO_V4L1 && I2C select VIDEO_BUF select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/trunk/drivers/media/video/ivtv/Kconfig b/trunk/drivers/media/video/ivtv/Kconfig index 0cc98a0e2496..e854f3f1b70f 100644 --- a/trunk/drivers/media/video/ivtv/Kconfig +++ b/trunk/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" - depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI + depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index a7562f7fc0b3..d24ab234394c 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -45,6 +45,8 @@ */ #define MMC_SHIFT 3 +static int major; + /* * There is one mmc_blk_data per slot. */ @@ -464,7 +466,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->queue.issue_fn = mmc_blk_issue_rq; md->queue.data = md; - md->disk->major = MMC_BLOCK_MAJOR; + md->disk->major = major; md->disk->first_minor = devidx << MMC_SHIFT; md->disk->fops = &mmc_bdops; md->disk->private_data = md; @@ -632,9 +634,14 @@ static int __init mmc_blk_init(void) { int res = -ENOMEM; - res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); - if (res) + res = register_blkdev(major, "mmc"); + if (res < 0) { + printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n", + major, res); goto out; + } + if (major == 0) + major = res; return mmc_register_driver(&mmc_driver); @@ -645,7 +652,7 @@ static int __init mmc_blk_init(void) static void __exit mmc_blk_exit(void) { mmc_unregister_driver(&mmc_driver); - unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); + unregister_blkdev(major, "mmc"); } module_init(mmc_blk_init); @@ -654,3 +661,5 @@ module_exit(mmc_blk_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); +module_param(major, int, 0444); +MODULE_PARM_DESC(major, "specify the major device number for MMC block driver"); diff --git a/trunk/drivers/mmc/host/au1xmmc.c b/trunk/drivers/mmc/host/au1xmmc.c index f967226d7505..b7156a4555b5 100644 --- a/trunk/drivers/mmc/host/au1xmmc.c +++ b/trunk/drivers/mmc/host/au1xmmc.c @@ -187,8 +187,9 @@ static void au1xmmc_tasklet_finish(unsigned long param) } static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, - struct mmc_command *cmd, unsigned int flags) + struct mmc_command *cmd) { + u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); switch (mmc_resp_type(cmd)) { @@ -212,16 +213,24 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, return MMC_ERR_INVALID; } - if (flags & MMC_DATA_READ) { - if (flags & MMC_DATA_MULTI) - mmccmd |= SD_CMD_CT_4; - else - mmccmd |= SD_CMD_CT_2; - } else if (flags & MMC_DATA_WRITE) { - if (flags & MMC_DATA_MULTI) - mmccmd |= SD_CMD_CT_3; - else - mmccmd |= SD_CMD_CT_1; + switch(cmd->opcode) { + case MMC_READ_SINGLE_BLOCK: + case SD_APP_SEND_SCR: + mmccmd |= SD_CMD_CT_2; + break; + case MMC_READ_MULTIPLE_BLOCK: + mmccmd |= SD_CMD_CT_4; + break; + case MMC_WRITE_BLOCK: + mmccmd |= SD_CMD_CT_1; + break; + + case MMC_WRITE_MULTIPLE_BLOCK: + mmccmd |= SD_CMD_CT_3; + break; + case MMC_STOP_TRANSMISSION: + mmccmd |= SD_CMD_CT_7; + break; } au_writel(cmd->arg, HOST_CMDARG(host)); @@ -656,7 +665,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) { struct au1xmmc_host *host = mmc_priv(mmc); - unsigned int flags = 0; int ret = MMC_ERR_NONE; WARN_ON(irqs_disabled()); @@ -669,12 +677,11 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) if (mrq->data) { FLUSH_FIFO(host); - flags = mrq->data->flags; ret = au1xmmc_prepare_data(host, mrq->data); } if (ret == MMC_ERR_NONE) - ret = au1xmmc_send_command(host, 0, mrq->cmd, flags); + ret = au1xmmc_send_command(host, 0, mrq->cmd); if (ret != MMC_ERR_NONE) { mrq->cmd->error = ret; diff --git a/trunk/drivers/mmc/host/pxamci.c b/trunk/drivers/mmc/host/pxamci.c index f8985c508bb9..d97d3864b57f 100644 --- a/trunk/drivers/mmc/host/pxamci.c +++ b/trunk/drivers/mmc/host/pxamci.c @@ -232,14 +232,20 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) /* * workaround for erratum #42: * Intel PXA27x Family Processor Specification Update Rev 001 - * A bogus CRC error can appear if the msb of a 136 bit - * response is a one. */ - if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) { - pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode); - } else -#endif + if (cmd->opcode == MMC_ALL_SEND_CID || + cmd->opcode == MMC_SEND_CSD || + cmd->opcode == MMC_SEND_CID) { + /* a bogus CRC error can appear if the msb of + the 15 byte response is a one */ + if ((cmd->resp[0] & 0x80000000) == 0) + cmd->error = MMC_ERR_BADCRC; + } else { + pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); + } +#else cmd->error = MMC_ERR_BADCRC; +#endif } pxamci_disable_irq(host, END_CMD_RES); diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index a359efdd77eb..ff5bf73cdd25 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -963,15 +963,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) sdhci_transfer_pio(host); - /* - * We currently don't do anything fancy with DMA - * boundaries, but as we can't disable the feature - * we need to at least restart the transfer. - */ - if (intmask & SDHCI_INT_DMA_END) - writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), - host->ioaddr + SDHCI_DMA_ADDRESS); - if (intmask & SDHCI_INT_DATA_END) sdhci_finish_data(host); } diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index c5baa197bc08..fb99cd445504 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2508,7 +2508,6 @@ config MLX4_CORE config MLX4_DEBUG bool "Verbose debugging output" if (MLX4_CORE && EMBEDDED) - depends on MLX4_CORE default y ---help--- This option causes debugging code to be compiled into the diff --git a/trunk/drivers/net/mlx4/alloc.c b/trunk/drivers/net/mlx4/alloc.c index dfbd5809d744..9ffdb9d29da9 100644 --- a/trunk/drivers/net/mlx4/alloc.c +++ b/trunk/drivers/net/mlx4/alloc.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "mlx4.h" diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index 0f11adb8eb4a..af016d0ea1c6 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -33,7 +33,6 @@ #include #include -#include #include diff --git a/trunk/drivers/net/mlx4/icm.c b/trunk/drivers/net/mlx4/icm.c index b7a4aa8476fb..e96feaed6ed4 100644 --- a/trunk/drivers/net/mlx4/icm.c +++ b/trunk/drivers/net/mlx4/icm.c @@ -33,7 +33,6 @@ #include #include -#include #include diff --git a/trunk/drivers/net/mlx4/main.c b/trunk/drivers/net/mlx4/main.c index 20b8c0d3ced4..4debb024eaf9 100644 --- a/trunk/drivers/net/mlx4/main.c +++ b/trunk/drivers/net/mlx4/main.c @@ -542,6 +542,8 @@ static int __devinit mlx4_setup_hca(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); int err; + MLX4_INIT_DOORBELL_LOCK(&priv->doorbell_lock); + err = mlx4_init_uar_table(dev); if (err) { mlx4_err(dev, "Failed to initialize " diff --git a/trunk/drivers/net/mlx4/mlx4.h b/trunk/drivers/net/mlx4/mlx4.h index 3d3b6d24d8d3..9befbae3d196 100644 --- a/trunk/drivers/net/mlx4/mlx4.h +++ b/trunk/drivers/net/mlx4/mlx4.h @@ -275,6 +275,7 @@ struct mlx4_priv { struct mlx4_uar driver_uar; void __iomem *kar; + MLX4_DECLARE_DOORBELL_LOCK(doorbell_lock) u32 rev_id; char board_id[MLX4_BOARD_ID_LEN]; diff --git a/trunk/drivers/net/mlx4/reset.c b/trunk/drivers/net/mlx4/reset.c index e4dfd4b11a4a..51eef8492e93 100644 --- a/trunk/drivers/net/mlx4/reset.c +++ b/trunk/drivers/net/mlx4/reset.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "mlx4.h" diff --git a/trunk/drivers/net/pasemi_mac.c b/trunk/drivers/net/pasemi_mac.c index 8d38425e46c3..bc7f3dee6e5b 100644 --- a/trunk/drivers/net/pasemi_mac.c +++ b/trunk/drivers/net/pasemi_mac.c @@ -85,7 +85,6 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) { struct pci_dev *pdev = mac->pdev; struct device_node *dn = pci_device_to_OF_node(pdev); - int len; const u8 *maddr; u8 addr[6]; @@ -95,17 +94,9 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - maddr = of_get_property(dn, "local-mac-address", &len); - - if (maddr && len == 6) { - memcpy(mac->mac_addr, maddr, 6); - return 0; - } - - /* Some old versions of firmware mistakenly uses mac-address - * (and as a string) instead of a byte array in local-mac-address. - */ + maddr = of_get_property(dn, "local-mac-address", NULL); + /* Fall back to mac-address for older firmware */ if (maddr == NULL) maddr = of_get_property(dn, "mac-address", NULL); @@ -115,7 +106,6 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { dev_warn(&pdev->dev, @@ -123,8 +113,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -EINVAL; } - memcpy(mac->mac_addr, addr, 6); - + memcpy(mac->mac_addr, addr, sizeof(addr)); return 0; } @@ -395,14 +384,17 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) { - unsigned int reg, pcnt; + unsigned int reg, stat; /* Re-enable packet count interrupts: finally * ack the packet count interrupt we got in rx_intr. */ - pcnt = *mac->rx_status & PAS_STATUS_PCNT_M; + pci_read_config_dword(mac->iob_pdev, + PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch), + &stat); - reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; + reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) + | PAS_IOB_DMA_RXCH_RESET_PINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), @@ -411,12 +403,14 @@ static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) { - unsigned int reg, pcnt; + unsigned int reg, stat; /* Re-enable packet count interrupts */ - pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; + pci_read_config_dword(mac->iob_pdev, + PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat); - reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; + reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) + | PAS_IOB_DMA_TXCH_RESET_PINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); @@ -597,24 +591,21 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) { struct net_device *dev = data; struct pasemi_mac *mac = netdev_priv(dev); - unsigned int reg, pcnt; + unsigned int reg; if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) return IRQ_NONE; pasemi_mac_clean_tx(mac); - pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; - - reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; + reg = PAS_IOB_DMA_TXCH_RESET_PINTC; if (*mac->tx_status & PAS_STATUS_SOFT) reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; if (*mac->tx_status & PAS_STATUS_ERROR) reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); return IRQ_HANDLED; @@ -983,7 +974,6 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) { spin_unlock_irqrestore(&txring->lock, flags); pasemi_mac_clean_tx(mac); - pasemi_mac_restart_tx_intr(mac); spin_lock_irqsave(&txring->lock, flags); if (txring->next_to_clean - txring->next_to_use == @@ -1220,7 +1210,6 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev) static struct pci_device_id pasemi_mac_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) }, { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) }, - { }, }; MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl); diff --git a/trunk/drivers/net/pasemi_mac.h b/trunk/drivers/net/pasemi_mac.h index c29ee159c33d..8bc0cea8b145 100644 --- a/trunk/drivers/net/pasemi_mac.h +++ b/trunk/drivers/net/pasemi_mac.h @@ -341,7 +341,7 @@ enum { PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) #define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4) #define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16 +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 0 #define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \ PAS_IOB_DMA_RXCH_RESET_PCNT_M) #define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020 @@ -352,7 +352,7 @@ enum { #define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001 #define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4) #define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16 +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 0 #define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \ PAS_IOB_DMA_TXCH_RESET_PCNT_M) #define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020 diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index db43e42bee35..81f24847c963 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -77,6 +77,7 @@ static const char version[] = #include #include +#include #include "smc911x.h" @@ -2083,11 +2084,12 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) lp->ctl_rspeed = 100; /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc911x_interrupt, - IRQF_SHARED | IRQF_TRIGGER_FALLING, dev->name, dev); + retval = request_irq(dev->irq, &smc911x_interrupt, IRQF_SHARED, dev->name, dev); if (retval) goto err_out; + set_irq_type(dev->irq, IRQT_FALLING); + #ifdef SMC_USE_DMA lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq); lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq); diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index c2ccbd098f53..0f667652fda9 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. * * Author: Shlomi Gridish * Li Yang @@ -3737,21 +3737,21 @@ static int ucc_geth_close(struct net_device *dev) const struct ethtool_ops ucc_geth_ethtool_ops = { }; -static phy_interface_t to_phy_interface(const char *phy_connection_type) +static phy_interface_t to_phy_interface(const char *interface_type) { - if (strcasecmp(phy_connection_type, "mii") == 0) + if (strcasecmp(interface_type, "mii") == 0) return PHY_INTERFACE_MODE_MII; - if (strcasecmp(phy_connection_type, "gmii") == 0) + if (strcasecmp(interface_type, "gmii") == 0) return PHY_INTERFACE_MODE_GMII; - if (strcasecmp(phy_connection_type, "tbi") == 0) + if (strcasecmp(interface_type, "tbi") == 0) return PHY_INTERFACE_MODE_TBI; - if (strcasecmp(phy_connection_type, "rmii") == 0) + if (strcasecmp(interface_type, "rmii") == 0) return PHY_INTERFACE_MODE_RMII; - if (strcasecmp(phy_connection_type, "rgmii") == 0) + if (strcasecmp(interface_type, "rgmii") == 0) return PHY_INTERFACE_MODE_RGMII; - if (strcasecmp(phy_connection_type, "rgmii-id") == 0) + if (strcasecmp(interface_type, "rgmii-id") == 0) return PHY_INTERFACE_MODE_RGMII_ID; - if (strcasecmp(phy_connection_type, "rtbi") == 0) + if (strcasecmp(interface_type, "rtbi") == 0) return PHY_INTERFACE_MODE_RTBI; return PHY_INTERFACE_MODE_MII; @@ -3819,21 +3819,29 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->phy_address = *prop; /* get the phy interface type, or default to MII */ - prop = of_get_property(np, "phy-connection-type", NULL); + prop = of_get_property(np, "interface-type", NULL); if (!prop) { /* handle interface property present in old trees */ prop = of_get_property(phy, "interface", NULL); - if (prop != NULL) { + if (prop != NULL) phy_interface = enet_to_phy_interface[*prop]; - max_speed = enet_to_speed[*prop]; - } else + else phy_interface = PHY_INTERFACE_MODE_MII; } else { phy_interface = to_phy_interface((const char *)prop); } - /* get speed, or derive from PHY interface */ - if (max_speed == 0) + /* get speed, or derive from interface */ + prop = of_get_property(np, "max-speed", NULL); + if (!prop) { + /* handle interface property present in old trees */ + prop = of_get_property(phy, "interface", NULL); + if (prop != NULL) + max_speed = enet_to_speed[*prop]; + } else { + max_speed = *prop; + } + if (!max_speed) { switch (phy_interface) { case PHY_INTERFACE_MODE_GMII: case PHY_INTERFACE_MODE_RGMII: @@ -3846,9 +3854,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma max_speed = SPEED_100; break; } + } if (max_speed == SPEED_1000) { - /* configure muram FIFOs for gigabit operation */ ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT; ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT; ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT; diff --git a/trunk/drivers/net/ucc_geth_mii.c b/trunk/drivers/net/ucc_geth_mii.c index f96966d4bcc2..27a1ef3b7b06 100644 --- a/trunk/drivers/net/ucc_geth_mii.c +++ b/trunk/drivers/net/ucc_geth_mii.c @@ -1,13 +1,12 @@ /* * drivers/net/ucc_geth_mii.c * - * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation - * Provides Bus interface for MII Management regs in the UCC register space + * Gianfar Ethernet Driver -- MIIM bus implementation + * Provides Bus interface for MIIM regs * - * Copyright (C) 2007 Freescale Semiconductor, Inc. + * Author: Li Yang * - * Authors: Li Yang - * Kim Phillips + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * 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 diff --git a/trunk/drivers/net/ucc_geth_mii.h b/trunk/drivers/net/ucc_geth_mii.h index d83437039919..98430fe0bfc6 100644 --- a/trunk/drivers/net/ucc_geth_mii.h +++ b/trunk/drivers/net/ucc_geth_mii.h @@ -1,13 +1,13 @@ /* * drivers/net/ucc_geth_mii.h * - * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation - * Provides Bus interface for MII Management regs in the UCC register space + * Gianfar Ethernet Driver -- MII Management Bus Implementation + * Driver for the MDIO bus controller in the Gianfar register space * - * Copyright (C) 2007 Freescale Semiconductor, Inc. + * Author: Andy Fleming + * Maintainer: Kumar Gala * - * Authors: Li Yang - * Kim Phillips + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * 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 diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 7bfbad57879d..02c0d52c9f76 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c b/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c index df076064a3e0..6c5be3ff578c 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/trunk/drivers/pci/hotplug/rpadlpar_sysfs.c @@ -129,9 +129,8 @@ struct kobj_type ktype_dlpar_io = { }; struct kset dlpar_io_kset = { - .kobj = {.name = DLPAR_KOBJ_NAME, - .ktype = &ktype_dlpar_io, - .parent = &pci_hotplug_slots_subsys.kobj}, + .subsys = &pci_hotplug_slots_subsys, + .kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,}, .ktype = &ktype_dlpar_io, }; diff --git a/trunk/drivers/sbus/char/bbc_i2c.c b/trunk/drivers/sbus/char/bbc_i2c.c index 178155bf9db6..8410587348f1 100644 --- a/trunk/drivers/sbus/char/bbc_i2c.c +++ b/trunk/drivers/sbus/char/bbc_i2c.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "bbc_i2c.h" diff --git a/trunk/drivers/sbus/char/display7seg.c b/trunk/drivers/sbus/char/display7seg.c index 3279a1b6501d..2d14a29effe4 100644 --- a/trunk/drivers/sbus/char/display7seg.c +++ b/trunk/drivers/sbus/char/display7seg.c @@ -20,7 +20,6 @@ #include /* EBus device */ #include /* OpenProm Library */ #include /* put_/get_user */ -#include #include diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index d28c14e23c32..e62d23f65180 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -1757,14 +1757,6 @@ config SCSI_ESP_CORE tristate "ESP Scsi Driver Core" depends on SCSI select SCSI_SPI_ATTRS - help - This is a core driver for NCR53c9x based scsi chipsets, - also known as "ESP" for Emulex Scsi Processor or - Enhanced Scsi Processor. This driver does not exist by - itself, there are front-end drivers which, when enabled, - select and enable this driver. One example is SCSI_SUNESP. - These front-end drivers provide probing, DMA, and register - access support for the core driver. config SCSI_SUNESP tristate "Sparc ESP Scsi Driver" diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 96557e6dba60..40d48566215c 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -1,6 +1,6 @@ /* sunhv.c: Serial driver for SUN4V hypervisor console. * - * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 2006 David S. Miller (davem@davemloft.net) */ #include @@ -35,51 +35,57 @@ #define CON_BREAK ((long)-1) #define CON_HUP ((long)-2) -#define IGNORE_BREAK 0x1 -#define IGNORE_ALL 0x2 +static inline long hypervisor_con_getchar(long *status) +{ + register unsigned long func asm("%o5"); + register unsigned long arg0 asm("%o0"); + register unsigned long arg1 asm("%o1"); -static char *con_write_page; -static char *con_read_page; + func = HV_FAST_CONS_GETCHAR; + arg0 = 0; + arg1 = 0; + __asm__ __volatile__("ta %6" + : "=&r" (func), "=&r" (arg0), "=&r" (arg1) + : "0" (func), "1" (arg0), "2" (arg1), + "i" (HV_FAST_TRAP)); -static int hung_up = 0; + *status = arg0; -static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit) + return (long) arg1; +} + +static inline long hypervisor_con_putchar(long ch) { - while (!uart_circ_empty(xmit)) { - long status = sun4v_con_putchar(xmit->buf[xmit->tail]); + register unsigned long func asm("%o5"); + register unsigned long arg0 asm("%o0"); - if (status != HV_EOK) - break; + func = HV_FAST_CONS_PUTCHAR; + arg0 = ch; + __asm__ __volatile__("ta %4" + : "=&r" (func), "=&r" (arg0) + : "0" (func), "1" (arg0), "i" (HV_FAST_TRAP)); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } + return (long) arg0; } -static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) -{ - while (!uart_circ_empty(xmit)) { - unsigned long ra = __pa(xmit->buf + xmit->tail); - unsigned long len, status, sent; +#define IGNORE_BREAK 0x1 +#define IGNORE_ALL 0x2 - len = CIRC_CNT_TO_END(xmit->head, xmit->tail, - UART_XMIT_SIZE); - status = sun4v_con_write(ra, len, &sent); - if (status != HV_EOK) - break; - xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1); - port->icount.tx += sent; - } -} +static int hung_up = 0; -static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) +static struct tty_struct *receive_chars(struct uart_port *port) { + struct tty_struct *tty = NULL; int saw_console_brk = 0; int limit = 10000; + if (port->info != NULL) /* Unopened serial console */ + tty = port->info->tty; + while (limit-- > 0) { long status; - long c = sun4v_con_getchar(&status); + long c = hypervisor_con_getchar(&status); + unsigned char flag; if (status == HV_EWOULDBLOCK) break; @@ -104,90 +110,27 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) continue; } + flag = TTY_NORMAL; port->icount.rx++; - - if (uart_handle_sysrq_char(port, c)) - continue; - - tty_insert_flip_char(tty, c, TTY_NORMAL); - } - - return saw_console_brk; -} - -static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) -{ - int saw_console_brk = 0; - int limit = 10000; - - while (limit-- > 0) { - unsigned long ra = __pa(con_read_page); - unsigned long bytes_read, i; - long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read); - - if (stat != HV_EOK) { - bytes_read = 0; - - if (stat == CON_BREAK) { - if (uart_handle_break(port)) - continue; - saw_console_brk = 1; - *con_read_page = 0; - bytes_read = 1; - } else if (stat == CON_HUP) { - hung_up = 1; - uart_handle_dcd_change(port, 0); + if (c == CON_BREAK) { + port->icount.brk++; + if (uart_handle_break(port)) continue; - } else { - /* HV_EWOULDBLOCK, etc. */ - break; - } + flag = TTY_BREAK; } - if (hung_up) { - hung_up = 0; - uart_handle_dcd_change(port, 1); - } - - for (i = 0; i < bytes_read; i++) - uart_handle_sysrq_char(port, con_read_page[i]); - - if (tty == NULL) + if (uart_handle_sysrq_char(port, c)) continue; - port->icount.rx += bytes_read; + if ((port->ignore_status_mask & IGNORE_ALL) || + ((port->ignore_status_mask & IGNORE_BREAK) && + (c == CON_BREAK))) + continue; - tty_insert_flip_string(tty, con_read_page, bytes_read); + tty_insert_flip_char(tty, c, flag); } - return saw_console_brk; -} - -struct sunhv_ops { - void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); - int (*receive_chars)(struct uart_port *port, struct tty_struct *tty); -}; - -static struct sunhv_ops bychar_ops = { - .transmit_chars = transmit_chars_putchar, - .receive_chars = receive_chars_getchar, -}; - -static struct sunhv_ops bywrite_ops = { - .transmit_chars = transmit_chars_write, - .receive_chars = receive_chars_read, -}; - -static struct sunhv_ops *sunhv_ops = &bychar_ops; - -static struct tty_struct *receive_chars(struct uart_port *port) -{ - struct tty_struct *tty = NULL; - - if (port->info != NULL) /* Unopened serial console */ - tty = port->info->tty; - - if (sunhv_ops->receive_chars(port, tty)) + if (saw_console_brk) sun_do_break(); return tty; @@ -204,7 +147,15 @@ static void transmit_chars(struct uart_port *port) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; - sunhv_ops->transmit_chars(port, xmit); + while (!uart_circ_empty(xmit)) { + long status = hypervisor_con_putchar(xmit->buf[xmit->tail]); + + if (status != HV_EOK) + break; + + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); @@ -261,7 +212,7 @@ static void sunhv_start_tx(struct uart_port *port) struct circ_buf *xmit = &port->info->xmit; while (!uart_circ_empty(xmit)) { - long status = sun4v_con_putchar(xmit->buf[xmit->tail]); + long status = hypervisor_con_putchar(xmit->buf[xmit->tail]); if (status != HV_EOK) break; @@ -280,10 +231,9 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) spin_lock_irqsave(&port->lock, flags); while (limit-- > 0) { - long status = sun4v_con_putchar(ch); + long status = hypervisor_con_putchar(ch); if (status == HV_EOK) break; - udelay(1); } spin_unlock_irqrestore(&port->lock, flags); @@ -304,15 +254,15 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state) { if (break_state) { unsigned long flags; - int limit = 10000; + int limit = 1000000; spin_lock_irqsave(&port->lock, flags); while (limit-- > 0) { - long status = sun4v_con_putchar(CON_BREAK); + long status = hypervisor_con_putchar(CON_BREAK); if (status == HV_EOK) break; - udelay(1); + udelay(2); } spin_unlock_irqrestore(&port->lock, flags); @@ -409,99 +359,38 @@ static struct uart_driver sunhv_reg = { static struct uart_port *sunhv_port; -/* Copy 's' into the con_write_page, decoding "\n" into - * "\r\n" along the way. We have to return two lengths - * because the caller needs to know how much to advance - * 's' and also how many bytes to output via con_write_page. - */ -static int fill_con_write_page(const char *s, unsigned int n, - unsigned long *page_bytes) -{ - const char *orig_s = s; - char *p = con_write_page; - int left = PAGE_SIZE; - - while (n--) { - if (*s == '\n') { - if (left < 2) - break; - *p++ = '\r'; - left--; - } else if (left < 1) - break; - *p++ = *s++; - left--; - } - *page_bytes = p - con_write_page; - return s - orig_s; -} - -static void sunhv_console_write_paged(struct console *con, const char *s, unsigned n) +static inline void sunhv_console_putchar(struct uart_port *port, char c) { - struct uart_port *port = sunhv_port; unsigned long flags; + int limit = 1000000; spin_lock_irqsave(&port->lock, flags); - while (n > 0) { - unsigned long ra = __pa(con_write_page); - unsigned long page_bytes; - unsigned int cpy = fill_con_write_page(s, n, - &page_bytes); - - n -= cpy; - s += cpy; - while (page_bytes > 0) { - unsigned long written; - int limit = 1000000; - - while (limit--) { - unsigned long stat; - - stat = sun4v_con_write(ra, page_bytes, - &written); - if (stat == HV_EOK) - break; - udelay(1); - } - if (limit <= 0) - break; - page_bytes -= written; - ra += written; - } - } - spin_unlock_irqrestore(&port->lock, flags); -} - -static inline void sunhv_console_putchar(struct uart_port *port, char c) -{ - int limit = 1000000; while (limit-- > 0) { - long status = sun4v_con_putchar(c); + long status = hypervisor_con_putchar(c); if (status == HV_EOK) break; - udelay(1); + udelay(2); } + + spin_unlock_irqrestore(&port->lock, flags); } -static void sunhv_console_write_bychar(struct console *con, const char *s, unsigned n) +static void sunhv_console_write(struct console *con, const char *s, unsigned n) { struct uart_port *port = sunhv_port; - unsigned long flags; int i; - spin_lock_irqsave(&port->lock, flags); for (i = 0; i < n; i++) { if (*s == '\n') sunhv_console_putchar(port, '\r'); sunhv_console_putchar(port, *s++); } - spin_unlock_irqrestore(&port->lock, flags); } static struct console sunhv_console = { .name = "ttyHV", - .write = sunhv_console_write_bychar, + .write = sunhv_console_write, .device = uart_console_device, .flags = CON_PRINTBUFFER, .index = -1, @@ -521,7 +410,6 @@ static inline struct console *SUNHV_CONSOLE(void) static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match) { struct uart_port *port; - unsigned long minor; int err; if (op->irqs[0] == 0xffffffff) @@ -531,22 +419,6 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m if (unlikely(!port)) return -ENOMEM; - minor = 1; - if (sun4v_hvapi_register(HV_GRP_CORE, 1, &minor) == 0 && - minor >= 1) { - err = -ENOMEM; - con_write_page = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!con_write_page) - goto out_free_port; - - con_read_page = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!con_read_page) - goto out_free_con_write_page; - - sunhv_console.write = sunhv_console_write_paged; - sunhv_ops = &bywrite_ops; - } - sunhv_port = port; port->line = 0; @@ -565,7 +437,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m err = uart_register_driver(&sunhv_reg); if (err) - goto out_free_con_read_page; + goto out_free_port; sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64; sunserial_current_minor += 1; @@ -591,12 +463,6 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m sunserial_current_minor -= 1; uart_unregister_driver(&sunhv_reg); -out_free_con_read_page: - kfree(con_read_page); - -out_free_con_write_page: - kfree(con_write_page); - out_free_port: kfree(port); sunhv_port = NULL; @@ -627,10 +493,6 @@ static struct of_device_id hv_match[] = { .name = "console", .compatible = "qcn", }, - { - .name = "console", - .compatible = "SUNW,sun4v-console", - }, {}, }; MODULE_DEVICE_TABLE(of, hv_match); diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index 225d6b2f82dd..c0a6dce800a3 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -484,7 +484,7 @@ static int spidev_probe(struct spi_device *spi) * Reusing minors is fine so long as udev or mdev is working. */ mutex_lock(&device_list_lock); - minor = find_first_zero_bit(minors, N_SPI_MINORS); + minor = find_first_zero_bit(minors, ARRAY_SIZE(minors)); if (minor < N_SPI_MINORS) { spidev->dev.parent = &spi->dev; spidev->dev.class = &spidev_class; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 4d7485fa553f..eebcb708cff1 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1535,7 +1535,7 @@ config FB_LEO config FB_XVR500 bool "Sun XVR-500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 + depends on FB && PCI && SPARC64 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1548,7 +1548,7 @@ config FB_XVR500 config FB_XVR2500 bool "Sun XVR-2500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 + depends on FB && PCI && SPARC64 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index 370cecc910db..579af632c8e8 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -47,6 +47,7 @@ struct file_system_type afs_fs_type = { static const struct super_operations afs_super_ops = { .statfs = afs_statfs, .alloc_inode = afs_alloc_inode, + .drop_inode = generic_delete_inode, .write_inode = afs_write_inode, .destroy_inode = afs_destroy_inode, .clear_inode = afs_clear_inode, diff --git a/trunk/fs/afs/write.c b/trunk/fs/afs/write.c index a03b92a0fe1d..28f37516c126 100644 --- a/trunk/fs/afs/write.c +++ b/trunk/fs/afs/write.c @@ -206,6 +206,7 @@ int afs_prepare_write(struct file *file, struct page *page, _leave(" = %d [prep]", ret); return ret; } + SetPageUptodate(page); } try_again: @@ -310,8 +311,8 @@ int afs_commit_write(struct file *file, struct page *page, spin_unlock(&vnode->writeback_lock); } - SetPageUptodate(page); set_page_dirty(page); + if (PageDirty(page)) _debug("dirtied"); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 0b73cd45a06d..1aad34ea61a4 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1,6 +1,6 @@ /* - * fs/eventpoll.c (Efficent event polling implementation) - * Copyright (C) 2001,...,2007 Davide Libenzi + * fs/eventpoll.c ( Efficent event polling implementation ) + * Copyright (C) 2001,...,2006 Davide Libenzi * * 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 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,14 +39,15 @@ #include #include #include +#include /* * LOCKING: * There are three level of locking required by epoll : * * 1) epmutex (mutex) - * 2) ep->mtx (mutex) - * 3) ep->lock (spinlock) + * 2) ep->sem (rw_semaphore) + * 3) ep->lock (rw_lock) * * The acquire order is the one listed above, from 1 to 3. * We need a spinlock (ep->lock) because we manipulate objects @@ -55,20 +57,20 @@ * a spinlock. During the event transfer loop (from kernel to * user space) we could end up sleeping due a copy_to_user(), so * we need a lock that will allow us to sleep. This lock is a - * mutex (ep->mtx). It is acquired during the event transfer loop, - * during epoll_ctl(EPOLL_CTL_DEL) and during eventpoll_release_file(). - * Then we also need a global mutex to serialize eventpoll_release_file() - * and ep_free(). - * This mutex is acquired by ep_free() during the epoll file + * read-write semaphore (ep->sem). It is acquired on read during + * the event transfer loop and in write during epoll_ctl(EPOLL_CTL_DEL) + * and during eventpoll_release_file(). Then we also need a global + * semaphore to serialize eventpoll_release_file() and ep_free(). + * This semaphore is acquired by ep_free() during the epoll file * cleanup path and it is also acquired by eventpoll_release_file() * if a file has been pushed inside an epoll set and it is then * close()d without a previous call toepoll_ctl(EPOLL_CTL_DEL). - * It is possible to drop the "ep->mtx" and to use the global - * mutex "epmutex" (together with "ep->lock") to have it working, - * but having "ep->mtx" will make the interface more scalable. + * It is possible to drop the "ep->sem" and to use the global + * semaphore "epmutex" (together with "ep->lock") to have it working, + * but having "ep->sem" will make the interface more scalable. * Events that require holding "epmutex" are very rare, while for - * normal operations the epoll private "ep->mtx" will guarantee - * a better scalability. + * normal operations the epoll private "ep->sem" will guarantee + * a greater scalability. */ #define DEBUG_EPOLL 0 @@ -100,8 +102,6 @@ #define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) -#define EP_UNACTIVE_PTR ((void *) -1L) - struct epoll_filefd { struct file *file; int fd; @@ -111,7 +111,7 @@ struct epoll_filefd { * Node that is linked into the "wake_task_list" member of the "struct poll_safewake". * It is used to keep track on all tasks that are currently inside the wake_up() code * to 1) short-circuit the one coming from the same task and same wait queue head - * (loop) 2) allow a maximum number of epoll descriptors inclusion nesting + * ( loop ) 2) allow a maximum number of epoll descriptors inclusion nesting * 3) let go the ones coming from other tasks. */ struct wake_task_node { @@ -129,42 +129,6 @@ struct poll_safewake { spinlock_t lock; }; -/* - * Each file descriptor added to the eventpoll interface will - * have an entry of this type linked to the "rbr" RB tree. - */ -struct epitem { - /* RB tree node used to link this structure to the eventpoll RB tree */ - struct rb_node rbn; - - /* List header used to link this structure to the eventpoll ready list */ - struct list_head rdllink; - - /* - * Works together "struct eventpoll"->ovflist in keeping the - * single linked chain of items. - */ - struct epitem *next; - - /* The file descriptor information this item refers to */ - struct epoll_filefd ffd; - - /* Number of active wait queue attached to poll operations */ - int nwait; - - /* List containing poll wait queues */ - struct list_head pwqlist; - - /* The "container" of this item */ - struct eventpoll *ep; - - /* List header used to link this item to the "struct file" items list */ - struct list_head fllink; - - /* The structure that describe the interested events and the source fd */ - struct epoll_event event; -}; - /* * This structure is stored inside the "private_data" member of the file * structure and rapresent the main data sructure for the eventpoll @@ -172,15 +136,15 @@ struct epitem { */ struct eventpoll { /* Protect the this structure access */ - spinlock_t lock; + rwlock_t lock; /* - * This mutex is used to ensure that files are not removed - * while epoll is using them. This is held during the event - * collection loop, the file cleanup path, the epoll file exit - * code and the ctl operations. + * This semaphore is used to ensure that files are not removed + * while epoll is using them. This is read-held during the event + * collection loop and it is write-held during the file cleanup + * path, the epoll file exit code and the ctl operations. */ - struct mutex mtx; + struct rw_semaphore sem; /* Wait queue used by sys_epoll_wait() */ wait_queue_head_t wq; @@ -191,15 +155,8 @@ struct eventpoll { /* List of ready file descriptors */ struct list_head rdllist; - /* RB tree root used to store monitored fd structs */ + /* RB-Tree root used to store monitored fd structs */ struct rb_root rbr; - - /* - * This is a single linked list that chains all the "struct epitem" that - * happened while transfering ready events to userspace w/out - * holding ->lock. - */ - struct epitem *ovflist; }; /* Wait structure used by the poll hooks */ @@ -220,6 +177,42 @@ struct eppoll_entry { wait_queue_head_t *whead; }; +/* + * Each file descriptor added to the eventpoll interface will + * have an entry of this type linked to the "rbr" RB tree. + */ +struct epitem { + /* RB-Tree node used to link this structure to the eventpoll rb-tree */ + struct rb_node rbn; + + /* List header used to link this structure to the eventpoll ready list */ + struct list_head rdllink; + + /* The file descriptor information this item refers to */ + struct epoll_filefd ffd; + + /* Number of active wait queue attached to poll operations */ + int nwait; + + /* List containing poll wait queues */ + struct list_head pwqlist; + + /* The "container" of this item */ + struct eventpoll *ep; + + /* The structure that describe the interested events and the source fd */ + struct epoll_event event; + + /* + * Used to keep track of the usage count of the structure. This avoids + * that the structure will desappear from underneath our processing. + */ + atomic_t usecnt; + + /* List header used to link this item to the "struct file" items list */ + struct list_head fllink; +}; + /* Wrapper struct used by poll queueing */ struct ep_pqueue { poll_table pt; @@ -227,7 +220,7 @@ struct ep_pqueue { }; /* - * This mutex is used to serialize ep_free() and eventpoll_release_file(). + * This semaphore is used to serialize ep_free() and eventpoll_release_file(). */ static struct mutex epmutex; @@ -241,7 +234,7 @@ static struct kmem_cache *epi_cache __read_mostly; static struct kmem_cache *pwq_cache __read_mostly; -/* Setup the structure that is used as key for the RB tree */ +/* Setup the structure that is used as key for the rb-tree */ static inline void ep_set_ffd(struct epoll_filefd *ffd, struct file *file, int fd) { @@ -249,7 +242,7 @@ static inline void ep_set_ffd(struct epoll_filefd *ffd, ffd->fd = fd; } -/* Compare RB tree keys */ +/* Compare rb-tree keys */ static inline int ep_cmp_ffd(struct epoll_filefd *p1, struct epoll_filefd *p2) { @@ -257,20 +250,20 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1, (p1->file < p2->file ? -1 : p1->fd - p2->fd)); } -/* Special initialization for the RB tree node to detect linkage */ +/* Special initialization for the rb-tree node to detect linkage */ static inline void ep_rb_initnode(struct rb_node *n) { rb_set_parent(n, n); } -/* Removes a node from the RB tree and marks it for a fast is-linked check */ +/* Removes a node from the rb-tree and marks it for a fast is-linked check */ static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r) { rb_erase(n, r); rb_set_parent(n, n); } -/* Fast check to verify that the item is linked to the main RB tree */ +/* Fast check to verify that the item is linked to the main rb-tree */ static inline int ep_rb_linked(struct rb_node *n) { return rb_parent(n) != n; @@ -387,12 +380,79 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) } } +/* + * Unlink the "struct epitem" from all places it might have been hooked up. + * This function must be called with write IRQ lock on "ep->lock". + */ +static int ep_unlink(struct eventpoll *ep, struct epitem *epi) +{ + int error; + + /* + * It can happen that this one is called for an item already unlinked. + * The check protect us from doing a double unlink ( crash ). + */ + error = -ENOENT; + if (!ep_rb_linked(&epi->rbn)) + goto error_return; + + /* + * Clear the event mask for the unlinked item. This will avoid item + * notifications to be sent after the unlink operation from inside + * the kernel->userspace event transfer loop. + */ + epi->event.events = 0; + + /* + * At this point is safe to do the job, unlink the item from our rb-tree. + * This operation togheter with the above check closes the door to + * double unlinks. + */ + ep_rb_erase(&epi->rbn, &ep->rbr); + + /* + * If the item we are going to remove is inside the ready file descriptors + * we want to remove it from this list to avoid stale events. + */ + if (ep_is_linked(&epi->rdllink)) + list_del_init(&epi->rdllink); + + error = 0; +error_return: + + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n", + current, ep, epi->ffd.file, error)); + + return error; +} + +/* + * Increment the usage count of the "struct epitem" making it sure + * that the user will have a valid pointer to reference. + */ +static void ep_use_epitem(struct epitem *epi) +{ + atomic_inc(&epi->usecnt); +} + +/* + * Decrement ( release ) the usage count by signaling that the user + * has finished using the structure. It might lead to freeing the + * structure itself if the count goes to zero. + */ +static void ep_release_epitem(struct epitem *epi) +{ + if (atomic_dec_and_test(&epi->usecnt)) + kmem_cache_free(epi_cache, epi); +} + /* * Removes a "struct epitem" from the eventpoll RB tree and deallocates - * all the associated resources. Must be called with "mtx" held. + * all the associated resources. */ static int ep_remove(struct eventpoll *ep, struct epitem *epi) { + int error; unsigned long flags; struct file *file = epi->ffd.file; @@ -412,21 +472,26 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) list_del_init(&epi->fllink); spin_unlock(&file->f_ep_lock); - if (ep_rb_linked(&epi->rbn)) - ep_rb_erase(&epi->rbn, &ep->rbr); + /* We need to acquire the write IRQ lock before calling ep_unlink() */ + write_lock_irqsave(&ep->lock, flags); - spin_lock_irqsave(&ep->lock, flags); - if (ep_is_linked(&epi->rdllink)) - list_del_init(&epi->rdllink); - spin_unlock_irqrestore(&ep->lock, flags); + /* Really unlink the item from the RB tree */ + error = ep_unlink(ep, epi); + + write_unlock_irqrestore(&ep->lock, flags); + + if (error) + goto error_return; /* At this point it is safe to free the eventpoll item */ - kmem_cache_free(epi_cache, epi); + ep_release_epitem(epi); - DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p)\n", - current, ep, file)); + error = 0; +error_return: + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n", + current, ep, file, error)); - return 0; + return error; } static void ep_free(struct eventpoll *ep) @@ -441,7 +506,7 @@ static void ep_free(struct eventpoll *ep) /* * We need to lock this because we could be hit by * eventpoll_release_file() while we're freeing the "struct eventpoll". - * We do not need to hold "ep->mtx" here because the epoll file + * We do not need to hold "ep->sem" here because the epoll file * is on the way to be removed and no one has references to it * anymore. The only hit might come from eventpoll_release_file() but * holding "epmutex" is sufficent here. @@ -460,7 +525,7 @@ static void ep_free(struct eventpoll *ep) /* * Walks through the whole tree by freeing each "struct epitem". At this * point we are sure no poll callbacks will be lingering around, and also by - * holding "epmutex" we can be sure that no file cleanup code will hit + * write-holding "sem" we can be sure that no file cleanup code will hit * us during this operation. So we can avoid the lock on "ep->lock". */ while ((rbp = rb_first(&ep->rbr)) != 0) { @@ -469,16 +534,16 @@ static void ep_free(struct eventpoll *ep) } mutex_unlock(&epmutex); - mutex_destroy(&ep->mtx); - kfree(ep); } static int ep_eventpoll_release(struct inode *inode, struct file *file) { struct eventpoll *ep = file->private_data; - if (ep) + if (ep) { ep_free(ep); + kfree(ep); + } DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep)); return 0; @@ -494,10 +559,10 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) poll_wait(file, &ep->poll_wait, wait); /* Check our condition */ - spin_lock_irqsave(&ep->lock, flags); + read_lock_irqsave(&ep->lock, flags); if (!list_empty(&ep->rdllist)) pollflags = POLLIN | POLLRDNORM; - spin_unlock_irqrestore(&ep->lock, flags); + read_unlock_irqrestore(&ep->lock, flags); return pollflags; } @@ -529,11 +594,9 @@ void eventpoll_release_file(struct file *file) * We don't want to get "file->f_ep_lock" because it is not * necessary. It is not necessary because we're in the "struct file" * cleanup path, and this means that noone is using this file anymore. - * So, for example, epoll_ctl() cannot hit here sicne if we reach this - * point, the file counter already went to zero and fget() would fail. - * The only hit might come from ep_free() but by holding the mutex + * The only hit might come from ep_free() but by holding the semaphore * will correctly serialize the operation. We do need to acquire - * "ep->mtx" after "epmutex" because ep_remove() requires it when called + * "ep->sem" after "epmutex" because ep_remove() requires it when called * from anywhere but ep_free(). */ mutex_lock(&epmutex); @@ -543,9 +606,9 @@ void eventpoll_release_file(struct file *file) ep = epi->ep; list_del_init(&epi->fllink); - mutex_lock(&ep->mtx); + down_write(&ep->sem); ep_remove(ep, epi); - mutex_unlock(&ep->mtx); + up_write(&ep->sem); } mutex_unlock(&epmutex); @@ -558,13 +621,12 @@ static int ep_alloc(struct eventpoll **pep) if (!ep) return -ENOMEM; - spin_lock_init(&ep->lock); - mutex_init(&ep->mtx); + rwlock_init(&ep->lock); + init_rwsem(&ep->sem); init_waitqueue_head(&ep->wq); init_waitqueue_head(&ep->poll_wait); INIT_LIST_HEAD(&ep->rdllist); ep->rbr = RB_ROOT; - ep->ovflist = EP_UNACTIVE_PTR; *pep = ep; @@ -574,18 +636,20 @@ static int ep_alloc(struct eventpoll **pep) } /* - * Search the file inside the eventpoll tree. The RB tree operations - * are protected by the "mtx" mutex, and ep_find() must be called with - * "mtx" held. + * Search the file inside the eventpoll tree. It add usage count to + * the returned item, so the caller must call ep_release_epitem() + * after finished using the "struct epitem". */ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd) { int kcmp; + unsigned long flags; struct rb_node *rbp; struct epitem *epi, *epir = NULL; struct epoll_filefd ffd; ep_set_ffd(&ffd, file, fd); + read_lock_irqsave(&ep->lock, flags); for (rbp = ep->rbr.rb_node; rbp; ) { epi = rb_entry(rbp, struct epitem, rbn); kcmp = ep_cmp_ffd(&ffd, &epi->ffd); @@ -594,10 +658,12 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd) else if (kcmp < 0) rbp = rbp->rb_left; else { + ep_use_epitem(epi); epir = epi; break; } } + read_unlock_irqrestore(&ep->lock, flags); DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n", current, file, epir)); @@ -620,7 +686,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n", current, epi->ffd.file, epi, ep)); - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); /* * If the event mask does not contain any poll(2) event, we consider the @@ -629,21 +695,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k * until the next EPOLL_CTL_MOD will be issued. */ if (!(epi->event.events & ~EP_PRIVATE_BITS)) - goto out_unlock; - - /* - * If we are trasfering events to userspace, we can hold no locks - * (because we're accessing user memory, and because of linux f_op->poll() - * semantics). All the events that happens during that period of time are - * chained in ep->ovflist and requeued later on. - */ - if (unlikely(ep->ovflist != EP_UNACTIVE_PTR)) { - if (epi->next == EP_UNACTIVE_PTR) { - epi->next = ep->ovflist; - ep->ovflist = epi; - } - goto out_unlock; - } + goto is_disabled; /* If this file is already in the ready list we exit soon */ if (ep_is_linked(&epi->rdllink)) @@ -662,8 +714,8 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k if (waitqueue_active(&ep->poll_wait)) pwake++; -out_unlock: - spin_unlock_irqrestore(&ep->lock, flags); +is_disabled: + write_unlock_irqrestore(&ep->lock, flags); /* We have to call this outside the lock */ if (pwake) @@ -714,9 +766,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) rb_insert_color(&epi->rbn, &ep->rbr); } -/* - * Must be called with "mtx" held. - */ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile, int fd) { @@ -737,8 +786,8 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, epi->ep = ep; ep_set_ffd(&epi->ffd, tfile, fd); epi->event = *event; + atomic_set(&epi->usecnt, 1); epi->nwait = 0; - epi->next = EP_UNACTIVE_PTR; /* Initialize the poll table using the queue callback */ epq.epi = epi; @@ -747,9 +796,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, /* * Attach the item to the poll hooks and get current event bits. * We can safely use the file* here because its usage count has - * been increased by the caller of this function. Note that after - * this operation completes, the poll callback can start hitting - * the new item. + * been increased by the caller of this function. */ revents = tfile->f_op->poll(tfile, &epq.pt); @@ -766,14 +813,11 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, list_add_tail(&epi->fllink, &tfile->f_ep_links); spin_unlock(&tfile->f_ep_lock); - /* - * Add the current item to the RB tree. All RB tree operations are - * protected by "mtx", and ep_insert() is called with "mtx" held. - */ - ep_rbtree_insert(ep, epi); - /* We have to drop the new item inside our item list to keep track of it */ - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); + + /* Add the current item to the rb-tree */ + ep_rbtree_insert(ep, epi); /* If the file is already "ready" we drop it inside the ready list */ if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) { @@ -786,7 +830,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, pwake++; } - spin_unlock_irqrestore(&ep->lock, flags); + write_unlock_irqrestore(&ep->lock, flags); /* We have to call this outside the lock */ if (pwake) @@ -802,14 +846,12 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, /* * We need to do this because an event could have been arrived on some - * allocated wait queue. Note that we don't care about the ep->ovflist - * list, since that is used/cleaned only inside a section bound by "mtx". - * And ep_insert() is called with "mtx" held. + * allocated wait queue. */ - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); if (ep_is_linked(&epi->rdllink)) list_del_init(&epi->rdllink); - spin_unlock_irqrestore(&ep->lock, flags); + write_unlock_irqrestore(&ep->lock, flags); kmem_cache_free(epi_cache, epi); error_return: @@ -818,7 +860,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, /* * Modify the interest event mask by dropping an event if the new mask - * has a match in the current file status. Must be called with "mtx" held. + * has a match in the current file status. */ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event) { @@ -840,28 +882,36 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even */ revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL); - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); /* Copy the data member from inside the lock */ epi->event.data = event->data; /* - * If the item is "hot" and it is not registered inside the ready - * list, push it inside. + * If the item is not linked to the RB tree it means that it's on its + * way toward the removal. Do nothing in this case. */ - if (revents & event->events) { - if (!ep_is_linked(&epi->rdllink)) { - list_add_tail(&epi->rdllink, &ep->rdllist); - - /* Notify waiting tasks that events are available */ - if (waitqueue_active(&ep->wq)) - __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | - TASK_INTERRUPTIBLE); - if (waitqueue_active(&ep->poll_wait)) - pwake++; + if (ep_rb_linked(&epi->rbn)) { + /* + * If the item is "hot" and it is not registered inside the ready + * list, push it inside. If the item is not "hot" and it is currently + * registered inside the ready list, unlink it. + */ + if (revents & event->events) { + if (!ep_is_linked(&epi->rdllink)) { + list_add_tail(&epi->rdllink, &ep->rdllist); + + /* Notify waiting tasks that events are available */ + if (waitqueue_active(&ep->wq)) + __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | + TASK_INTERRUPTIBLE); + if (waitqueue_active(&ep->poll_wait)) + pwake++; + } } } - spin_unlock_irqrestore(&ep->lock, flags); + + write_unlock_irqrestore(&ep->lock, flags); /* We have to call this outside the lock */ if (pwake) @@ -870,50 +920,36 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even return 0; } -static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *events, - int maxevents) +/* + * This function is called without holding the "ep->lock" since the call to + * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ + * because of the way poll() is traditionally implemented in Linux. + */ +static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, + struct epoll_event __user *events, int maxevents) { int eventcnt, error = -EFAULT, pwake = 0; unsigned int revents; unsigned long flags; - struct epitem *epi, *nepi; - struct list_head txlist; - - INIT_LIST_HEAD(&txlist); - - /* - * We need to lock this because we could be hit by - * eventpoll_release_file() and epoll_ctl(EPOLL_CTL_DEL). - */ - mutex_lock(&ep->mtx); + struct epitem *epi; + struct list_head injlist; - /* - * Steal the ready list, and re-init the original one to the - * empty list. Also, set ep->ovflist to NULL so that events - * happening while looping w/out locks, are not lost. We cannot - * have the poll callback to queue directly on ep->rdllist, - * because we are doing it in the loop below, in a lockless way. - */ - spin_lock_irqsave(&ep->lock, flags); - list_splice(&ep->rdllist, &txlist); - INIT_LIST_HEAD(&ep->rdllist); - ep->ovflist = NULL; - spin_unlock_irqrestore(&ep->lock, flags); + INIT_LIST_HEAD(&injlist); /* * We can loop without lock because this is a task private list. * We just splice'd out the ep->rdllist in ep_collect_ready_items(). - * Items cannot vanish during the loop because we are holding "mtx". + * Items cannot vanish during the loop because we are holding "sem" in + * read. */ - for (eventcnt = 0; !list_empty(&txlist) && eventcnt < maxevents;) { - epi = list_first_entry(&txlist, struct epitem, rdllink); - - list_del_init(&epi->rdllink); + for (eventcnt = 0; !list_empty(txlist) && eventcnt < maxevents;) { + epi = list_first_entry(txlist, struct epitem, rdllink); + prefetch(epi->rdllink.next); /* * Get the ready file event set. We can safely use the file - * because we are holding the "mtx" and this will guarantee - * that both the file and the item will not vanish. + * because we are holding the "sem" in read and this will + * guarantee that both the file and the item will not vanish. */ revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL); revents &= epi->event.events; @@ -921,8 +957,8 @@ static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *event /* * Is the event mask intersect the caller-requested one, * deliver the event to userspace. Again, we are holding - * "mtx", so no operations coming from userspace can change - * the item. + * "sem" in read, so no operations coming from userspace + * can change the item. */ if (revents) { if (__put_user(revents, @@ -934,59 +970,59 @@ static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *event epi->event.events &= EP_PRIVATE_BITS; eventcnt++; } + /* - * At this point, noone can insert into ep->rdllist besides - * us. The epoll_ctl() callers are locked out by us holding - * "mtx" and the poll callback will queue them in ep->ovflist. + * This is tricky. We are holding the "sem" in read, and this + * means that the operations that can change the "linked" status + * of the epoll item (epi->rbn and epi->rdllink), cannot touch + * them. Also, since we are "linked" from a epi->rdllink POV + * (the item is linked to our transmission list we just + * spliced), the ep_poll_callback() cannot touch us either, + * because of the check present in there. Another parallel + * epoll_wait() will not get the same result set, since we + * spliced the ready list before. Note that list_del() still + * shows the item as linked to the test in ep_poll_callback(). */ + list_del(&epi->rdllink); if (!(epi->event.events & EPOLLET) && - (revents & epi->event.events)) - list_add_tail(&epi->rdllink, &ep->rdllist); + (revents & epi->event.events)) + list_add_tail(&epi->rdllink, &injlist); + else { + /* + * Be sure the item is totally detached before re-init + * the list_head. After INIT_LIST_HEAD() is committed, + * the ep_poll_callback() can requeue the item again, + * but we don't care since we are already past it. + */ + smp_mb(); + INIT_LIST_HEAD(&epi->rdllink); + } } error = 0; -errxit: + errxit: - spin_lock_irqsave(&ep->lock, flags); /* - * During the time we spent in the loop above, some other events - * might have been queued by the poll callback. We re-insert them - * here (in case they are not already queued, or they're one-shot). + * If the re-injection list or the txlist are not empty, re-splice + * them to the ready list and do proper wakeups. */ - for (nepi = ep->ovflist; (epi = nepi) != NULL; - nepi = epi->next, epi->next = EP_UNACTIVE_PTR) { - if (!ep_is_linked(&epi->rdllink) && - (epi->event.events & ~EP_PRIVATE_BITS)) - list_add_tail(&epi->rdllink, &ep->rdllist); - } - /* - * We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after - * releasing the lock, events will be queued in the normal way inside - * ep->rdllist. - */ - ep->ovflist = EP_UNACTIVE_PTR; - - /* - * In case of error in the event-send loop, or in case the number of - * ready events exceeds the userspace limit, we need to splice the - * "txlist" back inside ep->rdllist. - */ - list_splice(&txlist, &ep->rdllist); + if (!list_empty(&injlist) || !list_empty(txlist)) { + write_lock_irqsave(&ep->lock, flags); - if (!list_empty(&ep->rdllist)) { + list_splice(txlist, &ep->rdllist); + list_splice(&injlist, &ep->rdllist); /* - * Wake up (if active) both the eventpoll wait list and the ->poll() - * wait list (delayed after we release the lock). + * Wake up ( if active ) both the eventpoll wait list and the ->poll() + * wait list. */ if (waitqueue_active(&ep->wq)) __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE); if (waitqueue_active(&ep->poll_wait)) pwake++; - } - spin_unlock_irqrestore(&ep->lock, flags); - mutex_unlock(&ep->mtx); + write_unlock_irqrestore(&ep->lock, flags); + } /* We have to call this outside the lock */ if (pwake) @@ -995,6 +1031,41 @@ static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *event return eventcnt == 0 ? error: eventcnt; } +/* + * Perform the transfer of events to user space. + */ +static int ep_events_transfer(struct eventpoll *ep, + struct epoll_event __user *events, int maxevents) +{ + int eventcnt; + unsigned long flags; + struct list_head txlist; + + INIT_LIST_HEAD(&txlist); + + /* + * We need to lock this because we could be hit by + * eventpoll_release_file() and epoll_ctl(EPOLL_CTL_DEL). + */ + down_read(&ep->sem); + + /* + * Steal the ready list, and re-init the original one to the + * empty list. + */ + write_lock_irqsave(&ep->lock, flags); + list_splice(&ep->rdllist, &txlist); + INIT_LIST_HEAD(&ep->rdllist); + write_unlock_irqrestore(&ep->lock, flags); + + /* Build result set in userspace */ + eventcnt = ep_send_events(ep, &txlist, events, maxevents); + + up_read(&ep->sem); + + return eventcnt; +} + static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, int maxevents, long timeout) { @@ -1012,7 +1083,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000; retry: - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); res = 0; if (list_empty(&ep->rdllist)) { @@ -1022,7 +1093,6 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, * ep_poll_callback() when events will become available. */ init_waitqueue_entry(&wait, current); - wait.flags |= WQ_FLAG_EXCLUSIVE; __add_wait_queue(&ep->wq, &wait); for (;;) { @@ -1039,9 +1109,9 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, break; } - spin_unlock_irqrestore(&ep->lock, flags); + write_unlock_irqrestore(&ep->lock, flags); jtimeout = schedule_timeout(jtimeout); - spin_lock_irqsave(&ep->lock, flags); + write_lock_irqsave(&ep->lock, flags); } __remove_wait_queue(&ep->wq, &wait); @@ -1051,7 +1121,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, /* Is it worth to try to dig for events ? */ eavail = !list_empty(&ep->rdllist); - spin_unlock_irqrestore(&ep->lock, flags); + write_unlock_irqrestore(&ep->lock, flags); /* * Try to transfer events to user space. In case we get 0 events and @@ -1059,17 +1129,18 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, * more luck. */ if (!res && eavail && - !(res = ep_send_events(ep, events, maxevents)) && jtimeout) + !(res = ep_events_transfer(ep, events, maxevents)) && jtimeout) goto retry; return res; } /* - * It opens an eventpoll file descriptor. The "size" parameter is there - * for historical reasons, when epoll was using an hash instead of an - * RB tree. With the current implementation, the "size" parameter is ignored - * (besides sanity checks). + * It opens an eventpoll file descriptor by suggesting a storage of "size" + * file descriptors. The size parameter is just an hint about how to size + * data structures. It won't prevent the user to store more than "size" + * file descriptors inside the epoll interface. It is the kernel part of + * the userspace epoll_create(2). */ asmlinkage long sys_epoll_create(int size) { @@ -1105,6 +1176,7 @@ asmlinkage long sys_epoll_create(int size) error_free: ep_free(ep); + kfree(ep); error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", current, size, error)); @@ -1114,7 +1186,8 @@ asmlinkage long sys_epoll_create(int size) /* * The following function implements the controller interface for * the eventpoll file that enables the insertion/removal/change of - * file descriptors inside the interest set. + * file descriptors inside the interest set. It represents + * the kernel part of the user space epoll_ctl(2). */ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) @@ -1164,13 +1237,9 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, */ ep = file->private_data; - mutex_lock(&ep->mtx); + down_write(&ep->sem); - /* - * Try to lookup the file inside our RB tree, Since we grabbed "mtx" - * above, we can be sure to be able to use the item looked up by - * ep_find() till we release the mutex. - */ + /* Try to lookup the file inside our RB tree */ epi = ep_find(ep, tfile, fd); error = -EINVAL; @@ -1197,7 +1266,13 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, error = -ENOENT; break; } - mutex_unlock(&ep->mtx); + /* + * The function ep_find() increments the usage count of the structure + * so, if this is not NULL, we need to release it. + */ + if (epi) + ep_release_epitem(epi); + up_write(&ep->sem); error_tgt_fput: fput(tfile); @@ -1303,7 +1378,7 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, if (sigmask) { if (error == -EINTR) { memcpy(¤t->saved_sigmask, &sigsaved, - sizeof(sigsaved)); + sizeof(sigsaved)); set_thread_flag(TIF_RESTORE_SIGMASK); } else sigprocmask(SIG_SETMASK, &sigsaved, NULL); diff --git a/trunk/include/asm-alpha/mmu_context.h b/trunk/include/asm-alpha/mmu_context.h index 6a5be1f7debf..0bd7bd2ccb90 100644 --- a/trunk/include/asm-alpha/mmu_context.h +++ b/trunk/include/asm-alpha/mmu_context.h @@ -85,8 +85,8 @@ __reload_thread(struct pcb_struct *pcb) * +-------------+----------------+--------------+ */ -#include #ifdef CONFIG_SMP +#include #define cpu_last_asn(cpuid) (cpu_data[cpuid].last_asn) #else extern unsigned long last_asn; diff --git a/trunk/include/asm-h8300/atomic.h b/trunk/include/asm-h8300/atomic.h index b4cf0ea97ede..21f54428c86b 100644 --- a/trunk/include/asm-h8300/atomic.h +++ b/trunk/include/asm-h8300/atomic.h @@ -37,7 +37,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) } #define atomic_sub(i, v) atomic_sub_return(i, v) -#define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0) static __inline__ int atomic_inc_return(atomic_t *v) { diff --git a/trunk/include/asm-i386/kdebug.h b/trunk/include/asm-i386/kdebug.h index a185b5f73e7f..05c3117788b9 100644 --- a/trunk/include/asm-i386/kdebug.h +++ b/trunk/include/asm-i386/kdebug.h @@ -27,6 +27,7 @@ enum die_val { DIE_GPF, DIE_CALL, DIE_NMI_IPI, + DIE_NMI_POST, DIE_PAGE_FAULT, }; diff --git a/trunk/include/asm-i386/processor.h b/trunk/include/asm-i386/processor.h index 338668bfb0a2..70f3515c3db0 100644 --- a/trunk/include/asm-i386/processor.h +++ b/trunk/include/asm-i386/processor.h @@ -749,13 +749,9 @@ extern unsigned long boot_option_idle_override; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; - extern void cpu_set_gdt(int); extern void switch_to_new_gdt(void); extern void cpu_init(void); -extern void init_gdt(int cpu); extern int force_mwait; diff --git a/trunk/include/asm-ia64/kdebug.h b/trunk/include/asm-ia64/kdebug.h index 320cd8e754ea..ba211e011a1d 100644 --- a/trunk/include/asm-ia64/kdebug.h +++ b/trunk/include/asm-ia64/kdebug.h @@ -28,24 +28,14 @@ */ #include -/* - * These are only here because kprobes.c wants them to implement a - * blatant layering violation. Will hopefully go away soon once all - * architectures are updated. - */ -static inline int register_page_fault_notifier(struct notifier_block *nb) -{ - return 0; -} -static inline int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return 0; -} +extern int register_page_fault_notifier(struct notifier_block *); +extern int unregister_page_fault_notifier(struct notifier_block *); enum die_val { DIE_BREAK = 1, DIE_FAULT, DIE_OOPS, + DIE_PAGE_FAULT, DIE_MACHINE_HALT, DIE_MACHINE_RESTART, DIE_MCA_MONARCH_ENTER, diff --git a/trunk/include/asm-ia64/kprobes.h b/trunk/include/asm-ia64/kprobes.h index 6382e52ec227..2abc98b336f3 100644 --- a/trunk/include/asm-ia64/kprobes.h +++ b/trunk/include/asm-ia64/kprobes.h @@ -120,7 +120,6 @@ struct arch_specific_insn { unsigned short slot; }; -extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); diff --git a/trunk/include/asm-ia64/unistd.h b/trunk/include/asm-ia64/unistd.h index d7781a2ddefe..f049bc40ca7d 100644 --- a/trunk/include/asm-ia64/unistd.h +++ b/trunk/include/asm-ia64/unistd.h @@ -296,14 +296,11 @@ #define __NR_getcpu 1304 #define __NR_epoll_pwait 1305 #define __NR_utimensat 1306 -#define __NR_signalfd 1307 -#define __NR_timerfd 1308 -#define __NR_eventfd 1309 #ifdef __KERNEL__ -#define NR_syscalls 286 /* length of syscall table */ +#define NR_syscalls 283 /* length of syscall table */ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND diff --git a/trunk/include/asm-m32r/system.h b/trunk/include/asm-m32r/system.h index 8ee73d3f316d..b291b2f72954 100644 --- a/trunk/include/asm-m32r/system.h +++ b/trunk/include/asm-m32r/system.h @@ -10,7 +10,6 @@ * Copyright (C) 2004, 2006 Hirokazu Takata */ -#include #include #ifdef __KERNEL__ @@ -155,7 +154,7 @@ extern void __xchg_called_with_bad_pointer(void); #define DCACHE_CLEAR(reg0, reg1, addr) #endif /* CONFIG_CHIP_M32700_TS1 */ -static __always_inline unsigned long +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { unsigned long flags; diff --git a/trunk/include/asm-m68k/uaccess.h b/trunk/include/asm-m68k/uaccess.h index 5c1264cf0c65..6a4cf2081512 100644 --- a/trunk/include/asm-m68k/uaccess.h +++ b/trunk/include/asm-m68k/uaccess.h @@ -361,9 +361,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) long strncpy_from_user(char *dst, const char __user *src, long count); long strnlen_user(const char __user *src, long n); -unsigned long __clear_user(void __user *to, unsigned long n); - -#define clear_user __clear_user +unsigned long clear_user(void __user *to, unsigned long n); #define strlen_user(str) strnlen_user(str, 32767) diff --git a/trunk/include/asm-sh64/dma-mapping.h b/trunk/include/asm-sh64/dma-mapping.h index c7c0f059cdc4..5efe906c59f7 100644 --- a/trunk/include/asm-sh64/dma-mapping.h +++ b/trunk/include/asm-sh64/dma-mapping.h @@ -35,10 +35,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(NULL, size, vaddr, dma_handle); } -#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) - static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) { @@ -53,7 +49,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, if (dev->bus == &pci_bus_type) return virt_to_bus(ptr); #endif - dma_cache_sync(dev, ptr, size, dir); + dma_cache_sync(ptr, size, dir); return virt_to_bus(ptr); } @@ -67,7 +63,7 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, for (i = 0; i < nents; i++) { #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) - dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset, + dma_cache_sync(page_address(sg[i].page) + sg[i].offset, sg[i].length, dir); #endif sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; @@ -98,7 +94,7 @@ static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle, if (dev->bus == &pci_bus_type) return; #endif - dma_cache_sync(dev, bus_to_virt(dma_handle), size, dir); + dma_cache_sync(bus_to_virt(dma_handle), size, dir); } static inline void dma_sync_single_range(struct device *dev, @@ -110,7 +106,7 @@ static inline void dma_sync_single_range(struct device *dev, if (dev->bus == &pci_bus_type) return; #endif - dma_cache_sync(dev, bus_to_virt(dma_handle) + offset, size, dir); + dma_cache_sync(bus_to_virt(dma_handle) + offset, size, dir); } static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, @@ -120,7 +116,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, for (i = 0; i < nelems; i++) { #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) - dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset, + dma_cache_sync(page_address(sg[i].page) + sg[i].offset, sg[i].length, dir); #endif sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; diff --git a/trunk/include/asm-sh64/irq_regs.h b/trunk/include/asm-sh64/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/trunk/include/asm-sh64/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh64/pgalloc.h b/trunk/include/asm-sh64/pgalloc.h index 6eccab770a6d..cb803e56cb64 100644 --- a/trunk/include/asm-sh64/pgalloc.h +++ b/trunk/include/asm-sh64/pgalloc.h @@ -14,9 +14,13 @@ * */ +#include #include -#include -#include + +#define pgd_quicklist (current_cpu_data.pgd_quick) +#define pmd_quicklist (current_cpu_data.pmd_quick) +#define pte_quicklist (current_cpu_data.pte_quick) +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) static inline void pgd_init(unsigned long page) { @@ -41,37 +45,84 @@ static inline pgd_t *get_pgd_slow(void) return ret; } -static inline pgd_t *pgd_alloc(struct mm_struct *mm) +static inline pgd_t *get_pgd_fast(void) +{ + unsigned long *ret; + + if ((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = 0; + pgtable_cache_size--; + } else + ret = (unsigned long *)get_pgd_slow(); + + if (ret) { + memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + } + return (pgd_t *)ret; +} + +static inline void free_pgd_fast(pgd_t *pgd) +{ + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; +} + +static inline void free_pgd_slow(pgd_t *pgd) { - return quicklist_alloc(0, GFP_KERNEL, NULL); + kfree((void *)pgd); } -static inline void pgd_free(pgd_t *pgd) +extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); +extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted); + +static inline pte_t *get_pte_fast(void) { - quicklist_free(0, NULL, pgd); + unsigned long *ret; + + if((ret = (unsigned long *)pte_quicklist) != NULL) { + pte_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + pgtable_cache_size--; + } + return (pte_t *)ret; } -static inline struct page *pte_alloc_one(struct mm_struct *mm, - unsigned long address) +static inline void free_pte_fast(pte_t *pte) { - void *pg = quicklist_alloc(0, GFP_KERNEL, NULL); - return pg ? virt_to_page(pg) : NULL; + *(unsigned long *)pte = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pte; + pgtable_cache_size++; } static inline void pte_free_kernel(pte_t *pte) { - quicklist_free(0, NULL, pte); + free_page((unsigned long)pte); } static inline void pte_free(struct page *pte) { - quicklist_free_page(0, NULL, pte); + __free_page(pte); } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return quicklist_alloc(0, GFP_KERNEL, NULL); + pte_t *pte; + + pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT|__GFP_ZERO); + + return pte; +} + +static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *pte; + + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + + return pte; } #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) @@ -91,23 +142,31 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, #elif defined(CONFIG_SH64_PGTABLE_3_LEVEL) -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - return quicklist_alloc(0, GFP_KERNEL, NULL); + pmd_t *pmd; + pmd = (pmd_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + return pmd; } -static inline void pmd_free(pmd_t *pmd) +static __inline__ void pmd_free(pmd_t *pmd) { - quicklist_free(0, NULL, pmd); + free_page((unsigned long) pmd); } -#define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) +#define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) #define __pmd_free_tlb(tlb,pmd) pmd_free(pmd) #else #error "No defined page table size" #endif +#define check_pgt_cache() do { } while (0) +#define pgd_free(pgd) free_pgd_slow(pgd) +#define pgd_alloc(mm) get_pgd_fast() + +extern int do_check_pgt_cache(int, int); + #define pmd_populate_kernel(mm, pmd, pte) \ set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) (pte))) @@ -117,9 +176,4 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) page_address (pte))); } -static inline void check_pgt_cache(void) -{ - quicklist_trim(0, NULL, 25, 16); -} - #endif /* __ASM_SH64_PGALLOC_H */ diff --git a/trunk/include/asm-sh64/sci.h b/trunk/include/asm-sh64/sci.h deleted file mode 100644 index 793c568b7820..000000000000 --- a/trunk/include/asm-sh64/sci.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sh64/thread_info.h b/trunk/include/asm-sh64/thread_info.h index f6d5117c53af..1f825cb163c3 100644 --- a/trunk/include/asm-sh64/thread_info.h +++ b/trunk/include/asm-sh64/thread_info.h @@ -78,13 +78,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_MEMDIE 4 -#define TIF_RESTORE_SIGMASK 5 /* Restore signal mask in do_signal */ -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_MEMDIE (1 << TIF_MEMDIE) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-sh64/unistd.h b/trunk/include/asm-sh64/unistd.h index ea3adc600b41..1f38a7aacaaf 100644 --- a/trunk/include/asm-sh64/unistd.h +++ b/trunk/include/asm-sh64/unistd.h @@ -9,14 +9,14 @@ * include/asm-sh64/unistd.h * * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2003 - 2007 Paul Mundt + * Copyright (C) 2003 Paul Mundt * Copyright (C) 2004 Sean McGoogan * * This file contains the system call numbers. * */ -#define __NR_restart_syscall 0 +#define __NR_setup 0 /* used only by init, to get system going */ #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 @@ -196,8 +196,8 @@ #define __NR_rt_sigtimedwait 177 #define __NR_rt_sigqueueinfo 178 #define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 +#define __NR_pread 180 +#define __NR_pwrite 181 #define __NR_chown 182 #define __NR_getcwd 183 #define __NR_capget 184 @@ -343,41 +343,10 @@ #define __NR_inotify_init 318 #define __NR_inotify_add_watch 319 #define __NR_inotify_rm_watch 320 -/* 321 is unused */ -#define __NR_migrate_pages 322 -#define __NR_openat 323 -#define __NR_mkdirat 324 -#define __NR_mknodat 325 -#define __NR_fchownat 326 -#define __NR_futimesat 327 -#define __NR_fstatat64 328 -#define __NR_unlinkat 329 -#define __NR_renameat 330 -#define __NR_linkat 331 -#define __NR_symlinkat 332 -#define __NR_readlinkat 333 -#define __NR_fchmodat 334 -#define __NR_faccessat 335 -#define __NR_pselect6 336 -#define __NR_ppoll 337 -#define __NR_unshare 338 -#define __NR_set_robust_list 339 -#define __NR_get_robust_list 340 -#define __NR_splice 341 -#define __NR_sync_file_range 342 -#define __NR_tee 343 -#define __NR_vmsplice 344 -#define __NR_move_pages 345 -#define __NR_getcpu 346 -#define __NR_epoll_pwait 347 -#define __NR_utimensat 348 -#define __NR_signalfd 349 -#define __NR_timerfd 350 -#define __NR_eventfd 351 -#ifdef __KERNEL__ +#ifdef __KERNEL__ -#define NR_syscalls 352 +#define NR_syscalls 321 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-sparc/kdebug.h b/trunk/include/asm-sparc/kdebug.h index 631f15ffef73..404d80767323 100644 --- a/trunk/include/asm-sparc/kdebug.h +++ b/trunk/include/asm-sparc/kdebug.h @@ -58,10 +58,6 @@ static inline void sp_enter_debugger(void) sp_enter_debugger(); \ } while(0) -enum die_val { - DIE_UNUSED, -}; - #endif /* !(__ASSEMBLY__) */ /* Some nice offset defines for assembler code. */ @@ -70,4 +66,8 @@ enum die_val { #define KDEBUG_DUNNO2_OFF 0x8 #define KDEBUG_TEACH_OFF 0xc +enum die_val { + DIE_UNUSED, +}; + #endif /* !(_SPARC_KDEBUG_H) */ diff --git a/trunk/include/asm-sparc/system.h b/trunk/include/asm-sparc/system.h index 8b4e23b3bb38..8b6d9c9c8b93 100644 --- a/trunk/include/asm-sparc/system.h +++ b/trunk/include/asm-sparc/system.h @@ -11,7 +11,6 @@ #include #include #include -#include #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-sparc64/dma-mapping.h b/trunk/include/asm-sparc64/dma-mapping.h index 9329429fb7f6..2f858a2df94a 100644 --- a/trunk/include/asm-sparc64/dma-mapping.h +++ b/trunk/include/asm-sparc64/dma-mapping.h @@ -10,13 +10,10 @@ /* need struct page definitions */ #include -#include - static inline int dma_supported(struct device *dev, u64 mask) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_dma_supported(to_pci_dev(dev), mask); } @@ -24,8 +21,7 @@ dma_supported(struct device *dev, u64 mask) static inline int dma_set_mask(struct device *dev, u64 dma_mask) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_set_dma_mask(to_pci_dev(dev), dma_mask); } @@ -34,8 +30,7 @@ static inline void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_iommu_ops->alloc_consistent(to_pci_dev(dev), size, dma_handle, flag); } @@ -44,8 +39,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle); } @@ -54,8 +48,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction); } @@ -64,8 +57,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction); } @@ -75,8 +67,7 @@ dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction); } @@ -85,8 +76,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction); } @@ -95,8 +85,7 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); } @@ -105,8 +94,7 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction); } @@ -115,8 +103,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, size, (int)direction); @@ -126,8 +113,7 @@ static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, size, (int)direction); @@ -137,8 +123,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction); } @@ -147,8 +132,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { - BUG_ON(dev->bus != &pci_bus_type && - dev->bus != &ebus_bus_type); + BUG_ON(dev->bus != &pci_bus_type); pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction); } diff --git a/trunk/include/asm-sparc64/hypervisor.h b/trunk/include/asm-sparc64/hypervisor.h index a5558c87556d..612bf319753f 100644 --- a/trunk/include/asm-sparc64/hypervisor.h +++ b/trunk/include/asm-sparc64/hypervisor.h @@ -940,54 +940,6 @@ struct hv_fault_status { */ #define HV_FAST_CONS_PUTCHAR 0x61 -/* con_read() - * TRAP: HV_FAST_TRAP - * FUNCTION: HV_FAST_CONS_READ - * ARG0: buffer real address - * ARG1: buffer size in bytes - * RET0: status - * RET1: bytes read or BREAK or HUP - * ERRORS: EWOULDBLOCK No character available. - * - * Reads characters into a buffer from the console device. If no - * character is available then an EWOULDBLOCK error is returned. - * If a character is available, then the returned status is EOK - * and the number of bytes read into the given buffer is provided - * in RET1. - * - * A virtual BREAK is represented by the 64-bit RET1 value -1. - * - * A virtual HUP signal is represented by the 64-bit RET1 value -2. - * - * If BREAK or HUP are indicated, no bytes were read into buffer. - */ -#define HV_FAST_CONS_READ 0x62 - -/* con_write() - * TRAP: HV_FAST_TRAP - * FUNCTION: HV_FAST_CONS_WRITE - * ARG0: buffer real address - * ARG1: buffer size in bytes - * RET0: status - * RET1: bytes written - * ERRORS: EWOULDBLOCK Output buffer currently full, would block - * - * Send a characters in buffer to the console device. Breaks must be - * sent using con_putchar(). - */ -#define HV_FAST_CONS_WRITE 0x63 - -#ifndef __ASSEMBLY__ -extern long sun4v_con_getchar(long *status); -extern long sun4v_con_putchar(long c); -extern long sun4v_con_read(unsigned long buffer, - unsigned long size, - unsigned long *bytes_read); -extern unsigned long sun4v_con_write(unsigned long buffer, - unsigned long size, - unsigned long *bytes_written); -#endif - /* Trap trace services. * * The hypervisor provides a trap tracing capability for privileged @@ -2169,41 +2121,8 @@ struct hv_mmu_statistics { #define HV_FAST_MMUSTAT_INFO 0x103 /* Function numbers for HV_CORE_TRAP. */ -#define HV_CORE_SET_VER 0x00 +#define HV_CORE_VER 0x00 #define HV_CORE_PUTCHAR 0x01 #define HV_CORE_EXIT 0x02 -#define HV_CORE_GET_VER 0x03 - -/* Hypervisor API groups for use with HV_CORE_SET_VER and - * HV_CORE_GET_VER. - */ -#define HV_GRP_SUN4V 0x0000 -#define HV_GRP_CORE 0x0001 -#define HV_GRP_INTR 0x0002 -#define HV_GRP_SOFT_STATE 0x0003 -#define HV_GRP_PCI 0x0100 -#define HV_GRP_LDOM 0x0101 -#define HV_GRP_SVC_CHAN 0x0102 -#define HV_GRP_NCS 0x0103 -#define HV_GRP_NIAG_PERF 0x0200 -#define HV_GRP_FIRE_PERF 0x0201 -#define HV_GRP_DIAG 0x0300 - -#ifndef __ASSEMBLY__ -extern unsigned long sun4v_get_version(unsigned long group, - unsigned long *major, - unsigned long *minor); -extern unsigned long sun4v_set_version(unsigned long group, - unsigned long major, - unsigned long minor, - unsigned long *actual_minor); - -extern int sun4v_hvapi_register(unsigned long group, unsigned long major, - unsigned long *minor); -extern void sun4v_hvapi_unregister(unsigned long group); -extern int sun4v_hvapi_get(unsigned long group, - unsigned long *major, - unsigned long *minor); -#endif #endif /* !(_SPARC64_HYPERVISOR_H) */ diff --git a/trunk/include/asm-x86_64/kdebug.h b/trunk/include/asm-x86_64/kdebug.h index d7e2bcf49e4f..74feae945a26 100644 --- a/trunk/include/asm-x86_64/kdebug.h +++ b/trunk/include/asm-x86_64/kdebug.h @@ -22,6 +22,7 @@ enum die_val { DIE_GPF, DIE_CALL, DIE_NMI_IPI, + DIE_NMI_POST, DIE_PAGE_FAULT, }; diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 0e69d2cf14aa..636502c02734 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -261,11 +261,5 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags); -asmlinkage long compat_sys_signalfd(int ufd, - const compat_sigset_t __user *sigmask, - compat_size_t sigsetsize); -asmlinkage long compat_sys_timerfd(int ufd, int clockid, int flags, - const struct compat_itimerspec __user *utmr); - #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 07aba87d369d..df4e6a510310 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -1281,6 +1281,7 @@ struct drive_list_entry { int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); +int ide_use_dma(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *); int ide_tune_dma(ide_drive_t *); void ide_dma_off(ide_drive_t *); @@ -1308,6 +1309,7 @@ extern int __ide_dma_timeout(ide_drive_t *); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ #else +static inline int ide_use_dma(ide_drive_t *drive) { return 0; } static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline int ide_tune_dma(ide_drive_t *drive) { return 0; } static inline void ide_dma_off(ide_drive_t *drive) { ; } @@ -1355,6 +1357,7 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) /* ide-lib.c */ u8 ide_rate_filter(ide_drive_t *, u8); +extern int ide_dma_enable(ide_drive_t *drive); extern char *ide_xfer_verbose(u8 xfer_rate); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index e007ae4dc41e..8bc32bb2fce2 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -52,9 +52,14 @@ #endif /* For assembly routines */ +#ifdef CONFIG_HOTPLUG_CPU +#define __INIT .section ".text","ax" +#define __INITDATA .section ".data","aw" +#else #define __INIT .section ".init.text","ax" -#define __FINIT .previous #define __INITDATA .section ".init.data","aw" +#endif +#define __FINIT .previous #ifndef __ASSEMBLY__ /* diff --git a/trunk/include/linux/io.h b/trunk/include/linux/io.h index 8423dd376514..09d351236379 100644 --- a/trunk/include/linux/io.h +++ b/trunk/include/linux/io.h @@ -27,16 +27,8 @@ struct device; void __iowrite32_copy(void __iomem *to, const void *from, size_t count); void __iowrite64_copy(void __iomem *to, const void *from, size_t count); -#ifdef CONFIG_MMU int ioremap_page_range(unsigned long addr, unsigned long end, unsigned long phys_addr, pgprot_t prot); -#else -static inline int ioremap_page_range(unsigned long addr, unsigned long end, - unsigned long phys_addr, pgprot_t prot) -{ - return 0; -} -#endif /* * Managed iomap interface diff --git a/trunk/include/linux/major.h b/trunk/include/linux/major.h index 7e7c9093919a..0a74c52924c9 100644 --- a/trunk/include/linux/major.h +++ b/trunk/include/linux/major.h @@ -152,8 +152,6 @@ #define USB_ACM_AUX_MAJOR 167 #define USB_CHAR_MAJOR 180 -#define MMC_BLOCK_MAJOR 179 - #define VXVM_MAJOR 199 /* VERITAS volume i/o driver */ #define VXSPEC_MAJOR 200 /* VERITAS volume config driver */ #define VXDMP_MAJOR 201 /* VERITAS volume multipath driver */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 3b1fbf49fa7d..ccd85e4d3b8f 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1288,7 +1288,6 @@ #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 #define PCI_DEVICE_ID_VIA_P4M890 0x0327 -#define PCI_DEVICE_ID_VIA_VT3324 0x0324 #define PCI_DEVICE_ID_VIA_VT3336 0x0336 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index c6c1f4a120e3..ea27065e80e6 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -60,8 +60,7 @@ struct kmem_cache { #define KMALLOC_SHIFT_LOW 3 #ifdef CONFIG_LARGE_ALLOCS -#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT) =< 25 ? \ - (MAX_ORDER + PAGE_SHIFT - 1) : 25) +#define KMALLOC_SHIFT_HIGH 25 #else #if !defined(CONFIG_MMU) || NR_CPUS > 512 || MAX_NUMNODES > 256 #define KMALLOC_SHIFT_HIGH 20 @@ -88,9 +87,6 @@ static inline int kmalloc_index(int size) */ WARN_ON_ONCE(size == 0); - if (size > (1 << KMALLOC_SHIFT_HIGH)) - return -1; - if (size > 64 && size <= 96) return 1; if (size > 128 && size <= 192) diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 74cc0fc6bb81..6c61263ff96d 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -311,7 +311,6 @@ int audit_match_class(int class, unsigned syscall) return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); } -#ifdef CONFIG_AUDITSYSCALL static inline int audit_match_class_bits(int class, u32 *mask) { int i; @@ -348,7 +347,6 @@ static int audit_match_signal(struct audit_entry *entry) return 1; } } -#endif /* Common user-space to kernel rule translation. */ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) diff --git a/trunk/kernel/power/main.c b/trunk/kernel/power/main.c index b98b80ccf437..40d56a31245e 100644 --- a/trunk/kernel/power/main.c +++ b/trunk/kernel/power/main.c @@ -97,26 +97,25 @@ static int suspend_prepare(suspend_state_t state) } } + if (pm_ops->prepare) { + if ((error = pm_ops->prepare(state))) + goto Thaw; + } + suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Some devices failed to suspend\n"); - goto Resume_console; + goto Resume_devices; } - if (pm_ops->prepare) { - if ((error = pm_ops->prepare(state))) - goto Resume_devices; - } - error = disable_nonboot_cpus(); if (!error) return 0; enable_nonboot_cpus(); - pm_finish(state); Resume_devices: + pm_finish(state); device_resume(); - Resume_console: resume_console(); Thaw: thaw_processes(); diff --git a/trunk/kernel/time/clocksource.c b/trunk/kernel/time/clocksource.c index 51b6a6a6158c..3db5c3c460d7 100644 --- a/trunk/kernel/time/clocksource.c +++ b/trunk/kernel/time/clocksource.c @@ -74,7 +74,7 @@ static struct clocksource *watchdog; static struct timer_list watchdog_timer; static DEFINE_SPINLOCK(watchdog_lock); static cycle_t watchdog_last; -static unsigned long watchdog_resumed; +static int watchdog_resumed; /* * Interval: 0.5sec Threshold: 0.0625s @@ -104,7 +104,9 @@ static void clocksource_watchdog(unsigned long data) spin_lock(&watchdog_lock); - resumed = test_and_clear_bit(0, &watchdog_resumed); + resumed = watchdog_resumed; + if (unlikely(resumed)) + watchdog_resumed = 0; wdnow = watchdog->read(); wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask); @@ -149,7 +151,9 @@ static void clocksource_watchdog(unsigned long data) } static void clocksource_resume_watchdog(void) { - set_bit(0, &watchdog_resumed); + spin_lock(&watchdog_lock); + watchdog_resumed = 1; + spin_unlock(&watchdog_lock); } static void clocksource_check_watchdog(struct clocksource *cs) diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index 3d1042f82a68..f9217bf644f6 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -273,8 +273,6 @@ static int timekeeping_resume(struct sys_device *dev) unsigned long flags; unsigned long now = read_persistent_clock(); - clocksource_resume(); - write_seqlock_irqsave(&xtime_lock, flags); if (now && (now > timekeeping_suspend_time)) { diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 5ec5490f8d85..a6c580ac084b 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -1499,6 +1499,8 @@ unregister_time_interpolator(struct time_interpolator *ti) prev = &curr->next; } + clocksource_resume(); + write_seqlock_irqsave(&xtime_lock, flags); if (ti == time_interpolator) { /* we lost the best time-interpolator: */ diff --git a/trunk/mm/Kconfig b/trunk/mm/Kconfig index 8ac412b45f18..a17da8bafe62 100644 --- a/trunk/mm/Kconfig +++ b/trunk/mm/Kconfig @@ -166,5 +166,5 @@ config ZONE_DMA_FLAG config NR_QUICK int depends on QUICKLIST - default "2" if (SUPERH && !SUPERH64) + default "2" if SUPERH default "1" diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index edb1b0b5cc8d..7b48b2ad00e7 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -670,8 +670,7 @@ struct page *find_or_create_page(struct address_space *mapping, page = find_lock_page(mapping, index); if (!page) { if (!cached_page) { - cached_page = - __page_cache_alloc(gfp_mask); + cached_page = alloc_page(gfp_mask); if (!cached_page) return NULL; } diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 5e3e8bc9838f..b39c8a69a4ff 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -2522,7 +2522,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, struct kmem_cache *s; down_write(&slub_lock); - s = find_mergeable(size, align, flags, ctor, dtor); + s = find_mergeable(size, align, flags, dtor, ctor); if (s) { s->refcount++; /* diff --git a/trunk/net/ipv4/proc.c b/trunk/net/ipv4/proc.c index cdbc6c135849..37ab5802ca08 100644 --- a/trunk/net/ipv4/proc.c +++ b/trunk/net/ipv4/proc.c @@ -109,17 +109,6 @@ static const struct snmp_mib snmp4_ipstats_list[] = { SNMP_MIB_SENTINEL }; -/* Following RFC4293 items are displayed in /proc/net/netstat */ -static const struct snmp_mib snmp4_ipextstats_list[] = { - SNMP_MIB_ITEM("InNoRoutes", IPSTATS_MIB_INNOROUTES), - SNMP_MIB_ITEM("InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS), - SNMP_MIB_ITEM("InMcastPkts", IPSTATS_MIB_INMCASTPKTS), - SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), - SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), - SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), - SNMP_MIB_SENTINEL -}; - static const struct snmp_mib snmp4_icmp_list[] = { SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), @@ -349,16 +338,6 @@ static int netstat_seq_show(struct seq_file *seq, void *v) snmp_fold_field((void **)net_statistics, snmp4_net_list[i].entry)); - seq_puts(seq, "\nIpExt:"); - for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) - seq_printf(seq, " %s", snmp4_ipextstats_list[i].name); - - seq_puts(seq, "\nIpExt:"); - for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) - seq_printf(seq, " %lu", - snmp_fold_field((void **)ip_statistics, - snmp4_ipextstats_list[i].entry)); - seq_putc(seq, '\n'); return 0; } diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 30a5cb1b203e..be0ee8a34f9b 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb) IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); hdr = ipv6_hdr(skb); - deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || + deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); /* diff --git a/trunk/net/sched/sch_prio.c b/trunk/net/sched/sch_prio.c index 6d7542c26e47..269a6e17c6c4 100644 --- a/trunk/net/sched/sch_prio.c +++ b/trunk/net/sched/sch_prio.c @@ -75,7 +75,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) band = res.classid; } band = TC_H_MIN(band) - 1; - if (band >= q->bands) + if (band > q->bands) return q->queues[q->prio2band[0]]; return q->queues[band]; diff --git a/trunk/net/xfrm/xfrm_hash.c b/trunk/net/xfrm/xfrm_hash.c index 55ab5792af56..37643bb8768a 100644 --- a/trunk/net/xfrm/xfrm_hash.c +++ b/trunk/net/xfrm/xfrm_hash.c @@ -22,8 +22,7 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz) n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL); else n = (struct hlist_head *) - __get_free_pages(GFP_KERNEL | __GFP_NOWARN, - get_order(sz)); + __get_free_pages(GFP_KERNEL, get_order(sz)); if (n) memset(n, 0, sz); diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index d0882e53b6fc..95271e8426a1 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -796,10 +796,6 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, struct hlist_head *chain; struct hlist_node *entry; - *err = -ENOENT; - if (xfrm_policy_id2dir(id) != dir) - return NULL; - *err = 0; write_lock_bh(&xfrm_policy_lock); chain = xfrm_policy_byidx + idx_hash(id);