From 5468e4f0c9b2b40db9c4209b54f012f10d7ab225 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 8 Jun 2006 17:59:31 +0100 Subject: [PATCH] --- yaml --- r: 27193 b: refs/heads/master c: d782f33df706f1b8a4496b41fd7d339c6e23aa59 h: refs/heads/master i: 27191: c8ca945c9fc0380ab9d734ebc2c0fe8af17e767d v: v3 --- [refs] | 2 +- trunk/Documentation/memory-barriers.txt | 348 ++++-------------- trunk/arch/arm/mach-ep93xx/ts72xx.c | 8 +- trunk/arch/arm/mach-sa1100/neponset.c | 8 + trunk/arch/i386/kernel/acpi/earlyquirk.c | 23 +- trunk/arch/i386/kernel/setup.c | 11 +- trunk/arch/powerpc/kernel/prom_init.c | 10 - trunk/arch/powerpc/kernel/signal_32.c | 11 +- trunk/arch/powerpc/kernel/signal_64.c | 2 - trunk/arch/powerpc/platforms/cell/setup.c | 11 +- trunk/arch/powerpc/platforms/pseries/setup.c | 8 - trunk/arch/sparc/kernel/smp.c | 11 - trunk/arch/sparc64/kernel/pci_sun4v.c | 124 +------ trunk/arch/sparc64/kernel/smp.c | 35 -- trunk/arch/sparc64/kernel/traps.c | 11 +- trunk/arch/x86_64/kernel/io_apic.c | 30 +- trunk/block/as-iosched.c | 13 +- trunk/block/cfq-iosched.c | 10 +- trunk/block/deadline-iosched.c | 13 +- trunk/block/elevator.c | 55 ++- trunk/block/noop-iosched.c | 7 +- trunk/drivers/acpi/processor_perflib.c | 5 +- trunk/drivers/char/Makefile | 2 +- trunk/drivers/char/n_tty.c | 4 +- trunk/drivers/message/fusion/mptspi.c | 2 - trunk/drivers/message/i2o/exec-osm.c | 72 ++-- trunk/drivers/message/i2o/iop.c | 4 +- trunk/drivers/net/e1000/e1000_ethtool.c | 5 +- trunk/drivers/net/e1000/e1000_main.c | 8 +- trunk/drivers/net/sky2.c | 4 - trunk/drivers/net/tg3.c | 144 +++++--- trunk/drivers/net/tg3.h | 3 +- .../net/wireless/bcm43xx/bcm43xx_dma.c | 31 +- trunk/drivers/pci/pci-driver.c | 13 +- trunk/drivers/pci/pci.c | 18 +- trunk/drivers/scsi/sata_mv.c | 3 - trunk/drivers/video/console/fbcon.c | 2 +- trunk/fs/debugfs/inode.c | 3 +- trunk/include/asm-s390/futex.h | 15 +- trunk/include/linux/elevator.h | 2 +- trunk/include/linux/i2o.h | 5 +- trunk/include/linux/mempolicy.h | 1 - trunk/include/linux/pci-acpi.h | 2 +- trunk/mm/vmscan.c | 2 +- 44 files changed, 339 insertions(+), 762 deletions(-) diff --git a/[refs] b/[refs] index 72e0d00b8aeb..541e8650d61a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d374c1c1281d6188a0d0676172b1c0e3de35c6e7 +refs/heads/master: d782f33df706f1b8a4496b41fd7d339c6e23aa59 diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt index 4710845dbac4..c61d8b876fdb 100644 --- a/trunk/Documentation/memory-barriers.txt +++ b/trunk/Documentation/memory-barriers.txt @@ -19,7 +19,6 @@ Contents: - Control dependencies. - SMP barrier pairing. - Examples of memory barrier sequences. - - Read memory barriers vs load speculation. (*) Explicit kernel barriers. @@ -249,7 +248,7 @@ And there are a number of things that _must_ or _must_not_ be assumed: we may get either of: STORE *A = X; Y = LOAD *A; - STORE *A = Y = X; + STORE *A = Y; ========================= @@ -345,12 +344,9 @@ Memory barriers come in four basic varieties: (4) General memory barriers. - A general memory barrier gives a guarantee that all the LOAD and STORE - operations specified before the barrier will appear to happen before all - the LOAD and STORE operations specified after the barrier with respect to - the other components of the system. - - A general memory barrier is a partial ordering over both loads and stores. + A general memory barrier is a combination of both a read memory barrier + and a write memory barrier. It is a partial ordering over both loads and + stores. General memory barriers imply both read and write memory barriers, and so can substitute for either. @@ -550,9 +546,9 @@ write barrier, though, again, a general barrier is viable: =============== =============== a = 1; - b = 2; x = b; + b = 2; x = a; - y = a; + y = b; Or: @@ -567,18 +563,6 @@ Or: Basically, the read barrier always has to be there, even though it can be of the "weaker" type. -[!] Note that the stores before the write barrier would normally be expected to -match the loads after the read barrier or data dependency barrier, and vice -versa: - - CPU 1 CPU 2 - =============== =============== - a = 1; }---- --->{ v = c - b = 2; } \ / { w = d - \ - c = 3; } / \ { x = a; - d = 4; }---- --->{ y = b; - EXAMPLES OF MEMORY BARRIER SEQUENCES ------------------------------------ @@ -616,8 +600,8 @@ STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E | | +------+ +-------+ : : | - | Sequence in which stores are committed to the - | memory system by CPU 1 + | Sequence in which stores committed to memory system + | by CPU 1 V @@ -699,12 +683,14 @@ then the following will occur: | : : | | | : : | CPU 2 | | +-------+ | | - | | X->9 |------>| | - | +-------+ | | - Makes sure all effects ---> \ ddddddddddddddddd | | - prior to the store of C \ +-------+ | | - are perceptible to ----->| B->2 |------>| | - subsequent loads +-------+ | | + \ | X->9 |------>| | + \ +-------+ | | + ----->| B->2 | | | + +-------+ | | + Makes sure all effects ---> ddddddddddddddddd | | + prior to the store of C +-------+ | | + are perceptible to | B->2 |------>| | + successive loads +-------+ | | : : +-------+ @@ -713,239 +699,73 @@ following sequence of events: CPU 1 CPU 2 ======================= ======================= - { A = 0, B = 9 } STORE A=1 - STORE B=2 - LOAD B - LOAD A - -Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in -some effectively random order, despite the write barrier issued by CPU 1: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | | A->0 |------>| | - | +-------+ | | - | : : +-------+ - \ : : - \ +-------+ - ---->| A->1 | - +-------+ - : : - - -If, however, a read barrier were to be placed between the load of E and the -load of A on CPU 2: - - CPU 1 CPU 2 - ======================= ======================= - { A = 0, B = 9 } - STORE A=1 + STORE C=3 - STORE B=2 - LOAD B - + STORE D=4 + STORE E=5 LOAD A - -then the partial ordering imposed by CPU 1 will be perceived correctly by CPU -2: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - | : : | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of B ---->| A->1 |------>| | - to be perceptible to CPU 2 +-------+ | | - : : +-------+ - - -To illustrate this more completely, consider what could happen if the code -contained a load of A either side of the read barrier: - - CPU 1 CPU 2 - ======================= ======================= - { A = 0, B = 9 } - STORE A=1 - - STORE B=2 LOAD B - LOAD A [first load of A] - - LOAD A [second load of A] - -Even though the two loads of A both occur after the load of B, they may both -come up with different values: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - | : : | | - | +-------+ | | - | | A->0 |------>| 1st | - | +-------+ | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of B ---->| A->1 |------>| 2nd | - to be perceptible to CPU 2 +-------+ | | - : : +-------+ - - -But it may be that the update to A from CPU 1 becomes perceptible to CPU 2 -before the read barrier completes anyway: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| A=1 |------ --->| A->0 | - | | +------+ \ +-------+ - | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | - | | +------+ | +-------+ - | |------>| B=2 |--- | : : - | | +------+ \ | : : +-------+ - +-------+ : : \ | +-------+ | | - ---------->| B->2 |------>| | - | +-------+ | CPU 2 | - | : : | | - \ : : | | - \ +-------+ | | - ---->| A->1 |------>| 1st | - +-------+ | | - rrrrrrrrrrrrrrrrr | | - +-------+ | | - | A->1 |------>| 2nd | - +-------+ | | - : : +-------+ - - -The guarantee is that the second load will always come up with A == 1 if the -load of B came up with B == 2. No such guarantee exists for the first load of -A; that may come up with either A == 0 or A == 1. - - -READ MEMORY BARRIERS VS LOAD SPECULATION ----------------------------------------- - -Many CPUs speculate with loads: that is they see that they will need to load an -item from memory, and they find a time where they're not using the bus for any -other loads, and so do the load in advance - even though they haven't actually -got to that point in the instruction execution flow yet. This permits the -actual load instruction to potentially complete immediately because the CPU -already has the value to hand. - -It may turn out that the CPU didn't actually need the value - perhaps because a -branch circumvented the load - in which case it can discard the value or just -cache it for later use. - -Consider: - - CPU 1 CPU 2 - ======================= ======================= - LOAD B - DIVIDE } Divide instructions generally - DIVIDE } take a long time to perform - LOAD A - -Which might appear as this: - - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - Once the divisions are complete --> : : ~-->| | - the CPU can then perform the : : | | - LOAD with immediate effect : : +-------+ - - -Placing a read barrier or a data dependency barrier just before the second -load: - - CPU 1 CPU 2 - ======================= ======================= - LOAD B - DIVIDE - DIVIDE - - LOAD A - -will force any value speculatively obtained to be reconsidered to an extent -dependent on the type of barrier used. If there was no change made to the -speculated memory location, then the speculated value will just be used: - - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - : : ~ | | - rrrrrrrrrrrrrrrr~ | | - : : ~ | | - : : ~-->| | - : : | | - : : +-------+ + LOAD C + LOAD D + LOAD E +Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in +some effectively random order, despite the write barrier issued by CPU 1: -but if there was an update or an invalidation from another CPU pending, then -the speculation will be cancelled and the value reloaded: + +-------+ : : + | | +------+ + | |------>| C=3 | } + | | : +------+ } + | | : | A=1 | } + | | : +------+ } + | CPU 1 | : | B=2 | }--- + | | +------+ } \ + | | wwwwwwwwwwwww} \ + | | +------+ } \ : : +-------+ + | | : | E=5 | } \ +-------+ | | + | | : +------+ } \ { | C->3 |------>| | + | |------>| D=4 | } \ { +-------+ : | | + | | +------+ \ { | E->5 | : | | + +-------+ : : \ { +-------+ : | | + Transfer -->{ | A->1 | : | CPU 2 | + from CPU 1 { +-------+ : | | + to CPU 2 { | D->4 | : | | + { +-------+ : | | + { | B->2 |------>| | + +-------+ | | + : : +-------+ + + +If, however, a read barrier were to be placed between the load of C and the +load of D on CPU 2, then the partial ordering imposed by CPU 1 will be +perceived correctly by CPU 2. - : : +-------+ - +-------+ | | - --->| B->2 |------>| | - +-------+ | CPU 2 | - : :DIVIDE | | - +-------+ | | - The CPU being busy doing a ---> --->| A->0 |~~~~ | | - division speculates on the +-------+ ~ | | - LOAD of A : : ~ | | - : :DIVIDE | | - : : ~ | | - : : ~ | | - rrrrrrrrrrrrrrrrr | | - +-------+ | | - The speculation is discarded ---> --->| A->1 |------>| | - and an updated value is +-------+ | | - retrieved : : +-------+ + +-------+ : : + | | +------+ + | |------>| C=3 | } + | | : +------+ } + | | : | A=1 | }--- + | | : +------+ } \ + | CPU 1 | : | B=2 | } \ + | | +------+ \ + | | wwwwwwwwwwwwwwww \ + | | +------+ \ : : +-------+ + | | : | E=5 | } \ +-------+ | | + | | : +------+ }--- \ { | C->3 |------>| | + | |------>| D=4 | } \ \ { +-------+ : | | + | | +------+ \ -->{ | B->2 | : | | + +-------+ : : \ { +-------+ : | | + \ { | A->1 | : | CPU 2 | + \ +-------+ | | + At this point the read ----> \ rrrrrrrrrrrrrrrrr | | + barrier causes all effects \ +-------+ | | + prior to the storage of C \ { | E->5 | : | | + to be perceptible to CPU 2 -->{ +-------+ : | | + { | D->4 |------>| | + +-------+ | | + : : +-------+ ======================== @@ -1081,7 +901,7 @@ IMPLICIT KERNEL MEMORY BARRIERS =============================== Some of the other functions in the linux kernel imply memory barriers, amongst -which are locking and scheduling functions. +which are locking, scheduling and memory allocation functions. This specification is a _minimum_ guarantee; any particular architecture may provide more substantial guarantees, but these may not be relied upon outside @@ -1146,20 +966,6 @@ equivalent to a full barrier, but a LOCK followed by an UNLOCK is not. barriers is that the effects instructions outside of a critical section may seep into the inside of the critical section. -A LOCK followed by an UNLOCK may not be assumed to be full memory barrier -because it is possible for an access preceding the LOCK to happen after the -LOCK, and an access following the UNLOCK to happen before the UNLOCK, and the -two accesses can themselves then cross: - - *A = a; - LOCK - UNLOCK - *B = b; - -may occur as: - - LOCK, STORE *B, STORE *A, UNLOCK - Locks and semaphores may not provide any guarantee of ordering on UP compiled systems, and so cannot be counted on in such a situation to actually achieve anything at all - especially with respect to I/O accesses - unless combined @@ -1210,6 +1016,8 @@ Other functions that imply barriers: (*) schedule() and similar imply full memory barriers. + (*) Memory allocation and release functions imply full memory barriers. + ================================= INTER-CPU LOCKING BARRIER EFFECTS diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index e24566b88a78..9be01b0c3f48 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -111,21 +111,21 @@ static void __init ts72xx_map_io(void) } } -static unsigned char ts72xx_rtc_readbyte(unsigned long addr) +static unsigned char ts72xx_rtc_readb(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); } -static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) +static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); } static struct m48t86_ops ts72xx_rtc_ops = { - .readbyte = ts72xx_rtc_readbyte, - .writebyte = ts72xx_rtc_writebyte, + .readb = ts72xx_rtc_readb, + .writeb = ts72xx_rtc_writeb, }; static struct platform_device ts72xx_rtc_device = { diff --git a/trunk/arch/arm/mach-sa1100/neponset.c b/trunk/arch/arm/mach-sa1100/neponset.c index 9e02bc3712a0..af6d2775cf82 100644 --- a/trunk/arch/arm/mach-sa1100/neponset.c +++ b/trunk/arch/arm/mach-sa1100/neponset.c @@ -59,6 +59,14 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg if (irr & (IRR_ETHERNET | IRR_USAR)) { desc->chip->mask(irq); + /* + * Ack the interrupt now to prevent re-entering + * this neponset handler. Again, this is safe + * since we'll check the IRR register prior to + * leaving. + */ + desc->chip->ack(irq); + if (irr & IRR_ETHERNET) { d = irq_desc + IRQ_NEPONSET_SMC9196; desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs); diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index 1649a175a206..2e3b643a4dc4 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -5,34 +5,17 @@ #include #include #include -#include - #include #include #include -#ifdef CONFIG_ACPI - -static int nvidia_hpet_detected __initdata; - -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) -{ - nvidia_hpet_detected = 1; - return 0; -} -#endif - static int __init check_bridge(int vendor, int device) { #ifdef CONFIG_ACPI - /* According to Nvidia all timer overrides are bogus unless HPET - is enabled. */ + /* According to Nvidia all timer overrides are bogus. Just ignore + them all. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_HPET, nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { - acpi_skip_timer_override = 1; - } + acpi_skip_timer_override = 1; } #endif if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index dd6b0e3386ce..846e1639ef7c 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -1547,18 +1547,15 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_map_memmap(); -#ifdef CONFIG_ACPI - /* - * Parse the ACPI tables for possible boot-time SMP configuration. - */ - acpi_boot_table_init(); -#endif - #ifdef CONFIG_X86_IO_APIC check_acpi_pci(); /* Checks more than just ACPI actually */ #endif #ifdef CONFIG_ACPI + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ + acpi_boot_table_init(); acpi_boot_init(); #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index f70bd090dacd..41e9ab40cd54 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -822,7 +822,6 @@ static void __init prom_send_capabilities(void) /* try calling the ibm,client-architecture-support method */ if (call_prom_ret("call-method", 3, 2, &ret, ADDR("ibm,client-architecture-support"), - root, ADDR(ibm_architecture_vec)) == 0) { /* the call exists... */ if (ret) @@ -1623,15 +1622,6 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; -#ifdef CONFIG_PPC64 - /* We must make sure we don't detect the IBM Cell - * blades as pSeries due to some firmware issues, - * so we do it here. - */ - if (strstr(p, RELOC("IBM,CBEA")) || - strstr(p, RELOC("IBM,CPBW-1.0"))) - return PLATFORM_GENERIC; -#endif /* CONFIG_PPC64 */ i += sl + 1; } } diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 8fdeca2d4597..01e3c08cb550 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -803,13 +803,10 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int if (__get_user(cmcp, &ucp->uc_regs)) return -EFAULT; mcp = (struct mcontext __user *)(u64)cmcp; - /* no need to check access_ok(mcp), since mcp < 4GB */ } #else if (__get_user(mcp, &ucp->uc_regs)) return -EFAULT; - if (!access_ok(VERIFY_READ, mcp, sizeof(*mcp))) - return -EFAULT; #endif restore_sigmask(&set); if (restore_user_regs(regs, mcp, sig)) @@ -911,14 +908,13 @@ int sys_debug_setcontext(struct ucontext __user *ctx, { struct sig_dbg_op op; int i; - unsigned char tmp; unsigned long new_msr = regs->msr; #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) unsigned long new_dbcr0 = current->thread.dbcr0; #endif for (i=0; ithread.dbcr0 = new_dbcr0; #endif - if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) - || __get_user(tmp, (u8 __user *) ctx) - || __get_user(tmp, (u8 __user *) (ctx + 1) - 1)) - return -EFAULT; - /* * If we get a fault copying the context into the kernel's * image of the user's registers, we can't just return -EFAULT diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index c2db642f4cdd..27f65b95184d 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -182,8 +182,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(msr, &sc->gp_regs[PT_MSR]); if (err) return err; - if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128))) - return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ if (v_regs != 0 && (msr & MSR_VEC) != 0) err |= __copy_from_user(current->thread.vr, v_regs, diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index fd3e5609e3e0..6574b22b3cf3 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -125,13 +125,14 @@ static void __init cell_init_early(void) static int __init cell_probe(void) { + /* XXX This is temporary, the Cell maintainer will come up with + * more appropriate detection logic + */ unsigned long root = of_get_flat_dt_root(); + if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 0; - if (of_flat_dt_is_compatible(root, "IBM,CBEA") || - of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 1; - - return 0; + return 1; } /* diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 3ba87835757e..5f79f01c44f2 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -389,7 +389,6 @@ static int __init pSeries_probe_hypertas(unsigned long node, static int __init pSeries_probe(void) { - unsigned long root = of_get_flat_dt_root(); char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), "device_type", NULL); if (dtype == NULL) @@ -397,13 +396,6 @@ static int __init pSeries_probe(void) if (strcmp(dtype, "chrp")) return 0; - /* Cell blades firmware claims to be chrp while it's not. Until this - * is fixed, we need to avoid those here. - */ - if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0") || - of_flat_dt_is_compatible(root, "IBM,CBEA")) - return 0; - DBG("pSeries detected, looking for LPAR capability...\n"); /* Now try to figure out if we are running on LPAR */ diff --git a/trunk/arch/sparc/kernel/smp.c b/trunk/arch/sparc/kernel/smp.c index 40b42c88e6a7..a93f5da6855d 100644 --- a/trunk/arch/sparc/kernel/smp.c +++ b/trunk/arch/sparc/kernel/smp.c @@ -69,17 +69,6 @@ void __init smp_store_cpu_info(int id) "clock-frequency", 0); cpu_data(id).prom_node = cpu_node; cpu_data(id).mid = cpu_get_hwmid(cpu_node); - - /* this is required to tune the scheduler correctly */ - /* is it possible to have CPUs with different cache sizes? */ - if (id == boot_cpu_id) { - int cache_line,cache_nlines; - cache_line = 0x20; - cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line); - cache_nlines = 0x8000; - cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines); - max_cache_size = cache_line * cache_nlines; - } if (cpu_data(id).mid < 0) panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); } diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 0c0895202970..2b7a1f316a93 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -599,128 +599,18 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { /* SUN4V PCI configuration space accessors. */ -struct pdev_entry { - struct pdev_entry *next; - u32 devhandle; - unsigned int bus; - unsigned int device; - unsigned int func; -}; - -#define PDEV_HTAB_SIZE 16 -#define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) -static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; - -static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) -{ - unsigned int val; - - val = (devhandle ^ (devhandle >> 4)); - val ^= bus; - val ^= device; - val ^= func; - - return val & PDEV_HTAB_MASK; -} - -static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) -{ - struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); - struct pdev_entry **slot; - - if (!p) - return -ENOMEM; - - slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; - p->next = *slot; - *slot = p; - - p->devhandle = devhandle; - p->bus = bus; - p->device = device; - p->func = func; - - return 0; -} - -/* Recursively descend into the OBP device tree, rooted at toplevel_node, - * looking for a PCI device matching bus and devfn. - */ -static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) -{ - toplevel_node = prom_getchild(toplevel_node); - - while (toplevel_node != 0) { - int ret = obp_find(pregs, toplevel_node, bus, devfn); - - if (ret != 0) - return ret; - - ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, - sizeof(*pregs) * PROMREG_MAX); - if (ret == 0 || ret == -1) - goto next_sibling; - - if (((pregs[0].phys_hi >> 16) & 0xff) == bus && - ((pregs[0].phys_hi >> 8) & 0xff) == devfn) - break; - - next_sibling: - toplevel_node = prom_getsibling(toplevel_node); - } - - return toplevel_node; -} - -static int pdev_htab_populate(struct pci_pbm_info *pbm) -{ - struct linux_prom_pci_registers pr[PROMREG_MAX]; - u32 devhandle = pbm->devhandle; - unsigned int bus; - - for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { - unsigned int devfn; - - for (devfn = 0; devfn < 256; devfn++) { - unsigned int device = PCI_SLOT(devfn); - unsigned int func = PCI_FUNC(devfn); - - if (obp_find(pr, pbm->prom_node, bus, devfn)) { - int err = pdev_htab_add(devhandle, bus, - device, func); - if (err) - return err; - } - } - } - - return 0; -} - -static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) +static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) { - struct pdev_entry *p; - - p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; - while (p) { - if (p->devhandle == devhandle && - p->bus == bus && - p->device == device && - p->func == func) - break; - - p = p->next; + if (bus == pbm->pci_first_busno) { + if (device == 0 && func == 0) + return 0; + return 1; } - return p; -} - -static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) -{ if (bus < pbm->pci_first_busno || bus > pbm->pci_last_busno) return 1; - return pdev_find(pbm->devhandle, bus, device, func) == NULL; + return 0; } static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, @@ -1173,8 +1063,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); - - pdev_htab_populate(pbm); } void sun4v_pci_init(int node, char *model_name) diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index f03d52d0b88d..4e8cd79156e0 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -1287,40 +1287,6 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } -static void __init smp_tune_scheduling(void) -{ - int instance, node; - unsigned int def, smallest = ~0U; - - def = ((tlb_type == hypervisor) ? - (3 * 1024 * 1024) : - (4 * 1024 * 1024)); - - instance = 0; - while (!cpu_find_by_instance(instance, &node, NULL)) { - unsigned int val; - - val = prom_getintdefault(node, "ecache-size", def); - if (val < smallest) - smallest = val; - - instance++; - } - - /* Any value less than 256K is nonsense. */ - if (smallest < (256U * 1024U)) - smallest = 256 * 1024; - - max_cache_size = smallest; - - if (smallest < 1U * 1024U * 1024U) - printk(KERN_INFO "Using max_cache_size of %uKB\n", - smallest / 1024U); - else - printk(KERN_INFO "Using max_cache_size of %uMB\n", - smallest / 1024U / 1024U); -} - /* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { @@ -1356,7 +1322,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } smp_store_cpu_info(boot_cpu_id); - smp_tune_scheduling(); } /* Set this up early so that things like the scheduler can init diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index 563db528e031..2793a5d82380 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -1797,9 +1797,7 @@ static const char *sun4v_err_type_to_str(u32 type) }; } -extern void __show_regs(struct pt_regs * regs); - -static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) +static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) { int cnt; @@ -1832,8 +1830,6 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, pfx, ent->err_raddr, ent->err_size, ent->err_cpu); - __show_regs(regs); - if ((cnt = atomic_read(ocnt)) != 0) { atomic_set(ocnt, 0); wmb(); @@ -1866,7 +1862,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) put_cpu(); - sun4v_log_error(regs, &local_copy, cpu, + sun4v_log_error(&local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); } @@ -1914,7 +1910,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset) } #endif - sun4v_log_error(regs, &local_copy, cpu, + sun4v_log_error(&local_copy, cpu, KERN_EMERG "NON-RESUMABLE ERROR", &sun4v_nonresum_oflow_cnt); @@ -2204,6 +2200,7 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw) void die_if_kernel(char *str, struct pt_regs *regs) { static int die_counter; + extern void __show_regs(struct pt_regs * regs); extern void smp_report_regs(void); int count = 0; diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 9cc7031b7151..0de3ea938830 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -271,18 +271,6 @@ __setup("enable_8254_timer", setup_enable_8254_timer); #include #include - -#ifdef CONFIG_ACPI - -static int nvidia_hpet_detected __initdata; - -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) -{ - nvidia_hpet_detected = 1; - return 0; -} -#endif - /* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC off. Check for an Nvidia or VIA PCI bridge and turn it off. Use pci direct infrastructure because this runs before the PCI subsystem. @@ -329,19 +317,11 @@ void __init check_ioapic(void) return; case PCI_VENDOR_ID_NVIDIA: #ifdef CONFIG_ACPI - /* - * All timer overrides on Nvidia are - * wrong unless HPET is enabled. - */ - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_HPET, - nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { - acpi_skip_timer_override = 1; - printk(KERN_INFO "Nvidia board " - "detected. Ignoring ACPI " - "timer override.\n"); - } + /* All timer overrides on Nvidia + seem to be wrong. Skip them. */ + acpi_skip_timer_override = 1; + printk(KERN_INFO + "Nvidia board detected. Ignoring ACPI timer override.\n"); #endif /* RED-PEN skip them on mptables too? */ return; diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index a7caf35ca0c2..e25a5d79ab27 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -1648,17 +1648,17 @@ static void as_exit_queue(elevator_t *e) * initialize elevator private data (as_data), and alloc a arq for * each request on the free lists */ -static void *as_init_queue(request_queue_t *q, elevator_t *e) +static int as_init_queue(request_queue_t *q, elevator_t *e) { struct as_data *ad; int i; if (!arq_pool) - return NULL; + return -ENOMEM; ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); if (!ad) - return NULL; + return -ENOMEM; memset(ad, 0, sizeof(*ad)); ad->q = q; /* Identify what queue the data belongs to */ @@ -1667,7 +1667,7 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) GFP_KERNEL, q->node); if (!ad->hash) { kfree(ad); - return NULL; + return -ENOMEM; } ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, @@ -1675,7 +1675,7 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) if (!ad->arq_pool) { kfree(ad->hash); kfree(ad); - return NULL; + return -ENOMEM; } /* anticipatory scheduling helpers */ @@ -1696,13 +1696,14 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) ad->antic_expire = default_antic_expire; ad->batch_expire[REQ_SYNC] = default_read_batch_expire; ad->batch_expire[REQ_ASYNC] = default_write_batch_expire; + e->elevator_data = ad; ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10; if (ad->write_batch_count < 2) ad->write_batch_count = 2; - return ad; + return 0; } /* diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index a46d030e092a..8e9d84825e1c 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -2251,14 +2251,14 @@ static void cfq_exit_queue(elevator_t *e) kfree(cfqd); } -static void *cfq_init_queue(request_queue_t *q, elevator_t *e) +static int cfq_init_queue(request_queue_t *q, elevator_t *e) { struct cfq_data *cfqd; int i; cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); if (!cfqd) - return NULL; + return -ENOMEM; memset(cfqd, 0, sizeof(*cfqd)); @@ -2288,6 +2288,8 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) for (i = 0; i < CFQ_QHASH_ENTRIES; i++) INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); + e->elevator_data = cfqd; + cfqd->queue = q; cfqd->max_queued = q->nr_requests / 4; @@ -2314,14 +2316,14 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; - return cfqd; + return 0; out_crqpool: kfree(cfqd->cfq_hash); out_cfqhash: kfree(cfqd->crq_hash); out_crqhash: kfree(cfqd); - return NULL; + return -ENOMEM; } static void cfq_slab_kill(void) diff --git a/trunk/block/deadline-iosched.c b/trunk/block/deadline-iosched.c index 3bd0415a9828..399fa1e60e1f 100644 --- a/trunk/block/deadline-iosched.c +++ b/trunk/block/deadline-iosched.c @@ -613,24 +613,24 @@ static void deadline_exit_queue(elevator_t *e) * initialize elevator private data (deadline_data), and alloc a drq for * each request on the free lists */ -static void *deadline_init_queue(request_queue_t *q, elevator_t *e) +static int deadline_init_queue(request_queue_t *q, elevator_t *e) { struct deadline_data *dd; int i; if (!drq_pool) - return NULL; + return -ENOMEM; dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); if (!dd) - return NULL; + return -ENOMEM; memset(dd, 0, sizeof(*dd)); dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES, GFP_KERNEL, q->node); if (!dd->hash) { kfree(dd); - return NULL; + return -ENOMEM; } dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, @@ -638,7 +638,7 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) if (!dd->drq_pool) { kfree(dd->hash); kfree(dd); - return NULL; + return -ENOMEM; } for (i = 0; i < DL_HASH_ENTRIES; i++) @@ -653,7 +653,8 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) dd->writes_starved = writes_starved; dd->front_merges = 1; dd->fifo_batch = fifo_batch; - return dd; + e->elevator_data = dd; + return 0; } static void deadline_put_request(request_queue_t *q, struct request *rq) diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index a0afdd317cef..8768a367fdde 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -121,16 +121,16 @@ static struct elevator_type *elevator_get(const char *name) return e; } -static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq) +static int elevator_attach(request_queue_t *q, struct elevator_queue *eq) { - return eq->ops->elevator_init_fn(q, eq); -} + int ret = 0; -static void elevator_attach(request_queue_t *q, struct elevator_queue *eq, - void *data) -{ q->elevator = eq; - eq->elevator_data = data; + + if (eq->ops->elevator_init_fn) + ret = eq->ops->elevator_init_fn(q, eq); + + return ret; } static char chosen_elevator[16]; @@ -181,7 +181,6 @@ int elevator_init(request_queue_t *q, char *name) struct elevator_type *e = NULL; struct elevator_queue *eq; int ret = 0; - void *data; INIT_LIST_HEAD(&q->queue_head); q->last_merge = NULL; @@ -203,13 +202,10 @@ int elevator_init(request_queue_t *q, char *name) if (!eq) return -ENOMEM; - data = elevator_init_queue(q, eq); - if (!data) { + ret = elevator_attach(q, eq); + if (ret) kobject_put(&eq->kobj); - return -ENOMEM; - } - elevator_attach(q, eq, data); return ret; } @@ -726,16 +722,13 @@ int elv_register_queue(struct request_queue *q) return error; } -static void __elv_unregister_queue(elevator_t *e) -{ - kobject_uevent(&e->kobj, KOBJ_REMOVE); - kobject_del(&e->kobj); -} - void elv_unregister_queue(struct request_queue *q) { - if (q) - __elv_unregister_queue(q->elevator); + if (q) { + elevator_t *e = q->elevator; + kobject_uevent(&e->kobj, KOBJ_REMOVE); + kobject_del(&e->kobj); + } } int elv_register(struct elevator_type *e) @@ -787,7 +780,6 @@ EXPORT_SYMBOL_GPL(elv_unregister); static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) { elevator_t *old_elevator, *e; - void *data; /* * Allocate new elevator @@ -796,12 +788,6 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) if (!e) return 0; - data = elevator_init_queue(q, e); - if (!data) { - kobject_put(&e->kobj); - return 0; - } - /* * Turn on BYPASS and drain all requests w/ elevator private data */ @@ -820,19 +806,19 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) elv_drain_elevator(q); } + spin_unlock_irq(q->queue_lock); + /* - * Remember old elevator. + * unregister old elevator data */ + elv_unregister_queue(q); old_elevator = q->elevator; /* * attach and start new elevator */ - elevator_attach(q, e, data); - - spin_unlock_irq(q->queue_lock); - - __elv_unregister_queue(old_elevator); + if (elevator_attach(q, e)) + goto fail; if (elv_register_queue(q)) goto fail_register; @@ -851,6 +837,7 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) */ elevator_exit(e); e = NULL; +fail: q->elevator = old_elevator; elv_register_queue(q); clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); diff --git a/trunk/block/noop-iosched.c b/trunk/block/noop-iosched.c index 56a7c620574f..f370e4a7fe6d 100644 --- a/trunk/block/noop-iosched.c +++ b/trunk/block/noop-iosched.c @@ -65,15 +65,16 @@ noop_latter_request(request_queue_t *q, struct request *rq) return list_entry(rq->queuelist.next, struct request, queuelist); } -static void *noop_init_queue(request_queue_t *q, elevator_t *e) +static int noop_init_queue(request_queue_t *q, elevator_t *e) { struct noop_data *nd; nd = kmalloc(sizeof(*nd), GFP_KERNEL); if (!nd) - return NULL; + return -ENOMEM; INIT_LIST_HEAD(&nd->queue); - return nd; + e->elevator_data = nd; + return 0; } static void noop_exit_queue(elevator_t *e) diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index f36db22ce1ae..abbdb37a7f5f 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -577,8 +577,6 @@ acpi_processor_register_performance(struct acpi_processor_performance return_VALUE(-EBUSY); } - WARN_ON(!performance); - pr->performance = performance; if (acpi_processor_get_performance_info(pr)) { @@ -611,8 +609,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance return_VOID; } - if (pr->performance) - kfree(pr->performance->states); + kfree(pr->performance->states); pr->performance = NULL; acpi_cpufreq_remove_file(pr); diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index fb919bfb2824..f5b01c6d498e 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -41,9 +41,9 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o +obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index b9371d5bf790..ede365d05387 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/drivers/char/n_tty.c @@ -1384,10 +1384,8 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { - n_tty_set_room(tty); + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) check_unthrottle(tty); - } if (b - buf >= minimum) break; diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index 3201de053943..f2a4d382ea19 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -831,7 +831,6 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) return rc; } -#ifdef CONFIG_PM /* * spi module resume handler */ @@ -847,7 +846,6 @@ mptspi_resume(struct pci_dev *pdev) return rc; } -#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/trunk/drivers/message/i2o/exec-osm.c b/trunk/drivers/message/i2o/exec-osm.c index 7bd4d85d0b42..5ea133c59afb 100644 --- a/trunk/drivers/message/i2o/exec-osm.c +++ b/trunk/drivers/message/i2o/exec-osm.c @@ -55,7 +55,6 @@ struct i2o_exec_wait { u32 m; /* message id */ struct i2o_message *msg; /* pointer to the reply message */ struct list_head list; /* node in global wait list */ - spinlock_t lock; /* lock before modifying */ }; /* Work struct needed to handle LCT NOTIFY replies */ @@ -88,7 +87,6 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void) return NULL; INIT_LIST_HEAD(&wait->list); - spin_lock_init(&wait->lock); return wait; }; @@ -127,7 +125,6 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, DECLARE_WAIT_QUEUE_HEAD(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; - long flags; int rc = 0; wait = i2o_exec_wait_alloc(); @@ -149,28 +146,33 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, wait->tcntxt = tcntxt++; msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); - wait->wq = &wq; - /* - * we add elements to the head, because if a entry in the list will - * never be removed, we have to iterate over it every time - */ - list_add(&wait->list, &i2o_exec_wait_list); - /* * Post the message to the controller. At some point later it will * return. If we time out before it returns then complete will be zero. */ i2o_msg_post(c, msg); - wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ); + if (!wait->complete) { + wait->wq = &wq; + /* + * we add elements add the head, because if a entry in the list + * will never be removed, we have to iterate over it every time + */ + list_add(&wait->list, &i2o_exec_wait_list); + + wait_event_interruptible_timeout(wq, wait->complete, + timeout * HZ); - spin_lock_irqsave(&wait->lock, flags); + wait->wq = NULL; + } - wait->wq = NULL; + barrier(); - if (wait->complete) + if (wait->complete) { rc = le32_to_cpu(wait->msg->body[0]) >> 24; - else { + i2o_flush_reply(c, wait->m); + i2o_exec_wait_free(wait); + } else { /* * We cannot remove it now. This is important. When it does * terminate (which it must do if the controller has not @@ -184,13 +186,6 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, rc = -ETIMEDOUT; } - spin_unlock_irqrestore(&wait->lock, flags); - - if (rc != -ETIMEDOUT) { - i2o_flush_reply(c, wait->m); - i2o_exec_wait_free(wait); - } - return rc; }; @@ -218,6 +213,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, { struct i2o_exec_wait *wait, *tmp; unsigned long flags; + static spinlock_t lock = SPIN_LOCK_UNLOCKED; int rc = 1; /* @@ -227,24 +223,23 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, * already expired. Not much we can do about that except log it for * debug purposes, increase timeout, and recompile. */ + spin_lock_irqsave(&lock, flags); list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { if (wait->tcntxt == context) { - spin_lock_irqsave(&wait->lock, flags); - list_del(&wait->list); + spin_unlock_irqrestore(&lock, flags); + wait->m = m; wait->msg = msg; wait->complete = 1; - if (wait->wq) - rc = 0; - else - rc = -1; + barrier(); - spin_unlock_irqrestore(&wait->lock, flags); - - if (rc) { + if (wait->wq) { + wake_up_interruptible(wait->wq); + rc = 0; + } else { struct device *dev; dev = &c->pdev->dev; @@ -253,13 +248,15 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, c->name); i2o_dma_free(dev, &wait->dma); i2o_exec_wait_free(wait); - } else - wake_up_interruptible(wait->wq); + rc = -1; + } return rc; } } + spin_unlock_irqrestore(&lock, flags); + osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, context); @@ -325,9 +322,14 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); static int i2o_exec_probe(struct device *dev) { struct i2o_device *i2o_dev = to_i2o_device(dev); + struct i2o_controller *c = i2o_dev->iop; i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); + c->exec = i2o_dev; + + i2o_exec_lct_notify(c, c->lct->change_ind + 1); + device_create_file(dev, &dev_attr_vendor_id); device_create_file(dev, &dev_attr_product_id); @@ -521,8 +523,6 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) struct device *dev; struct i2o_message *msg; - down(&c->lct_lock); - dev = &c->pdev->dev; if (i2o_dma_realloc @@ -545,8 +545,6 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) i2o_msg_post(c, msg); - up(&c->lct_lock); - return 0; }; diff --git a/trunk/drivers/message/i2o/iop.c b/trunk/drivers/message/i2o/iop.c index febbdd4e0605..492167446936 100644 --- a/trunk/drivers/message/i2o/iop.c +++ b/trunk/drivers/message/i2o/iop.c @@ -804,6 +804,8 @@ void i2o_iop_remove(struct i2o_controller *c) /* Ask the IOP to switch to RESET state */ i2o_iop_reset(c); + + put_device(&c->device); } /** @@ -1057,7 +1059,7 @@ struct i2o_controller *i2o_iop_alloc(void) snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); if (i2o_pool_alloc - (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32), + (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4, I2O_MSG_INPOOL_MIN)) { kfree(c); return ERR_PTR(-ENOMEM); diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index d1c705b412c2..ecccca35c6f4 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -870,16 +870,13 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, - netdev)) { + if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { shared_int = FALSE; } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){ *data = 1; return -1; } - DPRINTK(PROBE,INFO, "testing %s interrupt\n", - (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 97e71a4fe8eb..ed15fcaedaf9 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -3519,7 +3519,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (rx_desc->status & E1000_RXD_STAT_DD) { - struct sk_buff *skb; + struct sk_buff *skb, *next_skb; u8 status; #ifdef CONFIG_E1000_NAPI if (*work_done >= work_to_do) @@ -3537,6 +3537,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; + next_skb = next_buffer->skb; + prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; @@ -3666,7 +3668,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb; + struct sk_buff *skb, *next_skb; unsigned int i, j; uint32_t length, staterr; int cleaned_count = 0; @@ -3695,6 +3697,8 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; + next_skb = next_buffer->skb; + prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 6b87c7a5c906..959109609d85 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -2183,9 +2183,6 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); - if (!~status) - return 0; - if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -3441,7 +3438,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) } } - pci_save_state(pdev); return sky2_set_power_state(hw, pci_choose_state(pdev, state)); } diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 862c226dbbe2..49ad60b72657 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.59" -#define DRV_MODULE_RELDATE "June 8, 2006" +#define DRV_MODULE_VERSION "3.58" +#define DRV_MODULE_RELDATE "May 22, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -4485,8 +4485,9 @@ static void tg3_disable_nvram_access(struct tg3 *tp) /* tp->lock is held. */ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) { - tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { switch (kind) { @@ -4567,12 +4568,13 @@ static int tg3_chip_reset(struct tg3 *tp) void (*write_op)(struct tg3 *, u32, u32); int i; - tg3_nvram_lock(tp); - - /* No matching tg3_nvram_unlock() after this because - * chip reset below will undo the nvram lock. - */ - tp->nvram_lock_cnt = 0; + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { + tg3_nvram_lock(tp); + /* No matching tg3_nvram_unlock() after this because + * chip reset below will undo the nvram lock. + */ + tp->nvram_lock_cnt = 0; + } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || @@ -4725,25 +4727,20 @@ static int tg3_chip_reset(struct tg3 *tp) tw32_f(MAC_MODE, 0); udelay(40); - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - - /* Chip might not be fitted with firmare. Some Sun onboard - * parts are configured like that. So don't signal the timeout - * of the above loop as an error, but do report the lack of - * running firmware once. - */ - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { - tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; - - printk(KERN_INFO PFX "%s: No firmware running.\n", - tp->dev->name); + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + if (i >= 100000) { + printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " + "firmware will not restart magic=%08x\n", + tp->dev->name, val); + return -ENODEV; + } } if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && @@ -9078,6 +9075,9 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) { int j; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) + return; + tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << @@ -9210,6 +9210,11 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) { int ret; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); + return -EINVAL; + } + if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); @@ -9442,6 +9447,11 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) { int ret; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n"); + return -EINVAL; + } + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & ~GRC_LCLCTRL_GPIO_OUTPUT1); @@ -9568,19 +9578,15 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); - /* The memory arbiter has to be enabled in order for SRAM accesses - * to succeed. Normally on powerup the tg3 chip firmware will make - * sure it is enabled, but other entities such as system netboot - * code might disable it. - */ - val = tr32(MEMARB_MODE); - tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); - tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Assume an onboard device by default. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + /* Do not even try poking around in here on Sun parts. */ + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + /* All SUN chips are built-in LOMs. */ + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + return; + } tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { @@ -9680,8 +9686,6 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - else - tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; @@ -9830,8 +9834,16 @@ static void __devinit tg3_read_partno(struct tg3 *tp) int i; u32 magic; + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + /* Sun decided not to put the necessary bits in the + * NVRAM of their onboard tg3 parts :( + */ + strcpy(tp->board_part_number, "Sun 570X"); + return; + } + if (tg3_nvram_read_swab(tp, 0x0, &magic)) - goto out_not_found; + return; if (magic == TG3_EEPROM_MAGIC) { for (i = 0; i < 256; i += 4) { @@ -9862,9 +9874,6 @@ static void __devinit tg3_read_partno(struct tg3 *tp) break; msleep(1); } - if (!(tmp16 & 0x8000)) - goto out_not_found; - pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, &tmp); tmp = cpu_to_le32(tmp); @@ -9956,6 +9965,37 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) } } +#ifdef CONFIG_SPARC64 +static int __devinit tg3_is_sun_570X(struct tg3 *tp) +{ + struct pci_dev *pdev = tp->pdev; + struct pcidev_cookie *pcp = pdev->sysdata; + + if (pcp != NULL) { + int node = pcp->prom_node; + u32 venid; + int err; + + err = prom_getproperty(node, "subsystem-vendor-id", + (char *) &venid, sizeof(venid)); + if (err == 0 || err == -1) + return 0; + if (venid == PCI_VENDOR_ID_SUN) + return 1; + + /* TG3 chips onboard the SunBlade-2500 don't have the + * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they + * are distinguishable from non-Sun variants by being + * named "network" by the firmware. Non-Sun cards will + * show up as being named "ethernet". + */ + if (!strcmp(pcp->prom_name, "network")) + return 1; + } + return 0; +} +#endif + static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -9972,6 +10012,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u16 pci_cmd; int err; +#ifdef CONFIG_SPARC64 + if (tg3_is_sun_570X(tp)) + tp->tg3_flags2 |= TG3_FLG2_SUN_570X; +#endif + /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary @@ -10267,7 +10312,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->write32 == tg3_write_indirect_reg32 || ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || + (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; /* Get eeprom hw config before calling tg3_set_power_state(). @@ -10548,7 +10594,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) #endif mac_offset = 0x7c; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && + !(tp->tg3_flags & TG3_FLG2_SUN_570X)) || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; @@ -10575,7 +10622,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) } if (!addr_ok) { /* Next, try NVRAM. */ - if (!tg3_nvram_read(tp, mac_offset + 0, &hi) && + if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && + !tg3_nvram_read(tp, mac_offset + 0, &hi) && !tg3_nvram_read(tp, mac_offset + 4, &lo)) { dev->dev_addr[0] = ((hi >> 16) & 0xff); dev->dev_addr[1] = ((hi >> 24) & 0xff); diff --git a/trunk/drivers/net/tg3.h b/trunk/drivers/net/tg3.h index ff0faab94bd5..0e29b885d449 100644 --- a/trunk/drivers/net/tg3.h +++ b/trunk/drivers/net/tg3.h @@ -2184,7 +2184,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -/* 0x00000002 available */ +#define TG3_FLG2_SUN_570X 0x00000002 #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2216,7 +2216,6 @@ struct tg3 { #define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) #define TG3_FLG2_1SHOT_MSI 0x10000000 #define TG3_FLG2_PHY_JITTER_BUG 0x20000000 -#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index d0318e525ba7..bbecba02e697 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -624,28 +624,25 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) static u16 generate_cookie(struct bcm43xx_dmaring *ring, int slot) { - u16 cookie = 0xF000; + u16 cookie = 0x0000; /* Use the upper 4 bits of the cookie as * DMA controller ID and store the slot number - * in the lower 12 bits. - * Note that the cookie must never be 0, as this - * is a special value used in RX path. + * in the lower 12 bits */ switch (ring->mmio_base) { default: assert(0); case BCM43xx_MMIO_DMA1_BASE: - cookie = 0xA000; break; case BCM43xx_MMIO_DMA2_BASE: - cookie = 0xB000; + cookie = 0x1000; break; case BCM43xx_MMIO_DMA3_BASE: - cookie = 0xC000; + cookie = 0x2000; break; case BCM43xx_MMIO_DMA4_BASE: - cookie = 0xD000; + cookie = 0x3000; break; } assert(((u16)slot & 0xF000) == 0x0000); @@ -663,16 +660,16 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm, struct bcm43xx_dmaring *ring = NULL; switch (cookie & 0xF000) { - case 0xA000: + case 0x0000: ring = dma->tx_ring0; break; - case 0xB000: + case 0x1000: ring = dma->tx_ring1; break; - case 0xC000: + case 0x2000: ring = dma->tx_ring2; break; - case 0xD000: + case 0x3000: ring = dma->tx_ring3; break; default: @@ -842,18 +839,8 @@ static void dma_rx(struct bcm43xx_dmaring *ring, /* We received an xmit status. */ struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; struct bcm43xx_xmitstatus stat; - int i = 0; stat.cookie = le16_to_cpu(hw->cookie); - while (stat.cookie == 0) { - if (unlikely(++i >= 10000)) { - assert(0); - break; - } - udelay(2); - barrier(); - stat.cookie = le16_to_cpu(hw->cookie); - } stat.flags = hw->flags; stat.cnt1 = hw->cnt1; stat.cnt2 = hw->cnt2; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 10e1a905c144..1456759936c5 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -285,9 +285,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) * Default resume method for devices that have no driver provided resume, * or not even a driver at all. */ -static int pci_default_resume(struct pci_dev *pci_dev) +static void pci_default_resume(struct pci_dev *pci_dev) { - int retval = 0; + int retval; /* restore the PCI config space */ pci_restore_state(pci_dev); @@ -297,21 +297,18 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); - - return retval; } static int pci_device_resume(struct device * dev) { - int error; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; if (drv && drv->resume) - error = drv->resume(pci_dev); + drv->resume(pci_dev); else - error = pci_default_resume(pci_dev); - return error; + pci_default_resume(pci_dev); + return 0; } static void pci_device_shutdown(struct device *dev) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 12286275b1c8..2329f941a0dc 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -461,23 +461,9 @@ int pci_restore_state(struct pci_dev *dev) { int i; - int val; - /* - * The Base Address register should be programmed before the command - * register(s) - */ - for (i = 15; i >= 0; i--) { - pci_read_config_dword(dev, i * 4, &val); - if (val != dev->saved_config_space[i]) { - printk(KERN_DEBUG "PM: Writing back config space on " - "device %s at offset %x (was %x, writing %x)\n", - pci_name(dev), i, - val, (int)dev->saved_config_space[i]); - pci_write_config_dword(dev,i * 4, - dev->saved_config_space[i]); - } - } + for (i = 0; i < 16; i++) + pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); pci_restore_msi_state(dev); pci_restore_msix_state(dev); return 0; diff --git a/trunk/drivers/scsi/sata_mv.c b/trunk/drivers/scsi/sata_mv.c index f16f92a6ec0f..9b8bca1ac1f0 100644 --- a/trunk/drivers/scsi/sata_mv.c +++ b/trunk/drivers/scsi/sata_mv.c @@ -2035,7 +2035,6 @@ static void mv_phy_reset(struct ata_port *ap) static void mv_eng_timeout(struct ata_port *ap) { struct ata_queued_cmd *qc; - unsigned long flags; printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); DPRINTK("All regs @ start of eng_timeout\n"); @@ -2047,10 +2046,8 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); - spin_lock_irqsave(&ap->host_set->lock, flags); mv_err_intr(ap, 0); mv_stop_and_reset(ap); - spin_unlock_irqrestore(&ap->host_set->lock, flags); WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); if (qc->flags & ATA_QCFLAG_ACTIVE) { diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 47ba1a79adcd..953eb8c171d6 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -1745,7 +1745,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, fbcon_redraw_move(vc, p, 0, t, count); ypan_up_redraw(vc, t, count); if (vc->vc_rows - b > 0) - fbcon_redraw_move(vc, p, b, + fbcon_redraw_move(vc, p, b - count, vc->vc_rows - b, b); } else fbcon_redraw_move(vc, p, t + count, b - t - count, t); diff --git a/trunk/fs/debugfs/inode.c b/trunk/fs/debugfs/inode.c index b55b4ea9a676..85d166cdcae4 100644 --- a/trunk/fs/debugfs/inode.c +++ b/trunk/fs/debugfs/inode.c @@ -67,13 +67,12 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d static int debugfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { - struct inode *inode; + struct inode *inode = debugfs_get_inode(dir->i_sb, mode, dev); int error = -EPERM; if (dentry->d_inode) return -EEXIST; - inode = debugfs_get_inode(dir->i_sb, mode, dev); if (inode) { d_instantiate(dentry, inode); dget(dentry); diff --git a/trunk/include/asm-s390/futex.h b/trunk/include/asm-s390/futex.h index 1802775568b9..40c25e166a9b 100644 --- a/trunk/include/asm-s390/futex.h +++ b/trunk/include/asm-s390/futex.h @@ -11,24 +11,23 @@ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ - " .long 0b,4b,2b,4b,3b,4b\n" \ + " .long 0b,2b,1b,2b\n" \ ".previous" #else /* __s390x__ */ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 8\n" \ - " .quad 0b,4b,2b,4b,3b,4b\n" \ + " .quad 0b,2b,1b,2b\n" \ ".previous" #endif /* __s390x__ */ #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ - asm volatile(" sacf 256\n" \ - "0: l %1,0(%6)\n" \ - "1: " insn \ - "2: cs %1,%2,0(%6)\n" \ - "3: jl 1b\n" \ + asm volatile(" l %1,0(%6)\n" \ + "0: " insn \ + " cs %1,%2,0(%6)\n" \ + "1: jl 0b\n" \ " lhi %0,0\n" \ - "4: sacf 0\n" \ + "2:\n" \ __futex_atomic_fixup \ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ "=m" (*uaddr) \ diff --git a/trunk/include/linux/elevator.h b/trunk/include/linux/elevator.h index 1713ace808bf..ad133fcfb239 100644 --- a/trunk/include/linux/elevator.h +++ b/trunk/include/linux/elevator.h @@ -21,7 +21,7 @@ typedef void (elevator_put_req_fn) (request_queue_t *, struct request *); typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *); typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *); -typedef void *(elevator_init_fn) (request_queue_t *, elevator_t *); +typedef int (elevator_init_fn) (request_queue_t *, elevator_t *); typedef void (elevator_exit_fn) (elevator_t *); struct elevator_ops diff --git a/trunk/include/linux/i2o.h b/trunk/include/linux/i2o.h index c115e9e840b4..dd7d627bf66f 100644 --- a/trunk/include/linux/i2o.h +++ b/trunk/include/linux/i2o.h @@ -1114,11 +1114,8 @@ static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c) mmsg->mfa = readl(c->in_port); if (unlikely(mmsg->mfa >= c->in_queue.len)) { - u32 mfa = mmsg->mfa; - mempool_free(mmsg, c->in_msg.mempool); - - if (mfa == I2O_QUEUE_EMPTY) + if(mmsg->mfa == I2O_QUEUE_EMPTY) return ERR_PTR(-EBUSY); return ERR_PTR(-EFAULT); } diff --git a/trunk/include/linux/mempolicy.h b/trunk/include/linux/mempolicy.h index f5fdca1d67e6..6a7621b2b12b 100644 --- a/trunk/include/linux/mempolicy.h +++ b/trunk/include/linux/mempolicy.h @@ -36,7 +36,6 @@ #include struct vm_area_struct; -struct mm_struct; #ifdef CONFIG_NUMA diff --git a/trunk/include/linux/pci-acpi.h b/trunk/include/linux/pci-acpi.h index 936ef82ed76a..4877e35ae202 100644 --- a/trunk/include/linux/pci-acpi.h +++ b/trunk/include/linux/pci-acpi.h @@ -50,7 +50,7 @@ extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); extern acpi_status pci_osc_support_set(u32 flags); #else -#if !defined(AE_ERROR) +#if !defined(acpi_status) typedef u32 acpi_status; #define AE_ERROR (acpi_status) (0x0001) #endif diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 440a733fe2e9..4649a63a8cb6 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1061,7 +1061,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, unsigned long nr_pages, loop_again: total_scanned = 0; nr_reclaimed = 0; - sc.may_writepage = !laptop_mode; + sc.may_writepage = !laptop_mode, sc.nr_mapped = read_page_state(nr_mapped); inc_page_state(pageoutrun);