diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch/sparc | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'arch/sparc')
28 files changed, 185 insertions, 363 deletions
diff --git a/arch/sparc/config.in b/arch/sparc/config.in index ef948c181..0a7c2140a 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -94,15 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y #fi -tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD -dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD -#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD -#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then -# bool ' Boot support' CONFIG_MD_BOOT -# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID -#fi +include drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index c8c79591c..d57c23c1f 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.60 2000/08/12 08:35:53 ecd Exp $ +# $Id: Makefile,v 1.61 2000/09/03 13:58:04 anton Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -22,7 +22,7 @@ IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o O_OBJS := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \ process.o signal.o ioport.o setup.o idprom.o \ sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \ - time.o windows.o cpu.o devices.o sclow.o solaris.o \ + time.o windows.o cpu.o devices.o sclow.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \ unaligned.o muldiv.o pcic.o semaphore.o diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f701027e0..c44fe3196 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.166 2000/06/19 06:24:36 davem Exp $ +/* $Id: entry.S,v 1.167 2000/09/06 00:45:00 davem Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1391,6 +1391,7 @@ flush_patch_two: mov %fp, %o1 ! arg1: usp std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr] add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr + mov 0, %o3 call C_LABEL(do_fork) mov %l5, %o7 @@ -1413,6 +1414,7 @@ flush_patch_three: 1: std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr] add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr + mov 0, %o3 call C_LABEL(do_fork) mov %l5, %o7 @@ -1430,6 +1432,7 @@ flush_patch_four: mov %fp, %o1 or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0 sethi %hi(C_LABEL(do_fork)), %l1 + mov 0, %o3 jmpl %l1 + %lo(C_LABEL(do_fork)), %g0 add %sp, REGWIN_SZ, %o2 diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index f2aa6cae4..eaa7fc4a3 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.106 2000/08/05 10:48:40 davem Exp $ +/* $Id: irq.c,v 1.109 2000/08/31 10:00:39 anton Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device @@ -8,7 +8,7 @@ * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1995 Pete A. Zaitcev (zaitcev@metabyte.com) * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) - * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au) + * Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com) */ #include <linux/config.h> @@ -196,41 +196,29 @@ void free_irq(unsigned int irq, void *dev_id) } #ifdef CONFIG_SMP -/* SMP interrupt locking on Sparc. */ -/* Who has global_irq_lock. */ +/* Who has the global irq brlock */ unsigned char global_irq_holder = NO_PROC_ID; -/* This protects IRQ's. */ -spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; - -/* Global IRQ locking depth. */ -atomic_t global_irq_count = ATOMIC_INIT(0); - void smp_show_backtrace_all_cpus(void); void show_backtrace(void); -#define MAXCOUNT 100000000 #define VERBOSE_DEBUG_IRQLOCK +#define MAXCOUNT 100000000 static void show(char * str) { - int i; int cpu = smp_processor_id(); + int i; printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [ ", atomic_read(&global_irq_count)); - - for (i = 0; i < NR_CPUS; i++) { - printk("%d ", local_irq_count(i)); - } - printk("]\n"); - - printk("bh: %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0)); - - for (i = 0; i < NR_CPUS; i++) { - printk("%d ", local_bh_count(cpu)); - } + printk("irq: %d [ ", irqs_running()); + for (i = 0; i < smp_num_cpus; i++) + printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]); + printk("]\nbh: %d [ ", + (spin_is_locked(&global_bh_lock) ? 1 : 0)); + for (i = 0; i < smp_num_cpus; i++) + printk("%u ", local_bh_count(i)); printk("]\n"); #ifdef VERBOSE_DEBUG_IRQLOCK @@ -240,48 +228,11 @@ static void show(char * str) #endif } + /* * We have to allow irqs to arrive between __sti and __cli */ -#define SYNC_OTHER_CORES(x) udelay(x+1) - -static inline void wait_on_irq(int cpu) -{ - int count = MAXCOUNT; - - for (;;) { - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!atomic_read(&global_irq_count)) { - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) - break; - } - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - spin_unlock(&global_irq_lock); - - for (;;) { - if (!--count) { - show("wait_on_irq"); - count = ~0; - } - __sti(); - SYNC_OTHER_CORES(cpu); - __cli(); - if (atomic_read(&global_irq_count)) - continue; - if (spin_is_locked (&global_irq_lock)) - continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) - continue; - if (spin_trylock(&global_irq_lock)) - break; - } - } -} +#define SYNC_OTHER_CORES(x) barrier() /* * This is called when we want to synchronize with @@ -292,8 +243,7 @@ static inline void wait_on_irq(int cpu) */ void synchronize_irq(void) { - if (atomic_read(&global_irq_count)) { - /* Stupid approach */ + if (irqs_running()) { cli(); sti(); } @@ -301,32 +251,37 @@ void synchronize_irq(void) static inline void get_irqlock(int cpu) { - int count = MAXCOUNT; + int count; - if (!spin_trylock(&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - do { - while (spin_is_locked(&global_irq_lock)) { - if (!--count) { - show("get_irqlock"); - count = ~0; - } - barrier(); + if ((unsigned char)cpu == global_irq_holder) + return; + + count = MAXCOUNT; +again: + br_write_lock(BR_GLOBALIRQ_LOCK); + for (;;) { + spinlock_t *lock; + + if (!irqs_running() && + (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock))) + break; + + br_write_unlock(BR_GLOBALIRQ_LOCK); + lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock; + while (irqs_running() || + spin_is_locked(lock) || + (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) { + if (!--count) { + show("get_irqlock"); + count = (~0 >> 1); } - } while (!spin_trylock(&global_irq_lock)); + __sti(); + SYNC_OTHER_CORES(cpu); + __cli(); + } + goto again; } - /* - * We also to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu); - /* - * Ok, finally.. - */ global_irq_holder = cpu; } @@ -344,7 +299,7 @@ static inline void get_irqlock(int cpu) */ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); @@ -374,9 +329,8 @@ void __global_sti(void) */ unsigned long __global_save_flags(void) { - int retval; - int local_enabled = 0; - unsigned long flags; + unsigned long flags, retval; + unsigned long local_enabled = 0; __save_flags(flags); diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index d5ce7038a..028612687 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.16 2000/07/11 01:38:57 davem Exp $ +/* $Id: pcic.c,v 1.18 2000/09/25 06:09:12 anton Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -35,11 +35,6 @@ #ifndef CONFIG_PCI -int pcibios_present(void) -{ - return 0; -} - asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, unsigned long off, @@ -940,7 +935,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, if(!suser()) return -EPERM; - lock_kernel(); switch(len) { case 1: pcibios_read_config_byte(bus, dfn, off, &ubyte); @@ -959,7 +953,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, err = -EINVAL; break; }; - unlock_kernel(); return err; } @@ -978,7 +971,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, if(!suser()) return -EPERM; - lock_kernel(); switch(len) { case 1: err = get_user(ubyte, (unsigned char *)buf); @@ -1006,7 +998,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, break; }; - unlock_kernel(); return err; } diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index f119c59ac..fe45f1f3c 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.151 2000/07/11 23:22:17 davem Exp $ +/* $Id: process.c,v 1.153 2000/09/06 00:45:01 davem Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -234,7 +234,6 @@ void show_backtrace(void) void smp_show_backtrace_all_cpus(void) { xc0((smpfunc_t) show_backtrace); - show_backtrace(); } #endif @@ -462,6 +461,7 @@ extern void ret_from_syscall(void); #endif int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, + unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 5398a9381..bce4ffcdf 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.118 2000/05/09 17:40:13 davem Exp $ +/* $Id: setup.c,v 1.119 2000/08/31 10:24:17 anton Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -80,12 +80,7 @@ void prom_sync_me(void) { unsigned long prom_tbr, flags; -#ifdef CONFIG_SMP - global_irq_holder = NO_PROC_ID; - *((unsigned char *)&global_irq_lock) = 0; - *((unsigned char *)&global_bh_lock) = 0; -#endif - __save_and_cli(flags); + save_and_cli(flags); __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr)); __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t" "nop\n\t" @@ -99,9 +94,9 @@ void prom_sync_me(void) prom_printf("PROM SYNC COMMAND...\n"); show_free_areas(); if(current->pid != 0) { - __sti(); + sti(); sys_sync(); - __cli(); + cli(); } prom_printf("Returning to prom\n"); @@ -109,7 +104,7 @@ void prom_sync_me(void) "nop\n\t" "nop\n\t" "nop\n\t" : : "r" (prom_tbr)); - __restore_flags(flags); + restore_flags(flags); return; } diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index bcad13dbc..6ac8c4b00 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.106 2000/07/07 04:25:17 davem Exp $ +/* $Id: signal.c,v 1.107 2000/09/05 21:44:54 davem Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 677b2c811..0e1944411 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -145,35 +145,33 @@ void __init smp_boot_cpus(void) void smp_flush_cache_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); - local_flush_cache_all(); } void smp_flush_tlb_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); - local_flush_tlb_all(); } void smp_flush_cache_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_mm(mm); + else xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); - - local_flush_cache_mm(mm); } } void smp_flush_tlb_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) { + if(mm->cpu_vm_mask == (1 << smp_processor_id())) { + local_flush_tlb_mm(mm); + } else { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) mm->cpu_vm_mask = (1 << smp_processor_id()); } - - local_flush_tlb_mm(mm); } } @@ -181,10 +179,10 @@ void smp_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_range(mm, start, end); + else xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, start, end); - - local_flush_cache_range(mm, start, end); } } @@ -192,10 +190,10 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_tlb_range(mm, start, end); + else xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, start, end); - - local_flush_tlb_range(mm, start, end); } } @@ -204,10 +202,10 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_page(vma, page); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); - - local_flush_cache_page(vma, page); } } @@ -216,10 +214,10 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_tlb_page(vma, page); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); - - local_flush_tlb_page(vma, page); } } @@ -233,7 +231,6 @@ void smp_flush_page_to_ram(unsigned long page) */ #if 1 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); - local_flush_page_to_ram(page); #else local_flush_page_to_ram(page); #endif @@ -241,10 +238,10 @@ void smp_flush_page_to_ram(unsigned long page) void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_sig_insns(mm, insn_addr); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); - - local_flush_sig_insns(mm, insn_addr); } /* Reschedule call back. */ diff --git a/arch/sparc/kernel/solaris.c b/arch/sparc/kernel/solaris.c deleted file mode 100644 index bcebd9262..000000000 --- a/arch/sparc/kernel/solaris.c +++ /dev/null @@ -1,39 +0,0 @@ -/* solaris.c: Solaris binary emulation, whee... - * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/errno.h> -#include <asm/solerrno.h> - -asmlinkage int solaris_open(const char *filename, int flags, int mode) -{ - int newflags; - int ret; - - lock_kernel(); - newflags = flags & 0xf; - flags &= ~0xf; - if(flags & 0x8050) - newflags |= FASYNC; - if(flags & 0x80) - newflags |= O_NONBLOCK; - if(flags & 0x100) - newflags |= O_CREAT; - if(flags & 0x200) - newflags |= O_TRUNC; - if(flags & 0x400) - newflags |= O_EXCL; - if(flags & 0x800) - newflags |= O_NOCTTY; - ret = sys_open(filename, newflags, mode); - unlock_kernel(); - return ret; -} diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c index c9bb60a86..a0e5f6ad2 100644 --- a/arch/sparc/kernel/sparc-stub.c +++ b/arch/sparc/kernel/sparc-stub.c @@ -123,7 +123,7 @@ extern char getDebugChar(void); /* read and return a single char */ */ #define BUFMAX 2048 -static int initialized = 0; /* !0 means we've been initialized */ +static int initialized; /* !0 means we've been initialized */ static const char hexchars[]="0123456789abcdef"; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index e05b20f4e..997e4d0ce 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.102 2000/08/05 10:48:40 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.104 2000/09/06 05:43:00 anton Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -111,13 +111,6 @@ EXPORT_SYMBOL_PRIVATE(_rw_read_enter); EXPORT_SYMBOL_PRIVATE(_rw_read_exit); EXPORT_SYMBOL_PRIVATE(_rw_write_enter); #endif -#ifdef CONFIG_SMP -EXPORT_SYMBOL(__global_save_flags); -EXPORT_SYMBOL(__global_restore_flags); -EXPORT_SYMBOL(__global_sti); -EXPORT_SYMBOL(__global_cli); -#endif - /* rw semaphores */ EXPORT_SYMBOL_NOVERS(___down_read); EXPORT_SYMBOL_NOVERS(___down_write); @@ -137,14 +130,22 @@ EXPORT_SYMBOL_PRIVATE(_change_bit); EXPORT_SYMBOL_PRIVATE(_set_le_bit); EXPORT_SYMBOL_PRIVATE(_clear_le_bit); -/* IRQ implementation. */ #ifdef CONFIG_SMP +/* Kernel wide locking */ EXPORT_SYMBOL(kernel_flag); + +/* IRQ implementation. */ EXPORT_SYMBOL(global_irq_holder); -EXPORT_SYMBOL(global_irq_lock); -EXPORT_SYMBOL(global_bh_lock); -EXPORT_SYMBOL(global_irq_count); EXPORT_SYMBOL(synchronize_irq); +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); + +/* Misc SMP information */ +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(__cpu_number_map); +EXPORT_SYMBOL(__cpu_logical_map); #endif EXPORT_SYMBOL(udelay); diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 280392629..3a4e93eb8 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -376,6 +376,9 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } + /* First, run local copy. */ + func(arg1, arg2, arg3, arg4, arg5); + { register int i; @@ -393,6 +396,8 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); + } else { + func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index d6c126d00..52c37f51b 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -405,6 +405,9 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } + /* First, run local copy. */ + func(arg1, arg2, arg3, arg4, arg5); + { register int i; @@ -422,6 +425,8 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); + } else { + func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c index dc26d2cc2..61df3ea6d 100644 --- a/arch/sparc/kernel/sunos_ioctl.c +++ b/arch/sparc/kernel/sunos_ioctl.c @@ -1,4 +1,4 @@ -/* $Id: sunos_ioctl.c,v 1.33 1999/07/28 12:59:03 anton Exp $ +/* $Id: sunos_ioctl.c,v 1.34 2000/09/03 14:10:56 anton Exp $ * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -39,7 +39,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg) { int ret = -EBADF; - lock_kernel(); if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) goto out; @@ -227,7 +226,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg) /* so stupid... */ ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); out: - unlock_kernel(); return ret; } diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c index d099c4e8a..fb7578554 100644 --- a/arch/sparc/kernel/sys_solaris.c +++ b/arch/sparc/kernel/sys_solaris.c @@ -16,30 +16,13 @@ #include <linux/smp_lock.h> #include <linux/module.h> -/* CHECKME: this stuff looks rather bogus */ asmlinkage int do_solaris_syscall (struct pt_regs *regs) { - int ret; - - lock_kernel(); - set_personality(PER_SVR4); - - if (current->exec_domain && current->exec_domain->handler){ - current->exec_domain->handler (0, regs); - - /* What is going on here? Why do we do this? */ - - /* XXX current->exec_domain->use_count = 0; XXX */ - - ret = regs->u_regs [UREG_I0]; - } else { - printk ("No solaris handler\n"); - send_sig (SIGSEGV, current, 1); - ret = 0; - } - unlock_kernel(); - return ret; + static int cnt = 0; + if (++cnt < 10) printk ("No solaris handler\n"); + force_sig(SIGSEGV, current); + return 0; } #ifndef CONFIG_SUNOS_EMUL @@ -48,9 +31,7 @@ do_sunos_syscall (struct pt_regs *regs) { static int cnt = 0; if (++cnt < 10) printk ("SunOS binary emulation not compiled in\n"); - lock_kernel(); force_sig (SIGSEGV, current); - unlock_kernel(); return 0; } #endif diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 43ffb3d33..980981592 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.56 2000/06/13 22:51:28 anton Exp $ +/* $Id: time.c,v 1.57 2000/09/16 07:33:45 davem Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -149,37 +149,6 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) write_unlock(&xtime_lock); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ static void __init kick_start_clock(void) { diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index 3564a4517..5c361f933 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.63 2000/06/04 06:23:52 anton Exp $ +/* $Id: traps.c,v 1.64 2000/09/03 15:00:49 anton Exp $ * arch/sparc/kernel/traps.c * * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) @@ -132,7 +132,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) { siginfo_t info; - lock_kernel(); if(type < 0x80) { /* Sun OS's puke from bad traps, Linux survives! */ printk("Unimplemented Sparc TRAP, type = %02lx\n", type); @@ -148,7 +147,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) info.si_addr = (void *)pc; info.si_trapno = type - 0x80; force_sig_info(SIGILL, &info, current); - unlock_kernel(); } void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -156,7 +154,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Kernel illegal instruction", regs); #ifdef TRAP_DEBUG @@ -166,7 +163,7 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon if (sparc_cpu_model == sun4c || sparc_cpu_model == sun4) { extern int do_user_muldiv (struct pt_regs *, unsigned long); if (!do_user_muldiv (regs, pc)) - goto out; + return; } info.si_signo = SIGILL; info.si_errno = 0; @@ -174,8 +171,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); -out: - unlock_kernel(); } void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -183,7 +178,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); info.si_signo = SIGILL; @@ -192,7 +186,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } /* XXX User may want to be allowed to do this. XXX */ @@ -202,7 +195,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon { siginfo_t info; - lock_kernel(); if(regs->psr & PSR_PS) { printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc, regs->u_regs[UREG_RETPC]); @@ -220,7 +212,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon info.si_addr = /* FIXME: Should dig out mna address */ (void *)0; info.si_trapno = 0; send_sig_info(SIGBUS, &info, current); - unlock_kernel(); } extern void fpsave(unsigned long *fpregs, unsigned long *fsr, @@ -237,7 +228,6 @@ static unsigned long init_fregs[32] __attribute__ ((aligned (8))) = void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { - lock_kernel(); /* Sanity check... */ if(psr & PSR_PS) die_if_kernel("Kernel gets FloatingPenguinUnit disabled trap", regs); @@ -246,7 +236,7 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, regs->psr |= PSR_EF; #ifndef CONFIG_SMP if(last_task_used_math == current) - goto out; + return; if(last_task_used_math) { /* Other processes fpu state, save away */ struct task_struct *fptask = last_task_used_math; @@ -270,10 +260,6 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, } current->flags |= PF_USEDFPU; #endif -#ifndef CONFIG_SMP -out: -#endif - unlock_kernel(); } static unsigned long fake_regs[32] __attribute__ ((aligned (8))); @@ -295,7 +281,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #else struct task_struct *fpt = current; #endif - lock_kernel(); put_psr(get_psr() | PSR_EF); /* If nobody owns the fpu right now, just clear the * error into our fake static buffer and hope it don't @@ -308,7 +293,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #endif fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth); regs->psr &= ~PSR_EF; - goto out; + return; } fpsave(&fpt->thread.float_regs[0], &fpt->thread.fsr, &fpt->thread.fpqueue[0], &fpt->thread.fpqdepth); @@ -361,7 +346,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, if(calls > 2) die_if_kernel("Too many Penguin-FPU traps from kernel mode", regs); - goto out; + return; } fsr = fpt->thread.fsr; @@ -389,8 +374,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, regs->psr &= ~PSR_EF; if(calls > 0) calls=0; -out: - unlock_kernel(); } void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -398,7 +381,6 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin overflow trap from kernel mode", regs); info.si_signo = SIGEMT; @@ -407,13 +389,11 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGEMT, &info, current); - unlock_kernel(); } void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { - lock_kernel(); #ifdef TRAP_DEBUG printk("Watchpoint detected at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -421,7 +401,6 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc if(psr & PSR_PS) panic("Tell me what a watchpoint trap is, and I'll then deal " "with such a beast..."); - unlock_kernel(); } void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -429,7 +408,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc { siginfo_t info; - lock_kernel(); #ifdef TRAP_DEBUG printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -440,7 +418,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc info.si_addr = (void *)pc; info.si_trapno = 0; force_sig_info(SIGBUS, &info, current); - unlock_kernel(); } void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -448,14 +425,12 @@ void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long np { siginfo_t info; - lock_kernel(); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_COPROC; info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -463,7 +438,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); #ifdef TRAP_DEBUG printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -474,7 +448,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -482,15 +455,12 @@ void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc { siginfo_t info; - lock_kernel(); info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = FPE_INTDIV; info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGFPE, &info, current); - - unlock_kernel(); } /* Since we have our mappings set up, on multiprocessors we can spin them diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index b323ccacd..642c986bd 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.91 2000/08/09 23:10:19 anton Exp $ +/* $Id: init.c,v 1.93 2000/08/31 11:40:55 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -89,8 +89,6 @@ pgprot_t kmap_prot; void __init kmap_init(void) { - unsigned long pteval; - /* cache the first kmap pte */ kmap_pte = kmap_get_fixed_pte(FIX_KMAP_BEGIN); kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); @@ -583,6 +581,6 @@ void flush_page_to_ram(struct page *page) { unsigned long vaddr; vaddr = kmap(page); - __flush_page_to_ram(page_address(page)); + __flush_page_to_ram((unsigned long)page_address(page)); kunmap(page); } diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 4f5bd16c5..408d59cbf 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $ +/* $Id: srmmu.c,v 1.222 2000/08/29 08:59:23 davem Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1323,8 +1323,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma, mapping = file->f_dentry->d_inode->i_mapping; offset = (address & PAGE_MASK) - vma->vm_start; spin_lock(&mapping->i_shared_lock); - vmaring = mapping->i_mmap; - do { + vmaring = mapping->i_mmap_shared; + if (vmaring != NULL) do { /* Do not mistake ourselves as another mapping. */ if(vmaring == vma) continue; diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 66bc3af7b..a99ce736e 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $ +/* $Id: sun4c.c,v 1.199 2000/08/29 08:59:23 davem Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -2404,8 +2404,8 @@ static void sun4c_vac_alias_fixup(struct vm_area_struct *vma, unsigned long addr mapping = vma->vm_file->f_dentry->d_inode->i_mapping; spin_lock(&mapping->i_shared_lock); - vmaring = mapping->i_mmap; - do { + vmaring = mapping->i_mmap_shared; + if (vmaring != NULL) do { unsigned long vaddr = vmaring->vm_start + offset; unsigned long start; diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c index c2b857459..bf61ff1a7 100644 --- a/arch/sparc/prom/console.c +++ b/arch/sparc/prom/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.22 2000/02/08 20:24:23 davem Exp $ +/* $Id: console.c,v 1.23 2000/08/26 02:38:03 anton Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * @@ -30,7 +30,7 @@ prom_nbgetchar(void) int i = -1; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_SUN4: @@ -49,7 +49,7 @@ prom_nbgetchar(void) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -63,7 +63,7 @@ prom_nbputchar(char c) unsigned long flags; int i = -1; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_SUN4: @@ -82,7 +82,7 @@ prom_nbputchar(char c) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -125,10 +125,10 @@ prom_query_input_device() return PROMDEV_I_UNK; }; case PROM_V3: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); if(prom_node_has_property(st_p, "keyboard")) return PROMDEV_IKBD; if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) { @@ -174,10 +174,10 @@ prom_query_output_device() break; case PROM_V2: case PROM_V3: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); if (propl >= 0 && propl == sizeof("display") && strncmp("display", propb, sizeof("display")) == 0) diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c index 463b07527..eb1207357 100644 --- a/arch/sparc/prom/devmap.c +++ b/arch/sparc/prom/devmap.c @@ -1,4 +1,4 @@ -/* $Id: devmap.c,v 1.6 1998/03/09 14:04:23 jj Exp $ +/* $Id: devmap.c,v 1.7 2000/08/26 02:38:03 anton Exp $ * promdevmap.c: Map device/IO areas to virtual addresses. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -29,13 +29,13 @@ prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes) unsigned long flags; char *ret; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0; else ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr, num_bytes); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -46,9 +46,9 @@ prom_unmapio(char *vaddr, unsigned int num_bytes) unsigned long flags; if(num_bytes == 0x0) return; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/devops.c b/arch/sparc/prom/devops.c index 5a58efa0b..61919b54f 100644 --- a/arch/sparc/prom/devops.c +++ b/arch/sparc/prom/devops.c @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.12 2000/01/29 01:09:12 anton Exp $ +/* $Id: devops.c,v 1.13 2000/08/26 02:38:03 anton Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -21,7 +21,7 @@ prom_devopen(char *dstr) { int handle; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); @@ -36,7 +36,7 @@ prom_devopen(char *dstr) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return handle; } @@ -46,7 +46,7 @@ int prom_devclose(int dhandle) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: (*(romvec->pv_v0devops.v0_devclose))(dhandle); @@ -59,7 +59,7 @@ prom_devclose(int dhandle) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return 0; } @@ -70,7 +70,7 @@ void prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); @@ -83,7 +83,7 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c index 3c2f2434d..86ce39910 100644 --- a/arch/sparc/prom/misc.c +++ b/arch/sparc/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.17 1998/07/21 10:36:22 jj Exp $ +/* $Id: misc.c,v 1.18 2000/08/26 02:38:03 anton Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * @@ -15,16 +15,18 @@ extern void restore_current(void); +spinlock_t prom_lock = SPIN_LOCK_UNLOCKED; + /* Reset and reboot the machine with the command 'bcommand'. */ void prom_reboot(char *bcommand) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_reboot))(bcommand); /* Never get here. */ restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); } /* Forth evaluate the expression contained in 'fstring'. */ @@ -34,13 +36,13 @@ prom_feval(char *fstring) unsigned long flags; if(!fstring || fstring[0] == 0) return; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); if(prom_vers == PROM_V0) (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring); else (*(romvec->pv_fortheval.v2_eval))(fstring); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); } /* We want to do this more nicely some day. */ @@ -66,10 +68,10 @@ prom_cmdline(void) prom_palette (1); #endif install_obp_ticker(); - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_abort))(); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); install_linux_ticker(); #ifdef CONFIG_SUN_AUXIO TURN_ON_LED; @@ -88,11 +90,11 @@ prom_halt(void) { unsigned long flags; again: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_halt))(); /* Never get here. */ restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); goto again; /* PROM is out to get me -DaveM */ } diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c index ba624673f..92fe3739f 100644 --- a/arch/sparc/prom/mp.c +++ b/arch/sparc/prom/mp.c @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.11 2000/01/29 01:09:12 anton Exp $ +/* $Id: mp.c,v 1.12 2000/08/26 02:38:03 anton Exp $ * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) * @@ -25,7 +25,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -37,7 +37,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -51,7 +51,7 @@ prom_stopcpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -63,7 +63,7 @@ prom_stopcpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -77,7 +77,7 @@ prom_idlecpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -89,7 +89,7 @@ prom_idlecpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -103,7 +103,7 @@ prom_restartcpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -115,7 +115,7 @@ prom_restartcpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } diff --git a/arch/sparc/prom/segment.c b/arch/sparc/prom/segment.c index 62b3f8542..09d646016 100644 --- a/arch/sparc/prom/segment.c +++ b/arch/sparc/prom/segment.c @@ -1,4 +1,4 @@ -/* $Id: segment.c,v 1.6 1998/03/09 14:04:27 jj Exp $ +/* $Id: segment.c,v 1.7 2000/08/26 02:38:03 anton Exp $ * segment.c: Prom routine to map segments in other contexts before * a standalone is completely mapped. This is for sun4 and * sun4c architectures only. @@ -21,9 +21,9 @@ void prom_putsegment(int ctx, unsigned long vaddr, int segment) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c index 2e79057d8..adfe6e75a 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.25 1998/09/17 11:04:58 jj Exp $ +/* $Id: tree.c,v 1.26 2000/08/26 02:38:03 anton Exp $ * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * @@ -26,10 +26,10 @@ int __prom_getchild(int node) unsigned long flags; int cnode; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_child(node); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return cnode; } @@ -57,10 +57,10 @@ int __prom_getsibling(int node) unsigned long flags; int cnode; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_nextnode(node); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return cnode; } @@ -93,10 +93,10 @@ int prom_getproplen(int node, char *prop) if((!node) || (!prop)) return -1; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_proplen(node, prop); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -113,10 +113,10 @@ int prom_getproperty(int node, char *prop, char *buffer, int bufsize) if((plen > bufsize) || (plen == 0) || (plen == -1)) return -1; /* Ok, things seem all right. */ - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_getprop(node, prop, buffer); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -226,10 +226,10 @@ char * __prom_nextprop(int node, char * oprop) unsigned long flags; char *prop; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); prop = prom_nodeops->no_nextprop(node, oprop); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return prop; } @@ -325,10 +325,10 @@ int prom_setprop(int node, char *pname, char *value, int size) if(size == 0) return 0; if((pname == 0) || (value == 0)) return 0; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_setprop(node, pname, value, size); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -337,10 +337,10 @@ int prom_inst2pkg(int inst) int node; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); node = (*romvec->pv_v2devops.v2_inst2pkg)(inst); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); if (node == -1) return 0; return node; } |