]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.14pre10 2.2.14pre10
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:20:22 +0000 (15:20 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:20:22 +0000 (15:20 -0500)
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)

47 files changed:
CREDITS
Documentation/Configure.help
Documentation/kernel-docs.txt
Documentation/networking/tlan.txt
MAINTAINERS
Makefile
arch/i386/vmlinux.lds [deleted file]
arch/ppc/boot/Makefile
arch/ppc/chrpboot/string.S [deleted file]
arch/ppc/kernel/chrp_setup.c
arch/ppc/kernel/gemini_setup.c
arch/ppc/kernel/head.S
arch/ppc/kernel/irq.c
arch/ppc/kernel/open_pic.c
arch/ppc/kernel/open_pic.h
arch/ppc/kernel/openpic.c
arch/ppc/kernel/pmac_pic.c
arch/ppc/kernel/process.c
arch/ppc/kernel/prom.c
arch/ppc/kernel/ptrace.c
arch/ppc/kernel/signal.c
arch/ppc/kernel/smp.c
arch/ppc/mm/init.c
arch/sparc/kernel/head.S
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/ttable.S
drivers/block/rd.c
drivers/net/sk98lin/Makefile
drivers/net/sk98lin/h/skdrv1st.h
drivers/scsi/advansys.c
drivers/scsi/advansys.h
drivers/scsi/atp870u.h
drivers/scsi/scsi.h
fs/buffer.c
fs/devices.c
fs/hfs/file_hdr.c
fs/nfs/dir.c
fs/super.c
include/asm-ppc/smp.h
include/asm-sparc/head.h
include/asm-sparc/ioctl.h
include/linux/fs.h
include/linux/hfs_fs.h
include/linux/openpic.h
include/scsi/scsi.h
kernel/ksyms.c
net/ipv6/tcp_ipv6.c

diff --git a/CREDITS b/CREDITS
index 962e9bd0f4e63aa228283a3a455984ab23dbf990..fac4dd8c95f5e52f5b3ae976be90e39f80026bfb 100644 (file)
--- 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
index 1bfe3f0c6c11d467a74b86f1d462e141887cfcaa..3d0434f8b0a4c31b891f9b894a27a92e73e08675 100644 (file)
@@ -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
index e56e465e8885fd260fef6c7e52ce3e5e709a02cb..8f76009c5eba1fc13fde70c84325cd20da1242b8 100644 (file)
        
      * 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"
        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.
        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
index d3de6ccd10a9a45889a80cda4129be1fbb02f837..4114be27a93764022580589a2499c5c8284dbfde 100644 (file)
@@ -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.
 
index 1d811af9fcd46a08aa00e238a514a4ded3b7d060..1b617feacffaebc96e1a9e4a4fdcdb0ea345b326 100644 (file)
@@ -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
index 07106ce6d3c905476b1b1b8828f4c30c849a9706..f14582e1a002eac086c59d329d4704a4c293df7b 100644 (file)
--- 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 (file)
index ecf90c2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-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) }
-}
index 41a8a915f4780503c8a332d01217ca5588e2762d..96b6ba306ecce10c6d0c39e6706e411440730a0b 100644 (file)
@@ -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 (file)
index ba83591..0000000
+++ /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
index 8d2d4e9b8db10afbd55fa329ec6aa4fb6ee7ccef..f80ad32365fe0ce5c00cbccceff749d3744cf540 100644 (file)
@@ -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
index d9abea743bda8c29f5c5a21450f6995075aec38c..de49c235d3ee1c7680e8f43d0e71bc909d9d7019 100644 (file)
@@ -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<<irq;
-       irq -= OPENPIC_VEC_SOURCE;
-       
+
        if (irq < 0) {
                printk(KERN_DEBUG "Bogus interrupt %d from pc=%lx\n", irq,
                       regs->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__ */
 }
 
index 898ce1d2768a517785caf85e3876fed95c0479e0..0c17abf080091a5a82a5ab0019104cf2f78db0ea 100644 (file)
@@ -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
index d0da0db398cb17aa859f2fca5e2b4570b7c2a66e..53395a4a3542d02d7281c42dce4d21a66e3a76d8 100644 (file)
@@ -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<<i) ) )
+       for ( i = 0; i < 32 ; i++ )
+               if ( ! (test_bit(i, (void *)cache_bitmask)) )
                {
-                       cache_bitmask |= (1<<i);
+                       set_bit(i,(void *)cache_bitmask);
                        return (void *)(&malloc_cache[i]);
                }
        return 0;
@@ -115,10 +115,10 @@ void *irq_kmalloc(size_t size, int pri)
 void irq_kfree(void *ptr)
 {
        unsigned int i;
-       for ( i = 0 ; i <= 3 ; i++ )
+       for ( i = 0 ; i < 32 ; i++ )
                if ( ptr == &malloc_cache[i] )
                {
-                       cache_bitmask &= ~(1<<i);
+                       clear_bit( i, (void *)cache_bitmask );
                        return;
                }
        kfree(ptr);
index eddf6e4d47f44ab1ba64a015554e14231e3f8be2..47b68e68fe2e882c1c24e1c0a469fe1c3deb94a4 100644 (file)
@@ -10,7 +10,7 @@
 #ifdef __SMP__
 void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
-       smp_message_recv();
+       smp_message_recv(cpl-OPENPIC_VEC_IPI);
 }
 #endif /* __SMP__ */
 
index 77b8a46d0ae262f0a138a71cdb1a5d4bf9011815..83ffb7f91d0ab9a59815f2ceb3ba9496d71420d5 100644 (file)
@@ -7,5 +7,7 @@
 extern struct hw_interrupt_type open_pic;
 
 void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+void openpic_enable_IPI(u_int ipi);
+void do_openpic_setup_cpu(void);
 
 #endif /* _PPC_KERNEL_OPEN_PIC_H */
index cb2f6454b9c28bef3b82cb101f03c543a6d88ce5..9fb8f274bda42eaeeee5e3ad16aaffdd83d248dc 100644 (file)
@@ -3,17 +3,14 @@
  *
  *  Copyright (C) 1997 Geert Uytterhoeven
  *
+ *  Fixed up IPI and restructured a bit
+ *    Cort Dougan <cort@ppc.kernel.org>
+ * 
  *  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 <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/signal.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-
+#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<<smp_processor_id()) );
+#endif 
+       openpic_set_priority(smp_processor_id(), 0);
+}    
 
+/*
+ *  Initialize a timer interrupt (and disable it)
+ *
+ *  timer: OpenPIC timer number
+ *  pri: interrupt source priority
+ *  vec: the vector it will produce
+ */
 void openpic_inittimer(u_int timer, u_int pri, u_int 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);
+       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));
 }
index 611372661026f9213128e6a52cf0d8f4d42f8f68..a1610c445bd0a77d9894057016995e7957a21557 100644 (file)
@@ -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
index a36c32995fe8352ea0da5fc2487bcabfc5e6cf24..9041fe3be2763c958b3377c1a236158103486a5e 100644 (file)
@@ -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 = &current->tss;
index 12546e5bf78022601e646474c8e89b7d2911c28a..23a594e90d61608f2614dcbc710df200c39bfaf7 100644 (file)
@@ -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 );
index 37c71dd40cfeb2dab8893e73ed9ad4b7fc295d2d..19e1c3fbab147b54a2194007c576babaf2f1505a 100644 (file)
@@ -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;
                }
 
index 05d5c6de3ad7141ae1ef85428191a718d31e8781..05a48d1b44f8e05214e9c7c63c4aff11d0d81246 100644 (file)
@@ -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;
 
 }
 
index ab7a2d74f65208a661e5b3e38b1f9794a8ab89d2..3de43f4cb5b944fbd1d2c9dc5cc9e2726affa154 100644 (file)
@@ -37,6 +37,8 @@
 #include <asm/gemini.h>
 
 #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<<target);
                        break;
                }
                break;
        }
-       
-       spin_unlock(&mesg_pass_lock);
 }
 
 void __init smp_boot_cpus(void)
@@ -298,8 +314,6 @@ void __init smp_boot_cpus(void)
                        break;
                }
        case _MACH_gemini:
-               for ( i = 0; i < 4 ; i++ )
-                       openpic_enable_IPI(i);
                 cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>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();
 }
+
index 9da48426effa593be99c75cb99c8eec7951b84e2..c672c86151e1693aa6026233c0045fd9425e9309 100644 (file)
@@ -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));
index 783feb814c7b214454eb3a2c3ae3531f593bbb78..849409fe141d7ae6e291c70fdfc95d55eddf8601 100644 (file)
@@ -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)
index d03aa26989a7ac8baa7564105225fdba7fca19b5..2fe05199fb082d964d70185aea381eb148e76721 100644 (file)
@@ -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 <asm/uaccess.h>
 #include <asm/fpumacro.h>
 #include <asm/lsu.h>
+#include <asm/psrcompat.h>
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #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)
 {
 }
index 7a45b3a8ed793165bb52614e9ccbe8e964dc6be1..5551b57d9933341afb117795d92dffa5c79db3b3 100644 (file)
@@ -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)
index 771183b7a455ac07f26963f7b20aeb87ec4f4d0f..f0971f5a5fa74c4918a2d280a3f96e3f47269e1a 100644 (file)
@@ -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;
index a5d1e8a7561a1b009028a17f96fa7315aa94181b..7dfe263beab27257822e0ec7b147c30f3db14a53 100644 (file)
@@ -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 *****************
index 4b24fa3bdbe12da78c3e6ce245312ff6b319f3dc..446c9b49d3b29aa848cd7c8a83946ea4754a5d38 100644 (file)
@@ -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)
index d43ba0129fe01e2e3e696855747eb6a0c53affad..93387842f5c3217d1cee356210350125b920d17d 100644 (file)
@@ -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
             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
     {
index 010cd6153cd308df58b3998fd22c328d8717d07c..4ae0bb33d99902ea9d1bfdd5e050a1c856238249 100644 (file)
@@ -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 */
index 74ed64d1133e42ce9c3a2c734d4564e9bfbc42da..cfe92eebed0989fefc94c3b4250ed51a1035844b 100644 (file)
@@ -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,                                             \
index 51ec1b46623ed31ada3e9034deab6c0daeb7d77c..167383b2b6dd50e64bd623b33edebd099a05f077 100644 (file)
@@ -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)
index 54babc970d108597bd35b3d58f5ff335304fe2cc..991a19cf21c2c779c7b71bc1788a4e644178142b 100644 (file)
@@ -24,6 +24,9 @@
  * - RMK
  */
 
+/* invalidate_buffers/set_blocksize/sync_dev race conditions and
+   fs corruption fixes, 1999, Andrea Arcangeli <andrea@suse.de> */
+
 #include <linux/malloc.h>
 #include <linux/locks.h>
 #include <linux/errno.h>
@@ -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);
 }
 
index 2ff69850a1b562b60a2753029a940974f164985d..756cb04035f6e4e78ef7383066dd3c170fc3e21a 100644 (file)
@@ -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);
index c1e1534b04dba61d6c405cefc2a0024fc39ce4cb..5df5c30be5fe9359e66972243995775bbdfd4836 100644 (file)
@@ -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[] */
index 5f257a20ee25cf5483f4d08870be4da20b7a0e75..6bfa519dd8358e10540734090abd4bc4371f5189 100644 (file)
@@ -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;
index a7fdd79b6edb51f8ad6dad0491a9b746635bf4df..7bec94a6edd69baafe445b04237f24c612ce51da 100644 (file)
@@ -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);
index 9186b39e5e8bbd2503027ad6017e2e37978170cc..9ccdb841a81c6a5e8491b8395fe56dcbc39ca961 100644 (file)
@@ -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
index 86b2c90786fab74ed0f87c0cc8fe98eddad6d9bb..9067b97a5cf401ec4b7c4671e0951ab90723b61a 100644 (file)
@@ -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
 
 #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.
  */
index e6c645fff337e2204af94650a40d7f6d458779cd..91ad6b78cf1c12b2a3122e630f4aed46ea947361 100644 (file)
@@ -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
 
 #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) */
index 5aed835c2a041aaab78a9c05a455d2db1bf0460b..548b9d74964d0e3d1303abe01caef11ac6242b64 100644 (file)
@@ -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);
index 36cf43f5e5f3c64e33528d4579f4ca9910302361..851bcb0ddc35467edae0d5e1cbc2d2030d4ee66d 100644 (file)
@@ -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 */
index 9cf18c5da1720c2eab0118b4c9603f1c51b379a8..681020420308f314bdca695ee64f4edf371f57b5 100644 (file)
      *  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
 
 
     /*
index 7720ae0c0d3351b1e4218ef68f2927c9d713029e..086ad3681cee09416d0758cf032992a23a239938 100644 (file)
@@ -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
index a771c9a632e7e2b44aade747d160b60f36b6fff9..c8a87b6ff6401d06ba8a1a7c126a514d121f4bf2 100644 (file)
@@ -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);
index 9fc6a8e6d9232f71302638151448204579b1d963..393a1d61156e5dacd3684d9d4e27979f66355717 100644 (file)
@@ -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