From 4154e3acb0183ebd0be4b0b0e4f637216effa63d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:20:22 -0500 Subject: [PATCH] Linux 2.2.14pre10 o Further PPC updates (Cort Dougan) o TCPv6 crash fix o Update Tlan driver maintainer (James Banks) o Fix syncookie URL (Daniel Roesen) o Move the scsi_malloc lock (Peter Blomgren) o Advansys update (Bob Frey) o Fix Acard compile as built in driver (Arjan van de Ven) o NFS directory link count fixes (Jim Winstead) o sk98 compile fixes (Christoph Goos) o Fix HFS back compatibility problem (Adrian Sun) o More PPC updates (Cort Dougan) o Sk98 update (Christoph Goos) o Update kernel-docs (Juan-Mariano de Goyeneche) o Buffer race on flush fixes (Andrea Arcangeli) --- CREDITS | 9 +- Documentation/Configure.help | 2 +- Documentation/kernel-docs.txt | 12 +- Documentation/networking/tlan.txt | 23 +- MAINTAINERS | 4 +- Makefile | 2 +- arch/i386/vmlinux.lds | 69 ---- arch/ppc/boot/Makefile | 2 +- arch/ppc/chrpboot/string.S | 206 ----------- arch/ppc/kernel/chrp_setup.c | 23 +- arch/ppc/kernel/gemini_setup.c | 30 +- arch/ppc/kernel/head.S | 15 +- arch/ppc/kernel/irq.c | 14 +- arch/ppc/kernel/open_pic.c | 2 +- arch/ppc/kernel/open_pic.h | 2 + arch/ppc/kernel/openpic.c | 550 ++++++++++++++---------------- arch/ppc/kernel/pmac_pic.c | 2 +- arch/ppc/kernel/process.c | 12 - arch/ppc/kernel/prom.c | 2 +- arch/ppc/kernel/ptrace.c | 12 +- arch/ppc/kernel/signal.c | 9 +- arch/ppc/kernel/smp.c | 188 +++++----- arch/ppc/mm/init.c | 16 + arch/sparc/kernel/head.S | 17 +- arch/sparc64/kernel/traps.c | 10 +- arch/sparc64/kernel/ttable.S | 5 +- drivers/block/rd.c | 7 +- drivers/net/sk98lin/Makefile | 11 +- drivers/net/sk98lin/h/skdrv1st.h | 6 + drivers/scsi/advansys.c | 28 +- drivers/scsi/advansys.h | 38 ++- drivers/scsi/atp870u.h | 1 + drivers/scsi/scsi.h | 1 + fs/buffer.c | 144 +++++--- fs/devices.c | 3 +- fs/hfs/file_hdr.c | 8 +- fs/nfs/dir.c | 6 +- fs/super.c | 5 +- include/asm-ppc/smp.h | 3 +- include/asm-sparc/head.h | 6 +- include/asm-sparc/ioctl.h | 10 +- include/linux/fs.h | 4 +- include/linux/hfs_fs.h | 14 +- include/linux/openpic.h | 7 +- include/scsi/scsi.h | 2 - kernel/ksyms.c | 2 +- net/ipv6/tcp_ipv6.c | 1 - 47 files changed, 696 insertions(+), 849 deletions(-) delete mode 100644 arch/i386/vmlinux.lds delete mode 100644 arch/ppc/chrpboot/string.S diff --git a/CREDITS b/CREDITS index 962e9bd0f4e6..fac4dd8c95f5 100644 --- a/CREDITS +++ b/CREDITS @@ -137,12 +137,9 @@ S: Notre Dame, Indiana S: USA N: James Banks -E: james.banks@caldera.com +E: james@sovereign.org D: TLAN network driver -S: Caldera, Inc. -S: 633 South 550 East -S: Provo, Utah 84606 -S: USA +D: Logitech Busmouse driver N: Paul Barton-Davis E: pbd@op.net @@ -866,7 +863,7 @@ S: CV5 8BZ S: United Kingdom N: Ron Holt -E: ron@caldera.com +E: ron@sovereign.org W: http://www.holt.org/ P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A 40 E3 FB 71 D1 C8 0B 56 D: Kernel development diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 1bfe3f0c6c11..3d0434f8b0a4 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1199,7 +1199,7 @@ CONFIG_SYN_COOKIES is no need for the legitimate users to change their TCP/IP software; SYN cookies work transparently to them. For technical information about SYN cookies, check out - ftp://koobera.math.uic.edu/pub/docs/syncookies-archive. + ftp://koobera.math.uic.edu/syncookies.html . If you are SYN flooded, the source address reported by the kernel is likely to have been forged by the attacker; it is only reported as diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt index e56e465e8885..8f76009c5eba 100644 --- a/Documentation/kernel-docs.txt +++ b/Documentation/kernel-docs.txt @@ -265,12 +265,10 @@ * Title: "Linux Kernel Module Programming Guide" Author: Ori Pomerantz. - URL: - http://www.leo.org/pub/comp/os/unix/linux/sunsite/docs/linux-doc-p - roject/module-programming-guide/index.html - Keywords: modules, free book, /proc, ioctls, system calls, + URL: http://www.linuxdoc.org/LDP/lkmpg/mpg.html + Keywords: modules, GPL book, /proc, ioctls, system calls, interrupt handlers . - Description: Very nice 92 pages free book on the topic of modules + Description: Very nice 92 pages GPL book on the topic of modules programming. Lots of examples. * Title: "Device File System (devfs) Overview" @@ -402,7 +400,7 @@ produced during the week. Published every Thursday. * Name: Kernel Traffic. - URL: http://lwn.net + URL: http://kt.linuxcare.com Keywords: linux-kernel mailing list, weekly kernel news. Description: Weekly newsletter covering the most relevant discussions of the linux-kernel mailing list. @@ -437,4 +435,4 @@ dcache. _________________________________________________________________ - Document last updated on Wed Oct 27 17:14:03 CEST 1999 + Document last updated on Tue Nov 30 11:20:00 CET 1999 diff --git a/Documentation/networking/tlan.txt b/Documentation/networking/tlan.txt index d3de6ccd10a9..4114be27a937 100644 --- a/Documentation/networking/tlan.txt +++ b/Documentation/networking/tlan.txt @@ -1,16 +1,27 @@ -TLAN driver for Linux, version 1.0 -README -Well, I'm back. The TLAN driver seems pretty stable, so I'm -declaring this cycle of development finished, and calling the -driver 1.0. I will, of course continue to work on improving -the driver, and work towards a 2.0 release. +I haven't had any time to do anything for a long time, and this isn't +likely to change. So there's a driver here for anyone looking to +carry forward a project :) + +For those who are looking for help, I can't. I haven't looked at +a kernel since the early 2.0 series, so I won't know what's going on. +Your best chance at help would be joining the TLAN mailing list and +posting your question there. + +You can join by sending "subscribe tlan" in the body of an email to +majordomo@vuser.vu.union.edu. + +Thanks to those who have (and who will ;) put work in to keep the TLAN +driver working as the kernel moves on. James james@sovereign.org +TLAN driver for Linux, version 1.0 +README + I. Supported Devices. diff --git a/MAINTAINERS b/MAINTAINERS index 1d811af9fcd4..1b617feacffa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -811,10 +811,8 @@ M: kgb@manjak.knm.org.pl S: Maintained TLAN NETWORK DRIVER -P: James Banks -M: james@sovereign.org L: tlan@vuser.vu.union.edu -S: Maintained +S: Orphan TOKEN-RING NETWORK DRIVER P: Paul Norton diff --git a/Makefile b/Makefile index 07106ce6d3c9..f14582e1a002 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 2 SUBLEVEL = 14 -EXTRAVERSION = pre9 +EXTRAVERSION = pre10 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds deleted file mode 100644 index ecf90c27c44f..000000000000 --- a/arch/i386/vmlinux.lds +++ /dev/null @@ -1,69 +0,0 @@ -/* ld script to make i386 Linux kernel - * Written by Martin Mares ; - */ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - . = 0xC0000000 + 0x100000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - .rodata : { *(.rodata) } - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - _end = . ; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 41a8a915f478..96b6ba306ecc 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -134,7 +134,7 @@ znetboot.initrd : zImage.initrd cp zImage.initrd $(TFTPIMAGE) clean: - rm -f vmlinux* zvmlinux* mkprep zImage* + rm -f vmlinux* zvmlinux* mkprep zImage* sImage* fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/chrpboot/string.S b/arch/ppc/chrpboot/string.S deleted file mode 100644 index ba83591b76f0..000000000000 --- a/arch/ppc/chrpboot/string.S +++ /dev/null @@ -1,206 +0,0 @@ -/* - * String handling functions for PowerPC. - * - * Copyright (C) 1996 Paul Mackerras. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#define r0 0 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 - - .globl strcpy -strcpy: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strncpy -strncpy: - cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r6) - bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ - blr - - .globl strcat -strcat: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r5) - cmpwi 0,r0,0 - bne 1b - addi r5,r5,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strcmp -strcmp: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r5) - cmpwi 1,r3,0 - lbzu r0,1(r4) - subf. r3,r0,r3 - beqlr 1 - beq 1b - blr - - .globl strlen -strlen: - addi r4,r3,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - bne 1b - subf r3,r3,r4 - blr - - .globl memset -memset: - rlwimi r4,r4,8,16,23 - rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) - beqlr - andi. r0,r6,3 - add r5,r0,r5 - subf r6,r0,r6 - rlwinm r0,r5,32-2,2,31 - mtctr r0 - bdz 6f -1: stwu r4,4(r6) - bdnz 1b -6: andi. r5,r5,3 -7: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r6,3 -8: stbu r4,1(r6) - bdnz 8b - blr - - .globl bcopy -bcopy: - mr r6,r3 - mr r3,r4 - mr r4,r6 - b memcpy - - .globl memmove -memmove: - cmplw 0,r3,r4 - bgt backwards_memcpy - /* fall through */ - - .globl memcpy -memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - addi r6,r3,-4 - addi r4,r4,-4 - beq 2f /* if less than 8 bytes to do */ - andi. r0,r6,3 /* get dest word aligned */ - mtctr r7 - bne 5f -1: lwz r7,4(r4) - lwzu r8,8(r4) - stw r7,4(r6) - stwu r8,8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,4(r4) - addi r5,r5,-4 - stwu r0,4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r4,r4,3 - addi r6,r6,3 -4: lbzu r0,1(r4) - stbu r0,1(r6) - bdnz 4b - blr -5: subfic r0,r0,4 - mtctr r0 -6: lbz r7,4(r4) - addi r4,r4,1 - stb r7,4(r6) - addi r6,r6,1 - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl backwards_memcpy -backwards_memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - add r6,r3,r5 - add r4,r4,r5 - beq 2f - andi. r0,r6,3 - mtctr r7 - bne 5f -1: lwz r7,-4(r4) - lwzu r8,-8(r4) - stw r7,-4(r6) - stwu r8,-8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,-4(r4) - subi r5,r5,4 - stwu r0,-4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 -4: lbzu r0,-1(r4) - stbu r0,-1(r6) - bdnz 4b - blr -5: mtctr r0 -6: lbzu r7,-1(r4) - stbu r7,-1(r6) - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl memcmp -memcmp: - cmpwi 0,r5,0 - blelr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r6) - lbzu r0,1(r4) - subf. r3,r0,r3 - bdnzt 2,1b - blr diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 8d2d4e9b8db1..f80ad32365fe 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -386,8 +386,8 @@ chrp_do_IRQ(struct pt_regs *regs, } } #endif /* __SMP__ */ - - irq = openpic_irq(0); + + irq = openpic_irq(smp_processor_id()); if (irq == IRQ_8259_CASCADE) { /* @@ -402,7 +402,7 @@ chrp_do_IRQ(struct pt_regs *regs, /* * Acknowledge as soon as possible to allow i8259 * interrupt nesting */ - openpic_eoi(0); + openpic_eoi(smp_processor_id()); openpic_eoi_done = 1; } if (irq == OPENPIC_VEC_SPURIOUS) @@ -429,7 +429,7 @@ chrp_do_IRQ(struct pt_regs *regs, } out: if (!openpic_eoi_done) - openpic_eoi(0); + openpic_eoi(smp_processor_id()); } __initfunc(void @@ -449,10 +449,6 @@ __initfunc(void open_pic.irq_offset = 16; for ( i = 16 ; i < NR_IRQS ; i++ ) irq_desc[i].ctl = &open_pic; - /* openpic knows that it's at irq 16 offset - * so we don't need to set it in the pic structure - * -- Cort - */ openpic_init(1); for ( i = 0 ; i < 16 ; i++ ) irq_desc[i].ctl = &i8259_pic; @@ -462,8 +458,14 @@ __initfunc(void xmon_irq, 0, "NMI", 0); #endif /* CONFIG_XMON */ #ifdef __SMP__ - request_irq(openpic_to_irq(OPENPIC_VEC_IPI), - openpic_ipi_action, 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, + 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action, + 0, "IPI1 (invalidate TLB)", 0); + request_irq(OPENPIC_VEC_IPI+2, openpic_ipi_action, + 0, "IPI2 (stop CPU)", 0); + request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action, + 0, "IPI3 (reschedule)", 0); #endif /* __SMP__ */ } @@ -472,7 +474,6 @@ __initfunc(void { adb_init(); - /* Should this be here? - Corey */ pmac_nvram_init(); #ifdef CONFIG_VT diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index d9abea743bda..de49c235d3ee 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -57,17 +57,7 @@ void gemini_do_IRQ(struct pt_regs *regs, int cpu, int isfake) { int irq, openpic_eoi_done = 0; - unsigned long bits = 0; - #ifdef __SMP__ - if (cpu != 0) { - if (!isfake) { - smp_message_recv(); - goto out; - } - goto out; - } - { unsigned int loops = 1000000; while(test_bit(0, &global_irq_lock)) { @@ -85,15 +75,12 @@ gemini_do_IRQ(struct pt_regs *regs, int cpu, int isfake) irq = openpic_irq(cpu); - if (irq == OPENPIC_VEC_SPURIOUS) { + if (irq == OPENPIC_VEC_SPURIOUS ) { ppc_spurious_interrupts++; openpic_eoi_done = 1; goto out; } - - bits = 1UL<nip); @@ -104,7 +91,7 @@ gemini_do_IRQ(struct pt_regs *regs, int cpu, int isfake) ppc_irq_dispatch_handler(regs, irq); out: if (!openpic_eoi_done) - openpic_eoi(0); + openpic_eoi(smp_processor_id()); } static inline unsigned long _get_HID1(void) @@ -384,11 +371,18 @@ void __init gemini_init_IRQ(void) /* gemini has no 8259 */ open_pic.irq_offset = 0; - for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ ) + for( i=0; i < NR_IRQS; i++ ) irq_desc[i].ctl = &open_pic; openpic_init(1); #ifdef __SMP__ - request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, + 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action, + 0, "IPI1 (invalidate TLB)", 0); + request_irq(OPENPIC_VEC_IPI+2, openpic_ipi_action, + 0, "IPI2 (stop CPU)", 0); + request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action, + 0, "IPI3 (reschedule)", 0); #endif /* __SMP__ */ } diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 898ce1d2768a..0c17abf08009 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -234,7 +234,7 @@ __start: .globl __secondary_start __secondary_start: /* Switch MMU off, clear BATs and flush TLB */ - bl mmu_off + bl mmu_off bl clear_bats bl flush_tlbs @@ -1346,7 +1346,6 @@ hash_page_patch_A: li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ tlbie r3 /* invalidate TLB entry */ - /* Search the primary PTEG for a PTE whose 1st word matches r5 */ mtctr r2 addi r3,r4,-8 @@ -2252,7 +2251,17 @@ do_signal_ret: stw r4,TSS+KSP(r2) /* save kernel stack pointer */ tophys(r3,r1,r3) mtspr SPRG2,r3 /* phys exception stack pointer */ -10: lwz r2,_CTR(r1) +10: +#ifdef CONFIG_SMP + /* see smp_invalidate_tlb_cpu for explanation */ + mfspr r3,PVR + rlwinm r3,r3,16,16,31 + cmpi 0,r3,8 + bne 1010f + bl smp_invalidate_tlb_cpu +1010: +#endif /* CONFIG_SMP */ + lwz r2,_CTR(r1) lwz r0,_LINK(r1) mtctr r2 mtlr r0 diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index d0da0db398cb..53395a4a3542 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -94,8 +94,8 @@ atomic_t ppc_n_lost_interrupts; * this needs to be removed. * -- Cort */ -static char cache_bitmask = 0; -static struct irqaction malloc_cache[8]; +static unsigned long cache_bitmask[1]; +static struct irqaction malloc_cache[32]; extern int mem_init_done; void *irq_kmalloc(size_t size, int pri) @@ -103,10 +103,10 @@ void *irq_kmalloc(size_t size, int pri) unsigned int i; if ( mem_init_done ) return kmalloc(size,pri); - for ( i = 0; i <= 3 ; i++ ) - if ( ! ( cache_bitmask & (1< + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ - -/* - * Note: Interprocessor Interrupt (IPI) and Timer support is incomplete - */ - - #include #include #include @@ -23,12 +20,11 @@ #include #include #include - +#include "open_pic.h" #define REGISTER_DEBUG #undef REGISTER_DEBUG - volatile struct OpenPIC *OpenPIC = NULL; u_int OpenPIC_NumInitSenses __initdata = 0; u_char *OpenPIC_InitSenses __initdata = NULL; @@ -36,11 +32,6 @@ u_char *OpenPIC_InitSenses __initdata = NULL; static u_int NumProcessors; static u_int NumSources; - - /* - * Accesses to the current processor's registers - */ - #ifndef __powerpc__ #define THIS_CPU Private #define CHECK_THIS_CPU do {} while (0) @@ -49,11 +40,6 @@ static u_int NumSources; #define CHECK_THIS_CPU check_arg_cpu(cpu) #endif - - /* - * Sanity checks - */ - #if 1 #define check_arg_ipi(ipi) \ if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \ @@ -67,9 +53,14 @@ static u_int NumSources; #define check_arg_pri(pri) \ if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); +/* + * I changed this to return to keep us from from trying to use irq #'s + * that we're using for IPI's. + * -- Cort + */ #define check_arg_irq(irq) \ if (irq < 0 || irq >= NumSources) \ - printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq); + /*printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/return; #define check_arg_cpu(cpu) \ if (cpu < 0 || cpu >= NumProcessors) \ printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); @@ -82,255 +73,229 @@ static u_int NumSources; #define check_arg_cpu(cpu) do {} while (0) #endif - - /* - * Dummy interrupt handler - */ - static void no_action(int ir1, void *dev, struct pt_regs *regs) {} - - /* - * I/O functions - */ - +/* + * I/O functions + */ #ifdef __i386__ static inline u_int ld_le32(volatile u_int *addr) { - return *addr; + return *addr; } static inline void out_le32(volatile u_int *addr, u_int val) { - *addr = val; + *addr = val; } #endif u_int openpic_read(volatile u_int *addr) { - u_int val; + u_int val; - val = ld_le32(addr); + val = ld_le32(addr); #ifdef REGISTER_DEBUG - printk("openpic_read(0x%08x) = 0x%08x\n", (u_int)addr, val); + printk("openpic_read(0x%08x) = 0x%08x\n", (u_int)addr, val); #endif - return val; + return val; } static inline void openpic_write(volatile u_int *addr, u_int val) { #ifdef REGISTER_DEBUG - printk("openpic_write(0x%08x, 0x%08x)\n", (u_int)addr, val); + printk("openpic_write(0x%08x, 0x%08x)\n", (u_int)addr, val); #endif - out_le32(addr, val); + out_le32(addr, val); } - static inline u_int openpic_readfield(volatile u_int *addr, u_int mask) { - u_int val = openpic_read(addr); - return val & mask; + u_int val = openpic_read(addr); + return val & mask; } inline void openpic_writefield(volatile u_int *addr, u_int mask, - u_int field) + u_int field) { - u_int val = openpic_read(addr); - openpic_write(addr, (val & ~mask) | (field & mask)); + u_int val = openpic_read(addr); + openpic_write(addr, (val & ~mask) | (field & mask)); } static inline void openpic_clearfield(volatile u_int *addr, u_int mask) { - openpic_writefield(addr, mask, 0); + openpic_writefield(addr, mask, 0); } static inline void openpic_setfield(volatile u_int *addr, u_int mask) { - openpic_writefield(addr, mask, mask); + openpic_writefield(addr, mask, mask); } - - /* - * Update a Vector/Priority register in a safe manner. The interrupt will - * be disabled. - */ - +/* + * Update a Vector/Priority register in a safe manner. The interrupt will + * be disabled. + */ static void openpic_safe_writefield(volatile u_int *addr, u_int mask, u_int field) { - openpic_setfield(addr, OPENPIC_MASK); - /* wait until it's not in use */ - while (openpic_read(addr) & OPENPIC_ACTIVITY); - openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); + openpic_setfield(addr, OPENPIC_MASK); + /* wait until it's not in use */ + while (openpic_read(addr) & OPENPIC_ACTIVITY); + openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); } - -/* -------- Global Operations ---------------------------------------------- */ - - - /* - * Initialize the OpenPIC - */ - +/* + * Initialize the OpenPIC + */ __initfunc(void openpic_init(int main_pic)) { - u_int t, i; - u_int timerfreq; - const char *version; + u_int t, i; + u_int timerfreq; + const char *version; - if (!OpenPIC) - panic("No OpenPIC found"); + if (!OpenPIC) + panic("No OpenPIC found"); - t = openpic_read(&OpenPIC->Global.Feature_Reporting0); - switch (t & OPENPIC_FEATURE_VERSION_MASK) { + t = openpic_read(&OpenPIC->Global.Feature_Reporting0); + switch (t & OPENPIC_FEATURE_VERSION_MASK) { case 1: - version = "1.0"; - break; + version = "1.0"; + break; case 2: - version = "1.2"; - break; + version = "1.2"; + break; case 3: - version = "1.3"; - break; + version = "1.3"; + break; default: - version = "?"; - break; - } - NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >> - OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; - NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> - OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; - printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, - NumProcessors, NumSources, OpenPIC); - timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); - printk("OpenPIC timer frequency is "); - if (timerfreq) - printk("%d Hz\n", timerfreq); - else - printk("not set\n"); - - if ( main_pic ) - { - /* Initialize timer interrupts */ - for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { - /* Disabled, Priority 0 */ - openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); - /* No processor */ - openpic_maptimer(i, 0); - } + version = "?"; + break; + } + NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >> + OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; + NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> + OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; + printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, + NumProcessors, NumSources, OpenPIC); + timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); + printk("OpenPIC timer frequency is "); + if (timerfreq) + printk("%d Hz\n", timerfreq); + else + printk("not set\n"); + + if ( main_pic ) + { + /* Initialize timer interrupts */ + for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { + /* Disabled, Priority 0 */ + openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); + /* No processor */ + openpic_maptimer(i, 0); + } - /* Initialize IPI interrupts */ - for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 0 */ - openpic_initipi(i, 0, OPENPIC_VEC_IPI+i); - } + /* Initialize IPI interrupts */ + for (i = 0; i < OPENPIC_NUM_IPI; i++) { + openpic_initipi(i, 10, OPENPIC_VEC_IPI+i); + } - /* Initialize external interrupts */ - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, OPENPIC_VEC_SOURCE, 1, 1); - /* Processor 0 */ - openpic_mapirq(0, 1<<0); - for (i = 1; i < NumSources; i++) { - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i, 0, - i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); - /* Processor 0 */ - openpic_mapirq(i, 1<<0); - } + /* Initialize external interrupts */ + for (i = 0; i < NumSources; i++) { + /* Enabled, Priority 8 */ + openpic_initirq(i, 8, open_pic.irq_offset+i, 0, + i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); + /* Processor 0 */ + openpic_mapirq(i, 1<<0); + } - /* Initialize the spurious interrupt */ - openpic_set_spurious(OPENPIC_VEC_SPURIOUS); - - if ( _machine != _MACH_gemini ) - { - if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, - "82c59 cascade", NULL)) - printk("Unable to get OpenPIC IRQ 0 for cascade\n"); - } - openpic_set_priority(0, 0); - openpic_disable_8259_pass_through(); - } + /* Initialize the spurious interrupt */ + openpic_set_spurious(OPENPIC_VEC_SPURIOUS); + + /* Gemini has no i8259 */ + if ( _machine != _MACH_gemini ) + { + /* SIOint (8259 cascade) is special */ + openpic_initirq(0, 8, open_pic.irq_offset, 1, 1); + openpic_mapirq(0, 1<<0); + if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, + "82c59 cascade", NULL)) + printk("Unable to get OpenPIC IRQ 0 for cascade\n"); + } + openpic_set_priority(0, 0); + openpic_disable_8259_pass_through(); + } } - /* - * Reset the OpenPIC - */ - +/* + * Reset the OpenPIC + */ void openpic_reset(void) { - openpic_setfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_RESET); + openpic_setfield(&OpenPIC->Global.Global_Configuration0, + OPENPIC_CONFIG_RESET); } - /* - * Enable/disable 8259 Pass Through Mode - */ - +/* + * Enable/disable 8259 Pass Through Mode + */ void openpic_enable_8259_pass_through(void) { - openpic_clearfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); + openpic_clearfield(&OpenPIC->Global.Global_Configuration0, + OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } void openpic_disable_8259_pass_through(void) { - openpic_setfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); + openpic_setfield(&OpenPIC->Global.Global_Configuration0, + OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } - #ifndef __i386__ - /* - * Find out the current interrupt - */ - +/* + * Find out the current interrupt + */ u_int openpic_irq(u_int cpu) { - u_int vec; - - check_arg_cpu(cpu); - vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, - OPENPIC_VECTOR_MASK); -#if 0 -if (vec != 22 /* SCSI */) -printk("++openpic_irq: %d\n", vec); -#endif - return vec; + u_int vec; + + check_arg_cpu(cpu); + vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, + OPENPIC_VECTOR_MASK); + return vec; } #endif - /* - * Signal end of interrupt (EOI) processing - */ - +/* + * Signal end of interrupt (EOI) processing + */ #ifndef __powerpc__ void openpic_eoi(void) #else void openpic_eoi(u_int cpu) #endif { - check_arg_cpu(cpu); - openpic_write(&OpenPIC->THIS_CPU.EOI, 0); + check_arg_cpu(cpu); + openpic_write(&OpenPIC->THIS_CPU.EOI, 0); } - /* - * Get/set the current task priority - */ - +/* + * Get/set the current task priority + */ #ifndef __powerpc__ u_int openpic_get_priority(void) #else u_int openpic_get_priority(u_int cpu) #endif { - CHECK_THIS_CPU; - return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, - OPENPIC_CURRENT_TASK_PRIORITY_MASK); + CHECK_THIS_CPU; + return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, + OPENPIC_CURRENT_TASK_PRIORITY_MASK); } #ifndef __powerpc__ @@ -339,183 +304,178 @@ void openpic_set_priority(u_int pri) void openpic_set_priority(u_int cpu, u_int pri) #endif { - CHECK_THIS_CPU; - check_arg_pri(pri); - openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, - OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri); + CHECK_THIS_CPU; + check_arg_pri(pri); + openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, + OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri); } - /* - * Get/set the spurious vector - */ - +/* + * Get/set the spurious vector + */ u_int openpic_get_spurious(void) { - return openpic_readfield(&OpenPIC->Global.Spurious_Vector, - OPENPIC_VECTOR_MASK); + return openpic_readfield(&OpenPIC->Global.Spurious_Vector, + OPENPIC_VECTOR_MASK); } void openpic_set_spurious(u_int vec) { - check_arg_vec(vec); - openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK, - vec); + check_arg_vec(vec); + openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK, + vec); } - - /* - * Initialize one or more CPUs - */ - +/* + * Initialize one or more CPUs + */ void openpic_init_processor(u_int cpumask) { - openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); + openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); } -/* -------- Interprocessor Interrupts -------------------------------------- */ - - - /* - * Initialize an interprocessor interrupt (and disable it) - * - * ipi: OpenPIC interprocessor interrupt number - * pri: interrupt source priority - * vec: the vector it will produce - */ - +/* + * Initialize an interprocessor interrupt (and disable it) + * + * ipi: OpenPIC interprocessor interrupt number + * pri: interrupt source priority + * vec: the vector it will produce + */ void openpic_initipi(u_int ipi, u_int pri, u_int vec) { - check_arg_timer(ipi); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, - (pri << OPENPIC_PRIORITY_SHIFT) | vec); + check_arg_timer(ipi); + check_arg_pri(pri); + check_arg_vec(vec); + openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), + OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, + (pri << OPENPIC_PRIORITY_SHIFT) | vec); } - - /* - * Send an IPI to one or more CPUs - */ - +/* + * Send an IPI to one or more CPUs + */ #ifndef __powerpc__ void openpic_cause_IPI(u_int ipi, u_int cpumask) #else void openpic_cause_IPI(u_int cpu, u_int ipi, u_int cpumask) #endif { - CHECK_THIS_CPU; - check_arg_ipi(ipi); - openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); + CHECK_THIS_CPU; + check_arg_ipi(ipi); + openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); } +void openpic_enable_IPI(u_int ipi) +{ + check_arg_ipi(ipi); + openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi), + OPENPIC_MASK); +} -/* -------- Timer Interrupts ----------------------------------------------- */ - - - /* - * Initialize a timer interrupt (and disable it) - * - * timer: OpenPIC timer number - * pri: interrupt source priority - * vec: the vector it will produce - */ +/* + * Do per-cpu setup for SMP systems. + * + * Get IPI's working and start taking interrupts. + * -- Cort + */ +void do_openpic_setup_cpu(void) +{ + int i; + + for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) + openpic_enable_IPI(i); +#if 0 + /* let the openpic know we want intrs */ + for ( i = 0; i < NumSources ; i++ ) + openpic_mapirq(i, openpic_read(&OpenPIC->Source[i].Destination) + | (1<Global.Timer[timer].Vector_Priority, - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, - (pri << OPENPIC_PRIORITY_SHIFT) | vec); + check_arg_timer(timer); + check_arg_pri(pri); + check_arg_vec(vec); + openpic_safe_writefield(&OpenPIC->Global.Timer[timer].Vector_Priority, + OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, + (pri << OPENPIC_PRIORITY_SHIFT) | vec); } - /* - * Map a timer interrupt to one or more CPUs - */ - +/* + * Map a timer interrupt to one or more CPUs + */ void openpic_maptimer(u_int timer, u_int cpumask) { - check_arg_timer(timer); - openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask); + check_arg_timer(timer); + openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask); } - -/* -------- Interrupt Sources ---------------------------------------------- */ - - - /* - * Enable/disable an interrupt source - */ - +/* + * Enable/disable an interrupt source + */ void openpic_enable_irq(u_int irq) { - check_arg_irq(irq); - openpic_clearfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); + check_arg_irq(irq); + openpic_clearfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); } void openpic_disable_irq(u_int irq) { - check_arg_irq(irq); - openpic_setfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); + check_arg_irq(irq); + openpic_setfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); } - - /* - * Initialize an interrupt source (and disable it!) - * - * irq: OpenPIC interrupt number - * pri: interrupt source priority - * vec: the vector it will produce - * pol: polarity (1 for positive, 0 for negative) - * sense: 1 for level, 0 for edge - */ - +/* + * Initialize an interrupt source (and disable it!) + * + * irq: OpenPIC interrupt number + * pri: interrupt source priority + * vec: the vector it will produce + * pol: polarity (1 for positive, 0 for negative) + * sense: 1 for level, 0 for edge + */ void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) { - check_arg_irq(irq); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | - OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL, - (pri << OPENPIC_PRIORITY_SHIFT) | vec | - (pol ? OPENPIC_SENSE_POLARITY : 0) | - (sense ? OPENPIC_SENSE_LEVEL : 0)); + check_arg_irq(irq); + check_arg_pri(pri); + check_arg_vec(vec); + openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, + OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | + OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL, + (pri << OPENPIC_PRIORITY_SHIFT) | vec | + (pol ? OPENPIC_SENSE_POLARITY : 0) | + (sense ? OPENPIC_SENSE_LEVEL : 0)); } - - /* - * Map an interrupt source to one or more CPUs - */ - +/* + * Map an interrupt source to one or more CPUs + */ void openpic_mapirq(u_int irq, u_int cpumask) { - check_arg_irq(irq); - openpic_write(&OpenPIC->Source[irq].Destination, cpumask); + check_arg_irq(irq); + openpic_write(&OpenPIC->Source[irq].Destination, cpumask); } - - /* - * Set the sense for an interrupt source (and disable it!) - * - * sense: 1 for level, 0 for edge - */ - +/* + * Set the sense for an interrupt source (and disable it!) + * + * sense: 1 for level, 0 for edge + */ void openpic_set_sense(u_int irq, int sense) { - check_arg_irq(irq); - openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, - OPENPIC_SENSE_LEVEL, - (sense ? OPENPIC_SENSE_LEVEL : 0)); -} - -void openpic_enable_IPI(u_int ipi) -{ - check_arg_ipi(ipi); - openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_MASK); + check_arg_irq(irq); + openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, + OPENPIC_SENSE_LEVEL, + (sense ? OPENPIC_SENSE_LEVEL : 0)); } diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index 611372661026..a1610c445bd0 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -168,7 +168,7 @@ pmac_do_IRQ(struct pt_regs *regs, if (xmon_2nd) xmon(regs); #endif - smp_message_recv(); + pmac_smp_message_recv(); goto out; } /* could be here due to a do_fake_interrupt call but we don't diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index a36c32995fe8..9041fe3be276 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -187,18 +187,6 @@ _switch_to(struct task_struct *prev, struct task_struct *new, prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; -#ifdef CONFIG_GEMINI - /* - * Force a context change on every processor switch for 750's. - * This prevents some corruption problems I was finding on the gemini. - * -- Cort - */ - if ( /*(new->processor != new->last_processor) &&*/ ((_get_PVR()>>16) == 8) ) - { - init_new_context(new->mm); - get_mmu_context(new); - } -#endif /* CONFIG_GEMINI */ #endif /* __SMP__ */ new_tss = &new->tss; old_tss = ¤t->tss; diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 12546e5bf780..23a594e90d61 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -539,7 +539,7 @@ prom_init(int r3, int r4, prom_entry pp) node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/")); if ( (int)call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),type, sizeof(type)) <= 0) - return; + return phys; /* copy the holding pattern code to someplace safe (8M) */ memcpy( (void *)(8<<20), RELOC(__secondary_hold), 0x100 ); diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index 37c71dd40cfe..19e1c3fbab14 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c @@ -413,11 +413,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; - - if ((addr & 3) || addr < 0 || addr > (PT_FPSCR << 2)) { - ret = -EIO; + + ret = -EIO; + if ((addr & 3) || addr < 0 || addr > (PT_FPSCR << 2)) goto out; - } tmp = 0; /* Default return condition */ addr = addr >> 2; /* temporary hack. */ @@ -430,9 +429,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) tmp = ((long *)child->tss.fpr)[addr - PT_FPR0]; } else - ret = -EIO; - if (!ret) - ret = put_user(tmp, (unsigned long *) data); + goto out; + ret = put_user(tmp, (unsigned long *) data); goto out; } diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 05d5c6de3ad7..05a48d1b44f8 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -471,8 +471,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) /* Whee! Actually deliver the signal. */ handle_signal(signr, ka, &info, oldset, regs, &newsp, frame); - setup_frame(regs, (struct sigregs *) frame, newsp); - return 1; + break; } if (regs->trap == 0x0C00 /* System Call! */ && @@ -484,7 +483,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) regs->result = 0; } - return 0; /* no signals delivered */ + if (newsp == frame) + return 0; /* no signals delivered */ + + setup_frame(regs, (struct sigregs *) frame, newsp); + return 1; } diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index ab7a2d74f652..3de43f4cb5b9 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -37,6 +37,8 @@ #include #include "time.h" +#include "open_pic.h" + int first_cpu_booted = 0; int smp_threads_ready = 0; volatile int smp_commenced = 0; @@ -110,34 +112,8 @@ void smp_local_timer_interrupt(struct pt_regs * regs) } } -/* - * Dirty hack to get smp message passing working. - * - * As it is now, if we're sending two message at the same time - * we have race conditions. The PowerSurge doesn't easily - * allow us to send IPI messages so we put the messages in - * smp_message[]. - * - * This is because don't have several IPI's on the PowerSurge even though - * we do on the chrp. It would be nice to use the actual IPI's on the chrp - * rather than this but having two methods of doing IPI isn't a good idea - * right now. - * -- Cort - */ -int smp_message[NR_CPUS]; -void smp_message_recv(void) +void smp_message_recv(int msg) { - int msg = smp_message[smp_processor_id()]; - - if ( _machine == _MACH_Pmac ) - { - /* clear interrupt */ - out_be32(PSURGE_INTR, ~0); - } - - /* make sure msg is for us */ - if ( msg == -1 ) return; - ipi_count++; switch( msg ) @@ -146,25 +122,72 @@ void smp_message_recv(void) __cli(); while (1) ; break; - case MSG_RESCHEDULE: + case MSG_RESCHEDULE: current->need_resched = 1; break; - case 0xf0f0: /* syncing time bases - just return */ + case MSG_INVALIDATE_TLB: + _tlbia(); + case 0xf0f0: /* pmac syncing time bases - just return */ break; default: printk("SMP %d: smp_message_recv(): unknown msg %d\n", smp_processor_id(), msg); break; } +} + +/* + * As it is now, if we're sending two message at the same time + * we have race conditions on Pmac. The PowerSurge doesn't easily + * allow us to send IPI messages so we put the messages in + * smp_message[]. + * + * This is because don't have several IPI's on the PowerSurge even though + * we do on the chrp. It would be nice to use actual IPI's such as with openpic + * rather than this. + * -- Cort + */ +int pmac_smp_message[NR_CPUS]; +void pmac_smp_message_recv(void) +{ + int msg = pmac_smp_message[smp_processor_id()]; + + /* clear interrupt */ + out_be32(PSURGE_INTR, ~0); + + /* make sure msg is for us */ + if ( msg == -1 ) return; + + smp_message_recv(msg); + /* reset message */ - smp_message[smp_processor_id()] = -1; + pmac_smp_message[smp_processor_id()] = -1; +} + + +/* + * 750's don't broadcast tlb invalidates so + * we have to emulate that behavior. + * -- Cort + */ +void smp_send_tlb_invalidate(int cpu) +{ + if ( (_get_PVR()>>16) == 8 ) + smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0); } void smp_send_reschedule(int cpu) { - /* This is only used if `cpu' is running an idle task, - so it will reschedule itself anyway... */ - /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/ + /* + * This is only used if `cpu' is running an idle task, + * so it will reschedule itself anyway... + * + * This isn't the case anymore since the other CPU could be + * sleeping and won't reschedule until the next interrupt (such + * as the timer). + * -- Cort + */ + smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0); } void smp_send_stop(void) @@ -172,38 +195,39 @@ void smp_send_stop(void) smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); } -spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED; void smp_message_pass(int target, int msg, unsigned long data, int wait) { int i; + if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) return; - spin_lock(&mesg_pass_lock); - - /* - * We assume here that the msg is not -1. If it is, - * the recipient won't know the message was destined - * for it. -- Cort - */ - - switch( target ) - { - case MSG_ALL: - smp_message[smp_processor_id()] = msg; - /* fall through */ - case MSG_ALL_BUT_SELF: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - if ( i != smp_processor_id () ) - smp_message[i] = msg; - break; - default: - smp_message[target] = msg; - break; - } - switch (_machine) { case _MACH_Pmac: + /* + * IPI's on the Pmac are a hack but without reasonable + * IPI hardware SMP on Pmac is a hack. + * + * We assume here that the msg is not -1. If it is, + * the recipient won't know the message was destined + * for it. -- Cort + */ + for ( i = 0; i <= smp_num_cpus ; i++ ) + pmac_smp_message[i] = -1; + switch( target ) + { + case MSG_ALL: + pmac_smp_message[smp_processor_id()] = msg; + /* fall through */ + case MSG_ALL_BUT_SELF: + for ( i = 0 ; i < smp_num_cpus ; i++ ) + if ( i != smp_processor_id () ) + pmac_smp_message[i] = msg; + break; + default: + pmac_smp_message[target] = msg; + break; + } /* interrupt secondary processor */ out_be32(PSURGE_INTR, ~0); out_be32(PSURGE_INTR, 0); @@ -214,35 +238,27 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) /* interrupt primary */ /**(volatile unsigned long *)(0xf3019000);*/ break; - case _MACH_chrp: case _MACH_prep: - /* - * There has to be some way of doing this better - - * perhaps a sent-to-all or send-to-all-but-self - * in the openpic. This gets us going for now, though. - * -- Cort - */ + case _MACH_gemini: + /* make sure we're sending something that translates to an IPI */ + if ( msg > 0x3 ) + break; switch ( target ) { case MSG_ALL: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - openpic_cause_IPI(i, 0, 0xffffffff ); + openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff); break; case MSG_ALL_BUT_SELF: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - if ( i != smp_processor_id () ) - openpic_cause_IPI(i, 0, - 0xffffffff & ~(1 << smp_processor_id())); + openpic_cause_IPI(smp_processor_id(), msg, + 0xffffffff & ~(1 << smp_processor_id())); break; default: - openpic_cause_IPI(target, 0, 1U << target); + openpic_cause_IPI(smp_processor_id(), msg, 1<>2; cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr; break; @@ -345,19 +359,6 @@ void __init smp_boot_cpus(void) case _MACH_chrp: *(unsigned long *)KERNELBASE = i; asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); -#if 0 - device = find_type_devices("cpu"); - /* assume cpu device list is in order, find the ith cpu */ - for ( a = i; device && a; device = device->next, a-- ) - ; - if ( !device ) - break; - printk( "Starting %s (%lu): ", device->full_name, - *(ulong *)get_property(device, "reg", NULL) ); - call_rtas( "start-cpu", 3, 1, NULL, - *(ulong *)get_property(device, "reg", NULL), - __pa(__secondary_start_chrp), i); -#endif break; case _MACH_prep: *MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE; @@ -390,6 +391,8 @@ void __init smp_boot_cpus(void) } } + if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) ) + do_openpic_setup_cpu(); if ( _machine == _MACH_Pmac ) { /* reset the entry point so if we get another intr we won't @@ -431,6 +434,13 @@ void __init smp_callin(void) #endif init_idle(); cpu_callin_map[current->processor] = 1; + /* + * Each processor has to do this and this is the best + * place to stick it for now. + * -- Cort + */ + if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) ) + do_openpic_setup_cpu(); while(!smp_commenced) barrier(); __sti(); @@ -448,8 +458,8 @@ int __init setup_profiling_timer(unsigned int multiplier) void __init smp_store_cpu_info(int id) { struct cpuinfo_PPC *c = &cpu_data[id]; - /* assume bogomips are same for everything */ c->loops_per_sec = loops_per_sec; c->pvr = _get_PVR(); } + diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 9da48426effa..c672c86151e1 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -116,6 +116,7 @@ static void print_mem_pieces(struct mem_pieces *); static void append_mem_piece(struct mem_pieces *, unsigned, unsigned); extern struct task_struct *current_set[NR_CPUS]; +unsigned long cpu_invalidate_tlb[NR_CPUS]; PTE *Hash, *Hash_end; unsigned long Hash_size, Hash_mask; @@ -497,6 +498,9 @@ local_flush_tlb_all(void) #ifndef CONFIG_8xx __clear_user(Hash, Hash_size); _tlbia(); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif #else asm volatile ("tlbia" : : ); #endif @@ -514,6 +518,9 @@ local_flush_tlb_mm(struct mm_struct *mm) mm->context = NO_CONTEXT; if (mm == current->mm) activate_context(current); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif #else asm volatile ("tlbia" : : ); #endif @@ -527,6 +534,9 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) flush_hash_page(vma->vm_mm->context, vmaddr); else flush_hash_page(0, vmaddr); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif #else asm volatile ("tlbia" : : ); #endif @@ -556,6 +566,9 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e { flush_hash_page(mm->context, start); } +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif #else asm volatile ("tlbia" : : ); #endif @@ -581,6 +594,9 @@ mmu_context_overflow(void) } read_unlock(&tasklist_lock); flush_hash_segments(0x10, 0xffffff); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif atomic_set(&next_mmu_context, 0); /* make sure current always has a context */ current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S index 783feb814c7b..849409fe141d 100644 --- a/arch/sparc/kernel/head.S +++ b/arch/sparc/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.95.2.3 1999/11/12 15:45:45 davem Exp $ +/* $Id: head.S,v 1.95.2.5 1999/12/02 11:51:56 davem Exp $ * head.S: The initial boot code for the Sparc port of Linux. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -173,7 +173,8 @@ t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9 t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) t_getcc:GETCC_TRAP /* Get Condition Codes */ t_setcc:SETCC_TRAP /* Set Condition Codes */ -t_bada2:BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) +t_getpsr:GETPSR_TRAP /* Get PSR Register */ +t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) t_slowi:INDIRECT_SOLARIS_SYSCALL(156) t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) @@ -253,8 +254,8 @@ C_LABEL(trapbase_cpu1): LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP - BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) @@ -325,8 +326,8 @@ C_LABEL(trapbase_cpu2): LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP - BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) @@ -397,8 +398,8 @@ C_LABEL(trapbase_cpu3): LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) - BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP - BAD_TRAP(0xa2) BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) + BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP + BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index d03aa26989a7..2fe05199fb08 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.58.2.1 1999/08/19 01:11:16 davem Exp $ +/* $Id: traps.c,v 1.58.2.2 1999/12/01 23:55:43 davem Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef CONFIG_KMOD #include #endif @@ -815,6 +816,13 @@ void cache_flush_trap(struct pt_regs *regs) } #endif +void do_getpsr(struct pt_regs *regs) +{ + regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate); + regs->tpc = regs->tnpc; + regs->tnpc += 4; +} + void trap_init(void) { } diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 7a45b3a8ed79..5551b57d9933 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -1,4 +1,4 @@ -/* $Id: ttable.S,v 1.28.2.1 1999/08/19 01:11:14 davem Exp $ +/* $Id: ttable.S,v 1.28.2.2 1999/12/01 23:55:44 davem Exp $ * ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -120,7 +120,8 @@ tl0_resv11c: TRAP_UTRAP(UT_TRAP_INSTRUCTION_28,0x11c) TRAP_UTRAP(UT_TRAP_INSTRUC tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUCTION_31,0x11f) tl0_getcc: GETCC_TRAP tl0_setcc: SETCC_TRAP -tl0_resv122: BTRAP(0x122) BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) +tl0_getpsr: TRAP(do_getpsr) +tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156) tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 771183b7a455..f0971f5a5fa7 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -191,7 +191,10 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un switch (cmd) { case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; - invalidate_buffers(inode->i_rdev); + /* special: we want to release the ramdisk memory, + it's not like with the other blockdevices where + this ioctl only flushes away the buffer cache. */ + destroy_buffers(inode->i_rdev); break; case BLKGETSIZE: /* Return device size */ @@ -347,7 +350,7 @@ void cleanup_module(void) int i; for (i = 0 ; i < NUM_RAMDISKS; i++) - invalidate_buffers(MKDEV(MAJOR_NR, i)); + destroy_buffers(MKDEV(MAJOR_NR, i)); unregister_blkdev( MAJOR_NR, "ramdisk" ); blk_dev[MAJOR_NR].request_fn = 0; diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile index a5d1e8a7561a..7dfe263beab2 100644 --- a/drivers/net/sk98lin/Makefile +++ b/drivers/net/sk98lin/Makefile @@ -19,11 +19,14 @@ else endif endif - # DBGDEF = \ -# -DDEBUG \ -# -DSK_DEBUG_CHKMOD=0x00010000L \ -# -DSK_DEBUG_CHKCAT=0xffff0000L +# -DDEBUG + +ifdef DEBUG +DBGDEF += \ +-DSK_DEBUG_CHKMOD=0x00000000L \ +-DSK_DEBUG_CHKCAT=0x00000000L +endif # **** possible debug modules for SK_DEBUG_CHKMOD ***************** diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h index 4b24fa3bdbe1..446c9b49d3b2 100644 --- a/drivers/net/sk98lin/h/skdrv1st.h +++ b/drivers/net/sk98lin/h/skdrv1st.h @@ -175,6 +175,12 @@ typedef struct s_DrvRlmtMbuf SK_MBUF; #ifdef DEBUG #define SK_DBG_PRINTF printk +#ifndef SK_DEBUG_CHKMOD +#define SK_DEBUG_CHKMOD 0 +#endif +#ifndef SK_DEBUG_CHKCAT +#define SK_DEBUG_CHKCAT 0 +#endif /* those come from the makefile */ #define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD) #define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index d43ba0129fe0..93387842f5c3 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1,5 +1,5 @@ -/* $Id: advansys.c,v 1.68 1999/11/19 01:57:47 bobf Exp bobf $ */ -#define ASC_VERSION "3.2L" /* AdvanSys Driver Version */ +/* $Id: advansys.c,v 1.69 1999/11/29 18:37:53 bobf Exp bobf $ */ +#define ASC_VERSION "3.2M" /* AdvanSys Driver Version */ /* * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters @@ -673,6 +673,10 @@ at line 7475. The reqp->sgblkp pointer must be initialized to NULL in adv_get_sglist(). + 3.2M (11/29/99): + 1. Really fix bug in adv_get_sglist(). + 2. Incorporate v2.3.29 changes into driver. + J. Known Problems/Fix List (XXX) 1. Need to add memory mapping workaround. Test the memory mapping. @@ -5389,9 +5393,14 @@ advansys_detect(Scsi_Host_Template *tpnt) /* BIOS start address. */ if (ASC_NARROW_BOARD(boardp)) { - shp->base = (char *) ((ulong) AscGetChipBiosAddress( - asc_dvc_varp->iop_base, - asc_dvc_varp->bus_type)); +#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29) + shp->base = +#else /* version >= v2.3.29 */ + shp->base = (char *) +#endif /* version < v2.3.29 */ + ((ulong) AscGetChipBiosAddress( + asc_dvc_varp->iop_base, + asc_dvc_varp->bus_type)); } else { /* * Fill-in BIOS board variables. The Wide BIOS saves @@ -5423,7 +5432,12 @@ advansys_detect(Scsi_Host_Template *tpnt) * Convert x86 realmode code segment to a linear * address by shifting left 4. */ - shp->base = (uchar *) ((ulong) boardp->bios_codeseg << 4); +#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29) + shp->base = +#else /* version >= v2.3.29 */ + shp->base = (char *) +#endif /* version < v2.3.29 */ + ((ulong) boardp->bios_codeseg << 4); } else { shp->base = 0; } @@ -7476,7 +7490,7 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp) slp = (struct scatterlist *) scp->request_buffer; sg_elem_cnt = scp->use_sg; prev_sg_block = NULL; - reqp->sgblkp == NULL; + reqp->sgblkp = NULL; do { diff --git a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h index 010cd6153cd3..4ae0bb33d999 100644 --- a/drivers/scsi/advansys.h +++ b/drivers/scsi/advansys.h @@ -1,4 +1,4 @@ -/* $Id: advansys.h,v 1.17 1998/01/08 21:23:49 bobf Exp bobf $ */ +/* $Id: advansys.h,v 1.18 1999/11/29 21:47:16 bobf Exp bobf $ */ /* * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters @@ -49,7 +49,9 @@ int advansys_reset(Scsi_Cmnd *, unsigned int); int advansys_biosparam(Disk *, int, int[]); #else /* version >= v1.3.0 */ int advansys_biosparam(Disk *, kdev_t, int[]); +#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28) extern struct proc_dir_entry proc_scsi_advansys; +#endif /* version < v2.3.28 */ int advansys_proc_info(char *, char **, off_t, int, int, int); #endif /* version >= v1.3.0 */ @@ -142,7 +144,7 @@ void advansys_setup(char *, int *); */ \ ENABLE_CLUSTERING, /* unsigned use_clustering:1 */ \ } -#else /* version >= v2.1.75 */ +#elif LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28) #define ADVANSYS { \ proc_dir: &proc_scsi_advansys, \ proc_info: advansys_proc_info, \ @@ -154,7 +156,7 @@ void advansys_setup(char *, int *); queuecommand: advansys_queuecommand, \ abort: advansys_abort, \ reset: advansys_reset, \ - bios_param: advansys_biosparam, \ + bios_param: advansys_biosparam, \ /* \ * Because the driver may control an ISA adapter 'unchecked_isa_dma' \ * must be set. The flag will be cleared in advansys_detect for non-ISA \ @@ -170,5 +172,33 @@ void advansys_setup(char *, int *); */ \ use_clustering: ENABLE_CLUSTERING, \ } -#endif /* version >= v2.1.75 */ +#else /* version >= v2.3.28 */ +#define ADVANSYS { \ + proc_name: "advansys", \ + proc_info: advansys_proc_info, \ + name: "advansys", \ + detect: advansys_detect, \ + release: advansys_release, \ + info: advansys_info, \ + command: advansys_command, \ + queuecommand: advansys_queuecommand, \ + abort: advansys_abort, \ + reset: advansys_reset, \ + bios_param: advansys_biosparam, \ + /* \ + * Because the driver may control an ISA adapter 'unchecked_isa_dma' \ + * must be set. The flag will be cleared in advansys_detect for non-ISA \ + * adapters. Refer to the comment in scsi_module.c for more information. \ + */ \ + unchecked_isa_dma: 1, \ + /* \ + * All adapters controlled by this driver are capable of large \ + * scatter-gather lists. According to the mid-level SCSI documentation \ + * this obviates any performance gain provided by setting \ + * 'use_clustering'. But empirically while CPU utilization is increased \ + * by enabling clustering, I/O throughput increases as well. \ + */ \ + use_clustering: ENABLE_CLUSTERING, \ +} +#endif /* version >= v2.3.28 */ #endif /* _ADVANSYS_H */ diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 74ed64d1133e..cfe92eebed09 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h @@ -38,6 +38,7 @@ void send_s870(unsigned char); extern const char *atp870u_info(struct Scsi_Host *); extern int atp870u_proc_info(char *, char **, off_t, int, int, int); +extern struct proc_dir_entry proc_scsi_atp870u; #define ATP870U { \ next: NULL, \ diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index 51ec1b46623e..167383b2b6dd 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -41,6 +41,7 @@ #define MAX_SCSI_DEVICE_CODE 14 extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; +extern spinlock_t scsi_malloc_lock; #ifdef DEBUG #define SCSI_TIMEOUT (5*HZ) diff --git a/fs/buffer.c b/fs/buffer.c index 54babc970d10..991a19cf21c2 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -24,6 +24,9 @@ * - RMK */ +/* invalidate_buffers/set_blocksize/sync_dev race conditions and + fs corruption fixes, 1999, Andrea Arcangeli */ + #include #include #include @@ -263,11 +266,14 @@ repeat: void sync_dev(kdev_t dev) { - sync_buffers(dev, 0); sync_supers(dev); sync_inodes(dev); - sync_buffers(dev, 0); DQUOT_SYNC(dev); + /* sync all the dirty buffers out to disk only _after_ all the + high level layers finished generated buffer dirty data + (or we'll return with some buffer still dirty on the blockdevice + so breaking the semantics of this call) */ + sync_buffers(dev, 0); /* * FIXME(eric) we need to sync the physical devices here. * This is because some (scsi) controllers have huge amounts of @@ -396,31 +402,6 @@ out: return err; } -void invalidate_buffers(kdev_t dev) -{ - int i; - int nlist; - struct buffer_head * bh; - - for(nlist = 0; nlist < NR_LIST; nlist++) { - bh = lru_list[nlist]; - for (i = nr_buffers_type[nlist]*2 ; --i > 0 ; bh = bh->b_next_free) { - if (bh->b_dev != dev) - continue; - wait_on_buffer(bh); - if (bh->b_dev != dev) - continue; - if (bh->b_count) - continue; - bh->b_flushtime = 0; - clear_bit(BH_Protected, &bh->b_state); - clear_bit(BH_Uptodate, &bh->b_state); - clear_bit(BH_Dirty, &bh->b_state); - clear_bit(BH_Req, &bh->b_state); - } - } -} - /* After several hours of tedious analysis, the following hash * function won. Do not mess with it... -DaveM */ @@ -492,11 +473,14 @@ static void remove_from_queues(struct buffer_head * bh) remove_from_lru_list(bh); } -static inline void put_last_free(struct buffer_head * bh) +static void put_last_free(struct buffer_head * bh) { if (bh) { struct buffer_head **bhp = &free_list[BUFSIZE_INDEX(bh->b_size)]; + bh->b_count = 0; + bh->b_state = 0; + remove_from_queues(bh); bh->b_dev = B_FREE; /* So it is obvious we are on the free list. */ /* Add to back of free list. */ @@ -516,7 +500,7 @@ static void insert_into_queues(struct buffer_head * bh) { /* put at end of free list */ if(bh->b_dev == B_FREE) { - put_last_free(bh); + panic("B_FREE inserted into queues"); } else { struct buffer_head **bhp = &lru_list[bh->b_list]; @@ -606,10 +590,61 @@ unsigned int get_hardblocksize(kdev_t dev) return 0; } +/* If invalidate_buffers() will trash dirty buffers, it means some kind + of fs corruption is going on. Trashing dirty data always imply losing + information that was supposed to be just stored on the physical layer + by the user. + + Thus invalidate_buffers in general usage is not allwowed to trash dirty + buffers. For example ioctl(FLSBLKBUF) expects dirty data to be preserved. + + NOTE: In the case where the user removed a removable-media-disk even if + there's still dirty data not synced on disk (due a bug in the device driver + or due an error of the user), by not destroying the dirty buffers we could + generate corruption also on the next media inserted, thus a parameter is + necessary to handle this case in the most safe way possible (trying + to not corrupt also the new disk inserted with the data belonging to + the old now corrupted disk). Also for the ramdisk the natural thing + to do in order to release the ramdisk memory is to destroy dirty buffers. + + These are two special cases. Normal usage imply the device driver + to issue a sync on the device (without waiting I/O completation) and + then an invalidate_buffers call that doesn't trashes dirty buffers. */ +void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers) +{ + int i, nlist, slept; + struct buffer_head * bh, * bhnext; + + again: + slept = 0; + for(nlist = 0; nlist < NR_LIST; nlist++) { + bh = lru_list[nlist]; + if (!bh) + continue; + for (i = nr_buffers_type[nlist] ; i > 0 ; + bh = bhnext, i--) + { + bhnext = bh->b_next_free; + if (bh->b_dev != dev) + continue; + if (buffer_locked(bh)) + { + slept = 1; + __wait_on_buffer(bh); + } + if (!bh->b_count && + (destroy_dirty_buffers || !buffer_dirty(bh))) + put_last_free(bh); + if (slept) + goto again; + } + } +} + void set_blocksize(kdev_t dev, int size) { extern int *blksize_size[]; - int i, nlist; + int i, nlist, slept; struct buffer_head * bh, *bhnext; if (!blksize_size[MAJOR(dev)]) @@ -631,27 +666,35 @@ void set_blocksize(kdev_t dev, int size) /* We need to be quite careful how we do this - we are moving entries * around on the free list, and we can get in a loop if we are not careful. */ - for(nlist = 0; nlist < NR_LIST; nlist++) { + again: + slept = 0; + for(nlist = 0; nlist < NR_LIST; nlist++) { bh = lru_list[nlist]; - for (i = nr_buffers_type[nlist]*2 ; --i > 0 ; bh = bhnext) { - if(!bh) - break; - - bhnext = bh->b_next_free; - if (bh->b_dev != dev) - continue; - if (bh->b_size == size) - continue; - bhnext->b_count++; - wait_on_buffer(bh); - bhnext->b_count--; - if (bh->b_dev == dev && bh->b_size != size) { - clear_bit(BH_Dirty, &bh->b_state); - clear_bit(BH_Uptodate, &bh->b_state); - clear_bit(BH_Req, &bh->b_state); - bh->b_flushtime = 0; + if (!bh) + continue; + for (i = nr_buffers_type[nlist] ; i > 0 ; + bh = bhnext, i--) + { + bhnext = bh->b_next_free; + if (bh->b_dev != dev || bh->b_size == size) + continue; + if (buffer_dirty(bh)) + printk(KERN_ERR "set_blocksize: dev %s buffer_dirty %lu size %lu\n", kdevname(dev), bh->b_blocknr, bh->b_size); + if (buffer_locked(bh)) + { + slept = 1; + wait_on_buffer(bh); } - remove_from_hash_queue(bh); + if (!bh->b_count) + put_last_free(bh); + else + printk(KERN_ERR + "set_blocksize: " + "b_count %d, dev %s, block %lu!\n", + bh->b_count, bdevname(bh->b_dev), + bh->b_blocknr); + if (slept) + goto again; } } } @@ -831,9 +874,6 @@ void __bforget(struct buffer_head * buf) __brelse(buf); return; } - buf->b_count = 0; - buf->b_state = 0; - remove_from_queues(buf); put_last_free(buf); } diff --git a/fs/devices.c b/fs/devices.c index 2ff69850a1b5..756cb04035f6 100644 --- a/fs/devices.c +++ b/fs/devices.c @@ -216,7 +216,8 @@ int check_disk_change(kdev_t dev) if (sb && invalidate_inodes(sb)) printk("VFS: busy inodes on changed media.\n"); - invalidate_buffers(dev); + /* special: trash all dirty data as well as the media is changed */ + destroy_buffers(dev); if (fops->revalidate) fops->revalidate(dev); diff --git a/fs/hfs/file_hdr.c b/fs/hfs/file_hdr.c index c1e1534b04db..5df5c30be5fe 100644 --- a/fs/hfs/file_hdr.c +++ b/fs/hfs/file_hdr.c @@ -164,10 +164,10 @@ const struct hfs_hdr_layout hfs_nat_hdr_layout = { __constant_htonl(HFS_HDR_VERSION_1), /* version */ 5, /* entries */ { /* descr[] */ - {HFS_HDR_FNAME, offsetof(struct hfs_dbl_hdr, real_name), ~0}, - {HFS_HDR_COMNT, offsetof(struct hfs_dbl_hdr, comment), 0}, - {HFS_HDR_OLDI, offsetof(struct hfs_dbl_hdr, create_time), 16}, - {HFS_HDR_FINFO, offsetof(struct hfs_dbl_hdr, finderinfo), 32}, + {HFS_HDR_FNAME, offsetof(struct hfs_nat_hdr, real_name), ~0}, + {HFS_HDR_COMNT, offsetof(struct hfs_nat_hdr, comment), 0}, + {HFS_HDR_OLDI, offsetof(struct hfs_nat_hdr, old_info), 16}, + {HFS_HDR_FINFO, offsetof(struct hfs_nat_hdr, finderinfo), 32}, {HFS_HDR_RSRC, HFS_NAT_HDR_LEN, ~0}, }, { /* order[] */ diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5f257a20ee25..6bfa519dd835 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -674,6 +674,8 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) nfs_invalidate_dircache(dir); error = nfs_proc_mkdir(NFS_DSERVER(dentry), NFS_FH(dentry->d_parent), dentry->d_name.name, &sattr, &fhandle, &fattr); + if (!error) + dir->i_nlink++; return error; } @@ -691,8 +693,8 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) /* Update i_nlink and invalidate dentry. */ if (!error) { d_drop(dentry); - if (dentry->d_inode->i_nlink) - dentry->d_inode->i_nlink --; + if (dir->i_nlink) + dir->i_nlink--; } return error; diff --git a/fs/super.c b/fs/super.c index a7fdd79b6edb..7bec94a6edd6 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1276,7 +1276,10 @@ int __init change_root(kdev_t new_root_dev,const char *put_old) umount_error = do_umount(old_root_dev,1, 0); if (!umount_error) { printk("okay\n"); - invalidate_buffers(old_root_dev); + /* special: the old device driver is going to be + a ramdisk and the point of this call is to free its + protected memory (even if dirty). */ + destroy_buffers(old_root_dev); return 0; } printk(KERN_ERR "error %d\n",umount_error); diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 9186b39e5e8b..9ccdb841a81c 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -27,7 +27,8 @@ extern unsigned long smp_proc_in_lock[NR_CPUS]; extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern void smp_store_cpu_info(int id); -extern void smp_message_recv(void); +extern void smp_message_recv(int); +extern void smp_send_tlb_invalidate(int); #define NO_PROC_ID 0xFF /* No processor magic marker */ #define PROC_CHANGE_PENALTY 20 diff --git a/include/asm-sparc/head.h b/include/asm-sparc/head.h index 86b2c90786fa..9067b97a5cf4 100644 --- a/include/asm-sparc/head.h +++ b/include/asm-sparc/head.h @@ -1,4 +1,4 @@ -/* $Id: head.h,v 1.36.2.1 1999/09/22 11:37:45 jj Exp $ */ +/* $Id: head.h,v 1.36.2.2 1999/12/01 23:55:47 davem Exp $ */ #ifndef __SPARC_HEAD_H #define __SPARC_HEAD_H @@ -93,6 +93,10 @@ #define SETCC_TRAP \ b setcc_trap_handler; mov %psr, %l0; nop; nop; +/* The Get PSR software trap for userland. */ +#define GETPSR_TRAP \ + mov %psr, %o0; jmpl %l2, %g0; rett %l2 + 4; nop; + /* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and * gets handled with another macro. */ diff --git a/include/asm-sparc/ioctl.h b/include/asm-sparc/ioctl.h index e6c645fff337..91ad6b78cf1c 100644 --- a/include/asm-sparc/ioctl.h +++ b/include/asm-sparc/ioctl.h @@ -1,4 +1,4 @@ -/* $Id: ioctl.h,v 1.5 1996/05/17 03:31:09 davem Exp $ */ +/* $Id: ioctl.h,v 1.5.12.1 1999/12/01 23:57:52 davem Exp $ */ #ifndef _SPARC_IOCTL_H #define _SPARC_IOCTL_H @@ -40,4 +40,12 @@ #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) +/* ...and for the PCMCIA... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + #endif /* !(_SPARC_IOCTL_H) */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 5aed835c2a04..548b9d74964d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -783,7 +783,9 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag) extern int check_disk_change(kdev_t dev); extern int invalidate_inodes(struct super_block * sb); extern void invalidate_inode_pages(struct inode *); -extern void invalidate_buffers(kdev_t dev); +#define invalidate_buffers(dev) __invalidate_buffers((dev), 0) +#define destroy_buffers(dev) __invalidate_buffers((dev), 1) +extern void __invalidate_buffers(kdev_t dev, int); extern int floppy_is_wp(int minor); extern void sync_inodes(kdev_t dev); extern void write_inode_now(struct inode *inode); diff --git a/include/linux/hfs_fs.h b/include/linux/hfs_fs.h index 36cf43f5e5f3..851bcb0ddc35 100644 --- a/include/linux/hfs_fs.h +++ b/include/linux/hfs_fs.h @@ -140,6 +140,19 @@ struct hfs_hdr_layout { *order[HFS_HDR_MAX]; /* 'descr' ordered by offset */ }; +/* header layout for netatalk's v1 appledouble file format */ +struct hfs_nat_hdr { + hfs_lword_t magic; + hfs_lword_t version; + hfs_byte_t homefs[16]; + hfs_word_t entries; + hfs_byte_t descrs[12*5]; + hfs_byte_t real_name[255]; /* id=3 */ + hfs_byte_t comment[200]; /* id=4 XXX: not yet implemented */ + hfs_byte_t old_info[16]; /* id=7 */ + hfs_u8 finderinfo[32]; /* id=9 */ +}; + /* * Default header layout for Netatalk and AppleDouble */ @@ -162,7 +175,6 @@ struct hfs_dbl_hdr { hfs_u8 prodosi[8]; /* id=11 */ }; - /* finder metadata for CAP */ struct hfs_cap_info { hfs_byte_t fi_fndr[32]; /* Finder's info */ diff --git a/include/linux/openpic.h b/include/linux/openpic.h index 9cf18c5da172..681020420308 100644 --- a/include/linux/openpic.h +++ b/include/linux/openpic.h @@ -50,10 +50,9 @@ * Vector numbers */ -#define OPENPIC_VEC_SOURCE 0x10 /* and up */ -#define OPENPIC_VEC_TIMER 0x40 /* and up */ -#define OPENPIC_VEC_IPI 0x50 /* and up */ -#define OPENPIC_VEC_SPURIOUS 99 +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 70 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 /* diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 7720ae0c0d33..086ad3681cee 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -18,8 +18,6 @@ * SCSI opcodes */ -extern spinlock_t scsi_malloc_lock; - #define TEST_UNIT_READY 0x00 #define REZERO_UNIT 0x01 #define REQUEST_SENSE 0x03 diff --git a/kernel/ksyms.c b/kernel/ksyms.c index a771c9a632e7..c8a87b6ff640 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -148,7 +148,7 @@ EXPORT_SYMBOL(filp_close); EXPORT_SYMBOL(fput); EXPORT_SYMBOL(put_filp); EXPORT_SYMBOL(check_disk_change); -EXPORT_SYMBOL(invalidate_buffers); +EXPORT_SYMBOL(__invalidate_buffers); EXPORT_SYMBOL(invalidate_inodes); EXPORT_SYMBOL(invalidate_inode_pages); EXPORT_SYMBOL(truncate_inode_pages); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9fc6a8e6d923..393a1d61156e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -632,7 +632,6 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr, if (dst == NULL) { struct flowi fl; - struct dst_entry *dst; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity -- 2.39.5