From 5cd2502ce547505f2f85d963424a3f2801dfae6a Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 15 Sep 2005 12:30:11 +0100 Subject: [PATCH] --- yaml --- r: 8982 b: refs/heads/master c: fea2efe3bba15f0aa8f840fbe052699808187cb6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/i386/Kconfig | 5 + trunk/arch/i386/lib/Makefile | 1 + trunk/arch/i386/lib/dec_and_lock.c | 42 ++++++ trunk/arch/ia64/Kconfig | 5 + trunk/arch/ia64/lib/Makefile | 1 + trunk/arch/ia64/lib/dec_and_lock.c | 42 ++++++ trunk/arch/m32r/Kconfig | 5 + trunk/arch/mips/Kconfig | 4 + trunk/arch/mips/lib/Makefile | 2 +- trunk/arch/mips/lib/dec_and_lock.c | 47 +++++++ trunk/arch/ppc/Kconfig | 4 + trunk/arch/ppc/lib/Makefile | 2 +- trunk/arch/ppc/lib/dec_and_lock.c | 38 ++++++ trunk/arch/ppc64/Kconfig | 4 + trunk/arch/ppc64/kernel/head.S | 6 +- trunk/arch/ppc64/lib/Makefile | 2 +- trunk/arch/ppc64/lib/dec_and_lock.c | 47 +++++++ trunk/arch/sparc64/Kconfig.debug | 8 ++ trunk/arch/sparc64/kernel/sparc64_ksyms.c | 3 + trunk/arch/sparc64/lib/Makefile | 2 + trunk/arch/sparc64/lib/dec_and_lock.S | 80 +++++++++++ trunk/arch/x86_64/Kconfig | 5 + trunk/arch/x86_64/kernel/x8664_ksyms.c | 4 + trunk/arch/x86_64/lib/Makefile | 2 + trunk/arch/x86_64/lib/dec_and_lock.c | 40 ++++++ trunk/arch/xtensa/Kconfig | 4 + trunk/drivers/char/epca.c | 84 ++++++------ trunk/drivers/char/epca.h | 12 +- trunk/drivers/char/vt.c | 5 +- trunk/drivers/net/8139cp.c | 46 +++---- trunk/drivers/net/bonding/bond_main.c | 3 - trunk/drivers/net/spider_net.c | 4 - trunk/drivers/s390/net/qeth.h | 4 +- trunk/drivers/s390/net/qeth_main.c | 133 ++++++++++--------- trunk/drivers/s390/net/qeth_sys.c | 17 +-- trunk/drivers/scsi/libata-core.c | 37 ++---- trunk/drivers/video/console/vgacon.c | 4 +- trunk/drivers/video/savage/savagefb-i2c.c | 11 +- trunk/drivers/video/savage/savagefb.h | 4 + trunk/drivers/video/savage/savagefb_driver.c | 11 +- trunk/fs/compat.c | 4 - trunk/include/asm-arm/arch-aaec2000/memory.h | 4 - trunk/include/asm-arm/arch-iop3xx/memory.h | 2 - trunk/include/asm-arm/arch-lh7a40x/memory.h | 4 - trunk/include/asm-arm/arch-omap/memory.h | 1 - trunk/include/asm-arm/arch-pxa/memory.h | 4 - trunk/include/asm-arm/arch-sa1100/memory.h | 4 - trunk/include/linux/netlink.h | 1 - trunk/include/net/ip_vs.h | 3 - trunk/lib/dec_and_lock.c | 35 ----- trunk/net/bridge/br_netfilter.c | 8 +- trunk/net/ipv4/igmp.c | 2 +- trunk/net/ipv4/ipvs/ip_vs_conn.c | 43 +----- trunk/net/ipv4/ipvs/ip_vs_core.c | 16 +-- trunk/net/ipv4/ipvs/ip_vs_sync.c | 20 +-- trunk/net/ipv4/tcp_input.c | 16 +-- trunk/net/ipv4/tcp_output.c | 2 - trunk/net/ipv6/mcast.c | 2 +- trunk/net/ipv6/udp.c | 5 +- 60 files changed, 614 insertions(+), 344 deletions(-) create mode 100644 trunk/arch/i386/lib/dec_and_lock.c create mode 100644 trunk/arch/ia64/lib/dec_and_lock.c create mode 100644 trunk/arch/mips/lib/dec_and_lock.c create mode 100644 trunk/arch/ppc/lib/dec_and_lock.c create mode 100644 trunk/arch/ppc64/lib/dec_and_lock.c create mode 100644 trunk/arch/sparc64/lib/dec_and_lock.S create mode 100644 trunk/arch/x86_64/lib/dec_and_lock.c diff --git a/[refs] b/[refs] index 73552e89e6cc..ee96722fb323 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bc9a5154a24d16d41cc79dbf1442de34454bc7db +refs/heads/master: fea2efe3bba15f0aa8f840fbe052699808187cb6 diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index d2703cda61ea..b22f003eaa6d 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -908,6 +908,11 @@ config IRQBALANCE The default yes will allow the kernel to do irq load balancing. Saying no will keep the kernel from doing irq load balancing. +config HAVE_DEC_LOCK + bool + depends on (SMP || PREEMPT) && X86_CMPXCHG + default y + # turning this on wastes a bunch of space. # Summit needs it only when NUMA is on config BOOT_IOREMAP diff --git a/trunk/arch/i386/lib/Makefile b/trunk/arch/i386/lib/Makefile index 914933e9ec3d..7b1932d20f96 100644 --- a/trunk/arch/i386/lib/Makefile +++ b/trunk/arch/i386/lib/Makefile @@ -7,3 +7,4 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o +lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff --git a/trunk/arch/i386/lib/dec_and_lock.c b/trunk/arch/i386/lib/dec_and_lock.c new file mode 100644 index 000000000000..8b81b2524fa6 --- /dev/null +++ b/trunk/arch/i386/lib/dec_and_lock.c @@ -0,0 +1,42 @@ +/* + * x86 version of "atomic_dec_and_lock()" using + * the atomic "cmpxchg" instruction. + * + * (For CPU's lacking cmpxchg, we use the slow + * generic version, and this one never even gets + * compiled). + */ + +#include +#include +#include + +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + +repeat: + counter = atomic_read(atomic); + newcount = counter-1; + + if (!newcount) + goto slow_path; + + asm volatile("lock; cmpxchgl %1,%2" + :"=a" (newcount) + :"r" (newcount), "m" (atomic->counter), "0" (counter)); + + /* If the above failed, "eax" will have changed */ + if (newcount != counter) + goto repeat; + return 0; + +slow_path: + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} +EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 945c15a0722b..ed25d66c8d50 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -298,6 +298,11 @@ config PREEMPT source "mm/Kconfig" +config HAVE_DEC_LOCK + bool + depends on (SMP || PREEMPT) + default y + config IA32_SUPPORT bool "Support for Linux/x86 binaries" help diff --git a/trunk/arch/ia64/lib/Makefile b/trunk/arch/ia64/lib/Makefile index cb1af597370b..799407e7726f 100644 --- a/trunk/arch/ia64/lib/Makefile +++ b/trunk/arch/ia64/lib/Makefile @@ -15,6 +15,7 @@ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o lib-$(CONFIG_MD_RAID5) += xor.o +lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED diff --git a/trunk/arch/ia64/lib/dec_and_lock.c b/trunk/arch/ia64/lib/dec_and_lock.c new file mode 100644 index 000000000000..c7ce92f968f1 --- /dev/null +++ b/trunk/arch/ia64/lib/dec_and_lock.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2003 Jerome Marchand, Bull S.A. + * Cleaned up by David Mosberger-Tang + * + * This file is released under the GPLv2, or at your option any later version. + * + * ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction. This + * code is an adaptation of the x86 version of "atomic_dec_and_lock()". + */ + +#include +#include +#include +#include + +/* + * Decrement REFCOUNT and if the count reaches zero, acquire the spinlock. Both of these + * operations have to be done atomically, so that the count doesn't drop to zero without + * acquiring the spinlock first. + */ +int +_atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock) +{ + int old, new; + + do { + old = atomic_read(refcount); + new = old - 1; + + if (unlikely (old == 1)) { + /* oops, we may be decrementing to zero, do it the slow way... */ + spin_lock(lock); + if (atomic_dec_and_test(refcount)) + return 1; + spin_unlock(lock); + return 0; + } + } while (cmpxchg(&refcount->counter, old, new) != old); + return 0; +} + +EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index 4d100f3886e1..1ef3987ebc6a 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -220,6 +220,11 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. +config HAVE_DEC_LOCK + bool + depends on (SMP || PREEMPT) + default n + config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 4cd724c05700..0eb71ac303af 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -1009,6 +1009,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config HAVE_DEC_LOCK + bool + default y + # # Select some configuration options automatically based on user selections. # diff --git a/trunk/arch/mips/lib/Makefile b/trunk/arch/mips/lib/Makefile index 037303412909..21b92b9dd013 100644 --- a/trunk/arch/mips/lib/Makefile +++ b/trunk/arch/mips/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial_copy.o memcpy.o promlib.o \ +lib-y += csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o \ strlen_user.o strncpy_user.o strnlen_user.o obj-y += iomap.o diff --git a/trunk/arch/mips/lib/dec_and_lock.c b/trunk/arch/mips/lib/dec_and_lock.c new file mode 100644 index 000000000000..fd82c84a93b7 --- /dev/null +++ b/trunk/arch/mips/lib/dec_and_lock.c @@ -0,0 +1,47 @@ +/* + * MIPS version of atomic_dec_and_lock() using cmpxchg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +/* + * This is an implementation of the notion of "decrement a + * reference count, and return locked if it decremented to zero". + * + * This implementation can be used on any architecture that + * has a cmpxchg, and where atomic->value is an int holding + * the value of the atomic (i.e. the high bits aren't used + * for a lock or anything like that). + */ +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + + for (;;) { + counter = atomic_read(atomic); + newcount = counter - 1; + if (!newcount) + break; /* do it the slow way */ + + newcount = cmpxchg(&atomic->counter, counter, newcount); + if (newcount == counter) + return 0; + } + + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} + +EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index 776941c75672..347ea284140b 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -26,6 +26,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config HAVE_DEC_LOCK + bool + default y + config PPC bool default y diff --git a/trunk/arch/ppc/lib/Makefile b/trunk/arch/ppc/lib/Makefile index 50358e4ea159..f1e1fb4144f0 100644 --- a/trunk/arch/ppc/lib/Makefile +++ b/trunk/arch/ppc/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc-specific library files.. # -obj-y := checksum.o string.o strcase.o div64.o +obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o obj-$(CONFIG_8xx) += rheap.o obj-$(CONFIG_CPM2) += rheap.o diff --git a/trunk/arch/ppc/lib/dec_and_lock.c b/trunk/arch/ppc/lib/dec_and_lock.c new file mode 100644 index 000000000000..b18f0d9a00fc --- /dev/null +++ b/trunk/arch/ppc/lib/dec_and_lock.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +/* + * This is an implementation of the notion of "decrement a + * reference count, and return locked if it decremented to zero". + * + * This implementation can be used on any architecture that + * has a cmpxchg, and where atomic->value is an int holding + * the value of the atomic (i.e. the high bits aren't used + * for a lock or anything like that). + */ +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + + for (;;) { + counter = atomic_read(atomic); + newcount = counter - 1; + if (!newcount) + break; /* do it the slow way */ + + newcount = cmpxchg(&atomic->counter, counter, newcount); + if (newcount == counter) + return 0; + } + + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} + +EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/arch/ppc64/Kconfig b/trunk/arch/ppc64/Kconfig index c658650af429..deca68ad644a 100644 --- a/trunk/arch/ppc64/Kconfig +++ b/trunk/arch/ppc64/Kconfig @@ -28,6 +28,10 @@ config GENERIC_ISA_DMA bool default y +config HAVE_DEC_LOCK + bool + default y + config EARLY_PRINTK bool default y diff --git a/trunk/arch/ppc64/kernel/head.S b/trunk/arch/ppc64/kernel/head.S index 72c61041151a..58c314738c99 100644 --- a/trunk/arch/ppc64/kernel/head.S +++ b/trunk/arch/ppc64/kernel/head.S @@ -1649,7 +1649,7 @@ _GLOBAL(__secondary_start) ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ - beq 98f /* branch if result is 0 */ + bne 98f mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ @@ -1813,7 +1813,7 @@ _STATIC(start_here_multiplatform) ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ - beq 98f /* branch if result is 0 */ + bne 98f mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ @@ -1834,7 +1834,7 @@ _STATIC(start_here_multiplatform) lwz r3,PLATFORM(r3) /* r3 = platform flags */ /* Test if bit 0 is set (LPAR bit) */ andi. r3,r3,PLATFORM_LPAR - bne 98f /* branch if result is !0 */ + bne 98f LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ diff --git a/trunk/arch/ppc64/lib/Makefile b/trunk/arch/ppc64/lib/Makefile index 0b6e967de948..76fbfa9f706f 100644 --- a/trunk/arch/ppc64/lib/Makefile +++ b/trunk/arch/ppc64/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc64-specific library files.. # -lib-y := checksum.o string.o strcase.o +lib-y := checksum.o dec_and_lock.o string.o strcase.o lib-y += copypage.o memcpy.o copyuser.o usercopy.o # Lock primitives are defined as no-ops in include/linux/spinlock.h diff --git a/trunk/arch/ppc64/lib/dec_and_lock.c b/trunk/arch/ppc64/lib/dec_and_lock.c new file mode 100644 index 000000000000..7b9d4da5cf92 --- /dev/null +++ b/trunk/arch/ppc64/lib/dec_and_lock.c @@ -0,0 +1,47 @@ +/* + * ppc64 version of atomic_dec_and_lock() using cmpxchg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +/* + * This is an implementation of the notion of "decrement a + * reference count, and return locked if it decremented to zero". + * + * This implementation can be used on any architecture that + * has a cmpxchg, and where atomic->value is an int holding + * the value of the atomic (i.e. the high bits aren't used + * for a lock or anything like that). + */ +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + + for (;;) { + counter = atomic_read(atomic); + newcount = counter - 1; + if (!newcount) + break; /* do it the slow way */ + + newcount = cmpxchg(&atomic->counter, counter, newcount); + if (newcount == counter) + return 0; + } + + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} + +EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/arch/sparc64/Kconfig.debug b/trunk/arch/sparc64/Kconfig.debug index af0e9411b83e..cd8d39fb954d 100644 --- a/trunk/arch/sparc64/Kconfig.debug +++ b/trunk/arch/sparc64/Kconfig.debug @@ -33,6 +33,14 @@ config DEBUG_BOOTMEM depends on DEBUG_KERNEL bool "Debug BOOTMEM initialization" +# We have a custom atomic_dec_and_lock() implementation but it's not +# compatible with spinlock debugging so we need to fall back on +# the generic version in that case. +config HAVE_DEC_LOCK + bool + depends on SMP && !DEBUG_SPINLOCK + default y + config MCOUNT bool depends on STACK_DEBUG diff --git a/trunk/arch/sparc64/kernel/sparc64_ksyms.c b/trunk/arch/sparc64/kernel/sparc64_ksyms.c index fb7a5370dbfc..cbb5e59824e5 100644 --- a/trunk/arch/sparc64/kernel/sparc64_ksyms.c +++ b/trunk/arch/sparc64/kernel/sparc64_ksyms.c @@ -163,6 +163,9 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); +#ifdef CONFIG_SMP +EXPORT_SYMBOL(_atomic_dec_and_lock); +#endif /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); diff --git a/trunk/arch/sparc64/lib/Makefile b/trunk/arch/sparc64/lib/Makefile index c295806500f7..d968aebe83b2 100644 --- a/trunk/arch/sparc64/lib/Makefile +++ b/trunk/arch/sparc64/lib/Makefile @@ -14,4 +14,6 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \ copy_in_user.o user_fixup.o memmove.o \ mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o +lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o + obj-y += iomap.o diff --git a/trunk/arch/sparc64/lib/dec_and_lock.S b/trunk/arch/sparc64/lib/dec_and_lock.S new file mode 100644 index 000000000000..8ee288dd0afc --- /dev/null +++ b/trunk/arch/sparc64/lib/dec_and_lock.S @@ -0,0 +1,80 @@ +/* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $ + * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" + * using cas and ldstub instructions. + * + * Copyright (C) 2000 David S. Miller (davem@redhat.com) + */ +#include +#include + + .text + .align 64 + + /* CAS basically works like this: + * + * void CAS(MEM, REG1, REG2) + * { + * START_ATOMIC(); + * if (*(MEM) == REG1) { + * TMP = *(MEM); + * *(MEM) = REG2; + * REG2 = TMP; + * } else + * REG2 = *(MEM); + * END_ATOMIC(); + * } + */ + + .globl _atomic_dec_and_lock +_atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */ +loop1: lduw [%o0], %g2 + subcc %g2, 1, %g7 + be,pn %icc, start_to_zero + nop +nzero: cas [%o0], %g2, %g7 + cmp %g2, %g7 + bne,pn %icc, loop1 + mov 0, %g1 + +out: + membar #StoreLoad | #StoreStore + retl + mov %g1, %o0 +start_to_zero: +#ifdef CONFIG_PREEMPT + ldsw [%g6 + TI_PRE_COUNT], %g3 + add %g3, 1, %g3 + stw %g3, [%g6 + TI_PRE_COUNT] +#endif +to_zero: + ldstub [%o1], %g3 + membar #StoreLoad | #StoreStore + brnz,pn %g3, spin_on_lock + nop +loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ + cmp %g2, %g7 + + be,pt %icc, out + mov 1, %g1 + lduw [%o0], %g2 + subcc %g2, 1, %g7 + be,pn %icc, loop2 + nop + membar #StoreStore | #LoadStore + stb %g0, [%o1] +#ifdef CONFIG_PREEMPT + ldsw [%g6 + TI_PRE_COUNT], %g3 + sub %g3, 1, %g3 + stw %g3, [%g6 + TI_PRE_COUNT] +#endif + + b,pt %xcc, nzero + nop +spin_on_lock: + ldub [%o1], %g3 + membar #LoadLoad + brnz,pt %g3, spin_on_lock + nop + ba,pt %xcc, to_zero + nop + nop diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 0969d570f3b5..e63323e03ea9 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -277,6 +277,11 @@ source "mm/Kconfig" config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y +config HAVE_DEC_LOCK + bool + depends on SMP + default y + config NR_CPUS int "Maximum number of CPUs (2-256)" range 2 256 diff --git a/trunk/arch/x86_64/kernel/x8664_ksyms.c b/trunk/arch/x86_64/kernel/x8664_ksyms.c index fd99ddd009bc..68ec03070e5a 100644 --- a/trunk/arch/x86_64/kernel/x8664_ksyms.c +++ b/trunk/arch/x86_64/kernel/x8664_ksyms.c @@ -178,6 +178,10 @@ EXPORT_SYMBOL(rwsem_down_write_failed_thunk); EXPORT_SYMBOL(empty_zero_page); +#ifdef CONFIG_HAVE_DEC_LOCK +EXPORT_SYMBOL(_atomic_dec_and_lock); +#endif + EXPORT_SYMBOL(die_chain); EXPORT_SYMBOL(register_die_notifier); diff --git a/trunk/arch/x86_64/lib/Makefile b/trunk/arch/x86_64/lib/Makefile index bba5db6cebd6..6b26a1c1e9ff 100644 --- a/trunk/arch/x86_64/lib/Makefile +++ b/trunk/arch/x86_64/lib/Makefile @@ -10,3 +10,5 @@ lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ thunk.o clear_page.o copy_page.o bitstr.o bitops.o lib-y += memcpy.o memmove.o memset.o copy_user.o + +lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff --git a/trunk/arch/x86_64/lib/dec_and_lock.c b/trunk/arch/x86_64/lib/dec_and_lock.c new file mode 100644 index 000000000000..ab43394dc775 --- /dev/null +++ b/trunk/arch/x86_64/lib/dec_and_lock.c @@ -0,0 +1,40 @@ +/* + * x86 version of "atomic_dec_and_lock()" using + * the atomic "cmpxchg" instruction. + * + * (For CPU's lacking cmpxchg, we use the slow + * generic version, and this one never even gets + * compiled). + */ + +#include +#include + +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + +repeat: + counter = atomic_read(atomic); + newcount = counter-1; + + if (!newcount) + goto slow_path; + + asm volatile("lock; cmpxchgl %1,%2" + :"=a" (newcount) + :"r" (newcount), "m" (atomic->counter), "0" (counter)); + + /* If the above failed, "eax" will have changed */ + if (newcount != counter) + goto repeat; + return 0; + +slow_path: + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 7e841aa2a4aa..2b6257bec4c3 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -26,6 +26,10 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config HAVE_DEC_LOCK + bool + default y + config GENERIC_HARDIRQS bool default y diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index 407708a001e4..58d3738a2b7f 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -534,7 +534,7 @@ static void shutdown(struct channel *ch) unsigned long flags; struct tty_struct *tty; - struct board_chan __iomem *bc; + struct board_chan *bc; if (!(ch->asyncflags & ASYNC_INITIALIZED)) return; @@ -618,7 +618,7 @@ static int pc_write(struct tty_struct * tty, struct channel *ch; unsigned long flags; int remain; - struct board_chan __iomem *bc; + struct board_chan *bc; /* ---------------------------------------------------------------- pc_write is primarily called directly by the kernel routine @@ -685,7 +685,7 @@ static int pc_write(struct tty_struct * tty, ------------------------------------------------------------------- */ dataLen = min(bytesAvailable, dataLen); - memcpy_toio(ch->txptr + head, buf, dataLen); + memcpy(ch->txptr + head, buf, dataLen); buf += dataLen; head += dataLen; amountCopied += dataLen; @@ -726,7 +726,7 @@ static int pc_write_room(struct tty_struct *tty) struct channel *ch; unsigned long flags; unsigned int head, tail; - struct board_chan __iomem *bc; + struct board_chan *bc; remain = 0; @@ -773,7 +773,7 @@ static int pc_chars_in_buffer(struct tty_struct *tty) int remain; unsigned long flags; struct channel *ch; - struct board_chan __iomem *bc; + struct board_chan *bc; /* --------------------------------------------------------- verifyChannel returns the channel from the tty struct @@ -830,7 +830,7 @@ static void pc_flush_buffer(struct tty_struct *tty) unsigned int tail; unsigned long flags; struct channel *ch; - struct board_chan __iomem *bc; + struct board_chan *bc; /* --------------------------------------------------------- verifyChannel returns the channel from the tty struct if it is valid. This serves as a sanity check. @@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp) struct channel *ch; unsigned long flags; int line, retval, boardnum; - struct board_chan __iomem *bc; + struct board_chan *bc; unsigned int head; line = tty->index; @@ -1041,7 +1041,7 @@ static int pc_open(struct tty_struct *tty, struct file * filp) ch->statusflags = 0; /* Save boards current modem status */ - ch->imodem = readb(&bc->mstat); + ch->imodem = bc->mstat; /* ---------------------------------------------------------------- Set receive head and tail ptrs to each other. This indicates @@ -1399,10 +1399,10 @@ static void post_fep_init(unsigned int crd) { /* Begin post_fep_init */ int i; - void __iomem *memaddr; - struct global_data __iomem *gd; + unsigned char *memaddr; + struct global_data *gd; struct board_info *bd; - struct board_chan __iomem *bc; + struct board_chan *bc; struct channel *ch; int shrinkmem = 0, lowwater ; @@ -1461,7 +1461,7 @@ static void post_fep_init(unsigned int crd) 8 and 64 of these structures. -------------------------------------------------------------------- */ - bc = memaddr + CHANSTRUCT; + bc = (struct board_chan *)(memaddr + CHANSTRUCT); /* ------------------------------------------------------------------- The below assignment will set gd to point at the BEGINING of @@ -1470,7 +1470,7 @@ static void post_fep_init(unsigned int crd) pointer begins at 0xd10. ---------------------------------------------------------------------- */ - gd = memaddr + GLOBAL; + gd = (struct global_data *)(memaddr + GLOBAL); /* -------------------------------------------------------------------- XEPORTS (address 0xc22) points at the number of channels the @@ -1493,7 +1493,6 @@ static void post_fep_init(unsigned int crd) for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */ unsigned long flags; - u16 tseg, rseg; ch->brdchan = bc; ch->mailbox = gd; @@ -1554,53 +1553,50 @@ static void post_fep_init(unsigned int crd) shrinkmem = 0; } - tseg = readw(&bc->tseg); - rseg = readw(&bc->rseg); - switch (bd->type) { case PCIXEM: case PCIXRJ: case PCIXR: /* Cover all the 2MEG cards */ - ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); - ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); + ch->txptr = memaddr + (((bc->tseg) << 4) & 0x1fffff); + ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x1fffff); + ch->txwin = FEPWIN | ((bc->tseg) >> 11); + ch->rxwin = FEPWIN | ((bc->rseg) >> 11); break; case PCXEM: case EISAXEM: /* Cover all the 32K windowed cards */ /* Mask equal to window size - 1 */ - ch->txptr = memaddr + ((tseg << 4) & 0x7fff); - ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); + ch->txptr = memaddr + (((bc->tseg) << 4) & 0x7fff); + ch->rxptr = memaddr + (((bc->rseg) << 4) & 0x7fff); + ch->txwin = FEPWIN | ((bc->tseg) >> 11); + ch->rxwin = FEPWIN | ((bc->rseg) >> 11); break; case PCXEVE: case PCXE: - ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff); - ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); - ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff); - ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 ); + ch->txptr = memaddr + (((bc->tseg - bd->memory_seg) << 4) & 0x1fff); + ch->txwin = FEPWIN | ((bc->tseg - bd->memory_seg) >> 9); + ch->rxptr = memaddr + (((bc->rseg - bd->memory_seg) << 4) & 0x1fff); + ch->rxwin = FEPWIN | ((bc->rseg - bd->memory_seg) >>9 ); break; case PCXI: case PC64XE: - ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); - ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); + ch->txptr = memaddr + ((bc->tseg - bd->memory_seg) << 4); + ch->rxptr = memaddr + ((bc->rseg - bd->memory_seg) << 4); ch->txwin = ch->rxwin = 0; break; } /* End switch bd->type */ ch->txbufhead = 0; - ch->txbufsize = readw(&bc->tmax) + 1; + ch->txbufsize = bc->tmax + 1; ch->rxbufhead = 0; - ch->rxbufsize = readw(&bc->rmax) + 1; + ch->rxbufsize = bc->rmax + 1; lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); @@ -1722,11 +1718,11 @@ static void epcapoll(unsigned long ignored) static void doevent(int crd) { /* Begin doevent */ - void __iomem *eventbuf; + void *eventbuf; struct channel *ch, *chan0; static struct tty_struct *tty; struct board_info *bd; - struct board_chan __iomem *bc; + struct board_chan *bc; unsigned int tail, head; int event, channel; int mstat, lstat; @@ -1821,7 +1817,7 @@ static void doevent(int crd) static void fepcmd(struct channel *ch, int cmd, int word_or_byte, int byte2, int ncmds, int bytecmd) { /* Begin fepcmd */ - unchar __iomem *memaddr; + unchar *memaddr; unsigned int head, cmdTail, cmdStart, cmdMax; long count; int n; @@ -2004,7 +2000,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) unsigned int cmdHead; struct termios *ts; - struct board_chan __iomem *bc; + struct board_chan *bc; unsigned mval, hflow, cflag, iflag; bc = ch->brdchan; @@ -2014,7 +2010,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) ts = tty->termios; if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */ cmdHead = readw(&bc->rin); - writew(cmdHead, &bc->rout); + bc->rout = cmdHead; cmdHead = readw(&bc->tin); /* Changing baud in mid-stream transmission can be wonderful */ /* --------------------------------------------------------------- @@ -2120,7 +2116,7 @@ static void receive_data(struct channel *ch) unchar *rptr; struct termios *ts = NULL; struct tty_struct *tty; - struct board_chan __iomem *bc; + struct board_chan *bc; int dataToRead, wrapgap, bytesAvailable; unsigned int tail, head; unsigned int wrapmask; @@ -2158,7 +2154,7 @@ static void receive_data(struct channel *ch) --------------------------------------------------------------------- */ if (!tty || !ts || !(ts->c_cflag & CREAD)) { - writew(head, &bc->rout); + bc->rout = head; return; } @@ -2274,7 +2270,7 @@ static int info_ioctl(struct tty_struct *tty, struct file * file, static int pc_tiocmget(struct tty_struct *tty, struct file *file) { struct channel *ch = (struct channel *) tty->driver_data; - struct board_chan __iomem *bc; + struct board_chan *bc; unsigned int mstat, mflag = 0; unsigned long flags; @@ -2355,7 +2351,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, unsigned long flags; unsigned int mflag, mstat; unsigned char startc, stopc; - struct board_chan __iomem *bc; + struct board_chan *bc; struct channel *ch = (struct channel *) tty->driver_data; void __user *argp = (void __user *)arg; @@ -2637,7 +2633,7 @@ static void pc_start(struct tty_struct *tty) spin_lock_irqsave(&epca_lock, flags); /* Just in case output was resumed because of a change in Digi-flow */ if (ch->statusflags & TXSTOPPED) { /* Begin transmit resume requested */ - struct board_chan __iomem *bc; + struct board_chan *bc; globalwinon(ch); bc = ch->brdchan; if (ch->statusflags & LOWWAIT) @@ -2731,7 +2727,7 @@ void digi_send_break(struct channel *ch, int msec) static void setup_empty_event(struct tty_struct *tty, struct channel *ch) { /* Begin setup_empty_event */ - struct board_chan __iomem *bc = ch->brdchan; + struct board_chan *bc = ch->brdchan; globalwinon(ch); ch->statusflags |= EMPTYWAIT; diff --git a/trunk/drivers/char/epca.h b/trunk/drivers/char/epca.h index 456d6c8f94a8..20eeb5a70e1a 100644 --- a/trunk/drivers/char/epca.h +++ b/trunk/drivers/char/epca.h @@ -128,17 +128,17 @@ struct channel unsigned long c_cflag; unsigned long c_lflag; unsigned long c_oflag; - unsigned char __iomem *txptr; - unsigned char __iomem *rxptr; + unsigned char *txptr; + unsigned char *rxptr; unsigned char *tmp_buf; struct board_info *board; - struct board_chan __iomem *brdchan; + struct board_chan *brdchan; struct digi_struct digiext; struct tty_struct *tty; wait_queue_head_t open_wait; wait_queue_head_t close_wait; struct work_struct tqueue; - struct global_data __iomem *mailbox; + struct global_data *mailbox; }; struct board_info @@ -149,8 +149,8 @@ struct board_info unsigned short numports; unsigned long port; unsigned long membase; - void __iomem *re_map_port; - void __iomem *re_map_membase; + unsigned char __iomem *re_map_port; + unsigned char *re_map_membase; unsigned long memory_seg; void ( * memwinon ) (struct board_info *, unsigned int) ; void ( * memwinoff ) (struct board_info *, unsigned int) ; diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index e91268e86833..1e33cb032e07 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -810,14 +810,13 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) * from the top and bottom of cursor position */ old_origin += (vc->vc_y - new_rows/2) * old_row_size; - end = old_origin + (old_row_size * new_rows); + end = old_origin + new_screen_size; } } else /* * Cursor near the top, copy contents from the top of buffer */ - end = (old_rows > new_rows) ? old_origin + - (old_row_size * new_rows) : + end = (old_rows > new_rows) ? old_origin + new_screen_size : vc->vc_scr_end; update_attr(vc); diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index bc537440ca02..34b80de34fae 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -353,6 +353,8 @@ struct cp_private { struct net_device_stats net_stats; struct cp_extra_stats cp_stats; + struct cp_dma_stats *nic_stats; + dma_addr_t nic_stats_dma; unsigned rx_tail ____cacheline_aligned; struct cp_desc *rx_ring; @@ -1141,6 +1143,10 @@ static int cp_alloc_rings (struct cp_private *cp) cp->rx_ring = mem; cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; + mem += (CP_RING_BYTES - CP_STATS_SIZE); + cp->nic_stats = mem; + cp->nic_stats_dma = cp->ring_dma + (CP_RING_BYTES - CP_STATS_SIZE); + return cp_init_rings(cp); } @@ -1181,6 +1187,7 @@ static void cp_free_rings (struct cp_private *cp) pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); cp->rx_ring = NULL; cp->tx_ring = NULL; + cp->nic_stats = NULL; } static int cp_open (struct net_device *dev) @@ -1509,17 +1516,13 @@ static void cp_get_ethtool_stats (struct net_device *dev, struct ethtool_stats *estats, u64 *tmp_stats) { struct cp_private *cp = netdev_priv(dev); - struct cp_dma_stats *nic_stats; - dma_addr_t dma; int i; - nic_stats = pci_alloc_consistent(cp->pdev, sizeof(*nic_stats), &dma); - if (!nic_stats) - return; + memset(cp->nic_stats, 0, sizeof(struct cp_dma_stats)); /* begin NIC statistics dump */ - cpw32(StatsAddr + 4, (u64)dma >> 32); - cpw32(StatsAddr, ((u64)dma & DMA_32BIT_MASK) | DumpStats); + cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16); + cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats); cpr32(StatsAddr); for (i = 0; i < 1000; i++) { @@ -1529,27 +1532,24 @@ static void cp_get_ethtool_stats (struct net_device *dev, } cpw32(StatsAddr, 0); cpw32(StatsAddr + 4, 0); - cpr32(StatsAddr); i = 0; - tmp_stats[i++] = le64_to_cpu(nic_stats->tx_ok); - tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok); - tmp_stats[i++] = le64_to_cpu(nic_stats->tx_err); - tmp_stats[i++] = le32_to_cpu(nic_stats->rx_err); - tmp_stats[i++] = le16_to_cpu(nic_stats->rx_fifo); - tmp_stats[i++] = le16_to_cpu(nic_stats->frame_align); - tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_1col); - tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_mcol); - tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_phys); - tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_bcast); - tmp_stats[i++] = le32_to_cpu(nic_stats->rx_ok_mcast); - tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort); - tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_err); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_err); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->rx_fifo); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->frame_align); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_1col); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->tx_ok_mcol); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_phys); + tmp_stats[i++] = le64_to_cpu(cp->nic_stats->rx_ok_bcast); + tmp_stats[i++] = le32_to_cpu(cp->nic_stats->rx_ok_mcast); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_abort); + tmp_stats[i++] = le16_to_cpu(cp->nic_stats->tx_underrun); tmp_stats[i++] = cp->cp_stats.rx_frags; if (i != CP_NUM_STATS) BUG(); - - pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma); } static struct ethtool_ops cp_ethtool_ops = { diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index f8dedb623dc0..94c9f68dd16b 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -2879,7 +2879,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) * This target is not on a VLAN */ if (rt->u.dst.dev == bond->dev) { - ip_rt_put(rt); dprintk("basa: rtdev == bond->dev: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); @@ -2899,7 +2898,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) } if (vlan_id) { - ip_rt_put(rt); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], vlan->vlan_ip, vlan_id); continue; @@ -2911,7 +2909,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) bond->dev->name, NIPQUAD(fl.fl4_dst), rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); } - ip_rt_put(rt); } } diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index c796f41b4a52..4e19220473d0 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1817,10 +1817,6 @@ spider_net_setup_phy(struct spider_net_card *card) /* LEDs active in both modes, autosense prio = fiber */ spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f); - /* switch off fibre autoneg */ - spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0xfc01); - spider_net_write_phy(card->netdev, 1, 0x0b, 0x0004); - phy->def->ops->read_link(phy); pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half"); diff --git a/trunk/drivers/s390/net/qeth.h b/trunk/drivers/s390/net/qeth.h index 2ad4797ce024..3a0285669adf 100644 --- a/trunk/drivers/s390/net/qeth.h +++ b/trunk/drivers/s390/net/qeth.h @@ -24,7 +24,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.142 $" +#define VERSION_QETH_H "$Revision: 1.139 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -1172,7 +1172,7 @@ extern int qeth_realloc_buffer_pool(struct qeth_card *, int); extern int -qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types); +qeth_set_large_send(struct qeth_card *); extern void qeth_fill_header(struct qeth_card *, struct qeth_hdr *, diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index 86582cf1e19e..79c74f3a11f5 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $ + * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ * * 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 @@ -29,6 +29,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/*** + * eye catcher; just for debugging purposes + */ +void volatile +qeth_eyecatcher(void) +{ + return; +} #include #include @@ -72,7 +80,7 @@ #include "qeth_eddp.h" #include "qeth_tso.h" -#define VERSION_QETH_C "$Revision: 1.224 $" +#define VERSION_QETH_C "$Revision: 1.214 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -2751,9 +2759,11 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, queue->card->perf_stats.outbound_do_qdio_start_time; #endif if (rc){ + QETH_DBF_SPRINTF(trace, 0, "qeth_flush_buffers: do_QDIO " + "returned error (%i) on device %s.", + rc, CARD_DDEV_ID(queue->card)); QETH_DBF_TEXT(trace, 2, "flushbuf"); QETH_DBF_TEXT_(trace, 2, " err%d", rc); - QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card)); queue->card->stats.tx_errors += count; /* this must not happen under normal circumstances. if it * happens something is really wrong -> recover */ @@ -2899,8 +2909,11 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, QETH_DBF_TEXT(trace, 6, "qdouhdl"); if (status & QDIO_STATUS_LOOK_FOR_ERROR) { if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ - QETH_DBF_TEXT(trace, 2, "achkcond"); - QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card)); + QETH_DBF_SPRINTF(trace, 2, "On device %s: " + "received active check " + "condition (0x%08x).", + CARD_BUS_ID(card), status); + QETH_DBF_TEXT(trace, 2, "chkcond"); QETH_DBF_TEXT_(trace, 2, "%08x", status); netif_stop_queue(card->dev); qeth_schedule_recovery(card); @@ -3343,32 +3356,26 @@ qeth_halt_channel(struct qeth_channel *channel) static int qeth_halt_channels(struct qeth_card *card) { - int rc1 = 0, rc2=0, rc3 = 0; + int rc = 0; QETH_DBF_TEXT(trace,3,"haltchs"); - rc1 = qeth_halt_channel(&card->read); - rc2 = qeth_halt_channel(&card->write); - rc3 = qeth_halt_channel(&card->data); - if (rc1) - return rc1; - if (rc2) - return rc2; - return rc3; + if ((rc = qeth_halt_channel(&card->read))) + return rc; + if ((rc = qeth_halt_channel(&card->write))) + return rc; + return qeth_halt_channel(&card->data); } static int qeth_clear_channels(struct qeth_card *card) { - int rc1 = 0, rc2=0, rc3 = 0; + int rc = 0; QETH_DBF_TEXT(trace,3,"clearchs"); - rc1 = qeth_clear_channel(&card->read); - rc2 = qeth_clear_channel(&card->write); - rc3 = qeth_clear_channel(&card->data); - if (rc1) - return rc1; - if (rc2) - return rc2; - return rc3; + if ((rc = qeth_clear_channel(&card->read))) + return rc; + if ((rc = qeth_clear_channel(&card->write))) + return rc; + return qeth_clear_channel(&card->data); } static int @@ -3438,23 +3445,23 @@ qeth_mpc_initialize(struct qeth_card *card) } if ((rc = qeth_cm_enable(card))){ QETH_DBF_TEXT_(setup, 2, "2err%d", rc); - goto out_qdio; + return rc; } if ((rc = qeth_cm_setup(card))){ QETH_DBF_TEXT_(setup, 2, "3err%d", rc); - goto out_qdio; + return rc; } if ((rc = qeth_ulp_enable(card))){ QETH_DBF_TEXT_(setup, 2, "4err%d", rc); - goto out_qdio; + return rc; } if ((rc = qeth_ulp_setup(card))){ QETH_DBF_TEXT_(setup, 2, "5err%d", rc); - goto out_qdio; + return rc; } if ((rc = qeth_alloc_qdio_buffers(card))){ QETH_DBF_TEXT_(setup, 2, "5err%d", rc); - goto out_qdio; + return rc; } if ((rc = qeth_qdio_establish(card))){ QETH_DBF_TEXT_(setup, 2, "6err%d", rc); @@ -3788,16 +3795,12 @@ static inline int qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, struct qeth_hdr **hdr, int ipv) { - int rc; #ifdef CONFIG_QETH_VLAN u16 *tag; #endif QETH_DBF_TEXT(trace, 6, "prepskb"); - rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); - if (rc) - return rc; #ifdef CONFIG_QETH_VLAN if (card->vlangrp && vlan_tx_tag_present(*skb) && ((ipv == 6) || card->options.layer2) ) { @@ -4248,8 +4251,7 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, } static inline int -qeth_get_elements_no(struct qeth_card *card, void *hdr, - struct sk_buff *skb, int elems) +qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) { int elements_needed = 0; @@ -4259,10 +4261,9 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, if (elements_needed == 0 ) elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) + skb->len) >> PAGE_SHIFT); - if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ + if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ PRINT_ERR("qeth_do_send_packet: invalid size of " - "IP packet (Number=%d / Length=%d). Discarded.\n", - (elements_needed+elems), skb->len); + "IP packet. Discarded."); return 0; } return elements_needed; @@ -4274,7 +4275,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) int ipv = 0; int cast_type; struct qeth_qdio_out_q *queue; - struct qeth_hdr *hdr = NULL; + struct qeth_hdr *hdr; int elements_needed = 0; enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; struct qeth_eddp_context *ctx = NULL; @@ -4336,11 +4337,9 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) return -EINVAL; } } else { - int elems = qeth_get_elements_no(card,(void*) hdr, skb, - elements_needed); - if (!elems) + elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); + if (!elements_needed) return -EINVAL; - elements_needed += elems; } if (card->info.type != QETH_CARD_TYPE_IQD) @@ -4505,11 +4504,7 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries) QETH_DBF_TEXT(trace,3,"arpstnoe"); - /* - * currently GuestLAN only supports the ARP assist function - * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES; - * thus we say EOPNOTSUPP for this ARP function - */ + /* TODO: really not supported by GuestLAN? */ if (card->info.guestlan) return -EOPNOTSUPP; if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { @@ -4686,6 +4681,14 @@ qeth_arp_query(struct qeth_card *card, char *udata) QETH_DBF_TEXT(trace,3,"arpquery"); + /* + * currently GuestLAN does only deliver all zeros on query arp, + * even though arp processing is supported (according to IPA supp. + * funcs flags); since all zeros is no valueable information, + * we say EOPNOTSUPP for all ARP functions + */ + /*if (card->info.guestlan) + return -EOPNOTSUPP; */ if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ IPA_ARP_PROCESSING)) { PRINT_WARN("ARP processing not supported " @@ -4891,9 +4894,10 @@ qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry) QETH_DBF_TEXT(trace,3,"arpadent"); /* - * currently GuestLAN only supports the ARP assist function - * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY; - * thus we say EOPNOTSUPP for this ARP function + * currently GuestLAN does only deliver all zeros on query arp, + * even though arp processing is supported (according to IPA supp. + * funcs flags); since all zeros is no valueable information, + * we say EOPNOTSUPP for all ARP functions */ if (card->info.guestlan) return -EOPNOTSUPP; @@ -4933,9 +4937,10 @@ qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry QETH_DBF_TEXT(trace,3,"arprment"); /* - * currently GuestLAN only supports the ARP assist function - * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY; - * thus we say EOPNOTSUPP for this ARP function + * currently GuestLAN does only deliver all zeros on query arp, + * even though arp processing is supported (according to IPA supp. + * funcs flags); since all zeros is no valueable information, + * we say EOPNOTSUPP for all ARP functions */ if (card->info.guestlan) return -EOPNOTSUPP; @@ -4973,10 +4978,11 @@ qeth_arp_flush_cache(struct qeth_card *card) QETH_DBF_TEXT(trace,3,"arpflush"); /* - * currently GuestLAN only supports the ARP assist function - * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE; - * thus we say EOPNOTSUPP for this ARP function - */ + * currently GuestLAN does only deliver all zeros on query arp, + * even though arp processing is supported (according to IPA supp. + * funcs flags); since all zeros is no valueable information, + * we say EOPNOTSUPP for all ARP functions + */ if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) return -EOPNOTSUPP; if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { @@ -7032,16 +7038,14 @@ qeth_setrouting_v6(struct qeth_card *card) } int -qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) +qeth_set_large_send(struct qeth_card *card) { int rc = 0; - if (card->dev == NULL) { - card->options.large_send = type; + if (card->dev == NULL) return 0; - } + netif_stop_queue(card->dev); - card->options.large_send = type; switch (card->options.large_send) { case QETH_LARGE_SEND_EDDP: card->dev->features |= NETIF_F_TSO | NETIF_F_SG; @@ -7062,6 +7066,7 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); break; } + netif_wake_queue(card->dev); return rc; } @@ -8252,6 +8257,7 @@ qeth_init(void) { int rc=0; + qeth_eyecatcher(); PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n", version, VERSION_QETH_C, VERSION_QETH_H, VERSION_QETH_MPC_H, VERSION_QETH_MPC_C, @@ -8332,6 +8338,7 @@ __exit qeth_exit(void) printk("qeth: removed\n"); } +EXPORT_SYMBOL(qeth_eyecatcher); module_init(qeth_init); module_exit(qeth_exit); MODULE_AUTHOR("Frank Pavlic "); diff --git a/trunk/drivers/s390/net/qeth_sys.c b/trunk/drivers/s390/net/qeth_sys.c index dda105b73063..98bedb0cb387 100644 --- a/trunk/drivers/s390/net/qeth_sys.c +++ b/trunk/drivers/s390/net/qeth_sys.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $) + * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.51 $) * * Linux on zSeries OSA Express and HiperSockets support * This file contains code related to sysfs. @@ -20,7 +20,7 @@ #include "qeth_mpc.h" #include "qeth_fs.h" -const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $"; +const char *VERSION_QETH_SYS_C = "$Revision: 1.51 $"; /*****************************************************************************/ /* */ @@ -722,13 +722,10 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c if (!card) return -EINVAL; - if (card->info.type == QETH_CARD_TYPE_IQD) { - PRINT_WARN("Layer2 on Hipersockets is not supported! \n"); - return -EPERM; - } if (((card->state != CARD_STATE_DOWN) && - (card->state != CARD_STATE_RECOVER))) + (card->state != CARD_STATE_RECOVER)) || + (card->info.type != QETH_CARD_TYPE_OSAE)) return -EPERM; i = simple_strtoul(buf, &tmp, 16); @@ -774,7 +771,9 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con if (!card) return -EINVAL; + tmp = strsep((char **) &buf, "\n"); + if (!strcmp(tmp, "no")){ type = QETH_LARGE_SEND_NO; } else if (!strcmp(tmp, "EDDP")) { @@ -787,8 +786,10 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con } if (card->options.large_send == type) return count; - if ((rc = qeth_set_large_send(card, type))) + card->options.large_send = type; + if ((rc = qeth_set_large_send(card))) return rc; + return count; } diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index d92273cbe0de..5cc53cd9323e 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -2465,12 +2465,9 @@ static unsigned long ata_pio_poll(struct ata_port *ap) * * LOCKING: * None. (executing in kernel thread context) - * - * RETURNS: - * Non-zero if qc completed, zero otherwise. */ -static int ata_pio_complete (struct ata_port *ap) +static void ata_pio_complete (struct ata_port *ap) { struct ata_queued_cmd *qc; u8 drv_stat; @@ -2489,14 +2486,14 @@ static int ata_pio_complete (struct ata_port *ap) if (drv_stat & (ATA_BUSY | ATA_DRQ)) { ap->pio_task_state = PIO_ST_LAST_POLL; ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; - return 0; + return; } } drv_stat = ata_wait_idle(ap); if (!ata_ok(drv_stat)) { ap->pio_task_state = PIO_ST_ERR; - return 0; + return; } qc = ata_qc_from_tag(ap, ap->active_tag); @@ -2505,10 +2502,6 @@ static int ata_pio_complete (struct ata_port *ap) ap->pio_task_state = PIO_ST_IDLE; ata_poll_qc_complete(qc, drv_stat); - - /* another command may start at this point */ - - return 1; } @@ -2716,7 +2709,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) next_sg: if (unlikely(qc->cursg >= qc->n_elem)) { - /* + /* * The end of qc->sg is reached and the device expects * more data to transfer. In order not to overrun qc->sg * and fulfill length specified in the byte count register, @@ -2728,7 +2721,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) unsigned int i; if (words) /* warning if bytes > 1 */ - printk(KERN_WARNING "ata%u: %u bytes trailing data\n", + printk(KERN_WARNING "ata%u: %u bytes trailing data\n", ap->id, bytes); for (i = 0; i < words; i++) @@ -2856,7 +2849,9 @@ static void ata_pio_block(struct ata_port *ap) if (is_atapi_taskfile(&qc->tf)) { /* no more data to transfer or unsupported ATAPI command */ if ((status & ATA_DRQ) == 0) { - ap->pio_task_state = PIO_ST_LAST; + ap->pio_task_state = PIO_ST_IDLE; + + ata_poll_qc_complete(qc, status); return; } @@ -2892,12 +2887,7 @@ static void ata_pio_error(struct ata_port *ap) static void ata_pio_task(void *_data) { struct ata_port *ap = _data; - unsigned long timeout; - int qc_completed; - -fsm_start: - timeout = 0; - qc_completed = 0; + unsigned long timeout = 0; switch (ap->pio_task_state) { case PIO_ST_IDLE: @@ -2908,7 +2898,7 @@ static void ata_pio_task(void *_data) break; case PIO_ST_LAST: - qc_completed = ata_pio_complete(ap); + ata_pio_complete(ap); break; case PIO_ST_POLL: @@ -2923,9 +2913,10 @@ static void ata_pio_task(void *_data) } if (timeout) - queue_delayed_work(ata_wq, &ap->pio_task, timeout); - else if (!qc_completed) - goto fsm_start; + queue_delayed_work(ata_wq, &ap->pio_task, + timeout); + else + queue_work(ata_wq, &ap->pio_task); } static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index 6ef6f7760e47..0705cd741411 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -1020,9 +1020,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) static int vgacon_resize(struct vc_data *c, unsigned int width, unsigned int height) { - if (width % 2 || width > ORIG_VIDEO_COLS || - height > (ORIG_VIDEO_LINES * vga_default_font_height)/ - c->vc_font.height) + if (width % 2 || width > ORIG_VIDEO_COLS || height > ORIG_VIDEO_LINES) return -EINVAL; if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */ diff --git a/trunk/drivers/video/savage/savagefb-i2c.c b/trunk/drivers/video/savage/savagefb-i2c.c index 3c98457783c4..959404ad68f4 100644 --- a/trunk/drivers/video/savage/savagefb-i2c.c +++ b/trunk/drivers/video/savage/savagefb-i2c.c @@ -274,13 +274,10 @@ int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid) if (!edid) { /* try to get from firmware */ - const u8 *e = fb_firmware_edid(info->device); - - if (e) { - edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (edid) - memcpy(edid, e, EDID_LENGTH); - } + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, fb_firmware_edid(info->device), + EDID_LENGTH); } if (out_edid) diff --git a/trunk/drivers/video/savage/savagefb.h b/trunk/drivers/video/savage/savagefb.h index ea17f7e0482c..d6f94742c9f2 100644 --- a/trunk/drivers/video/savage/savagefb.h +++ b/trunk/drivers/video/savage/savagefb.h @@ -60,6 +60,8 @@ #define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) +#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) || (chip == S3_PROSAVAGEDDR)) + /* Chip tags. These are used to group the adapters into * related families. */ @@ -72,6 +74,8 @@ typedef enum { S3_PROSAVAGE, S3_SUPERSAVAGE, S3_SAVAGE2000, + S3_PROSAVAGEDDR, + S3_TWISTER, S3_LAST } savage_chipset; diff --git a/trunk/drivers/video/savage/savagefb_driver.c b/trunk/drivers/video/savage/savagefb_driver.c index 7c285455c924..b5ca3ef8271f 100644 --- a/trunk/drivers/video/savage/savagefb_driver.c +++ b/trunk/drivers/video/savage/savagefb_driver.c @@ -1773,7 +1773,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par) } } - if (S3_SAVAGE_MOBILE_SERIES(par->chip) && !par->crtonly) + if (S3_SAVAGE_MOBILE_SERIES(par->chip) || + (S3_MOBILE_TWISTER_SERIES(par->chip) && !par->crtonly)) par->display_type = DISP_LCD; else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi)) par->display_type = DISP_DFP; @@ -1782,7 +1783,7 @@ static int __devinit savage_init_hw (struct savagefb_par *par) /* Check LCD panel parrmation */ - if (par->display_type == DISP_LCD) { + if (par->chip == S3_SAVAGE_MX) { unsigned char cr6b = VGArCR( 0x6b ); int panelX = (VGArSEQ (0x61) + @@ -1921,15 +1922,15 @@ static int __devinit savage_init_fb_info (struct fb_info *info, snprintf (info->fix.id, 16, "ProSavageKM"); break; case FB_ACCEL_S3TWISTER_P: - par->chip = S3_PROSAVAGE; + par->chip = S3_TWISTER; snprintf (info->fix.id, 16, "TwisterP"); break; case FB_ACCEL_S3TWISTER_K: - par->chip = S3_PROSAVAGE; + par->chip = S3_TWISTER; snprintf (info->fix.id, 16, "TwisterK"); break; case FB_ACCEL_PROSAVAGE_DDR: - par->chip = S3_PROSAVAGE; + par->chip = S3_PROSAVAGEDDR; snprintf (info->fix.id, 16, "ProSavageDDR"); break; case FB_ACCEL_PROSAVAGE_DDRK: diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index a719e158e002..ac3fb9ed8eea 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -44,8 +44,6 @@ #include #include #include -#include -#include #include /* siocdevprivate_ioctl */ @@ -1489,8 +1487,6 @@ int compat_do_execve(char * filename, /* execve success */ security_bprm_free(bprm); - acct_update_integrals(current); - update_mem_hiwater(current); kfree(bprm); return retval; } diff --git a/trunk/include/asm-arm/arch-aaec2000/memory.h b/trunk/include/asm-arm/arch-aaec2000/memory.h index 681b6a6171a1..79c90813bc3e 100644 --- a/trunk/include/asm-arm/arch-aaec2000/memory.h +++ b/trunk/include/asm-arm/arch-aaec2000/memory.h @@ -64,10 +64,6 @@ #define NODE_MAX_MEM_SHIFT 26 #define NODE_MAX_MEM_SIZE (1 << NODE_MAX_MEM_SHIFT) -#else - -#define PFN_TO_NID(addr) (0) - #endif /* CONFIG_DISCONTIGMEM */ #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/trunk/include/asm-arm/arch-iop3xx/memory.h b/trunk/include/asm-arm/arch-iop3xx/memory.h index dc4735cb0c10..45351f5cd904 100644 --- a/trunk/include/asm-arm/arch-iop3xx/memory.h +++ b/trunk/include/asm-arm/arch-iop3xx/memory.h @@ -36,6 +36,4 @@ #endif -#define PFN_TO_NID(addr) (0) - #endif diff --git a/trunk/include/asm-arm/arch-lh7a40x/memory.h b/trunk/include/asm-arm/arch-lh7a40x/memory.h index 7e2fea372663..c650e6feb9d5 100644 --- a/trunk/include/asm-arm/arch-lh7a40x/memory.h +++ b/trunk/include/asm-arm/arch-lh7a40x/memory.h @@ -85,10 +85,6 @@ (((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT) # endif -#else - -# define PFN_TO_NID(addr) (0) - #endif #endif diff --git a/trunk/include/asm-arm/arch-omap/memory.h b/trunk/include/asm-arm/arch-omap/memory.h index 84f81e315a25..ef32d61eec7a 100644 --- a/trunk/include/asm-arm/arch-omap/memory.h +++ b/trunk/include/asm-arm/arch-omap/memory.h @@ -86,6 +86,5 @@ #endif /* CONFIG_ARCH_OMAP1510 */ -#define PHYS_TO_NID(addr) (0) #endif diff --git a/trunk/include/asm-arm/arch-pxa/memory.h b/trunk/include/asm-arm/arch-pxa/memory.h index 217a80b820ff..58bad9748b5c 100644 --- a/trunk/include/asm-arm/arch-pxa/memory.h +++ b/trunk/include/asm-arm/arch-pxa/memory.h @@ -67,10 +67,6 @@ #define LOCAL_MAP_NR(addr) \ (((unsigned long)(addr) & 0x03ffffff) >> PAGE_SHIFT) -#else - -#define PFN_TO_NID(addr) (0) - #endif #endif diff --git a/trunk/include/asm-arm/arch-sa1100/memory.h b/trunk/include/asm-arm/arch-sa1100/memory.h index 32d3d5bde34d..8743ff5c1b23 100644 --- a/trunk/include/asm-arm/arch-sa1100/memory.h +++ b/trunk/include/asm-arm/arch-sa1100/memory.h @@ -99,10 +99,6 @@ __arch_adjust_zones(int node, unsigned long *size, unsigned long *holes) #define LOCAL_MAP_NR(addr) \ (((unsigned long)(addr) & 0x07ffffff) >> PAGE_SHIFT) -#else - -#define PFN_TO_NID(addr) (0) - #endif #endif diff --git a/trunk/include/linux/netlink.h b/trunk/include/linux/netlink.h index bdebdc564506..7bbd25970c9e 100644 --- a/trunk/include/linux/netlink.h +++ b/trunk/include/linux/netlink.h @@ -20,7 +20,6 @@ #define NETLINK_IP6_FW 13 #define NETLINK_DNRTMSG 14 /* DECnet routing messages */ #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ -#define NETLINK_GENERIC 16 #define MAX_LINKS 32 diff --git a/trunk/include/net/ip_vs.h b/trunk/include/net/ip_vs.h index 06b4235aa016..e426641c519f 100644 --- a/trunk/include/net/ip_vs.h +++ b/trunk/include/net/ip_vs.h @@ -84,7 +84,6 @@ #define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */ #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ -#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ /* Move it to better place one day, for now keep it unique */ #define NFC_IPVS_PROPERTY 0x10000 @@ -740,8 +739,6 @@ enum { extern struct ip_vs_conn *ip_vs_conn_in_get (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); -extern struct ip_vs_conn *ip_vs_ct_in_get -(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); extern struct ip_vs_conn *ip_vs_conn_out_get (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); diff --git a/trunk/lib/dec_and_lock.c b/trunk/lib/dec_and_lock.c index 305a9663aee3..2377af057d09 100644 --- a/trunk/lib/dec_and_lock.c +++ b/trunk/lib/dec_and_lock.c @@ -1,41 +1,7 @@ #include #include #include -#include -#ifdef __HAVE_ARCH_CMPXCHG -/* - * This is an implementation of the notion of "decrement a - * reference count, and return locked if it decremented to zero". - * - * This implementation can be used on any architecture that - * has a cmpxchg, and where atomic->value is an int holding - * the value of the atomic (i.e. the high bits aren't used - * for a lock or anything like that). - */ -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - - for (;;) { - counter = atomic_read(atomic); - newcount = counter - 1; - if (!newcount) - break; /* do it the slow way */ - - newcount = cmpxchg(&atomic->counter, counter, newcount); - if (newcount == counter) - return 0; - } - - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} -#else /* * This is an architecture-neutral, but slow, * implementation of the notion of "decrement @@ -67,6 +33,5 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) spin_unlock(lock); return 0; } -#endif EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index d8e36b775125..2d52fee63a8c 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -214,11 +214,9 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) .tos = RT_TOS(iph->tos)} }, .proto = 0}; if (!ip_route_output_key(&rt, &fl)) { - /* - Bridged-and-DNAT'ed traffic doesn't - * require ip_forwarding. - * - Deal with redirected traffic. */ - if (((struct dst_entry *)rt)->dev == dev || - rt->rt_type == RTN_LOCAL) { + /* Bridged-and-DNAT'ed traffic doesn't + * require ip_forwarding. */ + if (((struct dst_entry *)rt)->dev == dev) { skb->dst = (struct dst_entry *)rt; goto bridged_dnat; } diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 70c44e4c3ceb..44607f4767b8 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -1603,7 +1603,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc) } pmc->sources = NULL; pmc->sfmode = MCAST_EXCLUDE; - pmc->sfcount[MCAST_INCLUDE] = 0; + pmc->sfcount[MCAST_EXCLUDE] = 0; pmc->sfcount[MCAST_EXCLUDE] = 1; } diff --git a/trunk/net/ipv4/ipvs/ip_vs_conn.c b/trunk/net/ipv4/ipvs/ip_vs_conn.c index f828fa2eb7de..e11952ea17af 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_conn.c +++ b/trunk/net/ipv4/ipvs/ip_vs_conn.c @@ -196,7 +196,6 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { if (s_addr==cp->caddr && s_port==cp->cport && d_port==cp->vport && d_addr==cp->vaddr && - ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && protocol==cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); @@ -228,40 +227,6 @@ struct ip_vs_conn *ip_vs_conn_in_get return cp; } -/* Get reference to connection template */ -struct ip_vs_conn *ip_vs_ct_in_get -(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) -{ - unsigned hash; - struct ip_vs_conn *cp; - - hash = ip_vs_conn_hashkey(protocol, s_addr, s_port); - - ct_read_lock(hash); - - list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (s_addr==cp->caddr && s_port==cp->cport && - d_port==cp->vport && d_addr==cp->vaddr && - cp->flags & IP_VS_CONN_F_TEMPLATE && - protocol==cp->protocol) { - /* HIT */ - atomic_inc(&cp->refcnt); - goto out; - } - } - cp = NULL; - - out: - ct_read_unlock(hash); - - IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", - ip_vs_proto_name(protocol), - NIPQUAD(s_addr), ntohs(s_port), - NIPQUAD(d_addr), ntohs(d_port), - cp?"hit":"not hit"); - - return cp; -} /* * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. @@ -402,7 +367,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) atomic_read(&dest->refcnt)); /* Update the connection counters */ - if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { + if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) { /* It is a normal connection, so increase the inactive connection counter because it is in TCP SYNRECV state (inactive) or other protocol inacive state */ @@ -441,7 +406,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp) atomic_read(&dest->refcnt)); /* Update the connection counters */ - if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { + if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) { /* It is a normal connection, so decrease the inactconns or activeconns counter */ if (cp->flags & IP_VS_CONN_F_INACTIVE) { @@ -502,7 +467,7 @@ int ip_vs_check_template(struct ip_vs_conn *ct) /* * Invalidate the connection template */ - if (ct->vport != 65535) { + if (ct->cport) { if (ip_vs_conn_unhash(ct)) { ct->dport = 65535; ct->vport = 65535; @@ -811,7 +776,7 @@ void ip_vs_random_dropentry(void) ct_write_lock_bh(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->flags & IP_VS_CONN_F_TEMPLATE) + if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT)) /* connection template */ continue; diff --git a/trunk/net/ipv4/ipvs/ip_vs_core.c b/trunk/net/ipv4/ipvs/ip_vs_core.c index 981cc3244ef2..3ac7eeca04ac 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_core.c +++ b/trunk/net/ipv4/ipvs/ip_vs_core.c @@ -243,10 +243,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc, if (ports[1] == svc->port) { /* Check if a template already exists */ if (svc->port != FTPPORT) - ct = ip_vs_ct_in_get(iph->protocol, snet, 0, + ct = ip_vs_conn_in_get(iph->protocol, snet, 0, iph->daddr, ports[1]); else - ct = ip_vs_ct_in_get(iph->protocol, snet, 0, + ct = ip_vs_conn_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (!ct || !ip_vs_check_template(ct)) { @@ -272,14 +272,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, iph->daddr, ports[1], dest->addr, dest->port, - IP_VS_CONN_F_TEMPLATE, + 0, dest); else ct = ip_vs_conn_new(iph->protocol, snet, 0, iph->daddr, 0, dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, + 0, dest); if (ct == NULL) return NULL; @@ -298,10 +298,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * port zero template: */ if (svc->fwmark) - ct = ip_vs_ct_in_get(IPPROTO_IP, snet, 0, + ct = ip_vs_conn_in_get(IPPROTO_IP, snet, 0, htonl(svc->fwmark), 0); else - ct = ip_vs_ct_in_get(iph->protocol, snet, 0, + ct = ip_vs_conn_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (!ct || !ip_vs_check_template(ct)) { @@ -326,14 +326,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, snet, 0, htonl(svc->fwmark), 0, dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, + 0, dest); else ct = ip_vs_conn_new(iph->protocol, snet, 0, iph->daddr, 0, dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, + 0, dest); if (ct == NULL) return NULL; diff --git a/trunk/net/ipv4/ipvs/ip_vs_sync.c b/trunk/net/ipv4/ipvs/ip_vs_sync.c index 2e5ced3d8062..574d1f509b46 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_sync.c +++ b/trunk/net/ipv4/ipvs/ip_vs_sync.c @@ -297,24 +297,16 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) p = (char *)buffer + sizeof(struct ip_vs_sync_mesg); for (i=0; inr_conns; i++) { - unsigned flags; - s = (struct ip_vs_sync_conn *)p; - flags = ntohs(s->flags); - if (!(flags & IP_VS_CONN_F_TEMPLATE)) - cp = ip_vs_conn_in_get(s->protocol, - s->caddr, s->cport, - s->vaddr, s->vport); - else - cp = ip_vs_ct_in_get(s->protocol, - s->caddr, s->cport, - s->vaddr, s->vport); + cp = ip_vs_conn_in_get(s->protocol, + s->caddr, s->cport, + s->vaddr, s->vport); if (!cp) { cp = ip_vs_conn_new(s->protocol, s->caddr, s->cport, s->vaddr, s->vport, s->daddr, s->dport, - flags, NULL); + ntohs(s->flags), NULL); if (!cp) { IP_VS_ERR("ip_vs_conn_new failed\n"); return; @@ -323,11 +315,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } else if (!cp->dest) { /* it is an entry created by the synchronization */ cp->state = ntohs(s->state); - cp->flags = flags | IP_VS_CONN_F_HASHED; + cp->flags = ntohs(s->flags) | IP_VS_CONN_F_HASHED; } /* Note that we don't touch its state and flags if it is a normal entry. */ - if (flags & IP_VS_CONN_F_SEQ_MASK) { + if (ntohs(s->flags) & IP_VS_CONN_F_SEQ_MASK) { opt = (struct ip_vs_sync_conn_options *)&s[1]; memcpy(&cp->in_seq, opt, sizeof(*opt)); p += FULL_CONN_SIZE; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index a7537c7bbd06..29222b964951 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -979,19 +979,14 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (!before(TCP_SKB_CB(skb)->seq, end_seq)) break; - in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && - !before(end_seq, TCP_SKB_CB(skb)->end_seq); - pcount = tcp_skb_pcount(skb); - if (pcount > 1 && !in_sack && - after(TCP_SKB_CB(skb)->end_seq, start_seq)) { + if (pcount > 1 && + (after(start_seq, TCP_SKB_CB(skb)->seq) || + before(end_seq, TCP_SKB_CB(skb)->end_seq))) { unsigned int pkt_len; - in_sack = !after(start_seq, - TCP_SKB_CB(skb)->seq); - - if (!in_sack) + if (after(start_seq, TCP_SKB_CB(skb)->seq)) pkt_len = (start_seq - TCP_SKB_CB(skb)->seq); else @@ -1004,6 +999,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ fack_count += pcount; + in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && + !before(end_seq, TCP_SKB_CB(skb)->end_seq); + sacked = TCP_SKB_CB(skb)->sacked; /* Account D-SACK for retransmitted packet. */ diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index b018e31b6530..c10e4435e3b1 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -435,8 +435,6 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss int nsize, old_factor; u16 flags; - BUG_ON(len >= skb->len); - nsize = skb_headlen(skb) - len; if (nsize < 0) nsize = 0; diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 519899fb11d5..29fed6e58d0a 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -1968,7 +1968,7 @@ static void ip6_mc_clear_src(struct ifmcaddr6 *pmc) } pmc->mca_sources = NULL; pmc->mca_sfmode = MCAST_EXCLUDE; - pmc->mca_sfcount[MCAST_INCLUDE] = 0; + pmc->mca_sfcount[MCAST_EXCLUDE] = 0; pmc->mca_sfcount[MCAST_EXCLUDE] = 1; } diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 2b9bf9bd177f..69b146843a20 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -405,8 +405,9 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, continue; if (!ipv6_addr_any(&np->rcv_saddr)) { - if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr)) - continue; + if (ipv6_addr_equal(&np->rcv_saddr, loc_addr)) + return s; + continue; } if(!inet6_mc_check(s, loc_addr, rmt_addr)) continue;