## Automatically generated incremental diff
## From:   linux-2.2.16-pre8
## To:     linux-2.2.16
## Robot:  $Id: make-incremental-diff,v 1.7 2001/12/04 05:19:54 hpa Exp hpa $

diff -urN linux-2.2.16-pre8/MAINTAINERS linux/MAINTAINERS
--- linux-2.2.16-pre8/MAINTAINERS	Mon Dec  3 22:05:04 2001
+++ linux/MAINTAINERS	Mon Dec  3 22:05:10 2001
@@ -257,7 +257,7 @@
 
 DIGI RIGHTSWITCH NETWORK DRIVER
 P:	Rick Richardson
-M:	rick@dgii.com
+M:	rick@remotepoint.com
 L:	linux-net@vger.rutgers.edu
 W:	http://www.dgii.com/linux/
 S:	Maintained
@@ -414,7 +414,7 @@
 
 IDE DRIVER [GENERAL]
 P:	Andre Hedrick
-M:	hedrick@astro.dyer.vanderbilt.edu
+M:	andre@linux-ide.org
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
diff -urN linux-2.2.16-pre8/Makefile linux/Makefile
--- linux-2.2.16-pre8/Makefile	Mon Dec  3 22:05:04 2001
+++ linux/Makefile	Mon Dec  3 22:05:10 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 16
-EXTRAVERSION = pre8
+EXTRAVERSION = 
 
 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.16-pre8/arch/alpha/boot/bootp.c linux/arch/alpha/boot/bootp.c
--- linux-2.2.16-pre8/arch/alpha/boot/bootp.c	Mon Aug  9 12:04:38 1999
+++ linux/arch/alpha/boot/bootp.c	Mon Dec  3 22:05:10 2001
@@ -171,8 +171,7 @@
 	srm_printk("Initrd positioned at %#lx\n", initrd_start);
 #endif
 
-	nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
-			      envval, sizeof(envval));
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
 	if (nbytes < 0 || nbytes >= sizeof(envval)) {
 		nbytes = 0;
 	}
diff -urN linux-2.2.16-pre8/arch/alpha/boot/main.c linux/arch/alpha/boot/main.c
--- linux-2.2.16-pre8/arch/alpha/boot/main.c	Mon Aug  9 12:04:38 1999
+++ linux/arch/alpha/boot/main.c	Mon Dec  3 22:05:10 2001
@@ -107,15 +107,15 @@
 	char bootdev[256];
 	long result;
 
-	result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
+	result = callback_getenv(ENV_BOOTED_DEV, bootdev, 255);
 	if (result < 0)
 		return result;
-	return srm_dispatch(CCB_OPEN, bootdev, result & 255);
+	return callback_open(bootdev, result & 255);
 }
 
 static inline long close(long dev)
 {
-	return srm_dispatch(CCB_CLOSE, dev);
+	return callback_close(dev);
 }
 
 static inline long load(long dev, unsigned long addr, unsigned long count)
@@ -124,7 +124,7 @@
 	extern char _end;
 	long result, boot_size = &_end - (char *) BOOT_ADDR;
 
-	result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
+	result = callback_getenv(ENV_BOOTED_FILE, bootfile, 255);
 	if (result < 0)
 		return result;
 	result &= 255;
@@ -132,7 +132,7 @@
 	if (result)
 		srm_printk("Boot file specification (%s) not implemented\n",
 		       bootfile);
-	return srm_dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
+	return callback_read(dev, count, addr, boot_size/512 + 1);
 }
 
 /*
@@ -176,8 +176,7 @@
 		return;
 	}
 
-	nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
-			  envval, sizeof(envval));
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
 	if (nbytes < 0) {
 		nbytes = 0;
 	}
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- linux-2.2.16-pre8/arch/alpha/kernel/bios32.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/kernel/bios32.c	Mon Dec  3 22:05:10 2001
@@ -327,6 +327,28 @@
  */
 #define ALIGN(val,align)	(((val) + ((align) - 1)) & ~((align) - 1))
 
+static short __inline__
+__disable_dev(struct pci_dev *dev)
+{
+	unsigned short cmd, orig_cmd;
+
+	pcibios_read_config_word(dev->bus->number, dev->devfn,
+				 PCI_COMMAND, &cmd);
+
+	orig_cmd = cmd;
+	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
+
+	pcibios_write_config_word(dev->bus->number, dev->devfn,
+				  PCI_COMMAND, cmd);
+	return orig_cmd;
+}
+
+static void __inline__
+__enable_dev(struct pci_dev *dev, short orig_cmd)
+{
+	pcibios_write_config_word(dev->bus->number, dev->devfn,
+				  PCI_COMMAND, orig_cmd);
+}
 
 /* 
  * The following structure records initial configuration of devices
@@ -344,6 +366,7 @@
 	struct srm_io_reset *next;
 	struct pci_dev *dev;
 	u32 io;
+	short cmd;
 	u8 reg;
 } *srm_io_resets;
 
@@ -354,6 +377,7 @@
 {
 	struct srm_irq_reset *qreset;
 	struct srm_io_reset *ireset;
+	struct pci_dev *last_dev;
 
 	/* Reset any IRQs that we changed.  */
 	for (qreset = srm_irq_resets; qreset ; qreset = qreset->next) {
@@ -370,6 +394,15 @@
 #endif
 	}
 
+	/* Disable any devices which had IO addresses that we changed.  */
+	last_dev = NULL;
+	for (ireset = srm_io_resets; ireset ; ireset = ireset->next) {
+		if (ireset->dev != last_dev) {
+			ireset->cmd = __disable_dev(ireset->dev);
+			last_dev = ireset->dev;
+		}
+	}
+
 	/* Reset any IO addresses that we changed.  */
 	for (ireset = srm_io_resets; ireset ; ireset = ireset->next) {
 		pcibios_write_config_dword(ireset->dev->bus->number,
@@ -383,31 +416,40 @@
 		       ireset->io);
 #endif
 	}
+
+	/* Re-enable any devices which had IO addresses that we changed.  */
+	last_dev = NULL;
+	for (ireset = srm_io_resets; ireset ; ireset = ireset->next) {
+		if (ireset->dev != last_dev) {
+			__enable_dev(ireset->dev, ireset->cmd);
+			last_dev = ireset->dev;
+		}
+	}
 }
 
 static void
 new_irq_reset(struct pci_dev *dev, u8 irq)
 {
-	struct srm_irq_reset *n;
-	n = kmalloc(sizeof(*n), GFP_KERNEL);
+	struct srm_irq_reset *new;
+	new = kmalloc(sizeof(*new), GFP_KERNEL);
 
-	n->next = srm_irq_resets;
-	n->dev = dev;
-	n->irq = irq;
-	srm_irq_resets = n;
+	new->next = srm_irq_resets;
+	new->dev = dev;
+	new->irq = irq;
+	srm_irq_resets = new;
 }
 
 static void
 new_io_reset(struct pci_dev *dev, u8 reg, u32 io)
 {
-	struct srm_io_reset *n;
-	n = kmalloc(sizeof(*n), GFP_KERNEL);
+	struct srm_io_reset *new;
+	new = kmalloc(sizeof(*new), GFP_KERNEL);
 
-	n->next = srm_io_resets;
-	n->dev = dev;
-	n->reg = reg;
-	n->io = io;
-	srm_io_resets = n;
+	new->next = srm_io_resets;
+	new->dev = dev;
+	new->reg = reg;
+	new->io = io;
+	srm_io_resets = new;
 }
 
 
@@ -418,9 +460,6 @@
 static void __init
 disable_dev(struct pci_dev *dev)
 {
-	struct pci_bus *bus;
-	unsigned short cmd;
-
 	/*
 	 * HACK: the PCI-to-EISA bridge does not seem to identify
 	 *       itself as a bridge... :-(
@@ -442,10 +481,11 @@
 	/*
 	 * We don't have code that will init the CYPRESS bridge correctly
 	 * so we do the next best thing, and depend on the previous
-	 * console code to do the right thing, and ignore it here... :-\
+	 * console code to do the right thing, and ignore it mostly... :-\
 	 */
 	if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
-	    dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
+	    dev->device == PCI_DEVICE_ID_CONTAQ_82C693 &&
+	    PCI_FUNC(dev->devfn) == 0) {
 		DBG_DEVS(("disable_dev: ignoring CYPRESS bridge...\n"));
 		return;
 	}
@@ -463,12 +503,7 @@
 	DBG_DEVS(("disable_dev: disabling %04x:%04x\n",
 		  dev->vendor, dev->device));
 
-	bus = dev->bus;
-	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
-
-	/* hack, turn it off first... */
-	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
-	pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd);
+	(void)__disable_dev(dev);
 }
 
 
@@ -489,6 +524,7 @@
 	unsigned int orig_base;
 	unsigned int alignto;
 	unsigned long handle;
+	int start_idx = 0;
 
 	/*
 	 * HACK: the PCI-to-EISA bridge does not seem to identify
@@ -511,18 +547,24 @@
 	/*
 	 * We don't have code that will init the CYPRESS bridge correctly
 	 * so we do the next best thing, and depend on the previous
-	 * console code to do the right thing, and ignore it here... :-\
+	 * console code to do the right thing, and ignore it mostly... :-\
 	 */
 	if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
 	    dev->device == PCI_DEVICE_ID_CONTAQ_82C693) {
+	    int func = PCI_FUNC(dev->devfn);
+	    if (func == 0) {
 		DBG_DEVS(("layout_dev: ignoring CYPRESS bridge...\n"));
 		return;
+	    }
+	    if (func == 1 || func == 2) { 
+		start_idx = 4; /* bypass BAR 0 - 3 for the IDE devs */
+	    }
 	}
 
 	bus = dev->bus;
 	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
 
-	for (idx = 0; idx <= 5; idx++) {
+	for (idx = start_idx; idx <= 5; idx++) {
 		off = PCI_BASE_ADDRESS_0 + 4*idx;
 		/*
 		 * Figure out how much space and of what type this
@@ -713,6 +755,46 @@
 		  dev->device, dev->class, cmd|PCI_COMMAND_MASTER));
 }
 
+/* We must save away the current bridge settings for restore during exit. */
+static void __init
+save_bridge_setup(struct pci_dev *bridge)
+{
+	unsigned int dword;
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_IO_BASE, &dword);
+	new_io_reset(bridge, PCI_IO_BASE, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_IO_BASE_UPPER16, &dword);
+	new_io_reset(bridge, PCI_IO_BASE_UPPER16, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_PREF_BASE_UPPER32, &dword);
+	new_io_reset(bridge, PCI_PREF_BASE_UPPER32, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_PREF_LIMIT_UPPER32, &dword);
+	new_io_reset(bridge, PCI_PREF_LIMIT_UPPER32, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_MEMORY_BASE, &dword);
+	new_io_reset(bridge, PCI_MEMORY_BASE, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_PREF_MEMORY_BASE, &dword);
+	new_io_reset(bridge, PCI_PREF_MEMORY_BASE, dword);
+
+	/* Must use dword that contains PCI_BRIDGE_CONTROL. */
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				  PCI_INTERRUPT_LINE, &dword);
+	new_io_reset(bridge, PCI_INTERRUPT_LINE, dword);
+
+	pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
+				   PCI_COMMAND, &dword);
+	new_io_reset(bridge, PCI_COMMAND, dword);
+}
+
 static int __init
 layout_bus(struct pci_bus *bus)
 {
@@ -764,6 +846,7 @@
 		if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
 			found_vga = 1;
 	}
+
 	/*
 	 * Recursively allocate space for all of the sub-buses:
 	 */
@@ -772,6 +855,7 @@
     	for (child = bus->children; child; child = child->next) {
 		found_vga += layout_bus(child);
 	}
+
 	/*
 	 * Align the current bases on 4K and 1MB boundaries:
 	 */
@@ -783,6 +867,8 @@
 
 		DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number));
 
+		save_bridge_setup(bridge);
+
 		/*
 		 * Set up the top and bottom of the PCI I/O segment
 		 * for this bus.
@@ -1364,7 +1450,6 @@
 layout_hoses(void)
 {
 	struct linux_hose_info * hose;
-	int i;
 
 	/* On multiple bus machines, we play games with pci_root in order
 	   that all of the busses are probed as part of the normal PCI
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/core_irongate.c linux/arch/alpha/kernel/core_irongate.c
--- linux-2.2.16-pre8/arch/alpha/kernel/core_irongate.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/kernel/core_irongate.c	Mon Dec  3 22:05:10 2001
@@ -295,7 +295,7 @@
 	       IRONGATE0->agpmode);
 }
 #else
-#define irongate_register_dump(x)	1
+#define irongate_register_dump(x)
 #endif
 
 void __init
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c
--- linux-2.2.16-pre8/arch/alpha/kernel/core_mcpcia.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/kernel/core_mcpcia.c	Mon Dec  3 22:05:10 2001
@@ -662,6 +662,65 @@
 }
 
 void
+mcpcia_print_system_area(unsigned long la_ptr)
+{
+	struct el_common *frame;
+	int i;
+
+	struct IOD_subpacket {
+	  unsigned long base;
+	  unsigned int whoami;
+	  unsigned int rsvd1;
+	  unsigned int pci_rev;
+	  unsigned int cap_ctrl;
+	  unsigned int hae_mem;
+	  unsigned int hae_io;
+	  unsigned int int_ctl;
+	  unsigned int int_reg;
+	  unsigned int int_mask0;
+	  unsigned int int_mask1;
+	  unsigned int mc_err0;
+	  unsigned int mc_err1;
+	  unsigned int cap_err;
+	  unsigned int rsvd2;
+	  unsigned int pci_err1;
+	  unsigned int mdpa_stat;
+	  unsigned int mdpa_syn;
+	  unsigned int mdpb_stat;
+	  unsigned int mdpb_syn;
+	  unsigned int rsvd3;
+	  unsigned int rsvd4;
+	  unsigned int rsvd5;
+	} *iodpp;
+
+	frame = (struct el_common *)la_ptr;
+
+	iodpp = (struct IOD_subpacket *) (la_ptr + frame->sys_offset);
+
+	for (i = 0; i < hose_count; i++, iodpp++) {
+	  printk("IOD %d Register Subpacket - Bridge Base Address %16lx\n",
+		 i, iodpp->base);
+	  printk("  WHOAMI      = %8x\n", iodpp->whoami);
+	  printk("  PCI_REV     = %8x\n", iodpp->pci_rev);
+	  printk("  CAP_CTRL    = %8x\n", iodpp->cap_ctrl);
+	  printk("  HAE_MEM     = %8x\n", iodpp->hae_mem);
+	  printk("  HAE_IO      = %8x\n", iodpp->hae_io);
+	  printk("  INT_CTL     = %8x\n", iodpp->int_ctl);
+	  printk("  INT_REG     = %8x\n", iodpp->int_reg);
+	  printk("  INT_MASK0   = %8x\n", iodpp->int_mask0);
+	  printk("  INT_MASK1   = %8x\n", iodpp->int_mask1);
+	  printk("  MC_ERR0     = %8x\n", iodpp->mc_err0);
+	  printk("  MC_ERR1     = %8x\n", iodpp->mc_err1);
+	  printk("  CAP_ERR     = %8x\n", iodpp->cap_err);
+	  printk("  PCI_ERR1    = %8x\n", iodpp->pci_err1);
+	  printk("  MDPA_STAT   = %8x\n", iodpp->mdpa_stat);
+	  printk("  MDPA_SYN    = %8x\n", iodpp->mdpa_syn);
+	  printk("  MDPB_STAT   = %8x\n", iodpp->mdpb_stat);
+	  printk("  MDPB_SYN    = %8x\n", iodpp->mdpb_syn);
+	}
+}
+
+void
 mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
 		     struct pt_regs * regs)
 {
@@ -709,6 +768,7 @@
 	    if (vector != 0x620 && vector != 0x630
 		&& ! MCPCIA_mcheck_expected[cpu]) {
 		mcpcia_print_uncorrectable(mchk_logout);
+		mcpcia_print_system_area(la_ptr);
 	    }
 	}
 
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- linux-2.2.16-pre8/arch/alpha/kernel/irq.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/kernel/irq.c	Mon Dec  3 22:05:10 2001
@@ -896,7 +896,14 @@
 unsigned long __init init_IRQ(unsigned long memory)
 {
 	wrent(entInt, 0);
+
 	alpha_mv.init_irq();
+
+        /* If we had wanted SRM console printk echoing early, undo it now. */
+        if (alpha_using_srm && srmcons_output) {
+                unregister_srm_console();
+        }
+
 	return memory;
 }
 
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- linux-2.2.16-pre8/arch/alpha/kernel/proto.h	Tue Jan  4 10:12:11 2000
+++ linux/arch/alpha/kernel/proto.h	Mon Dec  3 22:05:10 2001
@@ -60,6 +60,7 @@
 					    struct linux_hose_info *hose);
 extern void irongate_init_arch(unsigned long *, unsigned long *);
 extern void irongate_machine_check(u64, u64, struct pt_regs *);
+extern int irongate_pci_clr_err(void);
 
 /* core_lca.c */
 extern int lca_hose_read_config_byte (u8, u8, u8, u8 *value,
@@ -164,6 +165,9 @@
 
 /* setup.c */
 extern unsigned long srm_hae;
+extern int srmcons_output;
+extern void register_srm_console(void);
+extern void unregister_srm_console(void);
 
 /* smp.c */
 extern void setup_smp(void);
@@ -219,6 +223,7 @@
 extern int ptrace_cancel_bpt (struct task_struct *child);
 
 /* ../mm/init.c */
+extern void switch_to_system_map(void);
 void srm_paging_stop(void);
 
 /* irq.c */
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- linux-2.2.16-pre8/arch/alpha/kernel/setup.c	Tue Jan  4 10:12:11 2000
+++ linux/arch/alpha/kernel/setup.c	Mon Dec  3 22:05:10 2001
@@ -40,7 +40,7 @@
 #include <asm/page.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-
+#include <asm/console.h>
 
 #include "proto.h"
 
@@ -52,6 +52,15 @@
 int alpha_using_srm, alpha_use_srm_setup;
 #endif
 
+/* Using SRM callbacks for initial console output. This works from
+   setup_arch() time through the end of init_IRQ(), as those places
+   are under our control.
+
+   By default, OFF; set it with a bootcommand arg of "srmcons".
+*/
+int srmcons_output = 0;
+
+/* For PS/2 presence */
 unsigned char aux_device_present = 0xaa;
 
 #define N(a) (sizeof(a)/sizeof(a[0]))
@@ -144,23 +153,31 @@
 setup_arch(char **cmdline_p, unsigned long * memory_start_p,
 	   unsigned long * memory_end_p)
 {
-	extern char _end[];
-
 	struct alpha_machine_vector *vec = NULL;
 	struct percpu_struct *cpu;
 	char *type_name, *var_name, *p;
 	unsigned long memory_end_override = 0;
+	extern char _end;
+	void *kernel_end = &_end; /* End of the kernel. */
 
 	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
 
+#ifdef CONFIG_ALPHA_GENERIC
+	/* Assume that we've booted from SRM if we havn't booted from MILO.
+	   Detect the later by looking for "MILO" in the system serial nr.  */
+	alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
+#endif
+
+	kernel_end = callback_init(kernel_end);
+
 	/* 
-	 * Locate the command line.
-	 */
+	   Process the command line.
 
-	/* Hack for Jensen... since we're restricted to 8 or 16 chars for
+	   Hack for Jensen... since we're restricted to 8 or 16 chars for
 	   boot flags depending on the boot mode, we need some shorthand.
 	   This should do for installation.  Later we'll add other
-	   abbreviations as well... */
+	   abbreviations as well...
+	*/
 	if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
 		strcpy(command_line, "root=/dev/fd0 load_ramdisk=1");
 	} else {
@@ -198,11 +215,20 @@
 			memory_end_override = get_memory_end_override(p+4);
 			continue;
 		}
+		if (strncmp(p, "srmcons", 7) == 0) {
+			srmcons_output = 1;
+			continue;
+		}
 	}
 
 	/* Replace the command line, not that we've killed it with strtok.  */
 	strcpy(command_line, saved_command_line);
 
+	/* If we want SRM console printk echoing early, do it now. */
+	if (alpha_using_srm && srmcons_output) {
+		register_srm_console();
+	}
+
 	/*
 	 * Indentify and reconfigure for the current system.
 	 */
@@ -228,12 +254,6 @@
 		alpha_mv = *vec;
 	}
 	
-#ifdef CONFIG_ALPHA_GENERIC
-	/* Assume that we've booted from SRM if we havn't booted from MILO.
-	   Detect the later by looking for "MILO" in the system serial nr.  */
-	alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
-#endif
-
 	printk("%s on %s%s%s using machine vector %s from %s\n",
 #ifdef CONFIG_ALPHA_GENERIC
 	       "Booting GENERIC",
@@ -258,7 +278,7 @@
 	wrmces(0x7);
 
 	/* Find our memory.  */
-	*memory_start_p = (unsigned long) _end;
+	*memory_start_p = (unsigned long)kernel_end;
 	*memory_end_p = find_end_memory();
 	if (memory_end_override && memory_end_override < *memory_end_p) {
 		printk("Overriding memory size from %luMB to %luMB\n",
@@ -342,7 +362,7 @@
 	struct memdesc_struct * memdesc;
 
 	memdesc = (struct memdesc_struct *)
-		(INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
+		(hwrpb->mddt_offset + (unsigned long)hwrpb);
 	cluster = memdesc->cluster;
 
 	for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
@@ -421,7 +441,7 @@
 static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
 
 static char tsunami_names[][16] = {
-	"0", "DP264", "Warhol", "Windjammer", "Monet", "Clipper",
+	"EarlyMonet", "DP264", "Warhol", "Windjammer", "Monet", "Clipper",
 	"Goldrush", "Webbrick", "Catamaran"
 };
 static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8};
@@ -508,7 +528,7 @@
 
 	static struct alpha_machine_vector *tsunami_vecs[]  __initlocaldata =
 	{
-		NULL,
+		&monet_mv,		/* HACK for early Monets */
 		&dp264_mv,		/* dp264 */
 		&dp264_mv,		/* warhol */
 		&dp264_mv,		/* windjammer */
@@ -543,7 +563,7 @@
 
 	if (!vec) {
 		/* Member ID is a bit-field. */
-		long member = (variation >> 10) & 0x3f;
+		long member = HWRPB_MEMBER_ID(variation);
 
 		switch (type) {
 		case ST_DEC_ALCOR:
@@ -832,3 +852,65 @@
 
 	return len;
 }
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
+/*
+ *      Manage the SRM callbacks as a "console".
+ */
+static struct console srmcons;
+
+void __init register_srm_console(void)
+{
+        register_console(&srmcons);
+}
+
+void __init unregister_srm_console(void)
+{
+        unregister_console(&srmcons);
+}
+
+static void srm_console_write(struct console *co, const char *s,
+                                unsigned count)
+{
+	srm_printk(s);
+}
+
+static kdev_t srm_console_device(struct console *c)
+{
+  /* Huh? */
+        return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static int srm_console_wait_key(struct console *co)
+{
+  /* Huh? */
+	return 1;
+}
+
+static int __init srm_console_setup(struct console *co, char *options)
+{
+	return 1;
+}
+
+static struct console srmcons = {
+        "srm0",
+        srm_console_write,
+        NULL,
+        srm_console_device,
+        srm_console_wait_key,
+        NULL,
+	srm_console_setup,
+        CON_PRINTBUFFER | CON_ENABLED, /* fake it out */
+        -1,
+        0,
+        NULL
+};
+
+#else
+void __init register_srm_console(void)
+{
+}
+void __init unregister_srm_console(void)
+{
+}
+#endif
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- linux-2.2.16-pre8/arch/alpha/kernel/sys_dp264.c	Tue Jan  4 10:12:11 2000
+++ linux/arch/alpha/kernel/sys_dp264.c	Mon Dec  3 22:05:10 2001
@@ -393,7 +393,12 @@
 	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
 	common_pci_fixup(monet_map_irq, monet_swizzle);
 	SMC669_Init(1);
-	es1888_init();
+
+	/* HACK: early Monets had a member ID of 0 and the ES1888
+	   located in a non-standard spot, so do this only for
+	   official Monets */
+	if (HWRPB_MEMBER_ID(hwrpb->sys_variation) != 0)
+		es1888_init();
 }
 
 static void __init
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c
--- linux-2.2.16-pre8/arch/alpha/kernel/sys_mikasa.c	Sun Sep  6 10:34:33 1998
+++ linux/arch/alpha/kernel/sys_mikasa.c	Mon Dec  3 22:05:10 2001
@@ -155,13 +155,14 @@
 mikasa_machine_check(unsigned long vector, unsigned long la_ptr,
 		     struct pt_regs * regs)
 {
-#define MCHK_NO_DEVSEL 0x205L
-#define MCHK_NO_TABT 0x204L
+#define MCHK_NO_DEVSEL 0x205U
+#define MCHK_NO_TABT 0x204U
 
 	struct el_common *mchk_header;
 	struct el_apecs_procdata *mchk_procdata;
 	struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata;
 	unsigned long *ptr;
+	unsigned int code; /* workaround EGCS problem */
 	int i;
 
 	mchk_header = (struct el_common *)la_ptr;
@@ -193,9 +194,11 @@
 	 * ignore the machine check.
 	 */
 
-	if (apecs_mcheck_expected
-	    && ((unsigned int)mchk_header->code == MCHK_NO_DEVSEL
-		|| (unsigned int)mchk_header->code == MCHK_NO_TABT)) {
+	code = mchk_header->code; /* workaround EGCS problem */
+
+	if (apecs_mcheck_expected &&
+	    (code == MCHK_NO_DEVSEL || code == MCHK_NO_TABT))
+	{
 		apecs_mcheck_expected = 0;
 		apecs_mcheck_taken = 1;
 		mb();
@@ -214,9 +217,9 @@
 		       vector);
 	}
 	else {
-		printk(KERN_CRIT "APECS machine check:\n");
-		printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx\n",
-		       vector, la_ptr);
+		printk(KERN_CRIT "MIKASA APECS machine check:\n");
+		printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx code=0x%x\n",
+		       vector, la_ptr, code);
 		printk(KERN_CRIT
 		       "  pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
 		       regs->pc, mchk_header->size, mchk_header->proc_offset,
@@ -274,7 +277,7 @@
 	DO_DEFAULT_RTC,
 	DO_CIA_IO,
 	DO_CIA_BUS,
-	machine_check:		mikasa_machine_check,
+	machine_check:		cia_machine_check,
 	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
 
 	nr_irqs:		32,
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/sys_nautilus.c linux/arch/alpha/kernel/sys_nautilus.c
--- linux-2.2.16-pre8/arch/alpha/kernel/sys_nautilus.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/kernel/sys_nautilus.c	Mon Dec  3 22:05:10 2001
@@ -94,7 +94,7 @@
 	{
 		unsigned char control;
 
-		cli();
+		__cli();
 
 		/* Reset periodic interrupt frequency.  */
 		CMOS_WRITE(0x26, RTC_FREQ_SELECT);
@@ -105,7 +105,7 @@
 		CMOS_WRITE(control, RTC_CONTROL);	
 		CMOS_READ(RTC_INTR_FLAGS);
 
-		sti();
+		__sti();
 	}
 #endif
 
@@ -115,7 +115,7 @@
 		break;
 	case LINUX_REBOOT_CMD_RESTART:
 		{
-			int v;
+			unsigned char v;
 			irongate_hose_read_config_byte(0, 0x07<<3, 0x43, &v, 0);
 			irongate_hose_write_config_byte(0, 0x07<<3, 0x43, v | 0x80, 0);
 			outb(1, 0x92);
@@ -504,7 +504,8 @@
 	break;
     }
 
-    printk(KERN_CRIT "> NAUTILUS Machine check 0x%x [%s]\n", vector, mchk_class);
+    printk(KERN_CRIT "> NAUTILUS Machine check 0x%lx [%s]\n",
+	   vector, mchk_class);
 
     if ( cpu_analysis )	
 	ev6_cpu_machine_check(  vector,
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- linux-2.2.16-pre8/arch/alpha/kernel/time.c	Mon Aug  9 12:04:38 1999
+++ linux/arch/alpha/kernel/time.c	Mon Dec  3 22:05:10 2001
@@ -236,7 +236,7 @@
 {
 	void (*irq_handler)(int, void *, struct pt_regs *);
 	unsigned int year, mon, day, hour, min, sec, cc1, cc2;
-	unsigned long cycle_freq, one_percent;
+	unsigned long cycle_freq, ppm_error;
 	long diff;
 
 	/*
@@ -261,17 +261,29 @@
 		cc1 = cc2;
 	}
 
-	/* If the given value is within 1% of what we calculated, 
-	   accept it.  Otherwise, use what we found.  */
-	cycle_freq = hwrpb->cycle_freq;
-	one_percent = cycle_freq / 100;
+	/* This code used to check for a 1% error.
+	 * PWS600au reports 598802395 which is way off. (ntpd has problems.)
+	 * So I tightened down the check.  Hal Murray, Feb 27, 2000.
+	 *
+	 * HWRPB cycle_freq may be 0 (uninitialized) due to MILO, so make
+	 * sure that we handle this case by forcing use of est_cycle_freq.
+	 */
+	if (!(cycle_freq = hwrpb->cycle_freq))
+		cycle_freq = est_cycle_freq;
+
 	diff = cycle_freq - est_cycle_freq;
 	if (diff < 0)
 		diff = -diff;
-	if (diff > one_percent) {
+	ppm_error = (diff * 1000000L) / cycle_freq;
+#if 0
+	printk("Alpha clock init: HWRPB %lu, Measured %lu, error=%lu ppm.\n",
+	       hwrpb->cycle_freq, est_cycle_freq, ppm_error);
+#endif
+	if (ppm_error > 1000) {
+		printk("HWRPB cycle frequency (%lu) seems inaccurate -"
+		       " using the measured value of %lu Hz\n",
+		       cycle_freq, est_cycle_freq);
 		cycle_freq = est_cycle_freq;
-		printk("HWRPB cycle frequency bogus.  Estimated %lu Hz\n",
-		       cycle_freq);
 	}
 	else {
 		est_cycle_freq = 0;
diff -urN linux-2.2.16-pre8/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- linux-2.2.16-pre8/arch/alpha/kernel/traps.c	Tue Jan  4 10:12:11 2000
+++ linux/arch/alpha/kernel/traps.c	Mon Dec  3 22:05:10 2001
@@ -652,7 +652,7 @@
 got_exception:
 	/* Ok, we caught the exception, but we don't want it.  Is there
 	   someone to pass it along to?  */
-	if ((fixup = search_exception_table(pc)) != 0) {
+	if ((fixup = search_exception_table(pc, regs.gp)) != 0) {
 		unsigned long newpc;
 		newpc = fixup_exception(una_reg, fixup, pc);
 
diff -urN linux-2.2.16-pre8/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- linux-2.2.16-pre8/arch/alpha/lib/Makefile	Sat Jan 16 17:02:51 1999
+++ linux/arch/alpha/lib/Makefile	Mon Dec  3 22:05:10 2001
@@ -2,13 +2,18 @@
 # Makefile for alpha-specific library files..
 #
 
+.S.s:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $<
+.S.o:
+	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $<
+
 OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
 	checksum.o csum_partial_copy.o strlen.o \
 	strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
 	strchr.o strrchr.o \
 	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
 	csum_ipv6_magic.o strcasecmp.o semaphore.o \
-	srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
+	callback_srm.o callback_init.o srm_puts.o srm_printk.o
 
 lib.a: $(OBJS)
 	$(AR) rcs lib.a $(OBJS)
diff -urN linux-2.2.16-pre8/arch/alpha/lib/callback_init.c linux/arch/alpha/lib/callback_init.c
--- linux-2.2.16-pre8/arch/alpha/lib/callback_init.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/callback_init.c	Mon Dec  3 22:05:10 2001
@@ -0,0 +1,83 @@
+/*
+ *      arch/alpha/lib/callback_init.c
+ */
+
+#include <asm/page.h>
+#include <asm/hwrpb.h>
+#include <asm/console.h>
+#include <asm/pgtable.h>
+#include <asm/init.h>
+
+#include "../kernel/proto.h"
+
+int callback_init_done = 0;
+
+/* This is the SRM version.  Maybe there will be a DBM version. */
+
+void * __init callback_init(void * kernel_end)
+{
+	int i, j;
+	unsigned long vaddr = CONSOLE_REMAP_START;
+	struct crb_struct * crb;
+	pgd_t * pgd = pgd_offset_k(vaddr);
+	pmd_t * pmd;
+	void * two_pte_pages;
+
+	/* Always page align the end of the kernel. */
+	kernel_end = (void *)
+	  (((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK);
+
+	if (!alpha_using_srm) {
+		switch_to_system_map();
+		return kernel_end;
+	}
+
+	/* Allocate some memory for the pages. */
+	two_pte_pages = kernel_end;
+	kernel_end = two_pte_pages + 2*PAGE_SIZE;
+	memset(two_pte_pages, 0, 2*PAGE_SIZE);
+
+	/* Starting at the HWRPB, locate the CRB. */
+	crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset);
+
+	/* Tell the console whither the console is to be remapped. */
+	if (srm_fixup(vaddr, (unsigned long)hwrpb))
+		__halt();		/* "We're boned."  --Bender */
+
+	/* Edit the procedure descriptors for DISPATCH and FIXUP. */
+	crb->dispatch_va = (struct procdesc_struct *)
+		(vaddr + (unsigned long)crb->dispatch_va - crb->map[0].va);
+	crb->fixup_va = (struct procdesc_struct *)
+		(vaddr + (unsigned long)crb->fixup_va - crb->map[0].va);
+
+	switch_to_system_map();
+
+	/*
+	 * Set up the first and second level PTEs for console callbacks.
+	 * There is an assumption here that only one of each is needed,
+	 * and this allows for 8MB.  Currently (late 1999), big consoles
+	 * are still under 3MB.
+	 */
+	pgd_set(pgd, (pmd_t *)two_pte_pages);
+	pmd = pmd_offset(pgd, vaddr);
+	pmd_set(pmd, (pte_t *)(two_pte_pages + PAGE_SIZE));
+
+	/*
+	 * Set up the third level PTEs and update the virtual addresses
+	 * of the CRB entries.
+	 */
+	for (i = 0; i < crb->map_entries; ++i) {
+		unsigned long paddr = crb->map[i].pa;
+		crb->map[i].va = vaddr;
+		for (j = 0; j < crb->map[i].count; ++j) {
+			set_pte(pte_offset(pmd, vaddr),
+				mk_pte_phys(paddr, PAGE_KERNEL));
+			paddr += PAGE_SIZE;
+			vaddr += PAGE_SIZE;
+		}
+	}
+
+	callback_init_done = 1;
+	return kernel_end;
+}
+
diff -urN linux-2.2.16-pre8/arch/alpha/lib/callback_srm.S linux/arch/alpha/lib/callback_srm.S
--- linux-2.2.16-pre8/arch/alpha/lib/callback_srm.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/callback_srm.S	Mon Dec  3 22:05:10 2001
@@ -0,0 +1,102 @@
+/*
+ *	arch/alpha/lib/callback_srm.S
+ */
+
+#include <linux/config.h>
+#include <asm/console.h>
+
+.text
+#define HWRPB_CRB_OFFSET 0xc0
+
+#if defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC)
+.align 4
+srm_dispatch:
+#if defined(CONFIG_ALPHA_GENERIC)
+	ldl	$4,alpha_using_srm
+	beq	$4,nosrm
+#endif
+	ldq	$0,hwrpb	# gp is set up by CALLBACK macro.
+	ldl	$25,0($25)	# Pick up the wrapper data.
+	mov	$20,$21		# Shift arguments right.
+	mov	$19,$20
+	ldq	$1,HWRPB_CRB_OFFSET($0)
+	mov	$18,$19
+	mov	$17,$18
+	mov	$16,$17
+	addq	$0,$1,$2	# CRB address
+	ldq	$27,0($2)	# DISPATCH procedure descriptor (VMS call std)
+	extwl	$25,0,$16	# SRM callback function code
+	ldq	$3,8($27)	# call address
+	extwl	$25,2,$25	# argument information (VMS calling std)
+	jmp	($3)		# Return directly to caller of wrapper.
+
+.align 4
+.globl	srm_fixup
+.ent	srm_fixup
+srm_fixup:
+	ldgp	$29,0($27)
+#if defined(CONFIG_ALPHA_GENERIC)
+	ldl	$4,alpha_using_srm
+	beq	$4,nosrm
+#endif
+	ldq	$0,hwrpb
+	ldq	$1,HWRPB_CRB_OFFSET($0)
+	addq	$0,$1,$2	# CRB address
+	ldq	$27,16($2)	# VA of FIXUP procedure descriptor
+	ldq	$3,8($27)	# call address
+	lda	$25,2($31)	# two integer arguments
+	jmp	($3)		# Return directly to caller of srm_fixup.
+.end    srm_fixup
+
+#if defined(CONFIG_ALPHA_GENERIC)
+.align 3
+nosrm:
+	lda	$0,-1($31)
+	ret
+#endif
+
+#define CALLBACK(NAME, CODE, ARG_CNT) \
+.align 4; .globl callback_##NAME; .ent callback_##NAME; callback_##NAME##: \
+ldgp $29,0($27); br $25,srm_dispatch; .word CODE, ARG_CNT; .end callback_##NAME
+
+#else /* defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC) */
+
+#define CALLBACK(NAME, CODE, ARG_CNT) \
+.align 3; .globl callback_##NAME; .ent callback_##NAME; callback_##NAME##: \
+lda $0,-1($31); ret; .end callback_##NAME
+
+.align 3
+.globl	srm_fixup
+.ent	srm_fixup
+srm_fixup:
+	lda	$0,-1($31)
+	ret
+.end	srm_fixup
+#endif /* defined(CONFIG_ALPHA_SRM) || defined(CONFIG_ALPHA_GENERIC) */
+
+CALLBACK(puts, CCB_PUTS, 4)
+CALLBACK(open, CCB_OPEN, 3)
+CALLBACK(close, CCB_CLOSE, 2)
+CALLBACK(read, CCB_READ, 5)
+CALLBACK(getenv, CCB_GET_ENV, 4)
+CALLBACK(setenv, CCB_SET_ENV, 4)
+CALLBACK(getc, CCB_GETC, 2)
+CALLBACK(reset_term, CCB_RESET_TERM, 2)
+CALLBACK(term_int, CCB_SET_TERM_INT, 3)
+CALLBACK(term_ctl, CCB_SET_TERM_CTL, 3)
+CALLBACK(process_keycode, CCB_PROCESS_KEYCODE, 3)
+CALLBACK(ioctl, CCB_IOCTL, 6)
+CALLBACK(write, CCB_WRITE, 5)
+CALLBACK(reset_env, CCB_RESET_ENV, 4)
+CALLBACK(save_env, CCB_SAVE_ENV, 1)
+CALLBACK(pswitch, CCB_PSWITCH, 3)
+CALLBACK(bios_emul, CCB_BIOS_EMUL, 5)
+	
+.data
+__alpha_using_srm:		# For use by bootpheader
+	.long 7			# value is not 1 for link debugging
+	.weak alpha_using_srm; alpha_using_srm = __alpha_using_srm
+__callback_init_done:           # For use by bootpheader
+        .long 7                 # value is not 1 for link debugging
+        .weak callback_init_done; callback_init_done = __callback_init_done
+
diff -urN linux-2.2.16-pre8/arch/alpha/lib/copy_user.S linux/arch/alpha/lib/copy_user.S
--- linux-2.2.16-pre8/arch/alpha/lib/copy_user.S	Fri Apr 30 08:22:19 1999
+++ linux/arch/alpha/lib/copy_user.S	Mon Dec  3 22:05:10 2001
@@ -80,7 +80,7 @@
 	extql $3,$7,$3
 	extqh $2,$7,$1
 	bis $3,$1,$1
-	stq $1,0($6)
+	EXO( stq $1,0($6) )
 	addq $7,8,$7
 	subq $0,8,$0
 	addq $6,8,$6
diff -urN linux-2.2.16-pre8/arch/alpha/lib/srm_dispatch.S linux/arch/alpha/lib/srm_dispatch.S
--- linux-2.2.16-pre8/arch/alpha/lib/srm_dispatch.S	Mon Oct 12 11:40:12 1998
+++ linux/arch/alpha/lib/srm_dispatch.S	Wed Dec 31 16:00:00 1969
@@ -1,43 +0,0 @@
-/*
- *	arch/alpha/lib/srm_dispatch.S
- */
-
-.globl	srm_dispatch
-.ent	srm_dispatch
-srm_dispatch:
-	.frame	$30,30,$26
-	subq	$30,80,$30
-	stq	$26,0($30)
-	stq	$8,8($30)
-	stq	$9,16($30)
-	stq	$10,24($30)
-	stq	$11,32($30)
-	stq	$12,40($30)
-	stq	$13,48($30)
-	stq	$14,56($30)
-	stq	$15,64($30)
-	stq	$29,72($30)
-	.mask	0x2400FF00, -80
-	.prologue 0
-
-	ldq	$1,hwrpb
-	ldq	$2,0xc0($1)		/* crb offset */
-	addq	$2,$1,$2		/* crb */
-	ldq	$27,0($2)		/* dispatch procedure value */
-
-	ldq	$2,8($27)		/* dispatch call address */
-	jsr	$26,($2)		/* call it (weird VMS call seq) */
-
-	ldq	$26,0($30)
-	ldq	$8,8($30)
-	ldq	$9,16($30)
-	ldq	$10,24($30)
-	ldq	$11,32($30)
-	ldq	$12,40($30)
-	ldq	$13,48($30)
-	ldq	$14,56($30)
-	ldq	$15,64($30)
-	ldq	$29,72($30)
-	addq	$30,80,$30
-	ret	$31,($26),1
-.end    srm_dispatch
diff -urN linux-2.2.16-pre8/arch/alpha/lib/srm_fixup.S linux/arch/alpha/lib/srm_fixup.S
--- linux-2.2.16-pre8/arch/alpha/lib/srm_fixup.S	Mon Oct 12 11:40:12 1998
+++ linux/arch/alpha/lib/srm_fixup.S	Wed Dec 31 16:00:00 1969
@@ -1,42 +0,0 @@
-/*
- *	arch/alpha/lib/srm_fixup.S
- */
-
-.globl	srm_fixup
-.ent	srm_fixup
-srm_fixup:
-	.frame	$30,30,$26
-	subq	$30,80,$30
-	stq	$26,0($30)
-	stq	$8,8($30)
-	stq	$9,16($30)
-	stq	$10,24($30)
-	stq	$11,32($30)
-	stq	$12,40($30)
-	stq	$13,48($30)
-	stq	$14,56($30)
-	stq	$15,64($30)
-	stq	$29,72($30)
-	.mask	0x2400FF00, -80
-	.prologue 0
-
-	ldq	$2,0xc0($17)		/* crb offset */
-	addq	$2,$1,$2		/* crb */
-	ldq	$27,16($2)		/* fixup procedure value */
-
-	ldq	$2,8($27)		/* dispatch call address */
-	jsr	$26,($2)		/* call it (weird VMS call seq) */
-
-	ldq	$26,0($30)
-	ldq	$8,8($30)
-	ldq	$9,16($30)
-	ldq	$10,24($30)
-	ldq	$11,32($30)
-	ldq	$12,40($30)
-	ldq	$13,48($30)
-	ldq	$14,56($30)
-	ldq	$15,64($30)
-	ldq	$29,72($30)
-	addq	$30,80,$30
-	ret	$31,($26),1
-.end    srm_fixup
diff -urN linux-2.2.16-pre8/arch/alpha/lib/srm_printk.c linux/arch/alpha/lib/srm_printk.c
--- linux-2.2.16-pre8/arch/alpha/lib/srm_printk.c	Mon Oct 12 11:40:12 1998
+++ linux/arch/alpha/lib/srm_printk.c	Mon Dec  3 22:05:10 2001
@@ -10,12 +10,31 @@
 {
 	static char buf[1024];
         va_list args;
-        long i;
+        long len, num_lf;
+        char *src, *dst;
 
         va_start(args, fmt);
-        i = vsprintf(buf,fmt,args);
+        len = vsprintf(buf, fmt, args);
         va_end(args);
 
-	srm_puts(buf);	
-        return i;
+        /* Count number of linefeeds in string. */
+        num_lf = 0;
+        for (src = buf; *src; ++src) {
+                if (*src == '\n') {
+                        ++num_lf;
+                }
+        }
+
+	/* Expand each linefeed into carriage-return/linefeed. */
+        if (num_lf) {
+                for (dst = src + num_lf; src >= buf; ) {
+                        if (*src == '\n') {
+                                *dst-- = '\r';
+                        }
+                        *dst-- = *src--;
+                }
+        }
+
+	srm_puts(buf, num_lf+len);	
+        return len;
 }
diff -urN linux-2.2.16-pre8/arch/alpha/lib/srm_puts.c linux/arch/alpha/lib/srm_puts.c
--- linux-2.2.16-pre8/arch/alpha/lib/srm_puts.c	Mon Oct 12 11:40:12 1998
+++ linux/arch/alpha/lib/srm_puts.c	Mon Dec  3 22:05:10 2001
@@ -5,30 +5,19 @@
 #include <linux/string.h>
 #include <asm/console.h>
 
-void
-srm_puts(const char *str)
+long
+srm_puts(const char *str, long len)
 {
-	/* Expand \n to \r\n as we go.  */
+        long remaining, written;
 
-	while (*str) {
-		long len;
-		const char *e = str;
+        if (!callback_init_done)
+                return len;
 
-		if (*str == '\n') {
-			if (srm_dispatch(CCB_PUTS, 0, "\r", 1) < 0)
-				return;
-			++e;
-		}
-
-		e = strchr(e, '\n') ? : strchr(e, '\0');
-		len = e - str;
-
-		while (len > 0) {
-			long written = srm_dispatch(CCB_PUTS, 0, str, len);
-			if (written < 0)
-				return;
-			len -= written & 0xffffffff;
-			str += written & 0xffffffff;
-		}
-	}
+        for (remaining = len; remaining > 0; remaining -= written)
+        {
+                written = callback_puts(0, str, remaining);
+                written &= 0xffffffff;
+                str += written;
+        }
+        return len;
 }
diff -urN linux-2.2.16-pre8/arch/alpha/mm/extable.c linux/arch/alpha/mm/extable.c
--- linux-2.2.16-pre8/arch/alpha/mm/extable.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/mm/extable.c	Mon Dec  3 22:05:10 2001
@@ -36,8 +36,8 @@
 
 register unsigned long gp __asm__("$29");
 
-unsigned
-search_exception_table(unsigned long addr)
+static unsigned
+search_exception_table_without_gp(unsigned long addr)
 {
 	unsigned ret;
 
@@ -59,4 +59,39 @@
 #endif
 
 	return 0;
+}
+
+unsigned
+search_exception_table(unsigned long addr, unsigned long exc_gp)
+{
+	unsigned ret;
+
+#ifndef CONFIG_MODULES
+	ret = search_one_table(__start___ex_table, __stop___ex_table - 1,
+			       addr - exc_gp);
+	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special. */
+	struct module *mp;
+	for (mp = module_list; mp ; mp = mp->next) {
+		if (!mp->ex_table_start)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr - exc_gp);
+		if (ret) return ret;
+	}
+#endif
+
+	/*
+	 * The search failed with the exception gp. To be safe, try the
+	 * old method before giving up.
+	 */
+	ret = search_exception_table_without_gp(addr);
+	if (ret) {
+		printk(KERN_ALERT, "%s: [%lx] EX_TABLE search fail with"
+		       "exc frame GP, success with raw GP\n",
+		       current->comm, addr);
+		return ret;
+	}
+        return 0;
 }
diff -urN linux-2.2.16-pre8/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c
--- linux-2.2.16-pre8/arch/alpha/mm/fault.c	Wed May  3 17:16:30 2000
+++ linux/arch/alpha/mm/fault.c	Mon Dec  3 22:05:10 2001
@@ -147,11 +147,11 @@
 
 no_context:
 	/* Are we prepared to handle this fault as an exception?  */
-	if ((fixup = search_exception_table(regs->pc)) != 0) {
+	if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
 		unsigned long newpc;
 		newpc = fixup_exception(dpf_reg, fixup, regs->pc);
-#if 0
-		printk("%s: Exception at [<%lx>] (%lx)\n",
+#if 1
+		printk("%s: Exception at [<%lx>] (%lx) handled successfully.\n",
 		       current->comm, regs->pc, newpc);
 #endif
 		regs->pc = newpc;
diff -urN linux-2.2.16-pre8/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- linux-2.2.16-pre8/arch/alpha/mm/init.c	Tue Jan  4 10:12:11 2000
+++ linux/arch/alpha/mm/init.c	Mon Dec  3 22:05:10 2001
@@ -182,6 +182,44 @@
 	return (struct thread_struct *) __reload_tss(pcb);
 }
 
+void
+switch_to_system_map(void)
+{
+	unsigned long newptbr;
+	struct thread_struct *original_pcb_ptr;
+
+	memset(swapper_pg_dir, 0, PAGE_SIZE);
+	newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
+	pgd_val(swapper_pg_dir[1023]) =
+		(newptbr << 32) | pgprot_val(PAGE_KERNEL);
+
+
+	/* Also set up the real kernel PCB while we're at it.  */
+	init_task.tss.ptbr = newptbr;
+	init_task.tss.pal_flags = 1;	/* set FEN, clear everything else */
+	init_task.tss.flags = 0;
+
+	hwrpb->vptb = 0xfffffffe00000000;
+	hwrpb_update_checksum(hwrpb);
+
+	wrvptptr(0xfffffffe00000000);
+	original_pcb_ptr = load_PCB(&init_task.tss);
+	tbia();
+
+	/* Save off the contents of the original PCB so that we can
+	   restore the original console's page tables for a clean reboot.
+
+	   Note that the PCB is supposed to be a physical address, but
+	   since KSEG values also happen to work, folks get confused.
+	   Check this here.  */
+
+	if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) {
+		original_pcb_ptr = (struct thread_struct *)
+		  phys_to_virt((unsigned long) original_pcb_ptr);
+	}
+	original_pcb = *original_pcb_ptr;
+}
+
 /*
  * paging_init() sets up the page tables: in the alpha version this actually
  * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
@@ -190,10 +228,8 @@
 paging_init(unsigned long start_mem, unsigned long end_mem)
 {
 	int i;
-	unsigned long newptbr;
 	struct memclust_struct * cluster;
 	struct memdesc_struct * memdesc;
-	struct thread_struct *original_pcb_ptr;
 
 	/* initialize mem_map[] */
 	start_mem = free_area_init(start_mem, end_mem);
@@ -221,41 +257,7 @@
 			clear_bit(PG_reserved, &mem_map[pfn++].flags);
 	}
 
-	/* Initialize the kernel's page tables.  Linux puts the vptb in
-	   the last slot of the L1 page table.  */
 	memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
-	memset(swapper_pg_dir, 0, PAGE_SIZE);
-	newptbr = MAP_NR(swapper_pg_dir);
-	pgd_val(swapper_pg_dir[1023]) =
-		(newptbr << 32) | pgprot_val(PAGE_KERNEL);
-
-	/* Set the vptb.  This is often done by the bootloader, but 
-	   shouldn't be required.  */
-	if (hwrpb->vptb != 0xfffffffe00000000) {
-		wrvptptr(0xfffffffe00000000);
-		hwrpb->vptb = 0xfffffffe00000000;
-		hwrpb_update_checksum(hwrpb);
-	}
-
-	/* Also set up the real kernel PCB while we're at it.  */
-	init_task.tss.ptbr = newptbr;
-	init_task.tss.pal_flags = 1;	/* set FEN, clear everything else */
-	init_task.tss.flags = 0;
-	original_pcb_ptr = load_PCB(&init_task.tss);
-	tbia();
-
-	/* Save off the contents of the original PCB so that we can
-	   restore the original console's page tables for a clean reboot.
-
-	   Note that the PCB is supposed to be a physical address, but
-	   since KSEG values also happen to work, folks get confused.
-	   Check this here.  */
-
-	if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) {
-		original_pcb_ptr = (struct thread_struct *)
-		  phys_to_virt((unsigned long) original_pcb_ptr);
-	}
-	original_pcb = *original_pcb_ptr;
 
 	return start_mem;
 }
diff -urN linux-2.2.16-pre8/arch/alpha/vmlinux.lds linux/arch/alpha/vmlinux.lds
--- linux-2.2.16-pre8/arch/alpha/vmlinux.lds	Tue May 13 22:41:00 1997
+++ linux/arch/alpha/vmlinux.lds	Mon Dec  3 22:05:10 2001
@@ -1,10 +1,11 @@
 OUTPUT_FORMAT("elf64-alpha")
 ENTRY(__start)
+PHDRS { kernel PT_LOAD ; }
 SECTIONS
 {
    . = 0xfffffc0000310000;
    _text = .;
-   .text : { *(.text) }
+   .text : { *(.text) } :kernel
    .text2 : { *(.text2) }
    _etext = .;
 
diff -urN linux-2.2.16-pre8/drivers/block/ide.c linux/drivers/block/ide.c
--- linux-2.2.16-pre8/drivers/block/ide.c	Mon Dec  3 22:05:04 2001
+++ linux/drivers/block/ide.c	Mon Dec  3 22:05:11 2001
@@ -274,6 +274,7 @@
 		if (!strncmp(id->model, "KODAK ATA_FLASH", 15)	/* Kodak */
 		 || !strncmp(id->model, "Hitachi CV", 10)		/* Hitachi */
 		 || !strncmp(id->model, "SunDisk SDCFB", 13)	/* SunDisk */
+		 || !strncmp(id->model, "ATA_FLASH", 9)	/* Simple Tech */
 		 || !strncmp(id->model, "HAGIWARA HPC", 12))	/* Hagiwara */
 		{
 			return 1;	/* yes, it is a flash memory card */
diff -urN linux-2.2.16-pre8/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- linux-2.2.16-pre8/drivers/i2o/i2o_block.c	Mon Dec  3 22:05:04 2001
+++ linux/drivers/i2o/i2o_block.c	Mon Dec  3 22:05:11 2001
@@ -1289,7 +1289,7 @@
 	  * so we just sleep for a little while and let it do it's thing
 	  */
 	 current->state = TASK_INTERRUPTIBLE;
-	 schedule_timeout(3*HZ);
+	 schedule_timeout(5*HZ);
 
 	 if(i2o_claim_device(d, &i2o_block_handler))
 	 {
diff -urN linux-2.2.16-pre8/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c
--- linux-2.2.16-pre8/drivers/i2o/i2o_config.c	Mon Dec  3 22:05:04 2001
+++ linux/drivers/i2o/i2o_config.c	Mon Dec  3 22:05:11 2001
@@ -42,7 +42,8 @@
 static int i2o_cfg_context = -1;
 static void *page_buf;
 static void *i2o_buffer;
-static spinlock_t i2o_config_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t i2o_queue_lock = SPIN_LOCK_UNLOCKED;
+
 struct wait_queue *i2o_wait_queue;
 
 #define MODINC(x,y) (x = x++ % y)
@@ -144,7 +145,7 @@
 				(unsigned char *)(msg + 5),
 				inf->event_q[inf->q_in].data_size);
 
-		spin_lock(&i2o_config_lock);
+		spin_lock(&i2o_queue_lock);
 		MODINC(inf->q_in, I2O_EVT_Q_LEN);
 		if(inf->q_len == I2O_EVT_Q_LEN)
 		{
@@ -156,7 +157,7 @@
 			// Keep I2OEVTGET on another CPU from touching this
 			inf->q_len++;
 		}
-		spin_unlock(&i2o_config_lock);
+		spin_unlock(&i2o_queue_lock);
 		
 
 //		printk(KERN_INFO "File %p w/id %d has %d events\n",
@@ -808,11 +809,12 @@
 
 	memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info));
 	MODINC(p->q_out, I2O_EVT_Q_LEN);
-	spin_lock_irqsave(&i2o_config_lock, flags);
+	spin_lock_irqsave(&i2o_queue_lock, flags);
+	/* FIXME - ought to lock the q_ values here!! */
 	p->q_len--;
 	kget.pending = p->q_len;
 	kget.lost = p->q_lost;
-	spin_unlock_irqrestore(&i2o_config_lock, flags);
+	spin_unlock_irqrestore(&i2o_queue_lock, flags);
 
 	__copy_to_user(uget, &kget, sizeof(struct i2o_evt_get));
 
@@ -838,9 +840,9 @@
 	tmp->q_lost = 0;
 	tmp->next = open_files;
 
-	spin_lock_irqsave(&i2o_config_lock, flags);
+	spin_lock_irqsave(&i2o_queue_lock, flags);
 	open_files = tmp;
-	spin_unlock_irqrestore(&i2o_config_lock, flags);
+	spin_unlock_irqrestore(&i2o_queue_lock, flags);
 	
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -854,7 +856,7 @@
 
 	p1 = p2 = NULL;
 
-	spin_lock_irqsave(&i2o_config_lock, flags);
+	spin_lock_irqsave(&i2o_queue_lock, flags);
 	for(p1 = open_files; p1; )
 	{
 		if(p1->q_id == id)
@@ -873,7 +875,7 @@
 		p2 = p1;
 		p1 = p1->next;
 	}
-	spin_unlock_irqrestore(&i2o_config_lock, flags);
+	spin_unlock_irqrestore(&i2o_queue_lock, flags);
 
 	MOD_DEC_USE_COUNT;
 	return 0;
diff -urN linux-2.2.16-pre8/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c
--- linux-2.2.16-pre8/drivers/i2o/i2o_core.c	Mon Dec  3 22:05:04 2001
+++ linux/drivers/i2o/i2o_core.c	Mon Dec  3 22:05:11 2001
@@ -180,11 +180,11 @@
 #define MODINC(x,y) (x = x++ % y)
 
 /*
- *	I2O configuration spinlock. This isnt a big deal for contention
+ *	I2O configuration semaphore. This isnt a big deal for contention
  *	so we have one only
  */
  
-static spinlock_t i2o_configuration_lock = SPIN_LOCK_UNLOCKED;
+static struct semaphore i2o_configuration_lock = MUTEX;
 
 
 /*
@@ -317,18 +317,18 @@
 int i2o_install_handler(struct i2o_handler *h)
 {
 	int i;
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	for(i=0;i<MAX_I2O_MODULES;i++)
 	{
 		if(i2o_handlers[i]==NULL)
 		{
 			h->context = i;
 			i2o_handlers[i]=h;
-			spin_unlock(&i2o_configuration_lock);
+			up(&i2o_configuration_lock);
 			return 0;
 		}
 	}
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return -ENOSPC;
 }
 
@@ -348,7 +348,7 @@
 {
 	int i;
 
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	d->controller=c;
 	d->owner=NULL;
 	d->next=c->devices;
@@ -358,7 +358,7 @@
 	for(i = 0; i < I2O_MAX_MANAGERS; i++)
 		d->managers[i] = NULL;
 
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return 0;
 }
 
@@ -431,11 +431,11 @@
 {
 	int ret;
 
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 
 	ret = __i2o_delete_device(d);
 
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 
 	return ret;
 }
@@ -447,7 +447,7 @@
 int i2o_install_controller(struct i2o_controller *c)
 {
 	int i;
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	for(i=0;i<MAX_I2O_CONTROLLERS;i++)
 	{
 		if(i2o_controllers[i]==NULL)
@@ -465,13 +465,13 @@
 			   sprintf(c->name, "i2o/iop%d", i);
 			   i2o_num_controllers++;
 			   sema_init(&c->lct_sem, 0);
-			   spin_unlock(&i2o_configuration_lock);
+			   up(&i2o_configuration_lock);
 			   return 0;
 
 		}
 	}
 	printk(KERN_ERR "No free i2o controller slots.\n");
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return -EBUSY;
 }
 
@@ -488,12 +488,12 @@
 	 if(c->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
 		  i2o_event_register(c, core_context, 0, 0, 0);
 
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	if((users=atomic_read(&c->users)))
 	{
 		printk(KERN_INFO "%s busy: %d users for controller.\n", c->name, users);
 		c->bus_disable(c); 
-		spin_unlock(&i2o_configuration_lock);
+		up(&i2o_configuration_lock);
 		return -EBUSY;
 	}
 	while(c->devices)
@@ -502,7 +502,7 @@
 		{
 			/* Shouldnt happen */
 			c->bus_disable(c); 
-			spin_unlock(&i2o_configuration_lock);
+			up(&i2o_configuration_lock);
 			return -EBUSY;
 		}
 	}
@@ -541,7 +541,7 @@
 			c->destructor(c);
 
 			*p=c->next;
-			spin_unlock(&i2o_configuration_lock);
+			up(&i2o_configuration_lock);
 
 			if(c->page_frame)
 				kfree(c->page_frame);
@@ -565,7 +565,7 @@
 		}
 		p=&((*p)->next);
 	}
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	printk(KERN_ERR "i2o_delete_controller: bad pointer!\n");
 	return -ENOENT;
 }
@@ -582,11 +582,11 @@
 	if(n<0 || n>=MAX_I2O_CONTROLLERS)
 		return NULL;
 	
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	c=i2o_controllers[n];
 	if(c!=NULL)
 		atomic_inc(&c->users);
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return c;
 }
 	
@@ -597,23 +597,23 @@
  */
 int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h)
 {
-	 spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 
 	if(d->owner)
 	{
 		printk(KERN_INFO "issue claim called, but dev has owner!");
-		spin_unlock(&i2o_configuration_lock);
+		up(&i2o_configuration_lock);
 		return -EBUSY;
 	}
 
 	if(i2o_issue_claim(d->controller,d->lct_data.tid, h->context, 1, I2O_CLAIM_PRIMARY))
 	{
-		spin_unlock(&i2o_configuration_lock);
+		up(&i2o_configuration_lock);
 		return -EBUSY;
 	}
 
 	d->owner=h;
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return 0;
 }
 
@@ -621,10 +621,10 @@
 {
 	int err = 0;
 
-	spin_lock(&i2o_configuration_lock);
+	down(&i2o_configuration_lock);
 	if(d->owner != h)
 	{
-		spin_unlock(&i2o_configuration_lock);
+		up(&i2o_configuration_lock);
 		return -ENOENT;
 	}
 
@@ -636,7 +636,7 @@
 
 	d->owner = NULL;
 
-	spin_unlock(&i2o_configuration_lock);
+	up(&i2o_configuration_lock);
 	return err;
 }
 
@@ -1178,7 +1178,7 @@
 	u32 *msg;
 	long time;
 
-	printk("begin RESET\n");
+	dprintk(("begin RESET\n"));
 	/* Quiesce all IOPs first */
 
 	for (iop = i2o_controller_chain; iop; iop = iop->next)
@@ -1484,13 +1484,13 @@
 	 * as we can't init the IOPs w/o a system table
 	 */	
 	 
-	printk("SYSTAB\n");
+	dprintk(("SYSTAB\n"));
 	if (i2o_build_sys_table() < 0) {
 		i2o_sys_shutdown();
 		return;
 	}
 
-	printk("ONLINE\n");
+	dprintk(("ONLINE\n"));
 
 	/* If IOP don't get online, we need to rebuild the System table */
 	for (iop = i2o_controller_chain; iop; iop = niop) {
@@ -1499,7 +1499,7 @@
 			goto rebuild_sys_tab;
 	}
 
-	printk("ACTIVE\n");
+	dprintk(("ACTIVE\n"));
 	
 	/* Active IOPs now in OPERATIONAL state
 	 *
@@ -1522,7 +1522,7 @@
 		i2o_event_register(iop, core_context, 0, 0, 0xFFFFFFFF);
 	}
 
-	printk("DONE\n");
+	dprintk(("DONE\n"));
 }
 
 /*
@@ -1548,9 +1548,8 @@
 {
 	/* In INIT state, Wait Inbound Q to initilaize (in i2o_status_get) */
 	/* In READY state, Get status */
-	u32 m;
 
-	printk("ACTIVATE\n");
+	dprintk(("ACTIVATE\n"));
 	
 	if (i2o_status_get(iop) < 0) {
 		printk(KERN_INFO "Unable to obtain status of IOP, attempting a reset.\n");
@@ -1575,42 +1574,30 @@
 	{
 		dprintk((KERN_INFO "%s: already running...trying to reset\n",
 			iop->name));
-		printk("Outbound q2\n");
-
-		if (i2o_init_outbound_q(iop) < 0) {
-			i2o_reset_controller(iop);			
+		dprintk(("Outbound q2\n"));
 
-			if (i2o_status_get(iop) < 0 || 
-				iop->status_block->iop_state != ADAPTER_STATE_RESET)
-			{
-				printk(KERN_CRIT "%s: Failed to initialize.\n", iop->name);
-				i2o_delete_controller(iop);
-				return -1;
-			}
-			if (i2o_init_outbound_q(iop) < 0) {
-				i2o_delete_controller(iop);
-				return -1;
-			}
-		}
-	}
-	else
-	{
-		printk("Outbound q\n");
-
-		if (i2o_init_outbound_q(iop) < 0) {
+		i2o_reset_controller(iop);			
+		if (i2o_status_get(iop) < 0 || iop->status_block->iop_state != ADAPTER_STATE_RESET)
+		{
+			printk(KERN_CRIT "%s: Failed to initialize.\n", iop->name);
 			i2o_delete_controller(iop);
 			return -1;
 		}
 	}
 
+	if (i2o_init_outbound_q(iop) < 0) {
+		i2o_delete_controller(iop);
+		return -1;
+	}
+
 	/* In HOLD state */
-	printk("HRT\n");
+	dprintk("HRT\n");
 	
 	if (i2o_hrt_get(iop) < 0) {
 		i2o_delete_controller(iop);
 		return -1;
 	}
-	printk("DONE\n");
+	dprintk("DONE\n");
 
 	return 0;
 }
@@ -2150,9 +2137,9 @@
 				    {
 		 			if(i2o_handlers[i] && i2o_handlers[i]->new_dev_notify && (i2o_handlers[i]->class&d->lct_data.class_id))
 					{
-						spin_lock(&i2o_dev_lock);
+						spin_lock_irqsave(&i2o_dev_lock, flags);
 						i2o_handlers[i]->new_dev_notify(c,d);
-						spin_unlock(&i2o_dev_lock);
+						spin_unlock_irqrestore(&i2o_dev_lock, flags);
 					}
 				    }
 
@@ -2214,6 +2201,7 @@
 	 void *tmp;
 	 char name[16];
 	 struct fs_struct *fs;
+	 unsigned long flags;
 
 	 lock_kernel();
 
@@ -2283,9 +2271,9 @@
 			   if(!found)
 			   {
 				dprintk((KERN_INFO "Deleted device!\n"));
-				spin_lock(&i2o_dev_lock);
+				spin_lock_irqsave(&i2o_dev_lock,flags);
 				i2o_delete_device(d);
-				spin_unlock(&i2o_dev_lock);
+				spin_unlock_irqrestore(&i2o_dev_lock,flags);
 			   }
 			   d = d1;
 		  }
diff -urN linux-2.2.16-pre8/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- linux-2.2.16-pre8/drivers/net/dgrs.c	Wed May  3 17:16:40 2000
+++ linux/drivers/net/dgrs.c	Mon Dec  3 22:05:11 2001
@@ -4,7 +4,7 @@
  *	The RightSwitch is a 4 (EISA) or 6 (PCI) port etherswitch and
  *	a NIC on an internal board.
  *
- *	Author: Rick Richardson, rick@dgii.com, rick_richardson@dgii.com
+ *	Author: Rick Richardson, rick@remotepoint.com
  *	Derived from the SVR4.2 (UnixWare) driver for the same card.
  *
  *	Copyright 1995-1996 Digi International Inc.
@@ -73,7 +73,7 @@
  *
  */
 
-static char *version = "$Id: dgrs.c,v 1.12 1996/12/21 13:43:58 rick Exp $";
+static char *version = "$Id: dgrs.c,v 1.13 2000/06/06 04:07:00 rick Exp $";
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -209,7 +209,7 @@
         I596_RFD        *rfdp;          /* Current RFD list */
         I596_RBD        *rbdp;          /* Current RBD list */
 
-        int             intrcnt;        /* Count of interrupts */
+        volatile int    intrcnt;        /* Count of interrupts */
 
         /*
          *      SE-4 (EISA) board variables
@@ -1193,7 +1193,7 @@
 	 */
 	if (priv->plxreg)
 		OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1);
-	rc = request_irq(dev->irq, &dgrs_intr, 0, "RightSwitch", dev);
+	rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev);
 	if (rc)
 		return (rc);
 
diff -urN linux-2.2.16-pre8/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- linux-2.2.16-pre8/drivers/net/via-rhine.c	Tue Oct 26 17:53:40 1999
+++ linux/drivers/net/via-rhine.c	Mon Dec  3 22:05:11 2001
@@ -508,7 +508,9 @@
 #ifndef MODULE
 int via_rhine_probe(struct device *dev)
 {
-	printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+	static int did_version = 0;
+	if (!did_version++)
+		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
 	return pci_etherdev_probe(dev, pci_tbl);
 }
 #endif
diff -urN linux-2.2.16-pre8/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- linux-2.2.16-pre8/fs/ncpfs/dir.c	Wed May  3 17:16:46 2000
+++ linux/fs/ncpfs/dir.c	Mon Dec  3 22:05:11 2001
@@ -1018,9 +1018,9 @@
 
 	error = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
 #ifdef CONFIG_NCPFS_STRONG
-	/* 9C is Invalid path.. It should be 8F, 90 - read only, but
-	   it is not :-( */
-	if (error == 0x9C && NCP_SERVER(dir)->m.flags & NCP_MOUNT_STRONG) { /* R/O */
+	/* 9C is Invalid path, used by traditional NW filesystem... 
+	   8F, 90 is Some/All read-only and is used by NSS :-( */
+	if ((error == 0x9C || error == 0x8F || error == 0x90) && NCP_SERVER(dir)->m.flags & NCP_MOUNT_STRONG) { /* R/O */
 		error = ncp_force_unlink(dir, dentry);
 	}
 #endif
@@ -1085,7 +1085,7 @@
 					    old_dir, _old_name,
 					    new_dir, _new_name);
 #ifdef CONFIG_NCPFS_STRONG
-	if ((error == 0x90 || error == -EACCES) && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) {	/* RO */
+	if ((error == 0x90 || error == 0x8B || error == -EACCES) && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) {	/* RO */
 		error = ncp_force_rename(old_dir, old_dentry, _old_name,
                                          new_dir, new_dentry, _new_name);
 	}
diff -urN linux-2.2.16-pre8/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- linux-2.2.16-pre8/fs/ncpfs/inode.c	Wed May  3 17:16:46 2000
+++ linux/fs/ncpfs/inode.c	Mon Dec  3 22:05:11 2001
@@ -105,8 +105,7 @@
 				switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
 					case aHIDDEN:
 						if (server->m.flags & NCP_MOUNT_SYMLINKS) {
-							if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE)
-							 && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+							if (inode->i_size <= NCP_MAX_SYMLINK_SIZE) {
 								inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
 								break;
 							}
@@ -168,8 +167,7 @@
 			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
 				case aHIDDEN:
 					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
-						if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE)
-						 && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+						if (inode->i_size <= NCP_MAX_SYMLINK_SIZE) {
 							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
 							break;
 						}
diff -urN linux-2.2.16-pre8/fs/ufs/inode.c linux/fs/ufs/inode.c
--- linux-2.2.16-pre8/fs/ufs/inode.c	Tue Jan  4 10:12:23 2000
+++ linux/fs/ufs/inode.c	Mon Dec  3 22:05:12 2001
@@ -336,6 +336,7 @@
 			goto repeat;
 		}
 		else {
+			brelse (bh);
 			return NULL;
 		}
 	}		
diff -urN linux-2.2.16-pre8/include/asm-alpha/console.h linux/include/asm-alpha/console.h
--- linux-2.2.16-pre8/include/asm-alpha/console.h	Mon Oct 12 11:40:13 1998
+++ linux/include/asm-alpha/console.h	Mon Dec  3 22:05:12 2001
@@ -22,6 +22,8 @@
 #define CCB_GET_ENV		0x22
 #define CCB_SAVE_ENV		0x23
 
+#define CCB_PSWITCH		0x30
+#define CCB_BIOS_EMUL		0x32
 /*
  * Environment variable numbers
  */
@@ -36,20 +38,33 @@
 #define ENV_BOOT_RESET		0x09
 #define ENV_DUMP_DEV		0x0A
 #define ENV_ENABLE_AUDIT	0x0B
-#define ENV_LICENCE		0x0C
+#define ENV_LICENSE		0x0C
 #define ENV_CHAR_SET		0x0D
 #define ENV_LANGUAGE		0x0E
 #define ENV_TTY_DEV		0x0F
 
+#define NO_SRM_CONSOLE		-1L
+
 #ifdef __KERNEL__
-extern long srm_dispatch(long code, ...);
-extern void srm_puts(const char *);
+#ifndef __ASSEMBLY__
+extern long callback_puts(long unit, const char *s, long length);
+extern long callback_open(const char *device, long length);
+extern long callback_close(long unit);
+extern long callback_read(long channel, long count, const char *buf, long lbn);
+extern long callback_getenv(long id, const char *buf, unsigned long buf_size);
+
+extern int srm_fixup(unsigned long new_callback_addr,
+		      unsigned long new_hwrpb_addr);
+extern long srm_puts(const char *, long len);
 extern long srm_printk(const char *, ...)
 	__attribute__ ((format (printf, 1, 2)));
 
 struct crb_struct;
 struct hwrpb_struct;
-extern long srm_fixup(struct crb_struct *, struct hwrpb_struct *);
+
+extern int callback_init_done;
+extern void * callback_init(void *);
+#endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
 #endif /* __AXP_CONSOLE_H */
diff -urN linux-2.2.16-pre8/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h
--- linux-2.2.16-pre8/include/asm-alpha/core_tsunami.h	Wed May  3 17:16:47 2000
+++ linux/include/asm-alpha/core_tsunami.h	Mon Dec  3 22:05:12 2001
@@ -80,6 +80,7 @@
 	tsunami_64	mpr2;
 	tsunami_64	mpr3;
 	tsunami_64	mctl;
+	tsunami_64	__pad1;
 	tsunami_64	ttr;
 	tsunami_64	tdr;
 	tsunami_64	dim2;
diff -urN linux-2.2.16-pre8/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h
--- linux-2.2.16-pre8/include/asm-alpha/hwrpb.h	Wed May  3 17:16:47 2000
+++ linux/include/asm-alpha/hwrpb.h	Mon Dec  3 22:05:12 2001
@@ -190,6 +190,8 @@
 	unsigned long dsr_offset;	/* "Dynamic System Recognition Data Block Table" */
 };
 
+#define HWRPB_MEMBER_ID(v)	(((v) >> 10) & 0x3f)
+
 #ifdef __KERNEL__
 
 extern struct hwrpb_struct *hwrpb;
diff -urN linux-2.2.16-pre8/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- linux-2.2.16-pre8/include/asm-alpha/pgtable.h	Wed May  3 17:16:47 2000
+++ linux/include/asm-alpha/pgtable.h	Mon Dec  3 22:05:12 2001
@@ -9,6 +9,7 @@
  * in <asm/page.h> (currently 8192).
  */
 #include <linux/config.h>
+#include <linux/mm.h>
 
 #include <asm/system.h>
 #include <asm/processor.h>	/* For TASK_SIZE */
@@ -219,7 +220,8 @@
 /* Number of pointers that fit on a page:  this will go away. */
 #define PTRS_PER_PAGE	(1UL << (PAGE_SHIFT-3))
 
-#define VMALLOC_START		0xFFFFFE0000000000
+#define CONSOLE_REMAP_START	0xFFFFFE0000000000
+#define VMALLOC_START		(CONSOLE_REMAP_START + PMD_SIZE)
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
 #define VMALLOC_END		(~0UL)
 
diff -urN linux-2.2.16-pre8/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- linux-2.2.16-pre8/include/asm-alpha/system.h	Tue Jan  4 10:12:24 2000
+++ linux/include/asm-alpha/system.h	Mon Dec  3 22:05:12 2001
@@ -137,6 +137,9 @@
 #define draina() \
 __asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory")
 
+#define __halt() \
+__asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
+
 enum implver_enum {
 	IMPLVER_EV4,
 	IMPLVER_EV5,
diff -urN linux-2.2.16-pre8/include/asm-alpha/uaccess.h linux/include/asm-alpha/uaccess.h
--- linux-2.2.16-pre8/include/asm-alpha/uaccess.h	Tue Oct 26 17:53:42 1999
+++ linux/include/asm-alpha/uaccess.h	Mon Dec  3 22:05:12 2001
@@ -530,7 +530,7 @@
 };
 
 /* Returns 0 if exception not found and fixup.unit otherwise.  */
-extern unsigned search_exception_table(unsigned long);
+extern unsigned search_exception_table(unsigned long, unsigned long);
 
 /* Returns the new pc */
 #define fixup_exception(map_reg, fixup_unit, pc)		\
