## Automatically generated incremental diff
## From:   linux-2.2.14-pre9
## To:     linux-2.2.14-pre10
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.2.14-pre9/arch/ppc/boot/Makefile linux-2.2.14-pre10/arch/ppc/boot/Makefile
--- linux-2.2.14-pre9/arch/ppc/boot/Makefile	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/boot/Makefile	2003-08-15 15:09:20.000000000 -0700
@@ -134,7 +134,7 @@
 	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 -urN linux-2.2.14-pre9/arch/ppc/chrpboot/string.S linux-2.2.14-pre10/arch/ppc/chrpboot/string.S
--- linux-2.2.14-pre9/arch/ppc/chrpboot/string.S	1998-01-12 15:18:13.000000000 -0800
+++ linux-2.2.14-pre10/arch/ppc/chrpboot/string.S	1969-12-31 16:00:00.000000000 -0800
@@ -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 -urN linux-2.2.14-pre9/arch/ppc/kernel/chrp_setup.c linux-2.2.14-pre10/arch/ppc/kernel/chrp_setup.c
--- linux-2.2.14-pre9/arch/ppc/kernel/chrp_setup.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/chrp_setup.c	2003-08-15 15:09:20.000000000 -0700
@@ -386,8 +386,8 @@
                 }
         }
 #endif /* __SMP__ */
-
-        irq = openpic_irq(0);
+	
+        irq = openpic_irq(smp_processor_id());
         if (irq == IRQ_8259_CASCADE)
         {
                 /*
@@ -402,7 +402,7 @@
                 /*
                  * 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 @@
 	}
 out:
         if (!openpic_eoi_done)
-                openpic_eoi(0);
+                openpic_eoi(smp_processor_id());
 }
 
 __initfunc(void
@@ -449,10 +449,6 @@
 	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 @@
 		    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 @@
 {
 	adb_init();
 
-	/* Should this be here? - Corey */
 	pmac_nvram_init();
 
 #ifdef CONFIG_VT
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/gemini_setup.c linux-2.2.14-pre10/arch/ppc/kernel/gemini_setup.c
--- linux-2.2.14-pre9/arch/ppc/kernel/gemini_setup.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/gemini_setup.c	2003-08-15 15:09:20.000000000 -0700
@@ -57,17 +57,7 @@
 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 @@
 
 	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 @@
 		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 @@
 
 	/* 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 -urN linux-2.2.14-pre9/arch/ppc/kernel/head.S linux-2.2.14-pre10/arch/ppc/kernel/head.S
--- linux-2.2.14-pre9/arch/ppc/kernel/head.S	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/head.S	2003-08-15 15:09:20.000000000 -0700
@@ -234,7 +234,7 @@
 	.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 @@
 	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 @@
 	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 -urN linux-2.2.14-pre9/arch/ppc/kernel/irq.c linux-2.2.14-pre10/arch/ppc/kernel/irq.c
--- linux-2.2.14-pre9/arch/ppc/kernel/irq.c	1999-08-25 17:29:46.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/irq.c	2003-08-15 15:09:20.000000000 -0700
@@ -94,8 +94,8 @@
  * 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 @@
 	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_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);
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/open_pic.c linux-2.2.14-pre10/arch/ppc/kernel/open_pic.c
--- linux-2.2.14-pre9/arch/ppc/kernel/open_pic.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/open_pic.c	2003-08-15 15:09:20.000000000 -0700
@@ -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__ */
 
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/openpic.c linux-2.2.14-pre10/arch/ppc/kernel/openpic.c
--- linux-2.2.14-pre9/arch/ppc/kernel/openpic.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/openpic.c	2003-08-15 15:09:20.000000000 -0700
@@ -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>
@@ -23,12 +20,11 @@
 #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 @@
 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 @@
 #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 @@
 #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 @@
 #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);
+		/* 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();
-    }
+		/* 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;
+	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;
+	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 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));
 }
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/open_pic.h linux-2.2.14-pre10/arch/ppc/kernel/open_pic.h
--- linux-2.2.14-pre9/arch/ppc/kernel/open_pic.h	1999-04-29 12:39:01.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/open_pic.h	2003-08-15 15:09:20.000000000 -0700
@@ -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 */
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/pmac_pic.c linux-2.2.14-pre10/arch/ppc/kernel/pmac_pic.c
--- linux-2.2.14-pre9/arch/ppc/kernel/pmac_pic.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/pmac_pic.c	2003-08-15 15:09:20.000000000 -0700
@@ -168,7 +168,7 @@
                         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 -urN linux-2.2.14-pre9/arch/ppc/kernel/process.c linux-2.2.14-pre10/arch/ppc/kernel/process.c
--- linux-2.2.14-pre9/arch/ppc/kernel/process.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/process.c	2003-08-15 15:09:20.000000000 -0700
@@ -187,18 +187,6 @@
 
 	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;
diff -urN linux-2.2.14-pre9/arch/ppc/kernel/prom.c linux-2.2.14-pre10/arch/ppc/kernel/prom.c
--- linux-2.2.14-pre9/arch/ppc/kernel/prom.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/prom.c	2003-08-15 15:09:20.000000000 -0700
@@ -539,7 +539,7 @@
 		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 -urN linux-2.2.14-pre9/arch/ppc/kernel/ptrace.c linux-2.2.14-pre10/arch/ppc/kernel/ptrace.c
--- linux-2.2.14-pre9/arch/ppc/kernel/ptrace.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/ptrace.c	2003-08-15 15:09:20.000000000 -0700
@@ -413,11 +413,10 @@
 	/* 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 @@
 				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 -urN linux-2.2.14-pre9/arch/ppc/kernel/signal.c linux-2.2.14-pre10/arch/ppc/kernel/signal.c
--- linux-2.2.14-pre9/arch/ppc/kernel/signal.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/signal.c	2003-08-15 15:09:20.000000000 -0700
@@ -471,8 +471,7 @@
 
 		/* 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 @@
 		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 -urN linux-2.2.14-pre9/arch/ppc/kernel/smp.c linux-2.2.14-pre10/arch/ppc/kernel/smp.c
--- linux-2.2.14-pre9/arch/ppc/kernel/smp.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/kernel/smp.c	2003-08-15 15:09:20.000000000 -0700
@@ -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 @@
 	}
 }
 
-/*
- * 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 @@
 		__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 @@
 	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 @@
 		/* 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 @@
 			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 @@
 		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 @@
 		}
 	}
 	
+	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 @@
 #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 @@
 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 -urN linux-2.2.14-pre9/arch/ppc/mm/init.c linux-2.2.14-pre10/arch/ppc/mm/init.c
--- linux-2.2.14-pre9/arch/ppc/mm/init.c	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/ppc/mm/init.c	2003-08-15 15:09:20.000000000 -0700
@@ -116,6 +116,7 @@
 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 @@
 #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 @@
 	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 @@
 		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 @@
 	{
 		flush_hash_page(mm->context, start);
 	}
+#ifdef __SMP__
+	smp_send_tlb_invalidate(0);
+#endif	
 #else
 	asm volatile ("tlbia" : : );
 #endif
@@ -581,6 +594,9 @@
 	}
 	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 -urN linux-2.2.14-pre9/arch/sparc/kernel/head.S linux-2.2.14-pre10/arch/sparc/kernel/head.S
--- linux-2.2.14-pre9/arch/sparc/kernel/head.S	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/arch/sparc/kernel/head.S	2003-08-15 15:09:20.000000000 -0700
@@ -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_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 @@
 	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 @@
 	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 @@
 	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 -urN linux-2.2.14-pre9/arch/sparc64/kernel/traps.c linux-2.2.14-pre10/arch/sparc64/kernel/traps.c
--- linux-2.2.14-pre9/arch/sparc64/kernel/traps.c	1999-10-19 17:14:00.000000000 -0700
+++ linux-2.2.14-pre10/arch/sparc64/kernel/traps.c	2003-08-15 15:09:20.000000000 -0700
@@ -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 @@
 }
 #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 -urN linux-2.2.14-pre9/arch/sparc64/kernel/ttable.S linux-2.2.14-pre10/arch/sparc64/kernel/ttable.S
--- linux-2.2.14-pre9/arch/sparc64/kernel/ttable.S	1999-10-19 17:14:00.000000000 -0700
+++ linux-2.2.14-pre10/arch/sparc64/kernel/ttable.S	2003-08-15 15:09:20.000000000 -0700
@@ -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_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 -urN linux-2.2.14-pre9/CREDITS linux-2.2.14-pre10/CREDITS
--- linux-2.2.14-pre9/CREDITS	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/CREDITS	2003-08-15 15:09:20.000000000 -0700
@@ -137,12 +137,9 @@
 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: 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 -urN linux-2.2.14-pre9/Documentation/Configure.help linux-2.2.14-pre10/Documentation/Configure.help
--- linux-2.2.14-pre9/Documentation/Configure.help	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/Documentation/Configure.help	2003-08-15 15:09:20.000000000 -0700
@@ -1199,7 +1199,7 @@
   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 -urN linux-2.2.14-pre9/Documentation/kernel-docs.txt linux-2.2.14-pre10/Documentation/kernel-docs.txt
--- linux-2.2.14-pre9/Documentation/kernel-docs.txt	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/Documentation/kernel-docs.txt	2003-08-15 15:09:20.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/Documentation/networking/tlan.txt linux-2.2.14-pre10/Documentation/networking/tlan.txt
--- linux-2.2.14-pre9/Documentation/networking/tlan.txt	1998-07-24 11:15:05.000000000 -0700
+++ linux-2.2.14-pre10/Documentation/networking/tlan.txt	2003-08-15 15:09:20.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/drivers/block/rd.c linux-2.2.14-pre10/drivers/block/rd.c
--- linux-2.2.14-pre9/drivers/block/rd.c	1999-08-09 12:04:39.000000000 -0700
+++ linux-2.2.14-pre10/drivers/block/rd.c	2003-08-15 15:09:20.000000000 -0700
@@ -191,7 +191,10 @@
 	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 @@
 	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 -urN linux-2.2.14-pre9/drivers/net/sk98lin/h/skdrv1st.h linux-2.2.14-pre10/drivers/net/sk98lin/h/skdrv1st.h
--- linux-2.2.14-pre9/drivers/net/sk98lin/h/skdrv1st.h	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/drivers/net/sk98lin/h/skdrv1st.h	2003-08-15 15:09:20.000000000 -0700
@@ -175,6 +175,12 @@
 
 #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 -urN linux-2.2.14-pre9/drivers/net/sk98lin/Makefile linux-2.2.14-pre10/drivers/net/sk98lin/Makefile
--- linux-2.2.14-pre9/drivers/net/sk98lin/Makefile	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/drivers/net/sk98lin/Makefile	2003-08-15 15:09:20.000000000 -0700
@@ -19,11 +19,14 @@
   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 -urN linux-2.2.14-pre9/drivers/scsi/advansys.c linux-2.2.14-pre10/drivers/scsi/advansys.c
--- linux-2.2.14-pre9/drivers/scsi/advansys.c	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/drivers/scsi/advansys.c	2003-08-15 15:09:21.000000000 -0700
@@ -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 @@
 
             /* 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 @@
                      * 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 @@
     slp = (struct scatterlist *) scp->request_buffer;
     sg_elem_cnt = scp->use_sg;
     prev_sg_block = NULL;
-    reqp->sgblkp == NULL;
+    reqp->sgblkp = NULL;
 
     do
     {
diff -urN linux-2.2.14-pre9/drivers/scsi/advansys.h linux-2.2.14-pre10/drivers/scsi/advansys.h
--- linux-2.2.14-pre9/drivers/scsi/advansys.h	1999-05-11 10:36:28.000000000 -0700
+++ linux-2.2.14-pre10/drivers/scsi/advansys.h	2003-08-15 15:09:21.000000000 -0700
@@ -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_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 @@
      */ \
     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 @@
     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 @@
      */ \
     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 -urN linux-2.2.14-pre9/drivers/scsi/atp870u.h linux-2.2.14-pre10/drivers/scsi/atp870u.h
--- linux-2.2.14-pre9/drivers/scsi/atp870u.h	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/drivers/scsi/atp870u.h	2003-08-15 15:09:21.000000000 -0700
@@ -38,6 +38,7 @@
 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 -urN linux-2.2.14-pre9/drivers/scsi/scsi.h linux-2.2.14-pre10/drivers/scsi/scsi.h
--- linux-2.2.14-pre9/drivers/scsi/scsi.h	1999-08-09 12:04:40.000000000 -0700
+++ linux-2.2.14-pre10/drivers/scsi/scsi.h	2003-08-15 15:09:21.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/fs/buffer.c linux-2.2.14-pre10/fs/buffer.c
--- linux-2.2.14-pre9/fs/buffer.c	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/fs/buffer.c	2003-08-15 15:09:21.000000000 -0700
@@ -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 @@
 
 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 @@
 	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 @@
 	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 @@
 {
 	/* 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 @@
 	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 @@
 	/* 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 @@
 		__brelse(buf);
 		return;
 	}
-	buf->b_count = 0;
-	buf->b_state = 0;
-	remove_from_queues(buf);
 	put_last_free(buf);
 }
 
diff -urN linux-2.2.14-pre9/fs/devices.c linux-2.2.14-pre10/fs/devices.c
--- linux-2.2.14-pre9/fs/devices.c	1998-12-23 11:39:49.000000000 -0800
+++ linux-2.2.14-pre10/fs/devices.c	2003-08-15 15:09:21.000000000 -0700
@@ -216,7 +216,8 @@
 	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 -urN linux-2.2.14-pre9/fs/hfs/file_hdr.c linux-2.2.14-pre10/fs/hfs/file_hdr.c
--- linux-2.2.14-pre9/fs/hfs/file_hdr.c	1999-05-12 13:26:34.000000000 -0700
+++ linux-2.2.14-pre10/fs/hfs/file_hdr.c	2003-08-15 15:09:21.000000000 -0700
@@ -164,10 +164,10 @@
 	__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 -urN linux-2.2.14-pre9/fs/nfs/dir.c linux-2.2.14-pre10/fs/nfs/dir.c
--- linux-2.2.14-pre9/fs/nfs/dir.c	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/fs/nfs/dir.c	2003-08-15 15:09:21.000000000 -0700
@@ -674,6 +674,8 @@
 	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 @@
 	/* 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 -urN linux-2.2.14-pre9/fs/super.c linux-2.2.14-pre10/fs/super.c
--- linux-2.2.14-pre9/fs/super.c	1999-08-09 12:04:41.000000000 -0700
+++ linux-2.2.14-pre10/fs/super.c	2003-08-15 15:09:21.000000000 -0700
@@ -1276,7 +1276,10 @@
 		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 -urN linux-2.2.14-pre9/include/asm-ppc/smp.h linux-2.2.14-pre10/include/asm-ppc/smp.h
--- linux-2.2.14-pre9/include/asm-ppc/smp.h	1999-04-29 12:39:07.000000000 -0700
+++ linux-2.2.14-pre10/include/asm-ppc/smp.h	2003-08-15 15:09:21.000000000 -0700
@@ -27,7 +27,8 @@
 
 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 -urN linux-2.2.14-pre9/include/asm-sparc/head.h linux-2.2.14-pre10/include/asm-sparc/head.h
--- linux-2.2.14-pre9/include/asm-sparc/head.h	1999-10-19 17:14:02.000000000 -0700
+++ linux-2.2.14-pre10/include/asm-sparc/head.h	2003-08-15 15:09:21.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/include/asm-sparc/ioctl.h linux-2.2.14-pre10/include/asm-sparc/ioctl.h
--- linux-2.2.14-pre9/include/asm-sparc/ioctl.h	1996-11-09 00:29:28.000000000 -0800
+++ linux-2.2.14-pre10/include/asm-sparc/ioctl.h	2003-08-15 15:09:21.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/include/linux/fs.h linux-2.2.14-pre10/include/linux/fs.h
--- linux-2.2.14-pre9/include/linux/fs.h	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/include/linux/fs.h	2003-08-15 15:09:21.000000000 -0700
@@ -783,7 +783,9 @@
 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 -urN linux-2.2.14-pre9/include/linux/hfs_fs.h linux-2.2.14-pre10/include/linux/hfs_fs.h
--- linux-2.2.14-pre9/include/linux/hfs_fs.h	1999-05-12 13:26:34.000000000 -0700
+++ linux-2.2.14-pre10/include/linux/hfs_fs.h	2003-08-15 15:09:21.000000000 -0700
@@ -140,6 +140,19 @@
 			*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 @@
 	hfs_u8          prodosi[8];     /* id=11 */
 };
 
-
 /* finder metadata for CAP */
 struct hfs_cap_info {
 	hfs_byte_t	fi_fndr[32];	/* Finder's info */
diff -urN linux-2.2.14-pre9/include/linux/openpic.h linux-2.2.14-pre10/include/linux/openpic.h
--- linux-2.2.14-pre9/include/linux/openpic.h	1999-03-19 10:51:42.000000000 -0800
+++ linux-2.2.14-pre10/include/linux/openpic.h	2003-08-15 15:09:21.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/include/scsi/scsi.h linux-2.2.14-pre10/include/scsi/scsi.h
--- linux-2.2.14-pre9/include/scsi/scsi.h	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/include/scsi/scsi.h	1999-03-15 16:11:31.000000000 -0800
@@ -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 -urN linux-2.2.14-pre9/kernel/ksyms.c linux-2.2.14-pre10/kernel/ksyms.c
--- linux-2.2.14-pre9/kernel/ksyms.c	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/kernel/ksyms.c	2003-08-15 15:09:21.000000000 -0700
@@ -148,7 +148,7 @@
 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 -urN linux-2.2.14-pre9/MAINTAINERS linux-2.2.14-pre10/MAINTAINERS
--- linux-2.2.14-pre9/MAINTAINERS	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/MAINTAINERS	2003-08-15 15:09:20.000000000 -0700
@@ -811,10 +811,8 @@
 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 -urN linux-2.2.14-pre9/Makefile linux-2.2.14-pre10/Makefile
--- linux-2.2.14-pre9/Makefile	2003-08-15 15:09:19.000000000 -0700
+++ linux-2.2.14-pre10/Makefile	2003-08-15 15:09:20.000000000 -0700
@@ -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 -urN linux-2.2.14-pre9/net/ipv6/tcp_ipv6.c linux-2.2.14-pre10/net/ipv6/tcp_ipv6.c
--- linux-2.2.14-pre9/net/ipv6/tcp_ipv6.c	2003-08-15 15:09:20.000000000 -0700
+++ linux-2.2.14-pre10/net/ipv6/tcp_ipv6.c	2003-08-15 15:09:21.000000000 -0700
@@ -632,7 +632,6 @@
 
 		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
